diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index be4eec28..64660f4e 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -1,17 +1,16 @@ const axios = require('axios') const _ = require('lodash/fp') -const hkdf = require('futoin-hkdf') const pify = require('pify') const fs = pify(require('fs')) const db = require('../db') -const mnemonicHelpers = require('../mnemonic-helpers') const configManager = require('../new-config-manager') const complianceTriggers = require('../compliance-triggers') const options = require('../options') const logger = require('../logger') const plugins = require('../plugins') +const { getOperatorId } = require('../operator') const TIMEOUT = 10000 const MAX_CONTENT_LENGTH = 2000 @@ -133,10 +132,10 @@ function sendRadar (data) { function mapRecord (rates, settings) { const timestamp = new Date().toISOString() - return Promise.all([getMachines(rates, settings), fs.readFile(options.mnemonicPath, 'utf8')]) - .then(([machines, mnemonic]) => { + return Promise.all([getMachines(rates, settings), getOperatorId('coinatmradar')]) + .then(([machines, operatorId]) => { return { - operatorId: computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)), + operatorId: operatorId, operator: { name: null, phone: null, @@ -157,7 +156,3 @@ function update (rates, settings) { .then(sendRadar) .catch(err => logger.error(`Failure to update CoinATMRadar`, err)) } - -function computeOperatorId (masterSeed) { - return hkdf(masterSeed, 16, { salt: 'lamassu-server-salt', info: 'operator-id' }).toString('hex') -} diff --git a/lib/middlewares/operatorId.js b/lib/middlewares/operatorId.js index 0dceb527..eeb7d6ac 100644 --- a/lib/middlewares/operatorId.js +++ b/lib/middlewares/operatorId.js @@ -1,34 +1,15 @@ -const pify = require('pify') -const fs = pify(require('fs')) -const hkdf = require('futoin-hkdf') - -const state = require('./state') -const mnemonicHelpers = require('../mnemonic-helpers') -const options = require('../options') -const logger = require('../logger') - -function computeOperatorId (masterSeed) { - return hkdf(masterSeed, 16, { salt: 'lamassu-server-salt', info: 'operator-id' }).toString('hex') -} - -function getMnemonic () { - if (state.mnemonic) return Promise.resolve(state.mnemonic) - return fs.readFile(options.mnemonicPath, 'utf8').then(mnemonic => { - state.mnemonic = mnemonic - return mnemonic - }) -} +const { getOperatorId } = require('../operator') function findOperatorId (req, res, next) { - return getMnemonic().then(mnemonic => { - return computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)) - }).then(id => { - res.locals.operatorId = id - return next() - }).catch(e => { - logger.error('Error while computing operator id\n' + e) - next(e) - }) + return getOperatorId('middleware') + .then(({ operatorId }) => { + res.locals.operatorId = operatorId + return next() + }) + .catch(e => { + console.error('Error while computing operator id\n' + e) + next(e) + }) } module.exports = findOperatorId diff --git a/lib/new-admin/middlewares/session.js b/lib/new-admin/middlewares/session.js index fbdf4465..41fc31a0 100644 --- a/lib/new-admin/middlewares/session.js +++ b/lib/new-admin/middlewares/session.js @@ -1,32 +1,21 @@ -const fs = require('fs') const express = require('express') const router = express.Router() -const hkdf = require('futoin-hkdf') const session = require('express-session') const PgSession = require('connect-pg-simple')(session) -const mnemonicHelpers = require('../../mnemonic-helpers') const db = require('../../db') const options = require('../../options') const { USER_SESSIONS_TABLE_NAME } = require('../../constants') - -const getSecret = () => { - const mnemonic = fs.readFileSync(options.mnemonicPath, 'utf8') - return hkdf( - mnemonicHelpers.toEntropyBuffer(mnemonic), - 16, - { info: 'operator-id' } - ).toString('hex') -} +const { getOperatorId } = require('../../operator') const hostname = options.hostname -router.use('*', session({ +router.use('*', async (req, res, next) => getOperatorId('authentication').then(({ operatorId }) => session({ store: new PgSession({ pgPromise: db, tableName: USER_SESSIONS_TABLE_NAME }), name: 'lamassu_sid', - secret: getSecret(), + secret: operatorId, resave: false, saveUninitialized: false, cookie: { @@ -36,6 +25,7 @@ router.use('*', session({ sameSite: true, maxAge: 60 * 10 * 1000 // 10 minutes } -})) +})(req, res, next)) +) module.exports = router diff --git a/lib/operator.js b/lib/operator.js new file mode 100644 index 00000000..63cbb768 --- /dev/null +++ b/lib/operator.js @@ -0,0 +1,10 @@ +const db = require('./db') +const _ = require('lodash/fp') + +function getOperatorId (service) { + const sql = `SELECT operator_id FROM operator_ids WHERE service = '${service}'` + return db.oneOrNone(sql) + .then(_.mapKeys(_.camelCase)) +} + +module.exports = { getOperatorId } diff --git a/migrations/1623413776161-create-operator-ids.js b/migrations/1623413776161-create-operator-ids.js new file mode 100644 index 00000000..b7f27830 --- /dev/null +++ b/migrations/1623413776161-create-operator-ids.js @@ -0,0 +1,60 @@ +var db = require('./db') +const pify = require('pify') +const fs = pify(require('fs')) +const hkdf = require('futoin-hkdf') + +const state = require('../lib/middlewares/state') +const mnemonicHelpers = require('../lib/mnemonic-helpers') +const options = require('../lib/options') + +function computeOperatorId (masterSeed) { + return hkdf(masterSeed, 16, { salt: 'lamassu-server-salt', info: 'operator-id' }).toString('hex') +} + +function getMnemonic () { + if (state.mnemonic) return Promise.resolve(state.mnemonic) + return fs.readFile(options.mnemonicPath, 'utf8').then(mnemonic => { + state.mnemonic = mnemonic + return mnemonic + }) +} + +function generateOperatorId () { + return getMnemonic().then(mnemonic => { + return computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)) + }).then(id => { + return id + }).catch(e => { + console.error('Error while computing operator id\n' + e) + throw e + }) +} + +exports.up = function (next) { + const sql = + [ + `CREATE TABLE operator_ids ( + id serial PRIMARY KEY, + operator_id TEXT NOT NULL, + service TEXT NOT NULL + )` + ] + generateOperatorId() + .then(operatorId => { + const sql2 = [ + `INSERT INTO operator_ids (operator_id, service) VALUES ('${operatorId}','middleware')`, + `INSERT INTO operator_ids (operator_id, service) VALUES ('${operatorId}','coinatmradar')`, + `INSERT INTO operator_ids (operator_id, service) VALUES ('${operatorId}','authentication')` + ] + db.multi(sql.concat(sql2), next) + .then(() => next()) + }) + .catch(e => { + db.multi(sql, next) + .then(() => next()) + }) +} + +exports.down = function (next) { + next() +}