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:
Sean McArthur 2017-06-28 15:10:22 -07:00
Родитель 96aae0e0ca
Коммит 0cfd39ca05
55 изменённых файлов: 530 добавлений и 595 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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(

Просмотреть файл

@ -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
)

Просмотреть файл

@ -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()
}
)