embark/lib/modules/authenticator/index.js

96 lines
2.8 KiB
JavaScript
Raw Normal View History

2018-09-06 15:30:06 +00:00
const uuid = require('uuid/v1');
2018-10-13 00:46:53 +00:00
const utils = require("../../utils/utils.js")
const keccak = require('keccakjs');
2018-09-06 15:30:06 +00:00
2018-09-06 20:06:07 +00:00
const ERROR_OBJ = {error: __('Wrong authentication token. Get your token from the Embark console by typing `token`')};
2018-09-06 15:30:06 +00:00
2018-09-06 20:06:07 +00:00
class Authenticator {
2018-09-06 15:30:06 +00:00
constructor(embark, _options) {
this.authToken = uuid();
2018-09-06 17:33:15 +00:00
this.embark = embark;
this.logger = embark.logger;
2018-09-06 20:06:07 +00:00
this.events = embark.events;
2018-09-06 15:30:06 +00:00
2018-09-06 17:33:15 +00:00
this.registerCalls();
2018-09-06 20:06:07 +00:00
this.registerEvents();
2018-09-06 17:33:15 +00:00
}
2018-09-06 15:30:06 +00:00
generateRequestHash(req) {
let cnonce = req.headers['x-embark-cnonce'];
let hash = new keccak();
let url = req.url;
let queryParamIndex = url.indexOf('?');
url = url.substring(0, queryParamIndex !== -1 ? queryParamIndex : url.length)
hash.update(cnonce);
hash.update(this.authToken);
hash.update(req.method);
hash.update(url);
return hash.digest('hex');
}
2018-09-06 17:33:15 +00:00
registerCalls() {
let self = this;
2018-09-06 17:33:15 +00:00
this.embark.registerAPICall(
2018-09-06 15:30:06 +00:00
'post',
2018-09-19 14:59:01 +00:00
'/embark-api/authenticate',
2018-09-06 15:30:06 +00:00
(req, res) => {
let hash = self.generateRequestHash(req);
if(hash !== req.headers['x-embark-request-hash']) {
2018-09-19 14:59:01 +00:00
this.logger.warn(__('Someone tried and failed to authenticate to the backend'));
2018-09-06 17:33:15 +00:00
this.logger.warn(__('- User-Agent: %s', req.headers['user-agent']));
this.logger.warn(__('- Referer: %s', req.headers.referer));
2018-09-06 20:06:07 +00:00
return res.send(ERROR_OBJ);
2018-09-06 15:30:06 +00:00
}
res.send({});
2018-09-06 15:30:06 +00:00
}
);
2018-09-06 17:33:15 +00:00
this.embark.registerConsoleCommand((cmd, _options) => {
return {
match: () => cmd === "token",
process: (callback) => {
2018-10-13 00:50:56 +00:00
callback(null, __('Your authentication token: %s \nYou can use the command `copytoken` to copy the authentication token to your clipboard', this.authToken));
2018-09-06 17:33:15 +00:00
}
};
});
2018-10-13 00:46:53 +00:00
this.embark.registerConsoleCommand((cmd, _options) => {
return {
match: () => cmd === "copytoken",
process: (callback) => {
utils.copyToClipboard(this.authToken)
callback(null, __('Token copied to clipboard: %s', this.authToken));
}
};
});
2018-09-06 15:30:06 +00:00
}
2018-09-06 20:06:07 +00:00
registerEvents() {
let self = this;
2018-09-06 20:06:07 +00:00
this.events.once('outputDone', () => {
2018-09-07 14:46:51 +00:00
const {port, host} = this.embark.config.webServerConfig;
2018-09-06 20:06:07 +00:00
this.logger.info(__('Access the web backend with the following url: %s',
2018-09-07 14:46:51 +00:00
(`http://${host}:${port}/embark?token=${this.authToken}`.underline)));
2018-09-06 20:06:07 +00:00
});
this.events.setCommandHandler('authenticator:authorize', (req, res, cb) => {
let authenticated = false;
if(!res.send) {
authenticated = (this.authToken === req.protocol);
} else {
let hash = self.generateRequestHash(req);
authenticated = (hash === req.headers['x-embark-request-hash']);
2018-09-06 20:06:07 +00:00
}
if(authenticated) return cb();
cb(ERROR_OBJ);
2018-09-06 20:06:07 +00:00
});
}
2018-09-06 15:30:06 +00:00
}
module.exports = Authenticator;