fix(api): permit lastAccessTime 0 in devices response

This commit is contained in:
Phil Booth 2016-02-25 14:23:42 +00:00
Родитель db0391a7f3
Коммит 405932314c
4 изменённых файлов: 115 добавлений и 11 удалений

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

@ -91,12 +91,13 @@ module.exports = function (
log.begin('Account.create', request)
var form = request.payload
var query = request.query
var email = form.email
var authSalt = crypto.randomBytes(32)
var authPW = Buffer(form.authPW, 'hex')
var locale = request.app.acceptLanguage
var userAgentString = request.headers['user-agent']
var service = form.service || request.query.service
var service = form.service || query.service
var preVerified, password, verifyHash, account, sessionToken, device
customs.check(request.app.clientAddress, email, 'accountCreate')
@ -204,7 +205,8 @@ module.exports = function (
email: account.email,
emailCode: account.emailCode,
emailVerified: account.emailVerified,
verifierSetAt: account.verifierSetAt
verifierSetAt: account.verifierSetAt,
createdAt: optionallyOverrideCreatedAt()
}, userAgentString)
.then(
function (result) {
@ -213,10 +215,17 @@ module.exports = function (
)
}
function optionallyOverrideCreatedAt () {
var createdAt = parseInt(query._createdAt)
if (createdAt < Date.now() && ! config.isProduction) {
return createdAt
}
}
function sendVerifyCode () {
if (! account.emailVerified) {
mailer.sendVerifyCode(account, account.emailCode, {
service: form.service || request.query.service,
service: form.service || query.service,
redirectTo: form.redirectTo,
resume: form.resume,
acceptLanguage: request.app.acceptLanguage
@ -253,7 +262,7 @@ module.exports = function (
response.device = butil.unbuffer(device)
}
if (request.query.keys !== 'true') {
if (query.keys !== 'true') {
return P.resolve(response)
}
@ -814,7 +823,7 @@ module.exports = function (
schema: isA.array().items(isA.object({
id: isA.string().length(32).regex(HEX_STRING).required(),
isCurrentDevice: isA.boolean().required(),
lastAccessTime: isA.number().positive(),
lastAccessTime: isA.number().min(0).required(),
name: isA.string().max(255).required(),
type: isA.string().max(16).required(),
pushCallback: isA.string().uri({ scheme: 'https' }).max(255).optional().allow('').allow(null),

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

@ -38,7 +38,7 @@ module.exports = function (log, crypto, P, hkdf, Bundle, error) {
this.algorithm = 'sha256'
this.uid = details.uid || null
this.lifetime = details.lifetime || Infinity
this.createdAt = details.createdAt || Date.now()
this.createdAt = details.createdAt >= 0 ? details.createdAt : Date.now()
}
// Create a new token of the given type.
@ -60,7 +60,6 @@ module.exports = function (log, crypto, P, hkdf, Bundle, error) {
Token.deriveTokenKeys(TokenType, bytes)
.then(
function (keys) {
details.createdAt = Date.now()
d.resolve(new TokenType(keys, details || {}))
}
)

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

@ -547,7 +547,11 @@ function getQueryString (options) {
}
if (options.serviceQuery) {
qs += 'service=' + options.serviceQuery
qs += 'service=' + options.serviceQuery + '&'
}
if (options.createdAt) {
qs += '_createdAt=' + options.createdAt
}
return qs

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

@ -196,7 +196,7 @@ TestServer.start(config)
t.equal(device.name, deviceInfo.name, 'device.name is correct')
t.equal(device.type, deviceInfo.type, 'device.type is correct')
t.equal(device.pushCallback, undefined, 'device.pushCallback is undefined')
t.deepEqual(device.pushPublicKey, undefined, 'device.pushPublicKey is undefined')
t.equal(device.pushPublicKey, undefined, 'device.pushPublicKey is undefined')
}
)
.then(
@ -210,7 +210,7 @@ TestServer.start(config)
t.equal(devices[0].name, deviceInfo.name, 'devices returned correct name')
t.equal(devices[0].type, deviceInfo.type, 'devices returned correct type')
t.equal(devices[0].pushCallback, null, 'devices returned undefined pushCallback')
t.deepEqual(devices[0].pushPublicKey, null, 'devices returned undefined pushPublicKey')
t.equal(devices[0].pushPublicKey, null, 'devices returned undefined pushPublicKey')
return client.destroyDevice(devices[0].id)
}
)
@ -230,7 +230,6 @@ TestServer.start(config)
return client.updateDevice({ type: 'mobile' })
.then(
function (r) {
console.error('!!!!! PHIL !!!!! ' + Object.keys(r))
t.fail('request should have failed')
}
)
@ -337,6 +336,99 @@ TestServer.start(config)
}
)
test(
// Regression test for https://github.com/mozilla/fxa-auth-server/issues/1197
'devices list, sessionToken.lastAccessTime === 0 (regression test for #1197)',
function (t) {
var email = server.uniqueEmail()
var password = 'test password'
var deviceInfo = {
name: 'test device',
type: 'mobile'
}
return Client.create(config.publicUrl, email, password, {
createdAt: '0',
device: deviceInfo
})
.then(
function (client) {
return client.devices()
.then(
function (devices) {
t.equal(devices.length, 1, 'devices returned one item')
t.strictEqual(devices[0].lastAccessTime, 0, 'devices returned correct lastAccessTime')
t.equal(devices[0].name, deviceInfo.name, 'devices returned correct name')
t.equal(devices[0].type, deviceInfo.type, 'devices returned correct type')
return client.destroyDevice(devices[0].id)
}
)
}
)
}
)
test(
'devices list, sessionToken.lastAccessTime === -1',
function (t) {
var email = server.uniqueEmail()
var password = 'test password'
var deviceInfo = {
name: 'test device',
type: 'mobile'
}
return Client.create(config.publicUrl, email, password, {
createdAt: '-1',
device: deviceInfo
})
.then(
function (client) {
return client.devices()
.then(
function (devices) {
t.equal(devices.length, 1, 'devices returned one item')
t.ok(devices[0].lastAccessTime > 0, 'devices returned correct lastAccessTime')
t.equal(devices[0].name, deviceInfo.name, 'devices returned correct name')
t.equal(devices[0].type, deviceInfo.type, 'devices returned correct type')
return client.destroyDevice(devices[0].id)
}
)
}
)
}
)
test(
'devices list, sessionToken.lastAccessTime === THE FUTURE',
function (t) {
var email = server.uniqueEmail()
var password = 'test password'
var deviceInfo = {
name: 'test device',
type: 'mobile'
}
var theFuture = Date.now() + 10000
return Client.create(config.publicUrl, email, password, {
createdAt: '' + theFuture,
device: deviceInfo
})
.then(
function (client) {
return client.devices()
.then(
function (devices) {
t.equal(devices.length, 1, 'devices returned one item')
t.ok(devices[0].lastAccessTime > 0, 'devices returned correct lastAccessTime')
t.ok(devices[0].lastAccessTime < theFuture, 'devices returned correct lastAccessTime')
t.equal(devices[0].name, deviceInfo.name, 'devices returned correct name')
t.equal(devices[0].type, deviceInfo.type, 'devices returned correct type')
return client.destroyDevice(devices[0].id)
}
)
}
)
}
)
test(
'teardown',
function (t) {