init
This commit is contained in:
commit
a75e5e12a9
|
@ -0,0 +1,2 @@
|
||||||
|
login
|
||||||
|
node_modules/
|
|
@ -0,0 +1,290 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Crawler = require("crawler");
|
||||||
|
var path = require('path');
|
||||||
|
var output = new(require('./src/console/output'));
|
||||||
|
var input = new(require('./src/console/input'))(process);
|
||||||
|
var pregMatch = require('./src/preg-match');
|
||||||
|
var logger = require('./src/logger.js');
|
||||||
|
var cookieBag = new(require('./src/cookie-bag.js'));
|
||||||
|
|
||||||
|
process.chdir(path.dirname(input.script));
|
||||||
|
|
||||||
|
var isDebugMode = input.has('debug');
|
||||||
|
|
||||||
|
if (!isDebugMode) {
|
||||||
|
process.on('uncaughtException', function() {
|
||||||
|
output.json({
|
||||||
|
error: true,
|
||||||
|
message: 'UncaughtException'
|
||||||
|
});
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.has('help')) {
|
||||||
|
output.write([
|
||||||
|
process.argv[0],
|
||||||
|
process.argv[1],
|
||||||
|
'[--crawler-debug]',
|
||||||
|
'[--crawler-info]',
|
||||||
|
'[--crawler-error]',
|
||||||
|
].join(' '));
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var handlerCrawlerError = function(response, e) {
|
||||||
|
output.json({
|
||||||
|
error: true,
|
||||||
|
message: {
|
||||||
|
body: response.body,
|
||||||
|
response: response,
|
||||||
|
error: e,
|
||||||
|
},
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var handlerCrawlerException = function(e, done) {
|
||||||
|
if (isDebugMode) {
|
||||||
|
throw e;
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
|
||||||
|
return output.json({
|
||||||
|
error: true,
|
||||||
|
message: e
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var headers = function(crawler) {
|
||||||
|
var datas = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
|
||||||
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||||
|
'Accept-Language': 'fr,fr-FR;q=0.5',
|
||||||
|
'Cookie': cookieBag.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (crawler.storage.hasOwnProperty('referer')) {
|
||||||
|
datas['referer'] = crawler.storage.referer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return datas;
|
||||||
|
}
|
||||||
|
|
||||||
|
var createCrawlerOptions = function(config) {
|
||||||
|
var options = {
|
||||||
|
maxConnections: 10,
|
||||||
|
retries: 1,
|
||||||
|
logger: logger,
|
||||||
|
jQuery: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
config = config || {};
|
||||||
|
|
||||||
|
for (var i in config) {
|
||||||
|
options[i] = config[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
var createCrawler = function(options) {
|
||||||
|
options = createCrawlerOptions(options || {});
|
||||||
|
|
||||||
|
if (!options.hasOwnProperty('callback') && options.hasOwnProperty('onSuccess')) {
|
||||||
|
options.callback = function(error, response, done) {
|
||||||
|
if (error) {
|
||||||
|
handlerCrawlerError(response, error);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
options.onSuccess(response, done);
|
||||||
|
} catch (e) {
|
||||||
|
return handlerCrawlerException(e, done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = new Crawler(options);
|
||||||
|
|
||||||
|
c.storage = {};
|
||||||
|
|
||||||
|
c.runCrawl = function(url) {
|
||||||
|
c.options.headers = headers(c);
|
||||||
|
|
||||||
|
return c.queue(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var UrlRefreshRequester = createCrawler({
|
||||||
|
onSuccess: function(response) {
|
||||||
|
cookieBag.handleResponse(response);
|
||||||
|
|
||||||
|
var urlRefresh = pregMatch(/"urlRefresh":"([^"]+)"/, response.body)[1];
|
||||||
|
|
||||||
|
LoginFormRequester.runCrawl(urlRefresh);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var LoginFormRequester = createCrawler({
|
||||||
|
onSuccess: function(response) {
|
||||||
|
cookieBag.handleResponse(response);
|
||||||
|
|
||||||
|
var urlPost = pregMatch(/"urlPost":"([^"]+)"/, response.body)[1];
|
||||||
|
var urlLogin = pregMatch(/"urlLogin":"([^"]+)"/, response.body)[1];
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
canary: pregMatch(/"canary":"([^"]+)"/, response.body)[1],
|
||||||
|
ctx: pregMatch(/ctx=(.+)/, urlLogin)[1],
|
||||||
|
hpgrequestid: pregMatch(/"sessionId":"([^"]+)"/, response.body)[1],
|
||||||
|
flowToken: pregMatch(/"sFT":"([^"]+)"/, response.body)[1],
|
||||||
|
f1: 'Suivant',
|
||||||
|
NewUser: 1,
|
||||||
|
CookieDisclosure: 1,
|
||||||
|
fspost: 0,
|
||||||
|
IsFidoSupported: 0,
|
||||||
|
FoundMSAs: null,
|
||||||
|
i2: 1,
|
||||||
|
i13: 0,
|
||||||
|
i17: '',
|
||||||
|
i18: '',
|
||||||
|
i19: 19471,
|
||||||
|
ps: 2,
|
||||||
|
psRNGCDefaultType: '',
|
||||||
|
psRNGCEntropy: '',
|
||||||
|
psRNGCSLK: '',
|
||||||
|
PPSX: '',
|
||||||
|
FoundMSAs: '',
|
||||||
|
type: 11,
|
||||||
|
LoginOptions: 3,
|
||||||
|
Irt: '',
|
||||||
|
IrtPartition: '',
|
||||||
|
hisRegion: '',
|
||||||
|
hisScaleUnit: '',
|
||||||
|
loginfmt: process.env.MS_OFFICE365_LOGIN,
|
||||||
|
login: process.env.MS_OFFICE365_LOGIN,
|
||||||
|
passwd: process.env.MS_OFFICE365_PASSWORD,
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginRequester.options.form = data;
|
||||||
|
|
||||||
|
LoginRequester.runCrawl('https://login.microsoftonline.com' + urlPost)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var LoginRequester = createCrawler({
|
||||||
|
method: 'POST',
|
||||||
|
onSuccess: function(response) {
|
||||||
|
cookieBag.handleResponse(response);
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
canary: pregMatch(/"canary":"([^"]+)"/, response.body)[1],
|
||||||
|
ctx: pregMatch(/"sCtx":"([^"]+)"/, response.body)[1],
|
||||||
|
hpgrequestid: pregMatch(/"sessionId":"([^"]+)"/, response.body)[1],
|
||||||
|
flowToken: pregMatch(/"sFT":"([^"]+)"/, response.body)[1],
|
||||||
|
LoginOptions: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
KmsiRequester.options.form = data;
|
||||||
|
|
||||||
|
KmsiRequester.runCrawl('https://login.microsoftonline.com/kmsi');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var KmsiRequester = createCrawler({
|
||||||
|
method: 'POST',
|
||||||
|
jQuery: true,
|
||||||
|
onSuccess: function(response) {
|
||||||
|
cookieBag.handleResponse(response);
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
code: response.$('[name="code"]').val(),
|
||||||
|
id_token: response.$('[name="id_token"]').val(),
|
||||||
|
session_state: response.$('[name="session_state"]').val(),
|
||||||
|
correlation_id: response.$('[name="correlation_id"]').val(),
|
||||||
|
};
|
||||||
|
|
||||||
|
SiteRequester.options.form = data;
|
||||||
|
SiteRequester.storage.referer = 'https://login.microsoftonline.com/kmsi';
|
||||||
|
SiteRequester.runCrawl(process.env.MS_OFFICE365_SITE + '_forms/default.aspx');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var SiteRequester = createCrawler({
|
||||||
|
method: 'POST',
|
||||||
|
jQuery: true,
|
||||||
|
onSuccess: function(response, done) {
|
||||||
|
cookieBag.handleResponse(response);
|
||||||
|
|
||||||
|
if (SiteRequester.storage.hasOwnProperty('finish')) {
|
||||||
|
output.json({
|
||||||
|
rtFa: cookieBag.get('rtFa'),
|
||||||
|
FedAuth: cookieBag.get('FedAuth'),
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SiteRequester.storage.hasOwnProperty('kmsi')) {
|
||||||
|
delete SiteRequester.storage.kmsi;
|
||||||
|
|
||||||
|
SiteRequester.storage.finish = true;
|
||||||
|
|
||||||
|
return KmsiRequester.options.onSuccess(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.headers.hasOwnProperty('location')) {
|
||||||
|
SiteRequester.options.method = 'GET';
|
||||||
|
|
||||||
|
var location = response.headers.location;
|
||||||
|
|
||||||
|
SiteRequester.runCrawl(location);
|
||||||
|
} else {
|
||||||
|
var urlPost = response.$('form').attr('action');
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
code: response.$('[name="code"]').val(),
|
||||||
|
id_token: response.$('[name="id_token"]').val(),
|
||||||
|
session_state: response.$('[name="session_state"]').val(),
|
||||||
|
correlation_id: response.$('[name="correlation_id"]').val(),
|
||||||
|
};
|
||||||
|
|
||||||
|
var params = urlPost.split('?')[1].split('&');
|
||||||
|
|
||||||
|
params.forEach(function(param) {
|
||||||
|
var name = pregMatch(/([a-zA-Z0-9_-]+)=/, param)[1];
|
||||||
|
var value = pregMatch(/=(.+)/, param)[1];
|
||||||
|
|
||||||
|
data[name] = decodeURIComponent(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
SiteRequester.options.method = 'POST';
|
||||||
|
SiteRequester.options.form = data;
|
||||||
|
SiteRequester.storage.referer = 'https://login.microsoftonline.com/kmsi';
|
||||||
|
SiteRequester.storage.kmsi = true;
|
||||||
|
SiteRequester.runCrawl(urlPost);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
UrlRefreshRequester.runCrawl(process.env.MS_OFFICE365_SITE);
|
||||||
|
} catch (e) {
|
||||||
|
if (isDebugMode) {
|
||||||
|
throw e;
|
||||||
|
} else {
|
||||||
|
output.json({
|
||||||
|
error: true,
|
||||||
|
message: e
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "sharepoint-webdav-oauth2-bot",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "sharepoint-webdav-oauth2-bot",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Simon Vieille <simon@deblan.fr>",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"class.extend": "^0.9.2",
|
||||||
|
"crawler": "^1.1.2",
|
||||||
|
"minimist": "^1.2.0",
|
||||||
|
"trim": "0.0.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Minimist = require('minimist');
|
||||||
|
var Class = require('class.extend');
|
||||||
|
|
||||||
|
var Input = Class.extend('Input', {
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param object process
|
||||||
|
*/
|
||||||
|
init: function(process) {
|
||||||
|
this.args = Minimist(process.argv.slice(2));
|
||||||
|
this.node = process.argv[0];
|
||||||
|
this.script = process.argv[1];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the given name argument.
|
||||||
|
*
|
||||||
|
* @param string name
|
||||||
|
* @param mixed default
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
get: function(name, defaultValue) {
|
||||||
|
if (this.has(name)) {
|
||||||
|
return this.args[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultValue !== undefined) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the given argument name exists.
|
||||||
|
*
|
||||||
|
* @param string name
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
has: function(name) {
|
||||||
|
return this.args.hasOwnProperty(name);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if args is empty.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
empty: function() {
|
||||||
|
return Object.keys(this.args).length === 1;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = Input;
|
|
@ -0,0 +1,37 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Class = require('class.extend');
|
||||||
|
|
||||||
|
var Output = Class.extend('Output', {
|
||||||
|
/**
|
||||||
|
* Convert and print data to json.
|
||||||
|
*
|
||||||
|
* @param mixed data
|
||||||
|
*/
|
||||||
|
json: function(data, pretty) {
|
||||||
|
data = JSON.stringify(
|
||||||
|
data,
|
||||||
|
function(key, value) {
|
||||||
|
if (value === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
pretty ? 2 : null
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.write(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print data.
|
||||||
|
*
|
||||||
|
* @param mixed data
|
||||||
|
*/
|
||||||
|
write: function(data) {
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = Output;
|
|
@ -0,0 +1,53 @@
|
||||||
|
var trim = require('trim');
|
||||||
|
|
||||||
|
var CookieBag = function() {
|
||||||
|
this.bag = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieBag.prototype.add = function(name, value) {
|
||||||
|
this.bag[name] = name + '=' + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieBag.prototype.get = function(name) {
|
||||||
|
var str = this.bag[name] || null;
|
||||||
|
|
||||||
|
if (!str) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = str.indexOf('=');
|
||||||
|
|
||||||
|
return str.substr(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieBag.prototype.toString = function() {
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
for (var i in this.bag) {
|
||||||
|
data.push(this.bag[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.join('; ');
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieBag.prototype.handleResponse = function(response) {
|
||||||
|
var headers = response.headers || {};
|
||||||
|
var cookies = headers['set-cookie'] || [];
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
cookies.forEach(function(cookie) {
|
||||||
|
var def = cookie.split(';')[0];
|
||||||
|
var index = def.indexOf('=');
|
||||||
|
|
||||||
|
var name = def.substr(0, index);
|
||||||
|
var value = def.substr(index + 1);
|
||||||
|
|
||||||
|
that.add(name, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieBag.prototype.clean = function() {
|
||||||
|
this.bag = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CookieBag;
|
|
@ -0,0 +1,26 @@
|
||||||
|
var output = new(require('./console/output'));
|
||||||
|
var input = new(require('./console/input'))(process);
|
||||||
|
|
||||||
|
var logCrawlerDebug = input.has('crawler-debug');
|
||||||
|
var logCrawlerInfo = input.has('crawler-info');
|
||||||
|
var logCrawlerError = input.has('crawler-error');
|
||||||
|
|
||||||
|
var writeLog = function(level, message) {
|
||||||
|
return output.write('[' + level.toUpperCase() + '] ' + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
log: function(level, message) {
|
||||||
|
if (level === 'debug' && logCrawlerDebug) {
|
||||||
|
return writeLog(level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level === 'info' && logCrawlerInfo) {
|
||||||
|
return writeLog(level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level === 'error' && logCrawlerError) {
|
||||||
|
return writeLog(level, message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
var pregMatch = function(regex, content) {
|
||||||
|
return content.match(regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = pregMatch;
|
Reference in New Issue