refactor(lib): use strings instead of buffers for as much as possible
This settles our dance of `Buffer` vs `String` down to simply this: > You have a `String`. You should (almost) never have a `Buffer`. Buffers are useful for talking about a specific set of bytes, without an encoding. In our app, the places where this is useful are: - crypto - mysql We don't actually speak MySQL in this repo anywhere, so that leaves us with only crypto. Instead of requiring the mental overhead of "Do I have a buffer or a string?" throughout all our code base, we can just push that completely into the crypto code. This *should* reduce bugs where we aren't sure if we have a `Buffer` or a `String`. If you're not in crypto, you should just have a `String`.
This commit is contained in:
Родитель
96aae0e0ca
Коммит
0cfd39ca05
|
@ -163,6 +163,12 @@ function main() {
|
|||
server.log.fatal(err)
|
||||
process.exit(8)
|
||||
})
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
server.log.fatal({
|
||||
op: 'promise.unhandledRejection',
|
||||
error: reason
|
||||
})
|
||||
})
|
||||
process.on('SIGINT', shutdown)
|
||||
server.log.on('error', shutdown)
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
'use strict'
|
||||
|
||||
const HEX = /^(?:[a-fA-F0-9]{2})+$/
|
||||
|
||||
module.exports.ONES = Buffer('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 'hex')
|
||||
|
||||
module.exports.buffersAreEqual = function buffersAreEqual(buffer1, buffer2) {
|
||||
buffer1 = Buffer.from(buffer1, 'hex')
|
||||
buffer2 = Buffer.from(buffer2, 'hex')
|
||||
var mismatch = buffer1.length - buffer2.length
|
||||
if (mismatch) {
|
||||
return false
|
||||
|
@ -20,6 +20,8 @@ module.exports.buffersAreEqual = function buffersAreEqual(buffer1, buffer2) {
|
|||
}
|
||||
|
||||
module.exports.xorBuffers = function xorBuffers(buffer1, buffer2) {
|
||||
buffer1 = Buffer.from(buffer1, 'hex')
|
||||
buffer2 = Buffer.from(buffer2, 'hex')
|
||||
if (buffer1.length !== buffer2.length) {
|
||||
throw new Error(
|
||||
'XOR buffers must be same length (%d != %d)',
|
||||
|
@ -33,46 +35,3 @@ module.exports.xorBuffers = function xorBuffers(buffer1, buffer2) {
|
|||
}
|
||||
return result
|
||||
}
|
||||
|
||||
module.exports.unbuffer = (object, inplace) => {
|
||||
return Object.keys(object).reduce((unbuffered, key) => {
|
||||
unbuffered[key] = unbufferDatum.call(object, key, object[key])
|
||||
return unbuffered
|
||||
}, inplace ? object : {})
|
||||
}
|
||||
|
||||
module.exports.unbufferDatum = unbufferDatum
|
||||
|
||||
// Invoked as the `replacer` in calls to JSON.stringify.
|
||||
// If you're going to call it elsewhere, `this` must be
|
||||
// set as it would be then.
|
||||
function unbufferDatum (key, value) {
|
||||
const unstringifiedValue = this[key]
|
||||
|
||||
if (Buffer.isBuffer(unstringifiedValue)) {
|
||||
return unstringifiedValue.toString('hex')
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
module.exports.bufferize = function bufferize(object, options) {
|
||||
var keys = Object.keys(object)
|
||||
options = options || {}
|
||||
var copy = options.inplace ? object : {}
|
||||
var ignore = options.ignore || []
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i]
|
||||
var value = object[key]
|
||||
if (
|
||||
ignore.indexOf(key) === -1 &&
|
||||
typeof value === 'string' &&
|
||||
HEX.test(value)
|
||||
) {
|
||||
copy[key] = Buffer(value, 'hex')
|
||||
} else {
|
||||
copy[key] = value
|
||||
}
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ module.exports = function(log, config) {
|
|||
|
||||
function Password(authPW, authSalt, version) {
|
||||
version = typeof(version) === 'number' ? version : 1
|
||||
this.authPW = authPW
|
||||
this.authSalt = authSalt
|
||||
this.authPW = Buffer.from(authPW, 'hex')
|
||||
this.authSalt = Buffer.from(authSalt, 'hex')
|
||||
this.version = version
|
||||
this.stretchPromise = hashVersions[version](authPW, authSalt)
|
||||
this.stretchPromise = hashVersions[version](this.authPW, this.authSalt)
|
||||
this.verifyHashPromise = this.stretchPromise.then(hkdfVerify)
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ module.exports = function(log, config) {
|
|||
return hkdf(stretched, context, null, 32)
|
||||
.then(
|
||||
function (wrapper) {
|
||||
return butil.xorBuffers(wrapper, wrapped)
|
||||
return butil.xorBuffers(wrapper, wrapped).toString('hex')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ module.exports = function(log, config) {
|
|||
Password.prototype.wrap = Password.prototype.unwrap
|
||||
|
||||
function hkdfVerify(stretched) {
|
||||
return hkdf(stretched, 'verifyHash', null, 32)
|
||||
return hkdf(stretched, 'verifyHash', null, 32).then(buf => buf.toString('hex'))
|
||||
}
|
||||
|
||||
Password.stat = function () {
|
||||
|
|
|
@ -16,7 +16,7 @@ function derive(input, salt, iterations, len) {
|
|||
var saltBits = sjcl.codec.hex.toBits(salt.toString('hex'))
|
||||
var result = sjcl.misc.pbkdf2(password, saltBits, iterations, len * 8, sjcl.misc.hmac)
|
||||
|
||||
return P.resolve(Buffer(sjcl.codec.hex.fromBits(result), 'hex'))
|
||||
return P.resolve(Buffer.from(sjcl.codec.hex.fromBits(result), 'hex'))
|
||||
}
|
||||
|
||||
module.exports.derive = derive
|
||||
|
|
|
@ -4,4 +4,33 @@
|
|||
|
||||
'use strict'
|
||||
|
||||
module.exports = require('../promise').promisify(require('crypto').randomBytes)
|
||||
const randomBytes = require('../promise').promisify(require('crypto').randomBytes)
|
||||
|
||||
function random(bytes) {
|
||||
if (arguments.length > 1) {
|
||||
bytes = Array.from(arguments)
|
||||
const sum = bytes.reduce((acc, val) => acc + val, 0)
|
||||
return randomBytes(sum).then(buf => {
|
||||
let pos = 0
|
||||
return bytes.map(num => {
|
||||
const slice = buf.slice(pos, pos + num)
|
||||
pos += num
|
||||
return slice
|
||||
})
|
||||
})
|
||||
} else {
|
||||
return randomBytes(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
random.hex = function hex() {
|
||||
return random.apply(null, arguments).then(bufs => {
|
||||
if (Array.isArray(bufs)) {
|
||||
return bufs.map(buf => buf.toString('hex'))
|
||||
} else {
|
||||
return bufs.toString('hex')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = random
|
||||
|
|
165
lib/db.js
165
lib/db.js
|
@ -9,7 +9,6 @@ const P = require('./promise')
|
|||
const Pool = require('./pool')
|
||||
const userAgent = require('./userAgent')
|
||||
|
||||
const bufferize = require('./crypto/butil').bufferize
|
||||
const random = require('./crypto/random')
|
||||
|
||||
module.exports = (
|
||||
|
@ -55,7 +54,7 @@ module.exports = (
|
|||
data.createdAt = data.verifierSetAt = Date.now()
|
||||
data.normalizedEmail = data.email.toLowerCase()
|
||||
return this.pool.put(
|
||||
'/account/' + data.uid.toString('hex'),
|
||||
'/account/' + data.uid,
|
||||
data
|
||||
)
|
||||
.then(
|
||||
|
@ -177,9 +176,8 @@ module.exports = (
|
|||
// READ
|
||||
|
||||
DB.prototype.checkPassword = function (uid, verifyHash) {
|
||||
verifyHash = Buffer(verifyHash).toString('hex')
|
||||
log.trace({ op: 'DB.checkPassword', uid: uid, verifyHash: verifyHash })
|
||||
return this.pool.post('/account/' + uid.toString('hex') + '/checkPassword',
|
||||
return this.pool.post('/account/' + uid + '/checkPassword',
|
||||
{
|
||||
'verifyHash': verifyHash
|
||||
})
|
||||
|
@ -198,7 +196,7 @@ module.exports = (
|
|||
|
||||
DB.prototype.accountExists = function (email) {
|
||||
log.trace({ op: 'DB.accountExists', email: email })
|
||||
return this.pool.head('/emailRecord/' + Buffer(email, 'utf8').toString('hex'))
|
||||
return this.pool.head('/emailRecord/' + hexEncode(email))
|
||||
.then(
|
||||
function () {
|
||||
return true
|
||||
|
@ -214,38 +212,14 @@ module.exports = (
|
|||
|
||||
DB.prototype.sessions = function (uid) {
|
||||
log.trace({ op: 'DB.sessions', uid: uid })
|
||||
return this.pool.get('/account/' + uid.toString('hex') + '/sessions')
|
||||
.then(
|
||||
function (body) {
|
||||
return body.map(function (sessionToken) {
|
||||
return bufferize(sessionToken, {
|
||||
ignore: [
|
||||
'uaBrowser',
|
||||
'uaBrowserVersion',
|
||||
'uaOS',
|
||||
'uaOSVersion',
|
||||
'uaDeviceType'
|
||||
]
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
return this.pool.get('/account/' + uid + '/sessions')
|
||||
}
|
||||
|
||||
DB.prototype.sessionToken = function (id) {
|
||||
log.trace({ op: 'DB.sessionToken', id: id })
|
||||
return this.pool.get('/sessionToken/' + id.toString('hex'))
|
||||
return this.pool.get('/sessionToken/' + id)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body, {
|
||||
ignore: [
|
||||
'uaBrowser',
|
||||
'uaBrowserVersion',
|
||||
'uaOS',
|
||||
'uaOSVersion',
|
||||
'uaDeviceType'
|
||||
]
|
||||
})
|
||||
function (data) {
|
||||
return SessionToken.fromHex(data.tokenData, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -257,18 +231,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.sessionTokenWithVerificationStatus = function (id) {
|
||||
log.trace({ op: 'DB.sessionTokenWithVerificationStatus', id: id })
|
||||
return this.pool.get('/sessionToken/' + id.toString('hex') + '/verified')
|
||||
return this.pool.get('/sessionToken/' + id + '/verified')
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body, {
|
||||
ignore: [
|
||||
'uaBrowser',
|
||||
'uaBrowserVersion',
|
||||
'uaOS',
|
||||
'uaOSVersion',
|
||||
'uaDeviceType'
|
||||
]
|
||||
})
|
||||
function (data) {
|
||||
return SessionToken.fromHex(data.tokenData, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -280,10 +245,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.keyFetchToken = function (id) {
|
||||
log.trace({ op: 'DB.keyFetchToken', id: id })
|
||||
return this.pool.get('/keyFetchToken/' + id.toString('hex'))
|
||||
return this.pool.get('/keyFetchToken/' + id)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
return KeyFetchToken.fromId(id, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -295,10 +259,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.keyFetchTokenWithVerificationStatus = function (id) {
|
||||
log.trace({ op: 'DB.keyFetchTokenWithVerificationStatus', id: id })
|
||||
return this.pool.get('/keyFetchToken/' + id.toString('hex') + '/verified')
|
||||
return this.pool.get('/keyFetchToken/' + id + '/verified')
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
return KeyFetchToken.fromId(id, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -310,10 +273,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.accountResetToken = function (id) {
|
||||
log.trace({ op: 'DB.accountResetToken', id: id })
|
||||
return this.pool.get('/accountResetToken/' + id.toString('hex'))
|
||||
return this.pool.get('/accountResetToken/' + id)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
return AccountResetToken.fromHex(data.tokenData, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -325,10 +287,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.passwordForgotToken = function (id) {
|
||||
log.trace({ op: 'DB.passwordForgotToken', id: id })
|
||||
return this.pool.get('/passwordForgotToken/' + id.toString('hex'))
|
||||
return this.pool.get('/passwordForgotToken/' + id)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
return PasswordForgotToken.fromHex(data.tokenData, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -340,10 +301,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.passwordChangeToken = function (id) {
|
||||
log.trace({ op: 'DB.passwordChangeToken', id: id })
|
||||
return this.pool.get('/passwordChangeToken/' + id.toString('hex'))
|
||||
return this.pool.get('/passwordChangeToken/' + id)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
return PasswordChangeToken.fromHex(data.tokenData, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -355,10 +315,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.emailRecord = function (email) {
|
||||
log.trace({ op: 'DB.emailRecord', email: email })
|
||||
return this.pool.get('/emailRecord/' + Buffer(email, 'utf8').toString('hex'))
|
||||
return this.pool.get('/emailRecord/' + hexEncode(email))
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
data.emailVerified = !! data.emailVerified
|
||||
return data
|
||||
},
|
||||
|
@ -373,10 +332,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.account = function (uid) {
|
||||
log.trace({ op: 'DB.account', uid: uid })
|
||||
return this.pool.get('/account/' + uid.toString('hex'))
|
||||
return this.pool.get('/account/' + uid)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
data.emailVerified = !! data.emailVerified
|
||||
return data
|
||||
},
|
||||
|
@ -392,11 +350,11 @@ module.exports = (
|
|||
DB.prototype.devices = function (uid) {
|
||||
log.trace({ op: 'DB.devices', uid: uid })
|
||||
|
||||
return this.pool.get('/account/' + uid.toString('hex') + '/devices')
|
||||
return this.pool.get('/account/' + uid + '/devices')
|
||||
.then(
|
||||
function (body) {
|
||||
return body.map(function (item) {
|
||||
return bufferize({
|
||||
return {
|
||||
id: item.id,
|
||||
sessionToken: item.sessionTokenId,
|
||||
lastAccessTime: marshallLastAccessTime(item.lastAccessTime, uid, item.email),
|
||||
|
@ -410,12 +368,7 @@ module.exports = (
|
|||
uaOS: item.uaOS,
|
||||
uaOSVersion: item.uaOSVersion,
|
||||
uaDeviceType: item.uaDeviceType
|
||||
}, {
|
||||
ignore: [
|
||||
'name', 'type', 'pushCallback', 'pushPublicKey', 'pushAuthKey',
|
||||
'uaBrowser', 'uaBrowserVersion', 'uaOS', 'uaOSVersion', 'uaDeviceType'
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
function (err) {
|
||||
|
@ -440,18 +393,9 @@ module.exports = (
|
|||
|
||||
DB.prototype.sessionWithDevice = function (id) {
|
||||
log.trace({ op: 'DB.sessionWithDevice', id: id })
|
||||
return this.pool.get('/sessionToken/' + id.toString('hex') + '/device')
|
||||
return this.pool.get('/sessionToken/' + id + '/device')
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body, {
|
||||
ignore: [
|
||||
'uaBrowser',
|
||||
'uaBrowserVersion',
|
||||
'uaOS',
|
||||
'uaOSVersion',
|
||||
'uaDeviceType'
|
||||
]
|
||||
})
|
||||
function (data) {
|
||||
return SessionToken.fromHex(data.tokenData, data)
|
||||
},
|
||||
function (err) {
|
||||
|
@ -493,13 +437,13 @@ module.exports = (
|
|||
DB.prototype.createDevice = function (uid, sessionTokenId, deviceInfo) {
|
||||
log.trace({ op: 'DB.createDevice', uid: uid, id: deviceInfo.id })
|
||||
|
||||
return random(16)
|
||||
return random.hex(16)
|
||||
.then(id => {
|
||||
deviceInfo.id = id
|
||||
deviceInfo.createdAt = Date.now()
|
||||
return this.pool.put(
|
||||
'/account/' + uid.toString('hex') +
|
||||
'/device/' + deviceInfo.id.toString('hex'),
|
||||
'/account/' + uid +
|
||||
'/device/' + deviceInfo.id,
|
||||
{
|
||||
sessionTokenId: sessionTokenId,
|
||||
createdAt: deviceInfo.createdAt,
|
||||
|
@ -524,7 +468,7 @@ module.exports = (
|
|||
// return an appropriate error.
|
||||
devices => {
|
||||
const isDuplicateDeviceId = devices.reduce((is, device) => {
|
||||
is || device.id.toString('hex') === deviceInfo.id.toString('hex')
|
||||
is || device.id === deviceInfo.id
|
||||
}, false)
|
||||
|
||||
if (isDuplicateDeviceId) {
|
||||
|
@ -543,8 +487,8 @@ module.exports = (
|
|||
DB.prototype.updateDevice = function (uid, sessionTokenId, deviceInfo) {
|
||||
log.trace({ op: 'DB.updateDevice', uid: uid, id: deviceInfo.id })
|
||||
return this.pool.post(
|
||||
'/account/' + uid.toString('hex') +
|
||||
'/device/' + deviceInfo.id.toString('hex') + '/update',
|
||||
'/account/' + uid +
|
||||
'/device/' + deviceInfo.id + '/update',
|
||||
{
|
||||
sessionTokenId: sessionTokenId,
|
||||
name: deviceInfo.name,
|
||||
|
@ -574,7 +518,7 @@ module.exports = (
|
|||
|
||||
DB.prototype.deleteAccount = function (authToken) {
|
||||
log.trace({ op: 'DB.deleteAccount', uid: authToken && authToken.uid })
|
||||
return this.pool.del('/account/' + authToken.uid.toString('hex'))
|
||||
return this.pool.del('/account/' + authToken.uid)
|
||||
}
|
||||
|
||||
DB.prototype.deleteSessionToken = function (sessionToken) {
|
||||
|
@ -641,7 +585,7 @@ module.exports = (
|
|||
}
|
||||
)
|
||||
return this.pool.del(
|
||||
'/account/' + uid.toString('hex') + '/device/' + deviceId.toString('hex')
|
||||
'/account/' + uid + '/device/' + deviceId
|
||||
)
|
||||
.catch(
|
||||
function (err) {
|
||||
|
@ -662,7 +606,7 @@ module.exports = (
|
|||
}
|
||||
)
|
||||
return this.pool.get(
|
||||
'/account/' + uid.toString('hex') + '/tokens/' + tokenVerificationId.toString('hex') + '/device'
|
||||
'/account/' + uid + '/tokens/' + tokenVerificationId + '/device'
|
||||
)
|
||||
.catch(
|
||||
function (err) {
|
||||
|
@ -680,7 +624,7 @@ module.exports = (
|
|||
log.trace({ op: 'DB.resetAccount', uid: accountResetToken && accountResetToken.uid })
|
||||
data.verifierSetAt = Date.now()
|
||||
return this.pool.post(
|
||||
'/account/' + accountResetToken.uid.toString('hex') + '/reset',
|
||||
'/account/' + accountResetToken.uid + '/reset',
|
||||
data
|
||||
)
|
||||
}
|
||||
|
@ -691,13 +635,13 @@ module.exports = (
|
|||
uid: account && account.uid,
|
||||
emailCode: emailCode
|
||||
})
|
||||
return this.pool.post('/account/' + account.uid.toString('hex') + '/verifyEmail/' + emailCode.toString('hex'))
|
||||
return this.pool.post('/account/' + account.uid + '/verifyEmail/' + emailCode)
|
||||
}
|
||||
|
||||
DB.prototype.verifyTokens = function (tokenVerificationId, accountData) {
|
||||
log.trace({ op: 'DB.verifyTokens', tokenVerificationId: tokenVerificationId })
|
||||
return this.pool.post(
|
||||
'/tokens/' + tokenVerificationId.toString('hex') + '/verify',
|
||||
'/tokens/' + tokenVerificationId + '/verify',
|
||||
{ uid: accountData.uid }
|
||||
)
|
||||
.then(
|
||||
|
@ -739,7 +683,7 @@ module.exports = (
|
|||
DB.prototype.updateLocale = function (uid, locale) {
|
||||
log.trace({ op: 'DB.updateLocale', uid: uid, locale: locale })
|
||||
return this.pool.post(
|
||||
'/account/' + uid.toString('hex') + '/locale',
|
||||
'/account/' + uid + '/locale',
|
||||
{ locale: locale }
|
||||
)
|
||||
}
|
||||
|
@ -779,7 +723,7 @@ module.exports = (
|
|||
params: params
|
||||
})
|
||||
|
||||
return this.pool.get('/securityEvents/' + params.uid.toString('hex') + '/ip/' + params.ipAddr)
|
||||
return this.pool.get('/securityEvents/' + params.uid + '/ip/' + params.ipAddr)
|
||||
}
|
||||
|
||||
DB.prototype.createUnblockCode = function (uid) {
|
||||
|
@ -790,7 +734,7 @@ module.exports = (
|
|||
return UnblockCode()
|
||||
.then(
|
||||
(unblock) => {
|
||||
return this.pool.put('/account/' + uid.toString('hex') + '/unblock/' + unblock)
|
||||
return this.pool.put('/account/' + uid + '/unblock/' + unblock)
|
||||
.then(
|
||||
() => {
|
||||
return unblock
|
||||
|
@ -818,7 +762,7 @@ module.exports = (
|
|||
op: 'DB.consumeUnblockCode',
|
||||
uid: uid
|
||||
})
|
||||
return this.pool.del('/account/' + uid.toString('hex') + '/unblock/' + code)
|
||||
return this.pool.del('/account/' + uid + '/unblock/' + code)
|
||||
.catch(
|
||||
function (err) {
|
||||
if (isNotFoundError(err)) {
|
||||
|
@ -844,7 +788,7 @@ module.exports = (
|
|||
email: email
|
||||
})
|
||||
|
||||
return this.pool.get('/emailBounces/' + Buffer(email, 'utf8').toString('hex'))
|
||||
return this.pool.get('/emailBounces/' + hexEncode(email))
|
||||
}
|
||||
|
||||
DB.prototype.accountEmails = function (uid) {
|
||||
|
@ -853,7 +797,7 @@ module.exports = (
|
|||
uid: uid
|
||||
})
|
||||
|
||||
return this.pool.get('/account/' + uid.toString('hex') + '/emails')
|
||||
return this.pool.get('/account/' + uid + '/emails')
|
||||
}
|
||||
|
||||
DB.prototype.getSecondaryEmail = function (email) {
|
||||
|
@ -862,10 +806,7 @@ module.exports = (
|
|||
email: email
|
||||
})
|
||||
|
||||
return this.pool.get('/email/' + Buffer(email, 'utf8').toString('hex'))
|
||||
.then((body) => {
|
||||
return bufferize(body)
|
||||
})
|
||||
return this.pool.get('/email/' + hexEncode(email))
|
||||
.catch((err) => {
|
||||
if (isNotFoundError(err)) {
|
||||
throw error.unknownSecondaryEmail()
|
||||
|
@ -881,7 +822,7 @@ module.exports = (
|
|||
uid: emailData.uid
|
||||
})
|
||||
|
||||
return this.pool.post('/account/' + uid.toString('hex') + '/emails', emailData)
|
||||
return this.pool.post('/account/' + uid + '/emails', emailData)
|
||||
.catch(
|
||||
function (err) {
|
||||
if (isEmailAlreadyExistsError(err)) {
|
||||
|
@ -898,7 +839,7 @@ module.exports = (
|
|||
uid: uid
|
||||
})
|
||||
|
||||
return this.pool.del('/account/' + uid.toString('hex') + '/emails/' + email)
|
||||
return this.pool.del('/account/' + uid + '/emails/' + email)
|
||||
.catch(
|
||||
function (err) {
|
||||
if (isEmailDeletePrimaryError(err)) {
|
||||
|
@ -912,10 +853,10 @@ module.exports = (
|
|||
DB.prototype.createSigninCode = function (uid, flowId) {
|
||||
log.trace({ op: 'DB.createSigninCode' })
|
||||
|
||||
return random(config.signinCodeSize)
|
||||
return random.hex(config.signinCodeSize)
|
||||
.then(code => {
|
||||
const data = { uid, createdAt: Date.now(), flowId }
|
||||
return this.pool.put(`/signinCodes/${code.toString('hex')}`, data)
|
||||
return this.pool.put(`/signinCodes/${code}`, data)
|
||||
.then(() => code, err => {
|
||||
if (isRecordAlreadyExistsError(err)) {
|
||||
log.warn({ op: 'DB.createSigninCode.duplicate' })
|
||||
|
@ -930,7 +871,7 @@ module.exports = (
|
|||
DB.prototype.consumeSigninCode = function (code) {
|
||||
log.trace({ op: 'DB.consumeSigninCode', code })
|
||||
|
||||
return this.pool.post(`/signinCodes/${code.toString('hex')}/consume`)
|
||||
return this.pool.post(`/signinCodes/${code}/consume`)
|
||||
.catch(err => {
|
||||
if (isNotFoundError(err)) {
|
||||
throw error.invalidSigninCode()
|
||||
|
@ -947,6 +888,10 @@ module.exports = (
|
|||
return err
|
||||
}
|
||||
|
||||
function hexEncode(str) {
|
||||
return Buffer(str, 'utf8').toString('hex')
|
||||
}
|
||||
|
||||
return DB
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ module.exports = function (log, db, push) {
|
|||
.then(function (device) {
|
||||
result = device
|
||||
return request.emitMetricsEvent(event, {
|
||||
uid: sessionToken.uid.toString('hex'),
|
||||
device_id: result.id.toString('hex'),
|
||||
uid: sessionToken.uid,
|
||||
device_id: result.id,
|
||||
is_placeholder: isPlaceholderDevice
|
||||
})
|
||||
})
|
||||
|
@ -39,7 +39,7 @@ module.exports = function (log, db, push) {
|
|||
deviceName = synthesizeName(deviceInfo)
|
||||
}
|
||||
if (sessionToken.tokenVerified) {
|
||||
push.notifyDeviceConnected(sessionToken.uid, deviceName, result.id.toString('hex'))
|
||||
push.notifyDeviceConnected(sessionToken.uid, deviceName, result.id)
|
||||
}
|
||||
if (isPlaceholderDevice) {
|
||||
log.info({
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = function (log, error) {
|
|||
return function start(bounceQueue, db) {
|
||||
|
||||
function accountDeleted(uid, email) {
|
||||
log.info({ op: 'accountDeleted', uid: uid.toString('hex'), email: email })
|
||||
log.info({ op: 'accountDeleted', uid: uid, email: email })
|
||||
}
|
||||
|
||||
function gotError(email, err) {
|
||||
|
|
|
@ -67,10 +67,6 @@ function isSampledUser (sampleRate, uid, key) {
|
|||
return false
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(uid)) {
|
||||
uid = uid.toString('hex')
|
||||
}
|
||||
|
||||
// Extract the maximum entropy we can safely handle as a number then reduce
|
||||
// it to a value between 0 and 1 for comparison against the sample rate.
|
||||
const cohort = parseInt(
|
||||
|
|
19
lib/log.js
19
lib/log.js
|
@ -9,7 +9,6 @@ const util = require('util')
|
|||
const mozlog = require('mozlog')
|
||||
const config = require('../config')
|
||||
const logConfig = config.get('log')
|
||||
const unbuffer = require('./crypto/butil').unbuffer
|
||||
|
||||
|
||||
function Lug(options) {
|
||||
|
@ -110,10 +109,10 @@ Lug.prototype.summary = function (request, response) {
|
|||
if (line.code >= 500) {
|
||||
line.trace = request.app.traced
|
||||
line.stack = response.stack
|
||||
this.error(unbuffer(line, true), response.message)
|
||||
this.error(line, response.message)
|
||||
}
|
||||
else {
|
||||
this.info(unbuffer(line, true))
|
||||
this.info(line)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +125,7 @@ Lug.prototype.notifyAttachedServices = function (name, request, data) {
|
|||
metricsContextData => {
|
||||
var e = {
|
||||
event: name,
|
||||
data: unbuffer(data)
|
||||
data: data
|
||||
}
|
||||
e.data.metricsContext = metricsContextData
|
||||
this.notifier.send(e)
|
||||
|
@ -159,7 +158,6 @@ Lug.prototype.flowEvent = function (data) {
|
|||
this.logger.info('flowEvent', data)
|
||||
}
|
||||
|
||||
var onUnhandledRejection
|
||||
module.exports = function (level, name, options) {
|
||||
if (arguments.length === 1 && typeof level === 'object') {
|
||||
options = level
|
||||
|
@ -181,16 +179,5 @@ module.exports = function (level, name, options) {
|
|||
}
|
||||
)
|
||||
|
||||
if (onUnhandledRejection) {
|
||||
process.removeListener('unhandledRejection', onUnhandledRejection)
|
||||
}
|
||||
onUnhandledRejection = (reason, promise) => {
|
||||
log.fatal({
|
||||
op: 'promise.unhandledRejection',
|
||||
error: reason
|
||||
})
|
||||
}
|
||||
process.on('unhandledRejection', onUnhandledRejection)
|
||||
|
||||
return log
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ module.exports = function (log, config) {
|
|||
|
||||
if (request.payload && request.payload.uid && request.payload.code) {
|
||||
return {
|
||||
uid: Buffer(request.payload.uid, 'hex'),
|
||||
uid: request.payload.uid,
|
||||
id: request.payload.code
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,12 +189,11 @@ function optionallySetService (data, request) {
|
|||
|
||||
function coalesceUid (data, request) {
|
||||
if (data && data.uid) {
|
||||
return Buffer.isBuffer(data.uid) ? data.uid.toString('hex') : data.uid
|
||||
return data.uid
|
||||
}
|
||||
|
||||
return request.auth &&
|
||||
request.auth.credentials &&
|
||||
request.auth.credentials.uid &&
|
||||
request.auth.credentials.uid.toString('hex')
|
||||
request.auth.credentials.uid
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
const P = require('./promise')
|
||||
const Poolee = require('poolee')
|
||||
const unbufferDatum = require('./crypto/butil').unbufferDatum
|
||||
|
||||
function parseUrl(url) {
|
||||
var match = /([a-zA-Z]+):\/\/(\S+)/.exec(url)
|
||||
|
@ -43,7 +42,7 @@ Pool.prototype.request = function (method, path, data) {
|
|||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: data ? JSON.stringify(data, unbufferDatum) : undefined
|
||||
data: data ? JSON.stringify(data) : undefined
|
||||
},
|
||||
handleResponse
|
||||
)
|
||||
|
|
10
lib/push.js
10
lib/push.js
|
@ -134,7 +134,7 @@ module.exports = function (log, db, config) {
|
|||
function reportPushError(err, uid, deviceId) {
|
||||
log.error({
|
||||
op: LOG_OP_PUSH_TO_DEVICES,
|
||||
uid: uid.toString('hex'),
|
||||
uid: uid,
|
||||
deviceId: deviceId,
|
||||
err: err
|
||||
})
|
||||
|
@ -323,7 +323,7 @@ module.exports = function (log, db, config) {
|
|||
version: PUSH_PAYLOAD_SCHEMA_VERSION,
|
||||
command: PUSH_COMMANDS.ACCOUNT_DESTROYED,
|
||||
data: {
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
}
|
||||
}))
|
||||
var options = { data: data, TTL: TTL_ACCOUNT_DESTROYED }
|
||||
|
@ -348,7 +348,7 @@ module.exports = function (log, db, config) {
|
|||
function (devices) {
|
||||
if (options.excludedDeviceIds) {
|
||||
devices = devices.filter(function(device) {
|
||||
return options.excludedDeviceIds.indexOf(device.id.toString('hex')) === -1
|
||||
return options.excludedDeviceIds.indexOf(device.id) === -1
|
||||
})
|
||||
}
|
||||
var pushOptions = filterOptions(options)
|
||||
|
@ -372,7 +372,7 @@ module.exports = function (log, db, config) {
|
|||
return db.devices(uid).then(
|
||||
function (devices) {
|
||||
devices = devices.filter(function(device) {
|
||||
return ids.indexOf(device.id.toString('hex')) !== -1
|
||||
return ids.indexOf(device.id) !== -1
|
||||
})
|
||||
if (devices.length === 0) {
|
||||
return P.reject('Devices ids not found in devices')
|
||||
|
@ -435,7 +435,7 @@ module.exports = function (log, db, config) {
|
|||
reportPushError(new Error(ERR_TOO_MANY_DEVICES), uid, null)
|
||||
}
|
||||
return P.each(devices, function(device) {
|
||||
var deviceId = device.id.toString('hex')
|
||||
var deviceId = device.id
|
||||
|
||||
log.trace({
|
||||
op: LOG_OP_PUSH_TO_DEVICES,
|
||||
|
|
|
@ -99,7 +99,7 @@ module.exports = (
|
|||
var form = request.payload
|
||||
var query = request.query
|
||||
var email = form.email
|
||||
var authPW = Buffer(form.authPW, 'hex')
|
||||
var authPW = form.authPW
|
||||
var locale = request.app.acceptLanguage
|
||||
var userAgentString = request.headers['user-agent']
|
||||
var service = form.service || query.service
|
||||
|
@ -158,7 +158,7 @@ module.exports = (
|
|||
throw error.verifiedSecondaryEmailAlreadyExists()
|
||||
}
|
||||
|
||||
return db.deleteEmail(Buffer.from(secondaryEmailRecord.uid, 'hex'), secondaryEmailRecord.email)
|
||||
return db.deleteEmail(secondaryEmailRecord.uid, secondaryEmailRecord.email)
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.errno !== error.ERRNO.SECONDARY_EMAIL_UNKNOWN) {
|
||||
|
@ -179,14 +179,11 @@ module.exports = (
|
|||
return P.resolve()
|
||||
}
|
||||
function generateRandomValues() {
|
||||
return random(16)
|
||||
.then(bytes => {
|
||||
emailCode = bytes
|
||||
tokenVerificationId = bytes
|
||||
return random(32)
|
||||
})
|
||||
.then(bytes => {
|
||||
authSalt = bytes
|
||||
return random.hex(16, 32)
|
||||
.then(hexes => {
|
||||
emailCode = hexes[0]
|
||||
tokenVerificationId = emailCode
|
||||
authSalt = hexes[1]
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -212,15 +209,15 @@ module.exports = (
|
|||
})
|
||||
}
|
||||
|
||||
return random(64)
|
||||
.then(bytes => db.createAccount({
|
||||
uid: uuid.v4('binary'),
|
||||
return random.hex(32, 32)
|
||||
.then(hexes => db.createAccount({
|
||||
uid: uuid.v4('binary').toString('hex'),
|
||||
createdAt: Date.now(),
|
||||
email: email,
|
||||
emailCode: emailCode,
|
||||
emailVerified: preVerified,
|
||||
kA: bytes.slice(0, 32), // 0..31
|
||||
wrapWrapKb: bytes.slice(32), // 32..63
|
||||
kA: hexes[0],
|
||||
wrapWrapKb: hexes[1],
|
||||
accountResetToken: null,
|
||||
passwordForgotToken: null,
|
||||
authSalt: authSalt,
|
||||
|
@ -234,7 +231,7 @@ module.exports = (
|
|||
account = result
|
||||
|
||||
return request.emitMetricsEvent('account.created', {
|
||||
uid: account.uid.toString('hex')
|
||||
uid: account.uid
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -291,7 +288,7 @@ module.exports = (
|
|||
// so stash the data against a synthesized "token" instead.
|
||||
return request.stashMetricsContext({
|
||||
uid: account.uid,
|
||||
id: account.emailCode.toString('hex')
|
||||
id: account.emailCode
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -320,7 +317,7 @@ module.exports = (
|
|||
.then(function () {
|
||||
// only create reminder if sendVerifyCode succeeds
|
||||
verificationReminder.create({
|
||||
uid: account.uid.toString('hex')
|
||||
uid: account.uid
|
||||
}).catch(function (err) {
|
||||
log.error({op: 'Account.verificationReminder.create', err: err})
|
||||
})
|
||||
|
@ -329,7 +326,7 @@ module.exports = (
|
|||
// Log server-side metrics for confirming verification rates
|
||||
log.info({
|
||||
op: 'account.create.confirm.start',
|
||||
uid: account.uid.toString('hex'),
|
||||
uid: account.uid,
|
||||
tokenVerificationId: tokenVerificationId
|
||||
})
|
||||
}
|
||||
|
@ -341,7 +338,7 @@ module.exports = (
|
|||
// Log possible email bounce, used for confirming verification rates
|
||||
log.error({
|
||||
op: 'account.create.confirm.error',
|
||||
uid: account.uid.toString('hex'),
|
||||
uid: account.uid,
|
||||
err: err,
|
||||
tokenVerificationId: tokenVerificationId
|
||||
})
|
||||
|
@ -385,13 +382,13 @@ module.exports = (
|
|||
|
||||
function createResponse () {
|
||||
var response = {
|
||||
uid: account.uid.toString('hex'),
|
||||
sessionToken: sessionToken.data.toString('hex'),
|
||||
uid: account.uid,
|
||||
sessionToken: sessionToken.data,
|
||||
authAt: sessionToken.lastAuthAt()
|
||||
}
|
||||
|
||||
if (keyFetchToken) {
|
||||
response.keyFetchToken = keyFetchToken.data.toString('hex')
|
||||
response.keyFetchToken = keyFetchToken.data
|
||||
}
|
||||
|
||||
return P.resolve(response)
|
||||
|
@ -435,7 +432,7 @@ module.exports = (
|
|||
|
||||
const form = request.payload
|
||||
const email = form.email
|
||||
const authPW = Buffer(form.authPW, 'hex')
|
||||
const authPW = form.authPW
|
||||
const service = request.payload.service || request.query.service
|
||||
const redirectTo = request.payload.redirectTo
|
||||
const resume = request.payload.resume
|
||||
|
@ -587,7 +584,7 @@ module.exports = (
|
|||
if (requestNow - code.createdAt > unblockCodeLifetime) {
|
||||
log.info({
|
||||
op: 'Account.login.unblockCode.expired',
|
||||
uid: emailRecord.uid.toString('hex')
|
||||
uid: emailRecord.uid
|
||||
})
|
||||
throw error.invalidUnblockCode()
|
||||
}
|
||||
|
@ -648,14 +645,14 @@ module.exports = (
|
|||
|
||||
log.info({
|
||||
op: 'Account.history.verified',
|
||||
uid: emailRecord.uid.toString('hex'),
|
||||
uid: emailRecord.uid,
|
||||
events: events.length,
|
||||
recency: coarseRecency
|
||||
})
|
||||
} else {
|
||||
log.info({
|
||||
op: 'Account.history.unverified',
|
||||
uid: emailRecord.uid.toString('hex'),
|
||||
uid: emailRecord.uid,
|
||||
events: events.length
|
||||
})
|
||||
}
|
||||
|
@ -667,7 +664,7 @@ module.exports = (
|
|||
log.error({
|
||||
op: 'Account.history.error',
|
||||
err: err,
|
||||
uid: emailRecord.uid.toString('hex')
|
||||
uid: emailRecord.uid
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -722,7 +719,7 @@ module.exports = (
|
|||
}
|
||||
|
||||
return request.emitMetricsEvent('account.login', {
|
||||
uid: emailRecord.uid.toString('hex')
|
||||
uid: emailRecord.uid
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -754,7 +751,7 @@ module.exports = (
|
|||
if (securityEventVerified && securityEventRecency < allowedRecency) {
|
||||
log.info({
|
||||
op: 'Account.ipprofiling.seenAddress',
|
||||
uid: account.uid.toString('hex')
|
||||
uid: account.uid
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
@ -768,7 +765,7 @@ module.exports = (
|
|||
if (accountAge <= skipForNewAccounts.maxAge) {
|
||||
log.info({
|
||||
op: 'account.signin.confirm.bypass.age',
|
||||
uid: account.uid.toString('hex')
|
||||
uid: account.uid
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
@ -801,8 +798,8 @@ module.exports = (
|
|||
return P.resolve()
|
||||
.then(() => {
|
||||
if (needsVerificationId) {
|
||||
return random(16).then(bytes => {
|
||||
tokenVerificationId = bytes
|
||||
return random.hex(16).then(hex => {
|
||||
tokenVerificationId = hex
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -832,7 +829,7 @@ module.exports = (
|
|||
// so stash the data against a synthesized "token" instead.
|
||||
return request.stashMetricsContext({
|
||||
uid: emailRecord.uid,
|
||||
id: tokenVerificationId.toString('hex')
|
||||
id: tokenVerificationId
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -885,7 +882,7 @@ module.exports = (
|
|||
if (didSigninUnblock) {
|
||||
log.info({
|
||||
op: 'Account.login.unverified.unblocked',
|
||||
uid: emailRecord.uid.toString('hex')
|
||||
uid: emailRecord.uid
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -967,7 +964,7 @@ module.exports = (
|
|||
if (doSigninConfirmation) {
|
||||
log.info({
|
||||
op: 'account.signin.confirm.start',
|
||||
uid: emailRecord.uid.toString('hex'),
|
||||
uid: emailRecord.uid,
|
||||
tokenVerificationId: tokenVerificationId
|
||||
})
|
||||
|
||||
|
@ -1011,8 +1008,8 @@ module.exports = (
|
|||
|
||||
function createResponse () {
|
||||
var response = {
|
||||
uid: sessionToken.uid.toString('hex'),
|
||||
sessionToken: sessionToken.data.toString('hex'),
|
||||
uid: sessionToken.uid,
|
||||
sessionToken: sessionToken.data,
|
||||
verified: sessionToken.emailVerified,
|
||||
authAt: sessionToken.lastAuthAt()
|
||||
}
|
||||
|
@ -1022,7 +1019,7 @@ module.exports = (
|
|||
return P.resolve(response)
|
||||
}
|
||||
|
||||
response.keyFetchToken = keyFetchToken.data.toString('hex')
|
||||
response.keyFetchToken = keyFetchToken.data
|
||||
|
||||
if (! emailRecord.emailVerified) {
|
||||
response.verified = false
|
||||
|
@ -1057,7 +1054,7 @@ module.exports = (
|
|||
reply({ exists: true, locale: sessionToken.locale })
|
||||
}
|
||||
else if (request.query.uid) {
|
||||
var uid = Buffer(request.query.uid, 'hex')
|
||||
var uid = request.query.uid
|
||||
db.account(uid)
|
||||
.then(
|
||||
function (account) {
|
||||
|
@ -1134,7 +1131,7 @@ module.exports = (
|
|||
if (auth.strategy === 'sessionToken') {
|
||||
uid = auth.credentials.uid
|
||||
} else {
|
||||
uid = Buffer(auth.credentials.user, 'hex')
|
||||
uid = auth.credentials.user
|
||||
}
|
||||
function hasProfileItemScope(item) {
|
||||
if (auth.strategy === 'sessionToken') {
|
||||
|
@ -1197,14 +1194,14 @@ module.exports = (
|
|||
.then(
|
||||
function () {
|
||||
return request.emitMetricsEvent('account.keyfetch', {
|
||||
uid: keyFetchToken.uid.toString('hex')
|
||||
uid: keyFetchToken.uid
|
||||
})
|
||||
}
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
return {
|
||||
bundle: keyFetchToken.keyBundle.toString('hex')
|
||||
bundle: keyFetchToken.keyBundle
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -1275,7 +1272,7 @@ module.exports = (
|
|||
}
|
||||
} else if (sessionToken.deviceId) {
|
||||
// Keep the old id, which is probably from a synthesized device record
|
||||
payload.id = sessionToken.deviceId.toString('hex')
|
||||
payload.id = sessionToken.deviceId
|
||||
}
|
||||
|
||||
if (payload.pushCallback && (! payload.pushPublicKey || ! payload.pushAuthKey)) {
|
||||
|
@ -1284,9 +1281,7 @@ module.exports = (
|
|||
}
|
||||
|
||||
devices.upsert(request, sessionToken, payload).then(
|
||||
function (device) {
|
||||
reply(butil.unbuffer(device))
|
||||
},
|
||||
reply,
|
||||
reply
|
||||
)
|
||||
|
||||
|
@ -1295,7 +1290,7 @@ module.exports = (
|
|||
// Check if anything has actually changed, and log lots metrics on what.
|
||||
function isSpuriousUpdate(payload, token) {
|
||||
var spurious = true
|
||||
if (! token.deviceId || payload.id !== token.deviceId.toString('hex')) {
|
||||
if (! token.deviceId || payload.id !== token.deviceId) {
|
||||
spurious = false
|
||||
}
|
||||
if (payload.name && payload.name !== token.deviceName) {
|
||||
|
@ -1369,19 +1364,18 @@ module.exports = (
|
|||
}
|
||||
|
||||
var endpointAction = 'devicesNotify'
|
||||
var stringUid = uid.toString('hex')
|
||||
|
||||
function catchPushError(err) {
|
||||
// push may fail due to not found devices or a bad push action
|
||||
// log the error but still respond with a 200.
|
||||
log.error({
|
||||
op: 'Account.devicesNotify',
|
||||
uid: stringUid,
|
||||
uid: uid,
|
||||
error: err
|
||||
})
|
||||
}
|
||||
|
||||
return customs.checkAuthenticated(endpointAction, ip, stringUid)
|
||||
return customs.checkAuthenticated(endpointAction, ip, uid)
|
||||
.then(function () {
|
||||
if (body.to === 'all') {
|
||||
push.pushToAllDevices(uid, endpointAction, pushOptions)
|
||||
|
@ -1400,12 +1394,12 @@ module.exports = (
|
|||
if (payload.data.collections.length === 1 && payload.data.collections[0] === 'clients') {
|
||||
var deviceId = undefined
|
||||
if (sessionToken.deviceId) {
|
||||
deviceId = sessionToken.deviceId.toString('hex')
|
||||
deviceId = sessionToken.deviceId
|
||||
}
|
||||
return request.emitMetricsEvent('sync.sentTabToDevice', {
|
||||
device_id: deviceId,
|
||||
service: 'sync',
|
||||
uid: stringUid
|
||||
uid: uid
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1457,7 +1451,7 @@ module.exports = (
|
|||
}
|
||||
|
||||
device.isCurrentDevice =
|
||||
device.sessionToken.toString('hex') === sessionToken.tokenId.toString('hex')
|
||||
device.sessionToken === sessionToken.tokenId
|
||||
|
||||
device.lastAccessTimeFormatted = localizeTimestamp.format(device.lastAccessTime,
|
||||
request.headers['accept-language'])
|
||||
|
@ -1469,7 +1463,7 @@ module.exports = (
|
|||
delete device.uaOSVersion
|
||||
delete device.uaDeviceType
|
||||
|
||||
return butil.unbuffer(device)
|
||||
return device
|
||||
}))
|
||||
},
|
||||
reply
|
||||
|
@ -1509,7 +1503,7 @@ module.exports = (
|
|||
db.sessions(uid).then(
|
||||
function (sessions) {
|
||||
reply(sessions.map(function (session) {
|
||||
session.id = session.tokenId.toString('hex')
|
||||
session.id = session.tokenId
|
||||
// if session has a device record
|
||||
session.isDevice = !! session.deviceId
|
||||
|
||||
|
@ -1523,7 +1517,7 @@ module.exports = (
|
|||
session.deviceType = session.uaDeviceType || 'desktop'
|
||||
}
|
||||
|
||||
session.isCurrentDevice = session.id === sessionToken.tokenId.toString('hex')
|
||||
session.isCurrentDevice = session.id === sessionToken.tokenId
|
||||
|
||||
session.lastAccessTimeFormatted = localizeTimestamp.format(session.lastAccessTime,
|
||||
request.headers['accept-language'])
|
||||
|
@ -1541,7 +1535,7 @@ module.exports = (
|
|||
delete session.uaOSVersion
|
||||
delete session.uaDeviceType
|
||||
|
||||
return butil.unbuffer(session)
|
||||
return session
|
||||
}))
|
||||
},
|
||||
reply
|
||||
|
@ -1582,7 +1576,7 @@ module.exports = (
|
|||
function (res) {
|
||||
result = res
|
||||
return request.emitMetricsEvent('device.deleted', {
|
||||
uid: uid.toString('hex'),
|
||||
uid: uid,
|
||||
device_id: id
|
||||
})
|
||||
}
|
||||
|
@ -1837,9 +1831,8 @@ module.exports = (
|
|||
}
|
||||
},
|
||||
handler: function (request, reply) {
|
||||
const uidHex = request.payload.uid
|
||||
const uid = Buffer(uidHex, 'hex')
|
||||
const code = Buffer(request.payload.code, 'hex')
|
||||
const uid = request.payload.uid
|
||||
const code = request.payload.code
|
||||
const service = request.payload.service || request.query.service
|
||||
const reminder = request.payload.reminder || request.query.reminder
|
||||
const type = request.payload.type || request.query.type
|
||||
|
@ -1880,11 +1873,11 @@ module.exports = (
|
|||
return db.accountEmails(account.uid)
|
||||
.then((emails) => {
|
||||
const isEmailVerification = emails.some((email) => {
|
||||
if (email.emailCode && (code.toString('hex') === email.emailCode)) {
|
||||
if (email.emailCode && (code === email.emailCode)) {
|
||||
matchedEmail = email
|
||||
log.info({
|
||||
op: 'account.verifyEmail.secondary.started',
|
||||
uid: uidHex,
|
||||
uid: uid,
|
||||
code: request.payload.code
|
||||
})
|
||||
return true
|
||||
|
@ -1901,7 +1894,7 @@ module.exports = (
|
|||
if (matchedEmail.isVerified) {
|
||||
log.info({
|
||||
op: 'account.verifyEmail.secondary.already-verified',
|
||||
uid: uidHex,
|
||||
uid: uid,
|
||||
code: request.payload.code
|
||||
})
|
||||
return P.resolve()
|
||||
|
@ -1911,7 +1904,7 @@ module.exports = (
|
|||
.then(() => {
|
||||
log.info({
|
||||
op: 'account.verifyEmail.secondary.confirmed',
|
||||
uid: uidHex,
|
||||
uid: uid,
|
||||
code: request.payload.code
|
||||
})
|
||||
return mailer.sendPostVerifySecondaryEmail(
|
||||
|
@ -1935,7 +1928,7 @@ module.exports = (
|
|||
log.error({
|
||||
op: 'Account.RecoveryEmailVerify',
|
||||
err: err,
|
||||
uid: uidHex,
|
||||
uid: uid,
|
||||
code: code
|
||||
})
|
||||
}
|
||||
|
@ -1958,11 +1951,11 @@ module.exports = (
|
|||
// Don't log sign-in confirmation success for the account verification case
|
||||
log.info({
|
||||
op: 'account.signin.confirm.success',
|
||||
uid: uidHex,
|
||||
uid: uid,
|
||||
code: request.payload.code
|
||||
})
|
||||
request.emitMetricsEvent('account.confirmed', {
|
||||
uid: uidHex
|
||||
uid: uid
|
||||
})
|
||||
push.notifyUpdate(uid, 'accountConfirm')
|
||||
}
|
||||
|
@ -1974,7 +1967,7 @@ module.exports = (
|
|||
}
|
||||
log.error({
|
||||
op: 'account.signin.confirm.invalid',
|
||||
uid: uidHex,
|
||||
uid: uid,
|
||||
code: request.payload.code,
|
||||
error: err
|
||||
})
|
||||
|
@ -1982,7 +1975,7 @@ module.exports = (
|
|||
})
|
||||
.then(function () {
|
||||
if (device) {
|
||||
push.notifyDeviceConnected(uid, device.name, device.id.toString('hex'))
|
||||
push.notifyDeviceConnected(uid, device.name, device.id)
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
|
@ -2005,7 +1998,7 @@ module.exports = (
|
|||
})
|
||||
.then(function () {
|
||||
return request.emitMetricsEvent('account.verified', {
|
||||
uid: uidHex
|
||||
uid: uid
|
||||
})
|
||||
})
|
||||
.then(function () {
|
||||
|
@ -2019,7 +2012,7 @@ module.exports = (
|
|||
name: reminderOp
|
||||
})
|
||||
return request.emitMetricsEvent('account.reminder', {
|
||||
uid: uidHex
|
||||
uid: uid
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -2028,7 +2021,7 @@ module.exports = (
|
|||
push.notifyUpdate(uid, 'accountVerify')
|
||||
// remove verification reminders
|
||||
verificationReminder.delete({
|
||||
uid: uidHex
|
||||
uid: uid
|
||||
}).catch(function (err) {
|
||||
log.error({op: 'Account.RecoveryEmailVerify', err: err})
|
||||
})
|
||||
|
@ -2190,7 +2183,7 @@ module.exports = (
|
|||
// Only delete secondary email if it is unverified and does not belong
|
||||
// to the current user.
|
||||
if (! secondaryEmailRecord.isVerified && ! butil.buffersAreEqual(secondaryEmailRecord.uid, uid)) {
|
||||
return db.deleteEmail(Buffer.from(secondaryEmailRecord.uid, 'hex'), secondaryEmailRecord.email)
|
||||
return db.deleteEmail(secondaryEmailRecord.uid, secondaryEmailRecord.email)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
@ -2201,9 +2194,9 @@ module.exports = (
|
|||
}
|
||||
|
||||
function generateRandomValues() {
|
||||
return random(16)
|
||||
.then(bytes => {
|
||||
emailData.emailCode = bytes
|
||||
return random.hex(16)
|
||||
.then(hex => {
|
||||
emailData.emailCode = hex
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2374,7 +2367,7 @@ module.exports = (
|
|||
}
|
||||
},
|
||||
handler: function (request, reply) {
|
||||
var uid = Buffer(request.payload.uid, 'hex')
|
||||
var uid = request.payload.uid
|
||||
var code = request.payload.unblockCode.toUpperCase()
|
||||
|
||||
log.begin('Account.RejectUnblockCode', request)
|
||||
|
@ -2413,7 +2406,7 @@ module.exports = (
|
|||
handler: function accountReset(request, reply) {
|
||||
log.begin('Account.reset', request)
|
||||
var accountResetToken = request.auth.credentials
|
||||
var authPW = Buffer(request.payload.authPW, 'hex')
|
||||
var authPW = request.payload.authPW
|
||||
var account, sessionToken, keyFetchToken, verifyHash, wrapKb, devicesToNotify
|
||||
var hasSessionToken = request.payload.sessionToken
|
||||
|
||||
|
@ -2448,10 +2441,10 @@ module.exports = (
|
|||
|
||||
function resetAccountData () {
|
||||
let authSalt, password, wrapWrapKb
|
||||
return random(64)
|
||||
.then(bytes => {
|
||||
authSalt = bytes.slice(0, 32) // 0..31
|
||||
wrapWrapKb = bytes.slice(32) // 32..63
|
||||
return random.hex(32, 32)
|
||||
.then(hexes => {
|
||||
authSalt = hexes[0]
|
||||
wrapWrapKb = hexes[1]
|
||||
password = new Password(authPW, authSalt, config.verifierVersion)
|
||||
return password.verifyHash()
|
||||
})
|
||||
|
@ -2482,7 +2475,7 @@ module.exports = (
|
|||
function (accountData) {
|
||||
account = accountData
|
||||
return request.emitMetricsEvent('account.reset', {
|
||||
uid: account.uid.toString('hex')
|
||||
uid: account.uid
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -2574,14 +2567,14 @@ module.exports = (
|
|||
|
||||
|
||||
var response = {
|
||||
uid: sessionToken.uid.toString('hex'),
|
||||
sessionToken: sessionToken.data.toString('hex'),
|
||||
uid: sessionToken.uid,
|
||||
sessionToken: sessionToken.data,
|
||||
verified: sessionToken.emailVerified,
|
||||
authAt: sessionToken.lastAuthAt()
|
||||
}
|
||||
|
||||
if (requestHelper.wantsKeys(request)) {
|
||||
response.keyFetchToken = keyFetchToken.data.toString('hex')
|
||||
response.keyFetchToken = keyFetchToken.data
|
||||
}
|
||||
|
||||
return response
|
||||
|
@ -2602,7 +2595,7 @@ module.exports = (
|
|||
handler: function accountDestroy(request, reply) {
|
||||
log.begin('Account.destroy', request)
|
||||
var form = request.payload
|
||||
var authPW = Buffer(form.authPW, 'hex')
|
||||
var authPW = form.authPW
|
||||
var uid
|
||||
var devicesToNotify
|
||||
customs.check(
|
||||
|
@ -2643,7 +2636,7 @@ module.exports = (
|
|||
.then(
|
||||
function () {
|
||||
return request.emitMetricsEvent('account.deleted', {
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
})
|
||||
}
|
||||
)
|
||||
|
|
|
@ -54,7 +54,7 @@ module.exports = function (
|
|||
handler: function (request, reply) {
|
||||
log.begin('Password.changeStart', request)
|
||||
var form = request.payload
|
||||
var oldAuthPW = Buffer(form.oldAuthPW, 'hex')
|
||||
var oldAuthPW = form.oldAuthPW
|
||||
|
||||
customs.check(
|
||||
request,
|
||||
|
@ -119,8 +119,8 @@ module.exports = function (
|
|||
function (tokens) {
|
||||
reply(
|
||||
{
|
||||
keyFetchToken: tokens.keyFetchToken.data.toString('hex'),
|
||||
passwordChangeToken: tokens.passwordChangeToken.data.toString('hex'),
|
||||
keyFetchToken: tokens.keyFetchToken.data,
|
||||
passwordChangeToken: tokens.passwordChangeToken.data,
|
||||
verified: tokens.keyFetchToken.emailVerified
|
||||
}
|
||||
)
|
||||
|
@ -150,8 +150,8 @@ module.exports = function (
|
|||
handler: function (request, reply) {
|
||||
log.begin('Password.changeFinish', request)
|
||||
var passwordChangeToken = request.auth.credentials
|
||||
var authPW = Buffer(request.payload.authPW, 'hex')
|
||||
var wrapKb = Buffer(request.payload.wrapKb, 'hex')
|
||||
var authPW = request.payload.authPW
|
||||
var wrapKb = request.payload.wrapKb
|
||||
var sessionTokenId = request.payload.sessionToken
|
||||
var wantsKeys = requestHelper.wantsKeys(request)
|
||||
const ip = request.app.clientAddress
|
||||
|
@ -169,8 +169,7 @@ module.exports = function (
|
|||
|
||||
function getSessionVerificationStatus() {
|
||||
if (sessionTokenId) {
|
||||
var tokenId = Buffer(sessionTokenId, 'hex')
|
||||
return db.sessionTokenWithVerificationStatus(tokenId)
|
||||
return db.sessionTokenWithVerificationStatus(sessionTokenId)
|
||||
.then(
|
||||
function (tokenData) {
|
||||
verifiedStatus = tokenData.tokenVerified
|
||||
|
@ -196,9 +195,9 @@ module.exports = function (
|
|||
|
||||
function changePassword() {
|
||||
let authSalt, password
|
||||
return random(32)
|
||||
.then(bytes => {
|
||||
authSalt = bytes
|
||||
return random.hex(32)
|
||||
.then(hex => {
|
||||
authSalt = hex
|
||||
password = new Password(authPW, authSalt, verifierVersion)
|
||||
return db.deletePasswordChangeToken(passwordChangeToken)
|
||||
})
|
||||
|
@ -230,7 +229,7 @@ module.exports = function (
|
|||
.then(
|
||||
function (result) {
|
||||
return request.emitMetricsEvent('account.changedPassword', {
|
||||
uid: passwordChangeToken.uid.toString('hex')
|
||||
uid: passwordChangeToken.uid
|
||||
})
|
||||
.then(
|
||||
function () {
|
||||
|
@ -287,7 +286,7 @@ module.exports = function (
|
|||
return P.resolve()
|
||||
.then(() => {
|
||||
if (! verifiedStatus) {
|
||||
return random(16)
|
||||
return random.hex(16)
|
||||
}
|
||||
})
|
||||
.then(maybeToken => {
|
||||
|
@ -337,14 +336,14 @@ module.exports = function (
|
|||
}
|
||||
|
||||
var response = {
|
||||
uid: sessionToken.uid.toString('hex'),
|
||||
sessionToken: sessionToken.data.toString('hex'),
|
||||
uid: sessionToken.uid,
|
||||
sessionToken: sessionToken.data,
|
||||
verified: sessionToken.emailVerified && sessionToken.tokenVerified,
|
||||
authAt: sessionToken.lastAuthAt()
|
||||
}
|
||||
|
||||
if (wantsKeys) {
|
||||
response.keyFetchToken = keyFetchToken.data.toString('hex')
|
||||
response.keyFetchToken = keyFetchToken.data
|
||||
}
|
||||
|
||||
return response
|
||||
|
@ -467,7 +466,7 @@ module.exports = function (
|
|||
function (passwordForgotToken) {
|
||||
reply(
|
||||
{
|
||||
passwordForgotToken: passwordForgotToken.data.toString('hex'),
|
||||
passwordForgotToken: passwordForgotToken.data,
|
||||
ttl: passwordForgotToken.ttl(),
|
||||
codeLength: passwordForgotToken.passCode.length,
|
||||
tries: passwordForgotToken.tries
|
||||
|
@ -563,7 +562,7 @@ module.exports = function (
|
|||
function () {
|
||||
reply(
|
||||
{
|
||||
passwordForgotToken: passwordForgotToken.data.toString('hex'),
|
||||
passwordForgotToken: passwordForgotToken.data,
|
||||
ttl: passwordForgotToken.ttl(),
|
||||
codeLength: passwordForgotToken.passCode.length,
|
||||
tries: passwordForgotToken.tries
|
||||
|
@ -596,7 +595,7 @@ module.exports = function (
|
|||
handler: function (request, reply) {
|
||||
log.begin('Password.forgotVerify', request)
|
||||
var passwordForgotToken = request.auth.credentials
|
||||
var code = Buffer(request.payload.code, 'hex')
|
||||
var code = request.payload.code
|
||||
|
||||
request.validateMetricsContext()
|
||||
|
||||
|
@ -653,7 +652,7 @@ module.exports = function (
|
|||
|
||||
reply(
|
||||
{
|
||||
accountResetToken: accountResetToken.data.toString('hex')
|
||||
accountResetToken: accountResetToken.data
|
||||
}
|
||||
)
|
||||
},
|
||||
|
|
|
@ -28,20 +28,19 @@ module.exports = function (log, db) {
|
|||
log.begin('Session.destroy', request)
|
||||
var sessionToken = request.auth.credentials
|
||||
var uid = request.auth.credentials.uid
|
||||
var uidHex = uid.toString('hex')
|
||||
|
||||
return P.resolve()
|
||||
.then(() => {
|
||||
if (request.payload && request.payload.customSessionToken) {
|
||||
const customTokenHex = request.payload.customSessionToken
|
||||
const customSessionToken = request.payload.customSessionToken
|
||||
|
||||
return db.sessionToken(customTokenHex)
|
||||
return db.sessionToken(customSessionToken)
|
||||
.then(function (tokenData) {
|
||||
// NOTE: validate that the token belongs to the same user
|
||||
if (tokenData && uidHex === tokenData.uid.toString('hex')) {
|
||||
if (tokenData && uid === tokenData.uid) {
|
||||
sessionToken = {
|
||||
id: Buffer.from(customTokenHex),
|
||||
uid: Buffer.from(uidHex)
|
||||
id: customSessionToken,
|
||||
uid: uid,
|
||||
}
|
||||
|
||||
return sessionToken
|
||||
|
@ -83,7 +82,7 @@ module.exports = function (log, db) {
|
|||
const sessionToken = request.auth.credentials
|
||||
reply({
|
||||
state: sessionToken.state,
|
||||
uid: sessionToken.uid.toString('hex')
|
||||
uid: sessionToken.uid
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ module.exports = (log, signer, db, domain, devices) => {
|
|||
.then(
|
||||
function () {
|
||||
if (sessionToken.deviceId) {
|
||||
deviceId = sessionToken.deviceId.toString('hex')
|
||||
deviceId = sessionToken.deviceId
|
||||
} else if (! service || service === 'sync') {
|
||||
// Synthesize a device record for Sync sessions that don't already have one.
|
||||
// Include the UA info so that we can synthesize a device name
|
||||
|
@ -74,7 +74,7 @@ module.exports = (log, signer, db, domain, devices) => {
|
|||
return devices.upsert(request, sessionToken, deviceInfo)
|
||||
.then(
|
||||
function (result) {
|
||||
deviceId = result.id.toString('hex')
|
||||
deviceId = result.id
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ module.exports = (log, signer, db, domain, devices) => {
|
|||
})
|
||||
}
|
||||
}
|
||||
uid = sessionToken.uid.toString('hex')
|
||||
uid = sessionToken.uid
|
||||
|
||||
return signer.sign(
|
||||
{
|
||||
|
|
|
@ -32,11 +32,11 @@ module.exports = (log, db, customs) => {
|
|||
request.validateMetricsContext()
|
||||
|
||||
customs.checkIpOnly(request, 'consumeSigninCode')
|
||||
.then(bufferizeSigninCode)
|
||||
.then(hexSigninCode)
|
||||
.then(consumeSigninCode)
|
||||
.then(reply, reply)
|
||||
|
||||
function bufferizeSigninCode () {
|
||||
function hexSigninCode () {
|
||||
let base64 = request.payload.code.replace(/-/g, '+').replace(/_/g, '/')
|
||||
|
||||
const padCount = base64.length % 4
|
||||
|
@ -44,7 +44,7 @@ module.exports = (log, db, customs) => {
|
|||
base64 += '='
|
||||
}
|
||||
|
||||
return Buffer.from(base64, 'base64')
|
||||
return Buffer.from(base64, 'base64').toString('hex')
|
||||
}
|
||||
|
||||
function consumeSigninCode (code) {
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
* 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 butil = require('../crypto/butil')
|
||||
var log = require('./log')('db')
|
||||
var P = require('../promise')
|
||||
var Pool = require('./pool')
|
||||
var qs = require('querystring')
|
||||
|
||||
var bufferize = butil.bufferize
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
function DB(options) {
|
||||
|
@ -36,10 +33,9 @@ module.exports = function () {
|
|||
}
|
||||
|
||||
DB.prototype.emailRecord = function (email) {
|
||||
return this.pool.get('/emailRecord/' + Buffer(email, 'utf8').toString('hex'))
|
||||
return this.pool.get('/emailRecord/' + Buffer.from(email, 'utf8').toString('hex'))
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
data.emailVerified = !! data.emailVerified
|
||||
return data
|
||||
},
|
||||
|
@ -51,10 +47,9 @@ module.exports = function () {
|
|||
|
||||
DB.prototype.account = function (uid) {
|
||||
log.trace({ op: 'DB.account', uid: uid })
|
||||
return this.pool.get('/account/' + uid.toString('hex'))
|
||||
return this.pool.get('/account/' + uid)
|
||||
.then(
|
||||
function (body) {
|
||||
var data = bufferize(body)
|
||||
function (data) {
|
||||
data.emailVerified = !! data.emailVerified
|
||||
return data
|
||||
},
|
||||
|
|
|
@ -61,8 +61,8 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
email: primaryEmail,
|
||||
flowId: opts.flowId,
|
||||
flowBeginTime: opts.flowBeginTime,
|
||||
uid: account.uid.toString('hex'),
|
||||
code: opts.code.toString('hex'),
|
||||
uid: account.uid,
|
||||
code: opts.code,
|
||||
service: opts.service,
|
||||
redirectTo: opts.redirectTo,
|
||||
resume: opts.resume,
|
||||
|
@ -84,7 +84,7 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
.then(function (mailer) {
|
||||
return mailer.verifyLoginEmail({
|
||||
acceptLanguage: opts.acceptLanguage || defaultLanguage,
|
||||
code: opts.code.toString('hex'),
|
||||
code: opts.code,
|
||||
ccEmails: ccEmails,
|
||||
email: primaryEmail,
|
||||
ip: opts.ip,
|
||||
|
@ -99,7 +99,7 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
uaBrowserVersion: opts.uaBrowserVersion,
|
||||
uaOS: opts.uaOS,
|
||||
uaOSVersion: opts.uaOSVersion,
|
||||
uid: account.uid.toString('hex')
|
||||
uid: account.uid
|
||||
})
|
||||
})
|
||||
},
|
||||
|
@ -111,7 +111,7 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
.then(function (mailer) {
|
||||
return mailer.verifySecondaryEmail({
|
||||
acceptLanguage: opts.acceptLanguage || defaultLanguage,
|
||||
code: opts.code.toString('hex'),
|
||||
code: opts.code,
|
||||
email: verifyEmailAddress,
|
||||
ip: opts.ip,
|
||||
location: opts.location,
|
||||
|
@ -123,7 +123,7 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
uaBrowserVersion: opts.uaBrowserVersion,
|
||||
uaOS: opts.uaOS,
|
||||
uaOSVersion: opts.uaOSVersion,
|
||||
uid: account.uid.toString('hex'),
|
||||
uid: account.uid,
|
||||
primaryEmail: primaryEmail
|
||||
})
|
||||
})
|
||||
|
@ -139,8 +139,8 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
email: primaryEmail,
|
||||
flowId: opts.flowId,
|
||||
flowBeginTime: opts.flowBeginTime,
|
||||
token: opts.token.data.toString('hex'),
|
||||
code: opts.code.toString('hex'),
|
||||
token: opts.token.data,
|
||||
code: opts.code,
|
||||
service: opts.service,
|
||||
redirectTo: opts.redirectTo,
|
||||
resume: opts.resume,
|
||||
|
@ -253,7 +253,7 @@ module.exports = function (log, config, error, bounces, translator, sender) {
|
|||
uaBrowserVersion: opts.uaBrowserVersion,
|
||||
uaOS: opts.uaOS,
|
||||
uaOSVersion: opts.uaOSVersion,
|
||||
uid: account.uid.toString('hex'),
|
||||
uid: account.uid,
|
||||
unblockCode: opts.unblockCode
|
||||
})
|
||||
})
|
||||
|
|
|
@ -98,7 +98,11 @@ module.exports = function (log, translator, templates, config) {
|
|||
}).text
|
||||
}
|
||||
|
||||
function urlSafeBase64 (buffer) {
|
||||
return buffer.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
||||
function urlSafeBase64 (hex) {
|
||||
return Buffer.from(hex, 'hex')
|
||||
.toString('base64')
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ module.exports = function (mailer, db, options) {
|
|||
// if account is not verified then send the reminder
|
||||
mailer.verificationReminderEmail({
|
||||
email: account.email,
|
||||
uid: account.uid.toString('hex'),
|
||||
code: account.emailCode.toString('hex'),
|
||||
uid: account.uid,
|
||||
code: account.emailCode,
|
||||
type: reminderData.type,
|
||||
acceptLanguage: account.locale
|
||||
})
|
||||
|
|
|
@ -77,7 +77,7 @@ function create(log, error, config, routes, db, translator) {
|
|||
if (! HEX_STRING.test(id)) {
|
||||
return process.nextTick(cb.bind(null, null, null)) // not found
|
||||
}
|
||||
dbGetFn(Buffer(id, 'hex'))
|
||||
dbGetFn(id)
|
||||
.then(
|
||||
function (token) {
|
||||
if (token.expired(Date.now())) {
|
||||
|
|
|
@ -34,6 +34,8 @@ module.exports = {
|
|||
// Encrypt the given buffer into a hex ciphertext string.
|
||||
//
|
||||
bundle(key, keyInfo, payload) {
|
||||
key = Buffer.from(key, 'hex')
|
||||
payload = Buffer.from(payload, 'hex')
|
||||
return deriveBundleKeys(key, keyInfo, payload.length)
|
||||
.then(
|
||||
function (keys) {
|
||||
|
@ -49,7 +51,8 @@ module.exports = {
|
|||
// Decrypt the given hex string into a buffer of plaintext data.
|
||||
//
|
||||
unbundle(key, keyInfo, payload) {
|
||||
payload = Buffer(payload, 'hex')
|
||||
key = Buffer.from(key, 'hex')
|
||||
payload = Buffer.from(payload, 'hex')
|
||||
var ciphertext = payload.slice(0, -32)
|
||||
var expectedHmac = payload.slice(-32)
|
||||
return deriveBundleKeys(key, keyInfo, ciphertext.length)
|
||||
|
@ -61,7 +64,7 @@ module.exports = {
|
|||
if (! butil.buffersAreEqual(mac, expectedHmac)) {
|
||||
throw error.invalidSignature()
|
||||
}
|
||||
return butil.xorBuffers(ciphertext, keys.xorKey)
|
||||
return butil.xorBuffers(ciphertext, keys.xorKey).toString('hex')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports = function (log, Token) {
|
|||
return token.bundleKeys(details.kA, details.wrapKb)
|
||||
.then(
|
||||
function (keyBundle) {
|
||||
token.keyBundle = Buffer(keyBundle, 'hex') //TODO see if we can skip hex
|
||||
token.keyBundle = keyBundle
|
||||
return token
|
||||
}
|
||||
)
|
||||
|
@ -48,6 +48,8 @@ module.exports = function (log, Token) {
|
|||
|
||||
KeyFetchToken.prototype.bundleKeys = function (kA, wrapKb) {
|
||||
log.trace({ op: 'keyFetchToken.bundleKeys', id: this.id })
|
||||
kA = Buffer.from(kA, 'hex')
|
||||
wrapKb = Buffer.from(wrapKb, 'hex')
|
||||
return this.bundle('account/keys', Buffer.concat([kA, wrapKb]))
|
||||
}
|
||||
|
||||
|
@ -57,8 +59,8 @@ module.exports = function (log, Token) {
|
|||
.then(
|
||||
function (plaintext) {
|
||||
return {
|
||||
kA: plaintext.slice(0, 32),
|
||||
wrapKb: plaintext.slice(32, 64)
|
||||
kA: plaintext.slice(0, 64), // strings, not buffers
|
||||
wrapKb: plaintext.slice(64, 128)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = (log, Token, lifetime) => {
|
|||
uid: details.uid,
|
||||
email: details.email
|
||||
})
|
||||
return random(16)
|
||||
return random.hex(16)
|
||||
.then(bytes => {
|
||||
details.passCode = bytes
|
||||
details.tries = 3
|
||||
|
|
|
@ -27,6 +27,8 @@ const Bundle = require('./bundle')
|
|||
const hkdf = require('../crypto/hkdf')
|
||||
const random = require('../crypto/random')
|
||||
|
||||
const KEYS = ['data', 'tokenId', 'authKey', 'bundleKey']
|
||||
|
||||
module.exports = (log, config) => {
|
||||
|
||||
// Token constructor.
|
||||
|
@ -35,10 +37,9 @@ module.exports = (log, config) => {
|
|||
// You probably want to call a helper rather than use this directly.
|
||||
//
|
||||
function Token(keys, details) {
|
||||
this.data = keys.data
|
||||
this.tokenId = keys.tokenId
|
||||
this.authKey = keys.authKey
|
||||
this.bundleKey = keys.bundleKey
|
||||
KEYS.forEach(name => {
|
||||
this[name] = keys[name] && keys[name].toString('hex')
|
||||
})
|
||||
this.algorithm = 'sha256'
|
||||
this.uid = details.uid || null
|
||||
this.lifetime = details.lifetime || Infinity
|
||||
|
@ -62,7 +63,7 @@ module.exports = (log, config) => {
|
|||
// This uses known seed data to derive the keys.
|
||||
//
|
||||
Token.createTokenFromHexData = function(TokenType, hexData, details) {
|
||||
var data = Buffer(hexData, 'hex')
|
||||
var data = Buffer.from(hexData, 'hex')
|
||||
return Token.deriveTokenKeys(TokenType, data)
|
||||
.then(keys => new TokenType(keys, details || {}))
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ module.exports = (log, config) => {
|
|||
Token.prototype,
|
||||
{
|
||||
id: {
|
||||
get: function () { return this.tokenId.toString('hex') }
|
||||
get: function () { return this.tokenId }
|
||||
},
|
||||
key: {
|
||||
get: function () { return this.authKey }
|
||||
|
|
|
@ -272,7 +272,7 @@ module.exports = config => {
|
|||
)
|
||||
.then(
|
||||
function () {
|
||||
this.wrapKb = butil.xorBuffers(this.kB, this.unwrapBKey)
|
||||
this.wrapKb = butil.xorBuffers(this.kB, this.unwrapBKey).toString('hex')
|
||||
return this.api.passwordChangeFinish(this.passwordChangeToken, this.authPW, this.wrapKb, headers, sessionToken)
|
||||
}.bind(this)
|
||||
)
|
||||
|
@ -312,7 +312,7 @@ module.exports = config => {
|
|||
this.keyFetchToken = null
|
||||
this.kA = keys.kA
|
||||
this.wrapKb = keys.wrapKb
|
||||
this.kB = keys.kB = butil.xorBuffers(this.wrapKb, this.unwrapBKey)
|
||||
this.kB = keys.kB = butil.xorBuffers(this.wrapKb, this.unwrapBKey).toString('hex')
|
||||
return keys
|
||||
}.bind(this),
|
||||
function (err) {
|
||||
|
|
|
@ -51,56 +51,4 @@ describe('butil', () => {
|
|||
|
||||
})
|
||||
|
||||
describe('.bufferize', () => {
|
||||
it(
|
||||
'should bufferize hex-looking values',
|
||||
() => {
|
||||
const argument = { foo: 'bar', baz: 'f00d' }
|
||||
const result = butil.bufferize(argument)
|
||||
assert.notEqual(result, argument)
|
||||
assert.equal(Object.keys(result).length, Object.keys(argument).length)
|
||||
assert.equal(typeof result.foo, 'string')
|
||||
assert.equal(result.foo, argument.foo)
|
||||
assert.ok(Buffer.isBuffer(result.baz))
|
||||
assert.equal(result.baz.length, 2)
|
||||
assert.equal(result.baz[0], 0xf0)
|
||||
assert.equal(result.baz[1], 0x0d)
|
||||
}
|
||||
)
|
||||
|
||||
it(
|
||||
'should convert in-place',
|
||||
() => {
|
||||
const argument = { foo: 'beef', bar: 'baz' }
|
||||
const result = butil.bufferize(argument, { inplace: true })
|
||||
assert.equal(result, argument)
|
||||
assert.equal(Object.keys(result).length, 2)
|
||||
assert.ok(Buffer.isBuffer(result.foo))
|
||||
assert.equal(result.foo.length, 2)
|
||||
assert.equal(result.foo[0], 0xbe)
|
||||
assert.equal(result.foo[1], 0xef)
|
||||
assert.equal(typeof result.bar, 'string')
|
||||
assert.equal(result.bar, 'baz')
|
||||
}
|
||||
)
|
||||
|
||||
it(
|
||||
'should ignore exceptions',
|
||||
() => {
|
||||
const argument = { foo: 'bar', baz: 'f00d', qux: 'beef' }
|
||||
const result = butil.bufferize(argument, { ignore: [ 'baz' ] })
|
||||
assert.notEqual(argument, result)
|
||||
assert.equal(Object.keys(result).length, Object.keys(argument).length)
|
||||
assert.equal(typeof result.foo, 'string')
|
||||
assert.equal(result.foo, argument.foo)
|
||||
assert.equal(typeof result.baz, 'string')
|
||||
assert.equal(result.baz, argument.baz)
|
||||
assert.ok(Buffer.isBuffer(result.qux))
|
||||
assert.equal(result.qux.length, 2)
|
||||
assert.equal(result.qux[0], 0xbe)
|
||||
assert.equal(result.qux[1], 0xef)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* 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/. */
|
||||
|
||||
'use strict'
|
||||
|
||||
const assert = require('insist')
|
||||
|
||||
const random = require('../../../lib/crypto/random')
|
||||
|
||||
describe('random', () => {
|
||||
|
||||
it('should generate random bytes', () => {
|
||||
return random(16)
|
||||
.then(bytes => {
|
||||
assert(Buffer.isBuffer(bytes))
|
||||
assert.equal(bytes.length, 16)
|
||||
|
||||
return random(32)
|
||||
})
|
||||
.then(bytes => {
|
||||
assert(Buffer.isBuffer(bytes))
|
||||
assert.equal(bytes.length, 32)
|
||||
})
|
||||
})
|
||||
|
||||
it('should generate several random bytes buffers', () => {
|
||||
return random(16, 8)
|
||||
.then(bufs => {
|
||||
assert.equal(bufs.length, 2)
|
||||
|
||||
const a = bufs[0]
|
||||
const b = bufs[1]
|
||||
|
||||
assert(Buffer.isBuffer(a))
|
||||
assert.equal(a.length, 16)
|
||||
|
||||
assert(Buffer.isBuffer(b))
|
||||
assert.equal(b.length, 8)
|
||||
})
|
||||
})
|
||||
|
||||
describe('hex', () => {
|
||||
it('should generate a random hex string', () => {
|
||||
return random.hex(16)
|
||||
.then(str => {
|
||||
assert.equal(typeof str, 'string')
|
||||
assert(/^[0-9a-f]+$/g.test(str))
|
||||
assert.equal(str.length, 32)
|
||||
|
||||
return random.hex(32)
|
||||
})
|
||||
.then(str => {
|
||||
assert.equal(typeof str, 'string')
|
||||
assert.equal(str.length, 64)
|
||||
})
|
||||
})
|
||||
|
||||
it('should generate several random hex strings', () => {
|
||||
return random.hex(16, 8)
|
||||
.then(strs => {
|
||||
assert.equal(strs.length, 2)
|
||||
|
||||
const a = strs[0]
|
||||
const b = strs[1]
|
||||
|
||||
assert.equal(typeof a, 'string')
|
||||
assert(/^[0-9a-f]+$/g.test(a))
|
||||
assert.equal(a.length, 32)
|
||||
|
||||
assert.equal(typeof b, 'string')
|
||||
assert(/^[0-9a-f]+$/g.test(b))
|
||||
assert.equal(b.length, 16)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -24,7 +24,7 @@ describe('devices', () => {
|
|||
beforeEach(() => {
|
||||
log = mocks.spyLog()
|
||||
deviceCreatedAt = Date.now()
|
||||
deviceId = crypto.randomBytes(16)
|
||||
deviceId = crypto.randomBytes(16).toString('hex')
|
||||
device = {
|
||||
name: 'foo',
|
||||
type: 'bar'
|
||||
|
@ -60,7 +60,7 @@ describe('devices', () => {
|
|||
log: log
|
||||
})
|
||||
sessionToken = {
|
||||
tokenId: crypto.randomBytes(16),
|
||||
tokenId: crypto.randomBytes(16).toString('hex'),
|
||||
uid: uuid.v4('binary'),
|
||||
tokenVerified: true
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ describe('devices', () => {
|
|||
event: 'device.created',
|
||||
service: undefined,
|
||||
userAgent: 'test user-agent',
|
||||
uid: sessionToken.uid.toString('hex'),
|
||||
device_id: deviceId.toString('hex'),
|
||||
uid: sessionToken.uid,
|
||||
device_id: deviceId,
|
||||
is_placeholder: false
|
||||
}, 'event data was correct')
|
||||
|
||||
|
@ -117,7 +117,7 @@ describe('devices', () => {
|
|||
assert.equal(args.length, 3, 'push.notifyDeviceConnected was passed three arguments')
|
||||
assert.equal(args[0], sessionToken.uid, 'first argument was uid')
|
||||
assert.equal(args[1], device.name, 'second arguent was device name')
|
||||
assert.equal(args[2], deviceId.toString('hex'), 'third argument was device id')
|
||||
assert.equal(args[2], deviceId, 'third argument was device id')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -189,8 +189,8 @@ describe('devices', () => {
|
|||
event: 'device.updated',
|
||||
service: undefined,
|
||||
userAgent: 'test user-agent',
|
||||
uid: sessionToken.uid.toString('hex'),
|
||||
device_id: deviceId.toString('hex'),
|
||||
uid: sessionToken.uid,
|
||||
device_id: deviceId,
|
||||
is_placeholder: false
|
||||
}, 'event data was correct')
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ describe('features', () => {
|
|||
it(
|
||||
'isSampledUser',
|
||||
() => {
|
||||
let uid = Buffer.alloc(32, 0xff)
|
||||
let uid = Array(64).fill('f').join('')
|
||||
let sampleRate = 1
|
||||
hashResult = Array(40).fill('f').join('')
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ var mocks = {
|
|||
})
|
||||
}
|
||||
mocks.mozlog.config = sinon.spy()
|
||||
const log = proxyquire('../../lib/log', mocks)('foo', 'bar')
|
||||
const log = proxyquire('../../lib/log', mocks)('foo', 'test')
|
||||
|
||||
const emitRouteFlowEvent = sinon.spy()
|
||||
|
||||
|
@ -33,7 +33,7 @@ describe('log', () => {
|
|||
var args = mocks.mozlog.config.args[0]
|
||||
assert.equal(args.length, 1, 'mozlog.config was passed one argument')
|
||||
assert.equal(Object.keys(args[0]).length, 4, 'number of mozlog.config arguments was correct')
|
||||
assert.equal(args[0].app, 'bar', 'app property was correct')
|
||||
assert.equal(args[0].app, 'test', 'app property was correct')
|
||||
assert.equal(args[0].level, 'foo', 'level property was correct')
|
||||
assert.equal(args[0].stream, process.stderr, 'stream property was correct')
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ describe('metricsContext', () => {
|
|||
() => {
|
||||
results.set = P.resolve('wibble')
|
||||
const token = {
|
||||
uid: Buffer.alloc(32, 'cd'),
|
||||
uid: Array(64).fill('c').join(''),
|
||||
id: 'foo'
|
||||
}
|
||||
return metricsContext.stash.call({
|
||||
|
@ -107,7 +107,7 @@ describe('metricsContext', () => {
|
|||
metricsContext: 'bar'
|
||||
}
|
||||
}, {
|
||||
uid: Buffer.alloc(32, 'cd'),
|
||||
uid: Array(64).fill('c').join(''),
|
||||
id: 'foo'
|
||||
}).then(result => {
|
||||
assert.equal(result, undefined, 'result is undefined')
|
||||
|
@ -157,7 +157,7 @@ describe('metricsContext', () => {
|
|||
return metricsContext.stash.call({
|
||||
payload: {}
|
||||
}, {
|
||||
uid: Buffer.alloc(32, 'cd'),
|
||||
uid: Array(64).fill('c').join(''),
|
||||
id: 'foo'
|
||||
}).then(result => {
|
||||
assert.equal(result, undefined, 'result is undefined')
|
||||
|
@ -235,7 +235,7 @@ describe('metricsContext', () => {
|
|||
() => {
|
||||
const time = Date.now() - 1
|
||||
const token = {
|
||||
uid: Buffer.alloc(32, '77'),
|
||||
uid: Array(64).fill('7').join(''),
|
||||
id: 'wibble'
|
||||
}
|
||||
results.get = P.resolve({
|
||||
|
@ -270,7 +270,7 @@ describe('metricsContext', () => {
|
|||
'metricsContext.gather with fake token',
|
||||
() => {
|
||||
const time = Date.now() - 1
|
||||
const uid = Buffer.alloc(32, '77')
|
||||
const uid = Array(64).fill('7').join('')
|
||||
const id = 'wibble'
|
||||
results.get = P.resolve({
|
||||
flowId: 'flowId',
|
||||
|
@ -278,7 +278,7 @@ describe('metricsContext', () => {
|
|||
})
|
||||
return metricsContext.gather.call({
|
||||
payload: {
|
||||
uid: uid.toString('hex'),
|
||||
uid: uid,
|
||||
code: id
|
||||
}
|
||||
}, {}).then(function (result) {
|
||||
|
@ -306,7 +306,7 @@ describe('metricsContext', () => {
|
|||
return metricsContext.gather.call({
|
||||
auth: {
|
||||
credentials: {
|
||||
uid: Buffer.alloc(32, 'cd')
|
||||
uid: Array(64).fill('c').join('')
|
||||
}
|
||||
}
|
||||
}, {}).then(function (result) {
|
||||
|
@ -355,7 +355,7 @@ describe('metricsContext', () => {
|
|||
return metricsContext.gather.call({
|
||||
auth: {
|
||||
credentials: {
|
||||
uid: Buffer.alloc(8, 'ff'),
|
||||
uid: Array(16).fill('f').join(''),
|
||||
id: 'bar'
|
||||
}
|
||||
},
|
||||
|
@ -383,7 +383,7 @@ describe('metricsContext', () => {
|
|||
return metricsContext.gather.call({
|
||||
auth: {
|
||||
credentials: {
|
||||
uid: Buffer.alloc(8, 'ff'),
|
||||
uid: Array(16).fill('f').join(''),
|
||||
id: 'bar'
|
||||
}
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ describe('metricsContext', () => {
|
|||
'metricsContext.clear with token',
|
||||
() => {
|
||||
const token = {
|
||||
uid: Buffer.alloc(32, '77'),
|
||||
uid: Array(64).fill('7').join(''),
|
||||
id: 'wibble'
|
||||
}
|
||||
return metricsContext.clear.call({
|
||||
|
@ -420,11 +420,11 @@ describe('metricsContext', () => {
|
|||
it(
|
||||
'metricsContext.clear with fake token',
|
||||
() => {
|
||||
const uid = Buffer.alloc(32, '66')
|
||||
const uid = Array(64).fill('6').join('')
|
||||
const id = 'blee'
|
||||
return metricsContext.clear.call({
|
||||
payload: {
|
||||
uid: uid.toString('hex'),
|
||||
uid: uid,
|
||||
code: id
|
||||
}
|
||||
}).then(() => {
|
||||
|
@ -449,7 +449,7 @@ describe('metricsContext', () => {
|
|||
'metricsContext.clear with memcached error',
|
||||
() => {
|
||||
const token = {
|
||||
uid: Buffer.alloc(32, '77'),
|
||||
uid: Array(64).fill('7').join(''),
|
||||
id: 'wibble'
|
||||
}
|
||||
results.del = P.reject(new Error('blee'))
|
||||
|
|
|
@ -144,7 +144,7 @@ describe('metrics/events', () => {
|
|||
const metricsContext = mocks.mockMetricsContext()
|
||||
const request = mocks.mockRequest({
|
||||
credentials: {
|
||||
uid: Buffer.from('deadbeef', 'hex')
|
||||
uid: 'deadbeef'
|
||||
},
|
||||
metricsContext,
|
||||
payload: {
|
||||
|
@ -289,7 +289,7 @@ describe('metrics/events', () => {
|
|||
}
|
||||
}
|
||||
})
|
||||
return events.emit.call(request, 'account.reminder', { uid: Buffer.from('deadbeef', 'hex') })
|
||||
return events.emit.call(request, 'account.reminder', { uid: 'deadbeef' })
|
||||
.then(() => {
|
||||
assert.equal(metricsContext.gather.callCount, 1, 'metricsContext.gather was called once')
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ var path = require('path')
|
|||
const P = require(`${ROOT_DIR}/lib/promise`)
|
||||
const mocks = require('../mocks')
|
||||
const mockLog = mocks.mockLog
|
||||
var mockUid = Buffer.from('foo')
|
||||
var mockUid = 'deadbeef'
|
||||
var mockConfig = {}
|
||||
|
||||
const PUSH_PAYLOADS_SCHEMA_PATH = `${ROOT_DIR}/docs/pushpayloads.schema.json`
|
||||
|
@ -746,7 +746,7 @@ describe('push', () => {
|
|||
version: 1,
|
||||
command: 'fxaccounts:account_destroyed',
|
||||
data: {
|
||||
uid: mockUid.toString('hex')
|
||||
uid: mockUid
|
||||
}
|
||||
}
|
||||
return push.notifyAccountDestroyed(mockUid, mockDevices).catch(function (err) {
|
||||
|
|
|
@ -19,6 +19,10 @@ var log = require('../../../lib/log')
|
|||
|
||||
var TEST_EMAIL = 'foo@gmail.com'
|
||||
|
||||
function hexString(bytes) {
|
||||
return crypto.randomBytes(bytes).toString('hex')
|
||||
}
|
||||
|
||||
var makeRoutes = function (options, requireMocks) {
|
||||
options = options || {}
|
||||
|
||||
|
@ -90,7 +94,7 @@ describe('/account/reset', function () {
|
|||
log: mockLog,
|
||||
metricsContext: mockMetricsContext,
|
||||
payload: {
|
||||
authPW: crypto.randomBytes(32).toString('hex'),
|
||||
authPW: hexString(32),
|
||||
sessionToken: true,
|
||||
metricsContext: {
|
||||
flowBeginTime: Date.now(),
|
||||
|
@ -101,14 +105,14 @@ describe('/account/reset', function () {
|
|||
keys: 'true'
|
||||
}
|
||||
})
|
||||
const keyFetchTokenId = crypto.randomBytes(16)
|
||||
const sessionTokenId = crypto.randomBytes(16)
|
||||
const keyFetchTokenId = hexString(16)
|
||||
const sessionTokenId = hexString(16)
|
||||
const mockDB = mocks.mockDB({
|
||||
uid: uid,
|
||||
email: TEST_EMAIL,
|
||||
keyFetchTokenId: keyFetchTokenId,
|
||||
sessionTokenId: sessionTokenId,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: hexString(32)
|
||||
})
|
||||
var mockCustoms = mocks.mockCustoms()
|
||||
var mockPush = mocks.mockPush()
|
||||
|
@ -142,7 +146,7 @@ describe('/account/reset', function () {
|
|||
event: 'account.reset',
|
||||
service: undefined,
|
||||
userAgent: 'test user-agent',
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
}, 'event data was correct')
|
||||
|
||||
assert.equal(mockDB.securityEvent.callCount, 1, 'db.securityEvent was called')
|
||||
|
@ -195,7 +199,7 @@ describe('/account/create', () => {
|
|||
metricsContext: mockMetricsContext,
|
||||
payload: {
|
||||
email: TEST_EMAIL,
|
||||
authPW: crypto.randomBytes(32).toString('hex'),
|
||||
authPW: hexString(32),
|
||||
service: 'sync',
|
||||
metricsContext: {
|
||||
flowBeginTime: Date.now(),
|
||||
|
@ -207,9 +211,9 @@ describe('/account/create', () => {
|
|||
}
|
||||
})
|
||||
var clientAddress = mockRequest.app.clientAddress
|
||||
var emailCode = crypto.randomBytes(16)
|
||||
var keyFetchTokenId = crypto.randomBytes(16)
|
||||
var sessionTokenId = crypto.randomBytes(16)
|
||||
var emailCode = hexString(16)
|
||||
var keyFetchTokenId = hexString(16)
|
||||
var sessionTokenId = hexString(16)
|
||||
var uid = uuid.v4('binary')
|
||||
var mockDB = mocks.mockDB({
|
||||
email: TEST_EMAIL,
|
||||
|
@ -277,7 +281,7 @@ describe('/account/create', () => {
|
|||
event: 'account.created',
|
||||
service: 'sync',
|
||||
userAgent: 'test user-agent',
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
}, 'event data was correct')
|
||||
|
||||
assert.equal(mockLog.flowEvent.callCount, 1, 'log.flowEvent was called once')
|
||||
|
@ -290,7 +294,7 @@ describe('/account/create', () => {
|
|||
flow_id: 'F1031DF1031DF1031DF1031DF1031DF1031DF1031DF1031DF1031DF1031DF103',
|
||||
locale: 'en-GB',
|
||||
time: now,
|
||||
uid: uid.toString('hex'),
|
||||
uid: uid,
|
||||
userAgent: 'test user-agent'
|
||||
}, 'flow event data was correct')
|
||||
|
||||
|
@ -307,7 +311,7 @@ describe('/account/create', () => {
|
|||
|
||||
args = mockMetricsContext.stash.args[1]
|
||||
assert.equal(args.length, 1, 'metricsContext.stash was passed one argument second time')
|
||||
assert.equal(args[0].id, emailCode.toString('hex'), 'argument was synthesized token')
|
||||
assert.equal(args[0].id, emailCode, 'argument was synthesized token')
|
||||
assert.deepEqual(args[0].uid, uid, 'token.uid was correct')
|
||||
assert.equal(mockMetricsContext.stash.thisValues[1], mockRequest, 'this was request')
|
||||
|
||||
|
@ -369,7 +373,7 @@ describe('/account/login', function () {
|
|||
log: mockLog,
|
||||
metricsContext: mockMetricsContext,
|
||||
payload: {
|
||||
authPW: crypto.randomBytes(32).toString('hex'),
|
||||
authPW: hexString(32),
|
||||
email: TEST_EMAIL,
|
||||
service: 'sync',
|
||||
reason: 'signin',
|
||||
|
@ -386,7 +390,7 @@ describe('/account/login', function () {
|
|||
log: mockLog,
|
||||
metricsContext: mockMetricsContext,
|
||||
payload: {
|
||||
authPW: crypto.randomBytes(32).toString('hex'),
|
||||
authPW: hexString(32),
|
||||
email: 'test@mozilla.com',
|
||||
service: 'dcdb5ae7add825d2',
|
||||
reason: 'signin',
|
||||
|
@ -402,7 +406,7 @@ describe('/account/login', function () {
|
|||
log: mockLog,
|
||||
query: {},
|
||||
payload: {
|
||||
authPW: crypto.randomBytes(32).toString('hex'),
|
||||
authPW: hexString(32),
|
||||
email: TEST_EMAIL,
|
||||
unblockCode: 'ABCD1234',
|
||||
service: 'dcdb5ae7add825d2',
|
||||
|
@ -414,8 +418,8 @@ describe('/account/login', function () {
|
|||
}
|
||||
}
|
||||
})
|
||||
var keyFetchTokenId = crypto.randomBytes(16)
|
||||
var sessionTokenId = crypto.randomBytes(16)
|
||||
var keyFetchTokenId = hexString(16)
|
||||
var sessionTokenId = hexString(16)
|
||||
var uid = uuid.v4('binary')
|
||||
var mockDB = mocks.mockDB({
|
||||
email: TEST_EMAIL,
|
||||
|
@ -495,7 +499,7 @@ describe('/account/login', function () {
|
|||
event: 'account.login',
|
||||
service: 'sync',
|
||||
userAgent: 'test user-agent',
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
}, 'event data was correct')
|
||||
|
||||
assert.equal(mockLog.flowEvent.callCount, 2, 'log.flowEvent was called twice')
|
||||
|
@ -508,7 +512,7 @@ describe('/account/login', function () {
|
|||
flowCompleteSignal: 'account.signed',
|
||||
locale: 'en-US',
|
||||
time: now,
|
||||
uid: uid.toString('hex'),
|
||||
uid: uid,
|
||||
userAgent: 'test user-agent'
|
||||
}, 'first flow event was correct')
|
||||
args = mockLog.flowEvent.args[1]
|
||||
|
@ -571,20 +575,20 @@ describe('/account/login', function () {
|
|||
|
||||
describe('sign-in unverified account', function () {
|
||||
it('sends email code', function () {
|
||||
var emailCode = crypto.randomBytes(16)
|
||||
var emailCode = hexString(16)
|
||||
mockDB.emailRecord = function () {
|
||||
return P.resolve({
|
||||
authSalt: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32),
|
||||
authSalt: hexString(32),
|
||||
data: hexString(32),
|
||||
email: TEST_EMAIL,
|
||||
emailVerified: false,
|
||||
emailCode: emailCode,
|
||||
kA: crypto.randomBytes(32),
|
||||
kA: hexString(32),
|
||||
lastAuthAt: function () {
|
||||
return Date.now()
|
||||
},
|
||||
uid: uid,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: hexString(32)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -612,16 +616,16 @@ describe('/account/login', function () {
|
|||
|
||||
mockDB.emailRecord = function () {
|
||||
return P.resolve({
|
||||
authSalt: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32),
|
||||
authSalt: hexString(32),
|
||||
data: hexString(32),
|
||||
email: TEST_EMAIL,
|
||||
emailVerified: true,
|
||||
kA: crypto.randomBytes(32),
|
||||
kA: hexString(32),
|
||||
lastAuthAt: function () {
|
||||
return Date.now()
|
||||
},
|
||||
uid: uid,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: hexString(32)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -648,16 +652,16 @@ describe('/account/login', function () {
|
|||
it('does not require verification when keys are not requested', function () {
|
||||
mockDB.emailRecord = function () {
|
||||
return P.resolve({
|
||||
authSalt: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32),
|
||||
authSalt: hexString(32),
|
||||
data: hexString(32),
|
||||
email: 'test@mozilla.com',
|
||||
emailVerified: true,
|
||||
kA: crypto.randomBytes(32),
|
||||
kA: hexString(32),
|
||||
lastAuthAt: function () {
|
||||
return Date.now()
|
||||
},
|
||||
uid: uid,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: hexString(32)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -684,16 +688,16 @@ describe('/account/login', function () {
|
|||
mockRequest.payload.email = 'test@mozilla.com'
|
||||
mockDB.emailRecord = function () {
|
||||
return P.resolve({
|
||||
authSalt: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32),
|
||||
authSalt: hexString(32),
|
||||
data: hexString(32),
|
||||
email: mockRequest.payload.email,
|
||||
emailVerified: false,
|
||||
kA: crypto.randomBytes(32),
|
||||
kA: hexString(32),
|
||||
lastAuthAt: function () {
|
||||
return Date.now()
|
||||
},
|
||||
uid: uid,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: hexString(32)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -720,17 +724,17 @@ describe('/account/login', function () {
|
|||
|
||||
mockDB.emailRecord = function () {
|
||||
return P.resolve({
|
||||
authSalt: crypto.randomBytes(32),
|
||||
authSalt: hexString(32),
|
||||
createdAt: Date.now() - accountCreatedSince,
|
||||
data: crypto.randomBytes(32),
|
||||
data: hexString(32),
|
||||
email: mockRequest.payload.email,
|
||||
emailVerified: true,
|
||||
kA: crypto.randomBytes(32),
|
||||
kA: hexString(32),
|
||||
lastAuthAt: function () {
|
||||
return Date.now()
|
||||
},
|
||||
uid: uid,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: hexString(32)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -869,7 +873,7 @@ describe('/account/login', function () {
|
|||
|
||||
assert.equal(!! record, true, 'log.info was called for Account.history')
|
||||
assert.equal(record.op, 'Account.history.verified')
|
||||
assert.equal(record.uid, uid.toString('hex'))
|
||||
assert.equal(record.uid, uid)
|
||||
assert.equal(record.events, 1)
|
||||
assert.equal(record.recency, 'day')
|
||||
})
|
||||
|
@ -895,7 +899,7 @@ describe('/account/login', function () {
|
|||
|
||||
assert.equal(!! record, true, 'log.info was called for Account.history')
|
||||
assert.equal(record.op, 'Account.history.unverified')
|
||||
assert.equal(record.uid, uid.toString('hex'))
|
||||
assert.equal(record.uid, uid)
|
||||
assert.equal(record.events, 1)
|
||||
})
|
||||
})
|
||||
|
@ -1068,14 +1072,14 @@ describe('/account/login', function () {
|
|||
})
|
||||
|
||||
describe('/account/keys', function () {
|
||||
var keyFetchTokenId = crypto.randomBytes(16)
|
||||
var keyFetchTokenId = hexString(16)
|
||||
var uid = uuid.v4('binary')
|
||||
const mockLog = mocks.spyLog()
|
||||
const mockRequest = mocks.mockRequest({
|
||||
credentials: {
|
||||
emailVerified: true,
|
||||
id: keyFetchTokenId.toString('hex'),
|
||||
keyBundle: crypto.randomBytes(16),
|
||||
id: keyFetchTokenId,
|
||||
keyBundle: hexString(16),
|
||||
tokenId: keyFetchTokenId,
|
||||
tokenVerificationId: undefined,
|
||||
tokenVerified: true,
|
||||
|
@ -1092,7 +1096,7 @@ describe('/account/keys', function () {
|
|||
|
||||
it('verified token', function () {
|
||||
return runTest(route, mockRequest, function (response) {
|
||||
assert.deepEqual(response, {bundle: mockRequest.auth.credentials.keyBundle.toString('hex')}, 'response was correct')
|
||||
assert.deepEqual(response, {bundle: mockRequest.auth.credentials.keyBundle}, 'response was correct')
|
||||
|
||||
assert.equal(mockDB.deleteKeyFetchToken.callCount, 1, 'db.deleteKeyFetchToken was called once')
|
||||
var args = mockDB.deleteKeyFetchToken.args[0]
|
||||
|
@ -1106,7 +1110,7 @@ describe('/account/keys', function () {
|
|||
event: 'account.keyfetch',
|
||||
service: undefined,
|
||||
userAgent: 'test user-agent',
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
}, 'event data was correct')
|
||||
})
|
||||
.then(function () {
|
||||
|
@ -1116,7 +1120,7 @@ describe('/account/keys', function () {
|
|||
})
|
||||
|
||||
it('unverified token', function () {
|
||||
mockRequest.auth.credentials.tokenVerificationId = crypto.randomBytes(16)
|
||||
mockRequest.auth.credentials.tokenVerificationId = hexString(16)
|
||||
mockRequest.auth.credentials.tokenVerified = false
|
||||
return runTest(route, mockRequest).then(() => assert.ok(false), response => {
|
||||
assert.equal(response.errno, 104, 'correct errno for unverified account')
|
||||
|
@ -1189,7 +1193,7 @@ describe('/account/destroy', function () {
|
|||
event: 'account.deleted',
|
||||
service: undefined,
|
||||
userAgent: 'test user-agent',
|
||||
uid: uid.toString('hex')
|
||||
uid: uid
|
||||
}, 'event data was correct')
|
||||
})
|
||||
})
|
||||
|
@ -1226,8 +1230,8 @@ describe('/account/sessions', function () {
|
|||
|
||||
var mockRequest = mocks.mockRequest({
|
||||
credentials: {
|
||||
uid: crypto.randomBytes(16),
|
||||
tokenId: crypto.randomBytes(16)
|
||||
uid: hexString(16),
|
||||
tokenId: hexString(16)
|
||||
},
|
||||
payload: {}
|
||||
})
|
||||
|
|
|
@ -78,8 +78,8 @@ function runTest (route, request, assertions) {
|
|||
|
||||
describe('/account/device', function () {
|
||||
var config = {}
|
||||
var uid = uuid.v4('binary')
|
||||
var deviceId = crypto.randomBytes(16)
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var deviceId = crypto.randomBytes(16).toString('hex')
|
||||
var mockRequest = mocks.mockRequest({
|
||||
credentials: {
|
||||
deviceCallbackPublicKey: '',
|
||||
|
@ -87,7 +87,7 @@ describe('/account/device', function () {
|
|||
deviceId: deviceId,
|
||||
deviceName: 'my awesome device',
|
||||
deviceType: 'desktop',
|
||||
tokenId: crypto.randomBytes(16),
|
||||
tokenId: crypto.randomBytes(16).toString('hex'),
|
||||
uid: uid
|
||||
},
|
||||
payload: {
|
||||
|
@ -115,7 +115,7 @@ describe('/account/device', function () {
|
|||
})
|
||||
|
||||
it('different data', function () {
|
||||
mockRequest.auth.credentials.deviceId = crypto.randomBytes(16)
|
||||
mockRequest.auth.credentials.deviceId = crypto.randomBytes(16).toString('hex')
|
||||
var payload = mockRequest.payload
|
||||
payload.name = 'my even awesomer device'
|
||||
payload.type = 'phone'
|
||||
|
@ -164,8 +164,8 @@ describe('/account/device', function () {
|
|||
|
||||
describe('/account/devices/notify', function () {
|
||||
var config = {}
|
||||
var uid = uuid.v4('binary')
|
||||
var deviceId = crypto.randomBytes(16)
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var deviceId = crypto.randomBytes(16).toString('hex')
|
||||
var mockLog = mocks.spyLog()
|
||||
var mockRequest = mocks.mockRequest({
|
||||
log: mockLog,
|
||||
|
@ -396,7 +396,7 @@ describe('/account/devices/notify', function () {
|
|||
|
||||
describe('/account/device/destroy', function () {
|
||||
it('should work', () => {
|
||||
var uid = uuid.v4('binary')
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var deviceId = crypto.randomBytes(16).toString('hex')
|
||||
var mockLog = mocks.spyLog()
|
||||
var mockDB = mocks.mockDB()
|
||||
|
@ -452,17 +452,17 @@ describe('/account/devices', function () {
|
|||
it('should return the devices list', () => {
|
||||
var mockRequest = mocks.mockRequest({
|
||||
credentials: {
|
||||
uid: crypto.randomBytes(16),
|
||||
tokenId: crypto.randomBytes(16)
|
||||
uid: crypto.randomBytes(16).toString('hex'),
|
||||
tokenId: crypto.randomBytes(16).toString('hex')
|
||||
},
|
||||
payload: {}
|
||||
})
|
||||
var unnamedDevice = { sessionToken: crypto.randomBytes(16) }
|
||||
var unnamedDevice = { sessionToken: crypto.randomBytes(16).toString('hex') }
|
||||
var mockDB = mocks.mockDB({
|
||||
devices: [
|
||||
{ name: 'current session', type: 'mobile', sessionToken: mockRequest.auth.credentials.tokenId },
|
||||
{ name: 'has no type', sessionToken: crypto.randomBytes(16) },
|
||||
{ name: 'has device type', sessionToken: crypto.randomBytes(16), uaDeviceType: 'wibble' },
|
||||
{ name: 'has no type', sessionToken: crypto.randomBytes(16).toString('hex') },
|
||||
{ name: 'has device type', sessionToken: crypto.randomBytes(16).toString('hex'), uaDeviceType: 'wibble' },
|
||||
unnamedDevice
|
||||
]
|
||||
})
|
||||
|
|
|
@ -61,11 +61,11 @@ describe('/password', () => {
|
|||
'/forgot/send_code',
|
||||
() => {
|
||||
var mockCustoms = mocks.mockCustoms()
|
||||
var uid = uuid.v4('binary')
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var mockDB = mocks.mockDB({
|
||||
email: TEST_EMAIL,
|
||||
passCode: 'foo',
|
||||
passwordForgotTokenId: crypto.randomBytes(16),
|
||||
passwordForgotTokenId: crypto.randomBytes(16).toString('hex'),
|
||||
uid: uid
|
||||
})
|
||||
var mockMailer = mocks.mockMailer()
|
||||
|
@ -130,7 +130,7 @@ describe('/password', () => {
|
|||
'/forgot/resend_code',
|
||||
() => {
|
||||
var mockCustoms = mocks.mockCustoms()
|
||||
var uid = uuid.v4('binary')
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var mockDB = mocks.mockDB()
|
||||
var mockMailer = mocks.mockMailer()
|
||||
var mockMetricsContext = mocks.mockMetricsContext()
|
||||
|
@ -157,7 +157,7 @@ describe('/password', () => {
|
|||
|
||||
var mockRequest = mocks.mockRequest({
|
||||
credentials: {
|
||||
data: crypto.randomBytes(16),
|
||||
data: crypto.randomBytes(16).toString('hex'),
|
||||
email: TEST_EMAIL,
|
||||
passCode: Buffer('abcdef', 'hex'),
|
||||
ttl: function () { return 17 },
|
||||
|
@ -190,15 +190,15 @@ describe('/password', () => {
|
|||
'/forgot/verify_code',
|
||||
() => {
|
||||
var mockCustoms = mocks.mockCustoms()
|
||||
var uid = uuid.v4('binary')
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var accountResetToken = {
|
||||
data: crypto.randomBytes(16)
|
||||
data: crypto.randomBytes(16).toString('hex')
|
||||
}
|
||||
var mockDB = mocks.mockDB({
|
||||
accountResetToken: accountResetToken,
|
||||
email: TEST_EMAIL,
|
||||
passCode: 'abcdef',
|
||||
passwordForgotTokenId: crypto.randomBytes(16),
|
||||
passwordForgotTokenId: crypto.randomBytes(16).toString('hex'),
|
||||
uid: uid
|
||||
})
|
||||
var mockMailer = mocks.mockMailer()
|
||||
|
@ -264,7 +264,7 @@ describe('/password', () => {
|
|||
it(
|
||||
'smoke',
|
||||
() => {
|
||||
var uid = uuid.v4('binary')
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var mockDB = mocks.mockDB({
|
||||
email: TEST_EMAIL,
|
||||
uid: uid
|
||||
|
@ -324,7 +324,7 @@ describe('/password', () => {
|
|||
it(
|
||||
'succeeds even if notification blocked',
|
||||
() => {
|
||||
var uid = uuid.v4('binary')
|
||||
var uid = uuid.v4('binary').toString('hex')
|
||||
var mockDB = mocks.mockDB({
|
||||
email: TEST_EMAIL,
|
||||
uid: uid
|
||||
|
|
|
@ -12,7 +12,7 @@ var mocks = require('../../mocks')
|
|||
var P = require('../../../lib/promise')
|
||||
|
||||
describe('/certificate/sign', () => {
|
||||
var deviceId = crypto.randomBytes(16)
|
||||
var deviceId = crypto.randomBytes(16).toString('hex')
|
||||
var mockDevices = mocks.mockDevices({
|
||||
deviceId: deviceId
|
||||
})
|
||||
|
@ -24,12 +24,12 @@ describe('/certificate/sign', () => {
|
|||
return Date.now()
|
||||
},
|
||||
locale: 'en',
|
||||
tokenId: crypto.randomBytes(16),
|
||||
tokenId: crypto.randomBytes(16).toString('hex'),
|
||||
uaBrowser: 'Firefox',
|
||||
uaBrowserVersion: '55',
|
||||
uaOS: 'Windows',
|
||||
uaOSVersion: '10',
|
||||
uid: uuid.v4('binary')
|
||||
uid: uuid.v4('binary').toString('hex')
|
||||
},
|
||||
log: mockLog,
|
||||
payload: {
|
||||
|
@ -112,7 +112,7 @@ describe('/certificate/sign', () => {
|
|||
|
||||
it('with deviceId', () => {
|
||||
mockRequest.query.service = 'sync'
|
||||
mockRequest.auth.credentials.deviceId = crypto.randomBytes(16)
|
||||
mockRequest.auth.credentials.deviceId = crypto.randomBytes(16).toString('hex')
|
||||
|
||||
return runTest({
|
||||
devices: mockDevices,
|
||||
|
|
|
@ -45,8 +45,7 @@ describe('/signinCodes/consume:', () => {
|
|||
assert.equal(db.consumeSigninCode.callCount, 1)
|
||||
const args = db.consumeSigninCode.args[0]
|
||||
assert.equal(args.length, 1)
|
||||
assert.ok(Buffer.isBuffer(args[0]))
|
||||
assert.equal(args[0].toString('base64'), '++//ff0=')
|
||||
assert.equal(args[0], 'fbefff7dfd')
|
||||
})
|
||||
|
||||
it('called log.flowEvent correctly', () => {
|
||||
|
|
|
@ -14,8 +14,8 @@ var TEST_EMAIL = 'test@restmail.net'
|
|||
var TEST_ACCOUNT_RECORD = {
|
||||
emailVerified: false,
|
||||
email: TEST_EMAIL,
|
||||
emailCode: Buffer.from('foo'),
|
||||
uid: Buffer.from('bar'),
|
||||
emailCode: 'deadbeaf',
|
||||
uid: 'c0ffee',
|
||||
locale: 'da, en-gb;q=0.8, en;q=0.7'
|
||||
}
|
||||
var REMINDER_TYPE = 'first'
|
||||
|
@ -51,12 +51,12 @@ it('_processReminder sends first reminder for unverified emails', function () {
|
|||
var mailer = new Mailer({}, {}, config.get('smtp'))
|
||||
sandbox.stub(mailer, 'send', function (vals) {
|
||||
assert.equal(vals.acceptLanguage, TEST_ACCOUNT_RECORD.locale, 'correct locale')
|
||||
assert.equal(vals.uid, TEST_ACCOUNT_RECORD.uid.toString('hex'), 'correct uid')
|
||||
assert.equal(vals.uid, TEST_ACCOUNT_RECORD.uid, 'correct uid')
|
||||
assert.equal(vals.email, TEST_ACCOUNT_RECORD.email, 'correct email')
|
||||
assert.equal(vals.template, 'verificationReminderFirstEmail', 'correct template')
|
||||
assert.equal(vals.subject, 'Hello again.', 'correct subject')
|
||||
assert.equal(vals.headers['X-Verify-Code'], TEST_ACCOUNT_RECORD.emailCode.toString('hex'), 'correct code')
|
||||
assert.ok(vals.templateValues.link.indexOf(TEST_ACCOUNT_RECORD.emailCode.toString('hex')) >= 0, 'correct link')
|
||||
assert.equal(vals.headers['X-Verify-Code'], TEST_ACCOUNT_RECORD.emailCode, 'correct code')
|
||||
assert.ok(vals.templateValues.link.indexOf(TEST_ACCOUNT_RECORD.emailCode) >= 0, 'correct link')
|
||||
done()
|
||||
})
|
||||
|
||||
|
@ -71,8 +71,8 @@ it('_processReminder sends second reminder for unverified emails', function () {
|
|||
var mailer = new Mailer({}, {}, config.get('smtp'))
|
||||
sandbox.stub(mailer, 'send', function (vals) {
|
||||
assert.equal(vals.template, 'verificationReminderSecondEmail', 'correct template')
|
||||
assert.equal(vals.headers['X-Verify-Code'], TEST_ACCOUNT_RECORD.emailCode.toString('hex'), 'correct code')
|
||||
assert.ok(vals.templateValues.link.indexOf(TEST_ACCOUNT_RECORD.emailCode.toString('hex')) >= 0, 'correct link')
|
||||
assert.equal(vals.headers['X-Verify-Code'], TEST_ACCOUNT_RECORD.emailCode, 'correct code')
|
||||
assert.ok(vals.templateValues.link.indexOf(TEST_ACCOUNT_RECORD.emailCode) >= 0, 'correct link')
|
||||
done()
|
||||
})
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ const KeyFetchToken = tokens.KeyFetchToken
|
|||
|
||||
const ACCOUNT = {
|
||||
uid: 'xxx',
|
||||
kA: Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex'),
|
||||
wrapKb: Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex'),
|
||||
kA: Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex').toString('hex'),
|
||||
wrapKb: Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex').toString('hex'),
|
||||
emailVerified: true
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,8 @@ describe('KeyFetchToken', () => {
|
|||
'should bundle / unbundle of keys',
|
||||
() => {
|
||||
let token = null
|
||||
const kA = crypto.randomBytes(32)
|
||||
const wrapKb = crypto.randomBytes(32)
|
||||
const kA = crypto.randomBytes(32).toString('hex')
|
||||
const wrapKb = crypto.randomBytes(32).toString('hex')
|
||||
return KeyFetchToken.create(ACCOUNT)
|
||||
.then(
|
||||
function (x) {
|
||||
|
@ -105,8 +105,8 @@ describe('KeyFetchToken', () => {
|
|||
() => {
|
||||
let token1 = null
|
||||
let token2 = null
|
||||
const kA = crypto.randomBytes(32)
|
||||
const wrapKb = crypto.randomBytes(32)
|
||||
const kA = crypto.randomBytes(32).toString('hex')
|
||||
const wrapKb = crypto.randomBytes(32).toString('hex')
|
||||
return KeyFetchToken.create(ACCOUNT)
|
||||
.then(
|
||||
function (x) {
|
||||
|
@ -146,10 +146,10 @@ describe('KeyFetchToken', () => {
|
|||
.then(
|
||||
function (x) {
|
||||
token = x
|
||||
assert.equal(token.data.toString('hex'), tokenData)
|
||||
assert.equal(token.id.toString('hex'), '3d0a7c02a15a62a2882f76e39b6494b500c022a8816e048625a495718998ba60')
|
||||
assert.equal(token.authKey.toString('hex'), '87b8937f61d38d0e29cd2d5600b3f4da0aa48ac41de36a0efe84bb4a9872ceb7')
|
||||
assert.equal(token.bundleKey.toString('hex'), '14f338a9e8c6324d9e102d4e6ee83b209796d5c74bb734a410e729e014a4a546')
|
||||
assert.equal(token.data, tokenData)
|
||||
assert.equal(token.id, '3d0a7c02a15a62a2882f76e39b6494b500c022a8816e048625a495718998ba60')
|
||||
assert.equal(token.authKey, '87b8937f61d38d0e29cd2d5600b3f4da0aa48ac41de36a0efe84bb4a9872ceb7')
|
||||
assert.equal(token.bundleKey, '14f338a9e8c6324d9e102d4e6ee83b209796d5c74bb734a410e729e014a4a546')
|
||||
}
|
||||
)
|
||||
.then(
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
var uuid = require('uuid')
|
||||
|
||||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex')
|
||||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
|
||||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex').toString('hex')
|
||||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex').toString('hex')
|
||||
|
||||
function createTestAccount() {
|
||||
var account = {
|
||||
uid: uuid.v4('binary'),
|
||||
uid: uuid.v4('binary').toString('hex'),
|
||||
email: 'foo' + Math.random() + '@bar.com',
|
||||
emailCode: zeroBuffer16,
|
||||
emailVerified: false,
|
||||
|
|
|
@ -208,14 +208,14 @@ function mockDB (data, errors) {
|
|||
}),
|
||||
createKeyFetchToken: sinon.spy(() => {
|
||||
return P.resolve({
|
||||
data: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32).toString('hex'),
|
||||
tokenId: data.keyFetchTokenId,
|
||||
uid: data.uid
|
||||
})
|
||||
}),
|
||||
createPasswordForgotToken: sinon.spy(() => {
|
||||
return P.resolve({
|
||||
data: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32).toString('hex'),
|
||||
passCode: data.passCode,
|
||||
tokenId: data.passwordForgotTokenId,
|
||||
uid: data.uid,
|
||||
|
@ -226,7 +226,7 @@ function mockDB (data, errors) {
|
|||
}),
|
||||
createSessionToken: sinon.spy(() => {
|
||||
return P.resolve({
|
||||
data: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32).toString('hex'),
|
||||
email: data.email,
|
||||
emailVerified: data.emailVerified,
|
||||
lastAuthAt: () => {
|
||||
|
@ -257,17 +257,17 @@ function mockDB (data, errors) {
|
|||
return P.reject(errors.emailRecord)
|
||||
}
|
||||
return P.resolve({
|
||||
authSalt: crypto.randomBytes(32),
|
||||
authSalt: crypto.randomBytes(32).toString('hex'),
|
||||
createdAt: data.createdAt || Date.now(),
|
||||
data: crypto.randomBytes(32),
|
||||
data: crypto.randomBytes(32).toString('hex'),
|
||||
email: data.email,
|
||||
emailVerified: data.emailVerified,
|
||||
kA: crypto.randomBytes(32),
|
||||
kA: crypto.randomBytes(32).toString('hex'),
|
||||
lastAuthAt: () => {
|
||||
return Date.now()
|
||||
},
|
||||
uid: data.uid,
|
||||
wrapWrapKb: crypto.randomBytes(32)
|
||||
wrapWrapKb: crypto.randomBytes(32).toString('hex')
|
||||
})
|
||||
}),
|
||||
forgotPasswordVerified: sinon.spy(() => {
|
||||
|
@ -313,12 +313,7 @@ function mockPush (methods) {
|
|||
// So far every push method has a uid for first argument, let's keep it simple.
|
||||
PUSH_METHOD_NAMES.forEach((name) => {
|
||||
if (! push[name]) {
|
||||
push[name] = sinon.spy(uid => {
|
||||
if (! (uid instanceof Uint8Array)) {
|
||||
throw new Error('The first param –uid– of ' + name + ' must be a Buffer!')
|
||||
}
|
||||
return P.resolve()
|
||||
})
|
||||
push[name] = sinon.spy(() => P.resolve())
|
||||
}
|
||||
})
|
||||
return push
|
||||
|
@ -330,7 +325,7 @@ function mockDevices (data) {
|
|||
return {
|
||||
upsert: sinon.spy(() => {
|
||||
return P.resolve({
|
||||
id: data.deviceId || crypto.randomBytes(16),
|
||||
id: data.deviceId || crypto.randomBytes(16).toString('hex'),
|
||||
name: data.deviceName || 'mock device name',
|
||||
type: data.deviceType || 'desktop'
|
||||
})
|
||||
|
|
|
@ -93,10 +93,10 @@ describe('remote account reset', function() {
|
|||
)
|
||||
.then(
|
||||
function (keys) {
|
||||
assert.ok(Buffer.isBuffer(keys.wrapKb), 'yep, wrapKb')
|
||||
assert.notDeepEqual(wrapKb, keys.wrapKb, 'wrapKb was reset')
|
||||
assert.deepEqual(kA, keys.kA, 'kA was not reset')
|
||||
assert.equal(client.kB.length, 32, 'kB exists, has the right length')
|
||||
assert.notEqual(wrapKb, keys.wrapKb, 'wrapKb was reset')
|
||||
assert.equal(kA, keys.kA, 'kA was not reset')
|
||||
assert.equal(typeof client.kB, 'string')
|
||||
assert.equal(client.kB.length, 64, 'kB exists, has the right length')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -174,10 +174,10 @@ describe('remote account reset', function() {
|
|||
)
|
||||
.then(
|
||||
function (keys) {
|
||||
assert.ok(Buffer.isBuffer(keys.wrapKb), 'yep, wrapKb')
|
||||
assert.notDeepEqual(wrapKb, keys.wrapKb, 'wrapKb was reset')
|
||||
assert.deepEqual(kA, keys.kA, 'kA was not reset')
|
||||
assert.equal(client.kB.length, 32, 'kB exists, has the right length')
|
||||
assert.notEqual(wrapKb, keys.wrapKb, 'wrapKb was reset')
|
||||
assert.equal(kA, keys.kA, 'kA was not reset')
|
||||
assert.equal(typeof client.kB, 'string')
|
||||
assert.equal(client.kB.length, 64, 'kB exists, has the right length')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ const DB = require('../../lib/db')(
|
|||
|
||||
var TOKEN_FRESHNESS_THRESHOLD = require('../../lib/tokens/session_token').TOKEN_FRESHNESS_THRESHOLD
|
||||
|
||||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex')
|
||||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
|
||||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex').toString('hex')
|
||||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex').toString('hex')
|
||||
|
||||
let account
|
||||
|
||||
|
@ -53,7 +53,7 @@ describe('remote db', function() {
|
|||
|
||||
beforeEach(() => {
|
||||
account = {
|
||||
uid: uuid.v4('binary'),
|
||||
uid: uuid.v4('binary').toString('hex'),
|
||||
email: dbServer.uniqueEmail(),
|
||||
emailCode: zeroBuffer16,
|
||||
emailVerified: false,
|
||||
|
@ -126,8 +126,8 @@ describe('remote db', function() {
|
|||
.then(function(sessions) {
|
||||
assert.equal(sessions.length, 1, 'sessions contains one item')
|
||||
assert.equal(Object.keys(sessions[0]).length, 16, 'session has correct number of properties')
|
||||
assert.ok(Buffer.isBuffer(sessions[0].tokenId), 'tokenId property is buffer')
|
||||
assert.equal(sessions[0].uid.toString('hex'), account.uid.toString('hex'), 'uid property is correct')
|
||||
assert.equal(typeof sessions[0].tokenId, 'string', 'tokenId property is not a buffer')
|
||||
assert.equal(sessions[0].uid, account.uid, 'uid property is correct')
|
||||
assert.ok(sessions[0].createdAt >= account.createdAt, 'createdAt property seems correct')
|
||||
assert.equal(sessions[0].uaBrowser, 'Firefox', 'uaBrowser property is correct')
|
||||
assert.equal(sessions[0].uaBrowserVersion, '41', 'uaBrowserVersion property is correct')
|
||||
|
@ -219,7 +219,7 @@ describe('remote db', function() {
|
|||
() => {
|
||||
var sessionToken
|
||||
var deviceInfo = {
|
||||
id: crypto.randomBytes(16),
|
||||
id: crypto.randomBytes(16).toString('hex'),
|
||||
name: '',
|
||||
type: 'mobile',
|
||||
pushCallback: 'https://foo/bar',
|
||||
|
@ -268,7 +268,7 @@ describe('remote db', function() {
|
|||
})
|
||||
})
|
||||
.then(function (device) {
|
||||
assert.ok(Buffer.isBuffer(device.id), 'device.id is set')
|
||||
assert.ok(device.id, 'device.id is set')
|
||||
assert.ok(device.createdAt > 0, 'device.createdAt is set')
|
||||
assert.equal(device.name, deviceInfo.name, 'device.name is correct')
|
||||
assert.equal(device.type, deviceInfo.type, 'device.type is correct')
|
||||
|
@ -292,7 +292,7 @@ describe('remote db', function() {
|
|||
return devices[0]
|
||||
})
|
||||
.then(function (device) {
|
||||
assert.ok(Buffer.isBuffer(device.id), 'device.id is set')
|
||||
assert.ok(device.id, 'device.id is set')
|
||||
assert.ok(device.lastAccessTime > 0, 'device.lastAccessTime is set')
|
||||
assert.equal(device.name, deviceInfo.name, 'device.name is correct')
|
||||
assert.equal(device.type, deviceInfo.type, 'device.type is correct')
|
||||
|
@ -658,13 +658,13 @@ describe('remote db', function() {
|
|||
|
||||
it('signinCodes', () => {
|
||||
let previousCode
|
||||
const flowId = crypto.randomBytes(32)
|
||||
const flowId = crypto.randomBytes(32).toString('hex')
|
||||
|
||||
// Create a signinCode without a flowId
|
||||
return db.createSigninCode(account.uid)
|
||||
.then(code => {
|
||||
assert.ok(Buffer.isBuffer(code), 'db.createSigninCode should return a buffer')
|
||||
assert.equal(code.length, config.signinCodeSize, 'db.createSigninCode should return the correct size code')
|
||||
assert.equal(typeof code, 'string', 'db.createSigninCode should return a string')
|
||||
assert.equal(Buffer.from(code, 'hex').length, config.signinCodeSize, 'db.createSigninCode should return the correct size code')
|
||||
|
||||
previousCode = code
|
||||
|
||||
|
@ -685,9 +685,9 @@ describe('remote db', function() {
|
|||
return db.createSigninCode(account.uid, flowId)
|
||||
})
|
||||
.then(code => {
|
||||
assert.ok(Buffer.isBuffer(code), 'db.createSigninCode should return a buffer')
|
||||
assert.equal(code.equals(previousCode), false, 'db.createSigninCode should not return a duplicate code')
|
||||
assert.equal(code.length, config.signinCodeSize, 'db.createSigninCode should return the correct size code')
|
||||
assert.equal(typeof code, 'string', 'db.createSigninCode should return a string')
|
||||
assert.notEqual(code, previousCode, 'db.createSigninCode should not return a duplicate code')
|
||||
assert.equal(Buffer.from(code, 'hex').length, config.signinCodeSize, 'db.createSigninCode should return the correct size code')
|
||||
|
||||
// Consume both signinCodes
|
||||
return P.all([
|
||||
|
@ -700,7 +700,7 @@ describe('remote db', function() {
|
|||
assert.equal(results[1].email, account.email, 'db.consumeSigninCode should return the email address')
|
||||
if (results[1].flowId) {
|
||||
// This assertion is conditional so that tests pass regardless of db version
|
||||
assert.equal(results[1].flowId, flowId.toString('hex'), 'db.consumeSigninCode should return the flowId')
|
||||
assert.equal(results[1].flowId, flowId, 'db.consumeSigninCode should return the flowId')
|
||||
}
|
||||
|
||||
// Attempt to consume a consumed signinCode
|
||||
|
|
|
@ -47,10 +47,10 @@ describe('remote flow', function() {
|
|||
)
|
||||
.then(
|
||||
function (keys) {
|
||||
assert.ok(Buffer.isBuffer(keys.kA), 'kA exists')
|
||||
assert.ok(Buffer.isBuffer(keys.wrapKb), 'wrapKb exists')
|
||||
assert.ok(Buffer.isBuffer(keys.kB), 'kB exists')
|
||||
assert.equal(client.kB.length, 32, 'kB exists, has the right length')
|
||||
assert.equal(typeof keys.kA, 'string', 'kA exists')
|
||||
assert.equal(typeof keys.wrapKb, 'string', 'wrapKb exists')
|
||||
assert.equal(typeof keys.kB, 'string', 'kB exists')
|
||||
assert.equal(client.kB.length, 64, 'kB exists, has the right length')
|
||||
}
|
||||
)
|
||||
.then(
|
||||
|
@ -91,10 +91,10 @@ describe('remote flow', function() {
|
|||
)
|
||||
.then(
|
||||
function (keys) {
|
||||
assert.ok(Buffer.isBuffer(keys.kA), 'kA exists')
|
||||
assert.ok(Buffer.isBuffer(keys.wrapKb), 'wrapKb exists')
|
||||
assert.ok(Buffer.isBuffer(keys.kB), 'kB exists')
|
||||
assert.equal(client.kB.length, 32, 'kB exists, has the right length')
|
||||
assert.equal(typeof keys.kA, 'string', 'kA exists')
|
||||
assert.equal(typeof keys.wrapKb, 'string', 'wrapKb exists')
|
||||
assert.equal(typeof keys.kB, 'string', 'kB exists')
|
||||
assert.equal(client.kB.length, 64, 'kB exists, has the right length')
|
||||
}
|
||||
)
|
||||
.then(
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
'use strict'
|
||||
|
||||
const assert = require('insist')
|
||||
var butil = require('../../lib/crypto/butil')
|
||||
var unbuffer = butil.unbuffer
|
||||
var config = require('../../config').getProperties()
|
||||
var TestServer = require('../test_mailer_server')
|
||||
|
||||
|
@ -56,7 +54,7 @@ describe('mailer db', () => {
|
|||
|
||||
return db.pool.put(
|
||||
'/account/' + accountData.uid.toString('hex'),
|
||||
unbuffer(accountData)
|
||||
accountData
|
||||
)
|
||||
})
|
||||
.then(function () {
|
||||
|
@ -80,7 +78,7 @@ describe('mailer db', () => {
|
|||
|
||||
return db.pool.put(
|
||||
'/account/' + accountData.uid.toString('hex'),
|
||||
unbuffer(accountData)
|
||||
accountData
|
||||
)
|
||||
})
|
||||
.then(function () {
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
const assert = require('insist')
|
||||
var P = require('../../lib/promise')
|
||||
var butil = require('../../lib/crypto/butil')
|
||||
var unbuffer = butil.unbuffer
|
||||
var config = require('../../config').getProperties()
|
||||
var TestServer = require('../test_mailer_server')
|
||||
var testHelper = require('../mailer_helper')
|
||||
|
@ -44,7 +42,7 @@ describe('mailer reminder db', () => {
|
|||
|
||||
return db.pool.put(
|
||||
'/account/' + accountData.uid.toString('hex'),
|
||||
unbuffer(accountData)
|
||||
accountData
|
||||
)
|
||||
})
|
||||
.then(function () {
|
||||
|
|
|
@ -101,10 +101,11 @@ describe('remote password forgot', function() {
|
|||
)
|
||||
.then(
|
||||
function (keys) {
|
||||
assert.ok(Buffer.isBuffer(keys.wrapKb), 'yep, wrapKb')
|
||||
assert.notDeepEqual(wrapKb, keys.wrapKb, 'wrapKb was reset')
|
||||
assert.deepEqual(kA, keys.kA, 'kA was not reset')
|
||||
assert.equal(client.kB.length, 32, 'kB exists, has the right length')
|
||||
assert.equal(typeof keys.wrapKb, 'string', 'yep, wrapKb')
|
||||
assert.notEqual(wrapKb, keys.wrapKb, 'wrapKb was reset')
|
||||
assert.equal(kA, keys.kA, 'kA was not reset')
|
||||
assert.equal(typeof client.kB, 'string')
|
||||
assert.equal(client.kB.length, 64, 'kB exists, has the right length')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ const DB = require('../../lib/db')(
|
|||
Token
|
||||
)
|
||||
|
||||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex')
|
||||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
|
||||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex').toString('hex')
|
||||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex').toString('hex')
|
||||
|
||||
var SESSION_TOKEN_UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:41.0) Gecko/20100101 Firefox/41.0'
|
||||
var ACCOUNT = {
|
||||
uid: uuid.v4('binary'),
|
||||
uid: uuid.v4('binary').toString('hex'),
|
||||
email: 'push' + Math.random() + '@bar.com',
|
||||
emailCode: zeroBuffer16,
|
||||
emailVerified: false,
|
||||
|
@ -68,7 +68,7 @@ describe('remote push db', function() {
|
|||
() => {
|
||||
var sessionTokenId
|
||||
var deviceInfo = {
|
||||
id: crypto.randomBytes(16),
|
||||
id: crypto.randomBytes(16).toString('hex'),
|
||||
name: 'my push device',
|
||||
type: 'mobile',
|
||||
pushCallback: 'https://foo/bar',
|
||||
|
|
|
@ -67,7 +67,6 @@ describe('remote signinCodes', function () {
|
|||
})
|
||||
})
|
||||
.then(result => assert.deepEqual(result, { email }, '/signinCodes/consume should return the email address'))
|
||||
.catch(err => assert.fail('/signinCodes/consume should succeed'))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ describe('remote verifier upgrade', function() {
|
|||
return Client.create(config.publicUrl, email, password, { preVerified: true, keys: true })
|
||||
.then(
|
||||
function (c) {
|
||||
uid = Buffer(c.uid, 'hex')
|
||||
uid = c.uid
|
||||
return server.stop()
|
||||
}
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче