Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ const ui = new UI(); // initialize the UI
app
.version(require('./package.json').version, '-V, --version')
.option('-v, --verbose', 'shows you every single step')
.option('-m, --mute', 'shows only the results of the analysis');
.option('-u, --audit', 'displays recommandations for further auditing')
.option('-z, --nfz', 'displays informations related to website report operating procedure, AKA NF Z67-147 in France.')
.option('-m, --mute', 'shows only the results of the analysis')

app
.command('scan [url]')
Expand All @@ -25,6 +27,7 @@ app
.option('-a, --analytics', 'checks for Google Analytics & Piwik')
.option('-t, --tracking', 'checks for Social Media tracking & embeds')
.option('-c, --cdn', 'checks for Content Delivery Networks')
.option('-k, --cookies [expiration delay, in month]', 'checks for cookies lifetime (< 13 month by defaut)', false)
//.option('-r, --recursive', 'tries to follow links to check every internal site', false)
.action((url, args) => {
// Error Handling
Expand All @@ -46,9 +49,12 @@ app
if (args.parent.mute) ui.set('silent');

// initialize the task runner
const tasks = new Tasks(url, ui);
const tasks = new Tasks(url, ui, args);

if (args.parent.audit) tasks.new('audit');
if (args.parent.nfz) tasks.new('nfz');
if (args.ssl) tasks.new('ssl');
if (args.cookies) tasks.new('cookies');
if (args.fonts) tasks.new('fonts');
if (args.prefetching) tasks.new('prefetching');
if (args.analytics) tasks.new('analytics');
Expand All @@ -72,4 +78,4 @@ app

app.parse(process.argv);

//if (!app.args.length) app.help();
//if (!app.args.length) app.help();
128 changes: 128 additions & 0 deletions lib/cookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*!
* cookies (adaptated from server-side cookies from https://github.com/pillarjs/cookies)
* Copyright(c) 2014 Jed Schmidt, http://jed.is/
* Copyright(c) 2015-2016 Douglas Christopher Wilson
* Copyright(c) 2018 Baptiste LARVOL-SIMON, http://www.e-glop.net/
* MIT Licensed
*/

'use strict'

var deprecate = require('depd')('cookies')
var Keygrip = require('keygrip')
var cache = {}

/**
* RegExp to match field-content in RFC 7230 sec 3.2
*
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
* field-vchar = VCHAR / obs-text
* obs-text = %x80-FF
*/

var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;

/**
* RegExp to match Same-Site cookie attribute value.
*/

var sameSiteRegExp = /^(?:lax|strict)$/i

function Cookies(response){
this.response = response;
}

/**
* @return Array
**/
Cookies.prototype.fetchAll = function() {
var header, cookies = [];

header = this.response.headers["set-cookie"];
if (!header) return [];

header.forEach(cook => {
var name,
attrs = [],
data = cook.split(/\\{0}; /)

name = data.shift().split('=');
data.forEach(attr => {
var dat = attr.split('=');
attrs[dat[0]] = dat[1];
});

cookies.push(new Cookie(name[0], name[1], attrs));
});

return cookies;
}

function Cookie(name, value, attrs) {
if (!fieldContentRegExp.test(name)) {
throw new TypeError('argument name is invalid');
}

if (value && !fieldContentRegExp.test(value)) {
throw new TypeError('argument value is invalid');
}

value || (this.expires = new Date(0))

this.name = name
this.value = value || ""

for (var name in attrs) {
switch ( name ) {
case 'secure':
this[name] = true;
break;
case 'expires':
this[name] = new Date(attrs[name]);
break;
default:
this[name] = attrs[name];
}
}

if (this.path && !fieldContentRegExp.test(this.path)) {
throw new TypeError('option path is invalid');
}

if (this.domain && !fieldContentRegExp.test(this.domain)) {
throw new TypeError('option domain is invalid');
}

if (this.sameSite && this.sameSite !== true && !sameSiteRegExp.test(this.sameSite)) {
throw new TypeError('option sameSite is invalid')
}
}

Cookie.prototype.path = "/";
Cookie.prototype.expires = undefined;
Cookie.prototype.domain = undefined;
Cookie.prototype.httpOnly = true;
Cookie.prototype.sameSite = false;
Cookie.prototype.secure = false;
Cookie.prototype.overwrite = false;

// back-compat so maxage mirrors maxAge
Object.defineProperty(Cookie.prototype, 'maxage', {
configurable: true,
enumerable: true,
get: function () { return this.maxAge },
set: function (val) { return this.maxAge = val }
});
deprecate.property(Cookie.prototype, 'maxage', '"maxage"; use "maxAge" instead')

function getPattern(name) {
if (cache[name]) return cache[name]

return cache[name] = new RegExp(
"(?:^|;) *" +
name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") +
"=([^;]*)"
)
}

module.exports = Cookies
39 changes: 39 additions & 0 deletions lib/recommendation-collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* recommendation-collection
* Copyright(c) 2018 Baptiste LARVOL-SIMON, http://www.e-glop.net/
* MIT Licensed
*/

'use strict'

function RecommendationCollection(){
}

RecommendationCollection.prototype.collection = {};

/**
* @return void
**/
RecommendationCollection.prototype.add = function(key, value) {
if ( !Array.isArray(this.collection[key]) ) {
this.collection[key] = []
}

this.collection[key].push(value);
}

/**
* @return Array
**/
RecommendationCollection.prototype.getTopics = function() {
return Object.keys(this.collection);
}

/**
* @return Array
**/
RecommendationCollection.prototype.getWarningsFor = function(key) {
return this.collection[key];
}

module.exports = RecommendationCollection;
Loading