diff --git a/bin/key_server.js b/bin/key_server.js index a17b36d9..a792a5f6 100755 --- a/bin/key_server.js +++ b/bin/key_server.js @@ -28,8 +28,19 @@ function main() { ) memoryMonitor.start() + var tokens = require('../tokens')(log) + // databases - var DB = require('../db/heap')(log) + var DB = require('../db/heap')( + log, + tokens.error, + tokens.AuthToken, + tokens.SessionToken, + tokens.KeyFetchToken, + tokens.AccountResetToken, + tokens.SrpToken, + tokens.ForgotPasswordToken + ) var db = new DB() // TODO: send to the SMTP server directly. In the future this may change diff --git a/db/heap.js b/db/heap.js index 41f05ad6..69ffe40e 100644 --- a/db/heap.js +++ b/db/heap.js @@ -1,19 +1,15 @@ -var inherits = require('util').inherits var P = require('p-promise') -var uuid = require('uuid') -var srp = require('srp') -var Bundle = require('../bundle') -var error = require('../models/error') -module.exports = function (log) { - - var Token = require('../models/token')(log, inherits, Bundle) - var AuthToken = require('../models/auth_token')(log, inherits, Token) - var SessionToken = require('../models/session_token')(log, inherits, Token) - var KeyFetchToken = require('../models/key_fetch_token')(log, inherits, Token) - var AccountResetToken = require('../models/account_reset_token')(log, inherits, Token) - var SrpToken = require('../models/srp_session')(log, P, uuid, srp, error) - var ForgotPasswordToken = require('../models/forgot_password_token')(log, inherits, Token) +module.exports = function ( + log, + error, + AuthToken, + SessionToken, + KeyFetchToken, + AccountResetToken, + SrpToken, + ForgotPasswordToken + ) { function Heap() { this.sessionTokens = {} diff --git a/models/auth_bundle.js b/models/auth_bundle.js deleted file mode 100644 index 0e5aedec..00000000 --- a/models/auth_bundle.js +++ /dev/null @@ -1,64 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -module.exports = function (log, inherits, Bundle, Account, tokens, error) { - - function AuthBundle() { - Bundle.call(this) - this.authToken = null - this.otherToken = null - } - inherits(AuthBundle, Bundle) - - AuthBundle.create = function (K, type) { - log.trace({ op: 'AuthBundle.create', type: type }) - return Bundle - .hkdf(K, type, null, 2 * 32) - .then( - function (key) { - var b = new AuthBundle() - b.hmacKey = key.slice(0, 32).toString('hex') - b.xorKey = key.slice(32, 64).toString('hex') - return b - } - ) - } - - AuthBundle.login = function (K, uid) { - log.trace({ op: 'AuthBundle.login', uid: uid }) - return AuthBundle.create(K, 'auth/finish') - .then( - function (b) { - return tokens.AuthToken.create(uid) - .then( - function (t) { - b.authToken = t - return { - bundle: b.bundle() - } - } - ) - } - ) - } - - AuthBundle.prototype.unbundle = function (hex) { - log.trace({ op: 'authBundle.unbundle' }) - var bundle = Buffer(hex, 'hex') - var ciphertext = bundle.slice(0, 32) - var hmac = bundle.slice(32, 64) - if (this.hmac(ciphertext).toString('hex') !== hmac.toString('hex')) { - throw error.invalidSignature() - } - var plaintext = this.xor(ciphertext) - return plaintext.slice(0, 32).toString('hex') - } - - AuthBundle.prototype.bundle = function () { - log.trace({ op: 'authBundle.bundle' }) - return this.bundleHexStrings([this.authToken.data]) - } - - return AuthBundle -} diff --git a/models/index.js b/models/index.js deleted file mode 100644 index 9be4c843..00000000 --- a/models/index.js +++ /dev/null @@ -1,103 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var crypto = require('crypto') -var inherits = require('util').inherits - -var P = require('p-promise') -var srp = require('srp') -var uuid = require('uuid') - -var Bundle = require('../bundle') -var error = require('./error') - -module.exports = function (log, config, dbs, mailer) { - - var Token = require('./token')(log, inherits, Bundle) - - var KeyFetchToken = require('./key_fetch_token')( - log, - inherits, - Token, - dbs.cache, - error - ) - var AccountResetToken = require('./account_reset_token')( - log, - inherits, - Token, - crypto, - dbs.store - ) - var SessionToken = require('./session_token')( - log, - inherits, - Token, - dbs.store - ) - var AuthToken = require('./auth_token')( - log, - inherits, - Token, - dbs.cache, - error - ) - var ForgotPasswordToken = require('./forgot_password_token')( - log, - inherits, - Token, - crypto, - dbs.cache, - mailer - ) - var tokens = { - AccountResetToken: AccountResetToken, - KeyFetchToken: KeyFetchToken, - SessionToken: SessionToken, - AuthToken: AuthToken, - ForgotPasswordToken: ForgotPasswordToken - } - - var RecoveryEmail = require('./recovery_email')( - log, - crypto, - P, - dbs.store, - mailer - ) - var Account = require('./account')( - log, - P, - tokens, - RecoveryEmail, - dbs.store, - config, - error - ) - var SrpSession = require('./srp_session')( - log, - P, - uuid, - srp, - dbs.cache, - error - ) - var AuthBundle = require('./auth_bundle')( - log, - inherits, - Bundle, - Account, - tokens, - error - ) - - return { - dbs: dbs, - Account: Account, - AuthBundle: AuthBundle, - RecoveryEmail: RecoveryEmail, - SrpSession: SrpSession, - tokens: tokens - } -} diff --git a/models/account_reset_token.js b/tokens/account_reset_token.js similarity index 97% rename from models/account_reset_token.js rename to tokens/account_reset_token.js index d32fdacb..8c3b5dce 100644 --- a/models/account_reset_token.js +++ b/tokens/account_reset_token.js @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -module.exports = function (log, inherits, Token, crypto, db) { +module.exports = function (log, inherits, Token, crypto) { var NULL = '0000000000000000000000000000000000000000000000000000000000000000' diff --git a/models/auth_token.js b/tokens/auth_token.js similarity index 98% rename from models/auth_token.js rename to tokens/auth_token.js index 9e582bef..479ddd7f 100644 --- a/models/auth_token.js +++ b/tokens/auth_token.js @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -module.exports = function (log, inherits, Token) { +module.exports = function (log, inherits, Token, error) { function AuthToken() { Token.call(this) diff --git a/models/error.js b/tokens/error.js similarity index 100% rename from models/error.js rename to tokens/error.js diff --git a/models/forgot_password_token.js b/tokens/forgot_password_token.js similarity index 64% rename from models/forgot_password_token.js rename to tokens/forgot_password_token.js index 1db6f79a..b5a19431 100644 --- a/models/forgot_password_token.js +++ b/tokens/forgot_password_token.js @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -module.exports = function (log, inherits, Token, crypto, db, mailer) { +module.exports = function (log, inherits, Token, crypto) { var LIFETIME = 1000 * 60 * 15 @@ -31,7 +31,27 @@ module.exports = function (log, inherits, Token, crypto, db, mailer) { t.data = data[0].toString('hex') t.id = key.slice(0, 32).toString('hex') t._key = key.slice(32, 64).toString('hex') - return t.save() + return t + } + ) + } + + ForgotPasswordToken.fromHex = function (string) { + log.trace({ op: 'ForgotPasswordToken.fromHex' }) + return Token + .tokenDataFromBytes( + 'password/forgot', + 2 * 32, + Buffer(string, 'hex') + ) + .then( + function (data) { + var key = data[1] + var t = new ForgotPasswordToken() + t.data = data[0].toString('hex') + t.id = key.slice(0, 32).toString('hex') + t._key = key.slice(32, 64).toString('hex') + return t } ) } diff --git a/tokens/index.js b/tokens/index.js new file mode 100644 index 00000000..213ec5db --- /dev/null +++ b/tokens/index.js @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var crypto = require('crypto') +var inherits = require('util').inherits + +var P = require('p-promise') +var srp = require('srp') +var uuid = require('uuid') + +var Bundle = require('../bundle') +var error = require('./error') + +module.exports = function (log) { + + var Token = require('./token')(log, inherits, Bundle) + + var KeyFetchToken = require('./key_fetch_token')(log, inherits, Token, error) + var AccountResetToken = require('./account_reset_token')( + log, + inherits, + Token, + crypto + ) + var SessionToken = require('./session_token')(log, inherits, Token) + var AuthToken = require('./auth_token')(log, inherits, Token, error) + var ForgotPasswordToken = require('./forgot_password_token')( + log, + inherits, + Token, + crypto + ) + var SrpToken = require('./srp_token')( + log, + P, + uuid, + srp, + error + ) + + return { + error: error, + AccountResetToken: AccountResetToken, + KeyFetchToken: KeyFetchToken, + SessionToken: SessionToken, + AuthToken: AuthToken, + ForgotPasswordToken: ForgotPasswordToken, + SrpToken: SrpToken + } +} diff --git a/models/key_fetch_token.js b/tokens/key_fetch_token.js similarity index 97% rename from models/key_fetch_token.js rename to tokens/key_fetch_token.js index e61fee5b..b3d578d5 100644 --- a/models/key_fetch_token.js +++ b/tokens/key_fetch_token.js @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -module.exports = function (log, inherits, Token, db, error) { +module.exports = function (log, inherits, Token, error) { function KeyFetchToken() { Token.call(this) diff --git a/models/session_token.js b/tokens/session_token.js similarity index 100% rename from models/session_token.js rename to tokens/session_token.js diff --git a/models/srp_session.js b/tokens/srp_token.js similarity index 89% rename from models/srp_session.js rename to tokens/srp_token.js index 7050cc7a..5908f608 100644 --- a/models/srp_session.js +++ b/tokens/srp_token.js @@ -9,7 +9,7 @@ module.exports = function (log, P, uuid, srp, error) { var alg = 'sha256' - function SrpSession() { + function SrpToken() { this.id = null this.uid = null this.N = null @@ -38,13 +38,13 @@ module.exports = function (log, P, uuid, srp, error) { return d.promise } - SrpSession.create = function (account) { - log.trace({ op: 'SrpSession.create', uid: account && account.uid }) + SrpToken.create = function (account) { + log.trace({ op: 'SrpToken.create', uid: account && account.uid }) var session = null return srpGenKey() .then( function (b) { - session = new SrpSession() + session = new SrpToken() session.id = uuid.v4() session.uid = account.uid session.N = srp.params[2048].N @@ -59,7 +59,7 @@ module.exports = function (log, P, uuid, srp, error) { ) } - SrpSession.prototype.finish = function (A, M1) { + SrpToken.prototype.finish = function (A, M1) { A = Buffer(A, 'hex') var N = srp.params[2048].N var S = srp.server_getS( @@ -81,7 +81,7 @@ module.exports = function (log, P, uuid, srp, error) { return this } - SrpSession.client2 = function (session, email, password) { + SrpToken.client2 = function (session, email, password) { return srpGenKey() .then( function (a) { @@ -111,5 +111,5 @@ module.exports = function (log, P, uuid, srp, error) { ) } - return SrpSession + return SrpToken } diff --git a/models/token.js b/tokens/token.js similarity index 100% rename from models/token.js rename to tokens/token.js