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" )
2018-10-16 16:48:51 +00:00
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
2018-10-16 16:48:51 +00:00
generateRequestHash ( req ) {
let cnonce = req . headers [ 'x-embark-cnonce' ] ;
let hash = new keccak ( ) ;
hash . update ( cnonce ) ;
hash . update ( this . authToken ) ;
hash . update ( req . method ) ;
hash . update ( req . url ) ;
return hash . digest ( 'hex' ) ;
}
2018-09-06 17:33:15 +00:00
registerCalls ( ) {
2018-10-16 16:48:51 +00:00
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 ) => {
2018-10-16 16:48:51 +00:00
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 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 ( ) {
2018-10-16 16:48:51 +00:00
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
} ) ;
2018-10-17 16:26:53 +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
}
2018-10-17 16:26:53 +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 ;