diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js index 1e6d936a..9a18f1ab 100644 --- a/embark-ui/src/actions/index.js +++ b/embark-ui/src/actions/index.js @@ -13,6 +13,13 @@ function action(type, payload = {}) { return {type, ...payload}; } +export const AUTHENTICATE = createRequestTypes('AUTHENTICATE'); +export const authenticate = { + request: (token) => action(AUTHENTICATE[REQUEST], {token}), + success: () => action(AUTHENTICATE[SUCCESS]), + failure: (error) => action(AUTHENTICATE[FAILURE], {error}) +}; + export const ACCOUNTS = createRequestTypes('ACCOUNTS'); export const accounts = { request: () => action(ACCOUNTS[REQUEST]), diff --git a/embark-ui/src/containers/AppContainer.js b/embark-ui/src/containers/AppContainer.js index 45312588..5a083088 100644 --- a/embark-ui/src/containers/AppContainer.js +++ b/embark-ui/src/containers/AppContainer.js @@ -9,6 +9,7 @@ import routes from '../routes'; import { initBlockHeader, + authenticate, processes as processesAction, versions as versionsAction, plugins as pluginsAction @@ -16,6 +17,7 @@ import { class AppContainer extends Component { componentDidMount() { + this.props.authenticate('Test'); this.props.initBlockHeader(); this.props.fetchProcesses(); this.props.fetchVersions(); @@ -34,6 +36,7 @@ class AppContainer extends Component { } AppContainer.propTypes = { + authenticate: PropTypes.func, initBlockHeader: PropTypes.func, fetchProcesses: PropTypes.func, fetchPlugins: PropTypes.func, @@ -44,8 +47,8 @@ export default connect( null, { initBlockHeader, + authenticate: authenticate.request, fetchProcesses: processesAction.request, - fetchVersions: versionsAction.request, fetchPlugins: pluginsAction.request }, diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index 07eaab57..f0b860b2 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -39,6 +39,7 @@ export const fetchFile = doRequest.bind(null, actions.file, api.fetchFile); export const postFile = doRequest.bind(null, actions.saveFile, api.postFile); export const deleteFile = doRequest.bind(null, actions.removeFile, api.deleteFile); export const fetchEthGas = doRequest.bind(null, actions.gasOracle, api.getEthGasAPI); +export const authenticate = doRequest.bind(null, actions.authenticate, api.authenticate); export const fetchCurrentFile = doRequest.bind(null, actions.currentFile, storage.fetchCurrentFile); export const postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile); @@ -170,6 +171,10 @@ export function *watchFetchEthGas() { yield takeEvery(actions.GAS_ORACLE[actions.REQUEST], fetchEthGas); } +export function *watchAuthenticate() { + yield takeEvery(actions.AUTHENTICATE[actions.REQUEST], authenticate); +} + function createChannel(socket) { return eventChannel(emit => { socket.onmessage = ((message) => { @@ -279,6 +284,7 @@ export default function *root() { fork(watchFetchCurrentFile), fork(watchPostCurrentFile), fork(watchFetchEthGas), + fork(watchAuthenticate), fork(watchListenGasOracle) ]); } diff --git a/embark-ui/src/services/api.js b/embark-ui/src/services/api.js index fd0d5944..d6ac5ba4 100644 --- a/embark-ui/src/services/api.js +++ b/embark-ui/src/services/api.js @@ -138,6 +138,10 @@ export function deleteFile(payload) { return destroy('/file', {params: payload}); } +export function authenticate(payload) { + return post('/authenticate', payload); +} + export function listenToChannel(channel) { return new WebSocket(`${constants.wsEndpoint}/communication/listenTo/${channel}`); } diff --git a/lib/core/engine.js b/lib/core/engine.js index 6bb16af1..cbbedec8 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -230,6 +230,7 @@ class Engine { webServerService() { this.registerModule('webserver', {plugins: this.plugins}); + this.registerModule('authenticator'); } storageService(_options) { diff --git a/lib/modules/authenticator/index.js b/lib/modules/authenticator/index.js new file mode 100644 index 00000000..e46e1026 --- /dev/null +++ b/lib/modules/authenticator/index.js @@ -0,0 +1,30 @@ +const uuid = require('uuid/v1'); + +class Authenticator { + + constructor(embark, _options) { + this.authToken = uuid(); + + + embark.events.on('outputDone', () => { + embark.logger.info(__('Access the web backend with the following url: %s', + ('http://localhost:8000/embark/' + this.authToken).underline)); + }); + + embark.registerAPICall( + 'post', + '/embark-api/authenticate', + (req, res) => { + if (req.body.token !== this.authToken) { + embark.logger.warn(__('Someone tried and failed to authenticate to the backend')); + embark.logger.warn(__('- User-Agent: %s', req.headers['user-agent'])); + embark.logger.warn(__('- Referer: %s', req.headers.referer)); + return res.status(403).send({error: __('Wrong authentication token')}); + } + res.send(); + } + ); + } +} + +module.exports = Authenticator;