fxa-auth-server/test/remote/certificate_sign_tests.js

252 строки
8.5 KiB
JavaScript

/* 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')
var TestServer = require('../test_server')
const Client = require('../client')()
var jwtool = require('fxa-jwtool')
var config = require('../../config').getProperties()
config.redis.sessionTokens.enabled = false
var pubSigKey = jwtool.JWK.fromFile(config.publicKeyFile)
var publicKey = {
'algorithm': 'RS',
'n': '4759385967235610503571494339196749614544606692567785790953934768202714280652973091341316862993582789079872007974809511698859885077002492642203267408776123',
'e': '65537'
}
describe('remote certificate sign', function() {
this.timeout(15000)
let server
before(() => {
return TestServer.start(config)
.then(s => {
server = s
})
})
it(
'certificate sign',
() => {
const email = server.uniqueEmail()
const password = 'allyourbasearebelongtous'
const duration = 1000 * 60 * 60 * 24 // 24 hours
let client = null
return Client.createAndVerify(config.publicUrl, email, password, server.mailbox, {keys:true})
.then(c => {
client = c
return client.sign(publicKey, duration)
})
.then(cert => {
assert.equal(typeof(cert), 'string', 'cert exists')
const payload = jwtool.verify(cert, pubSigKey.pem)
assert.equal(payload.iss, config.domain, 'issuer is correct')
assert.equal(payload.principal.email.split('@')[0], client.uid, 'cert has correct uid')
assert.ok(payload['fxa-generation'] > 0, 'cert has non-zero generation number')
assert.ok(new Date() - new Date(payload['fxa-lastAuthAt'] * 1000) < 1000 * 60 * 60, 'lastAuthAt is plausible')
assert.equal(payload['fxa-verifiedEmail'], email, 'verifiedEmail is correct')
assert.equal(payload['fxa-tokenVerified'], true, 'tokenVerified is correct')
assert.deepEqual(payload['fxa-amr'].sort(), ['email', 'pwd'], 'amr values are correct')
assert.equal(payload['fxa-aal'], 1, 'aal value is correct')
})
}
)
it(
'certificate sign with TOTP',
() => {
const email = server.uniqueEmail()
const password = 'allyourbasearebelongtous'
const duration = 1000 * 60 * 60 * 24 // 24 hours
let client = null
return Client.createAndVerifyAndTOTP(config.publicUrl, email, password, server.mailbox, {keys:true})
.then(c => {
client = c
return client.sign(publicKey, duration)
})
.then(cert => {
assert.equal(typeof(cert), 'string', 'cert exists')
const payload = jwtool.verify(cert, pubSigKey.pem)
assert.equal(payload.iss, config.domain, 'issuer is correct')
assert.equal(payload.principal.email.split('@')[0], client.uid, 'cert has correct uid')
assert.ok(payload['fxa-generation'] > 0, 'cert has non-zero generation number')
assert.ok(new Date() - new Date(payload['fxa-lastAuthAt'] * 1000) < 1000 * 60 * 60, 'lastAuthAt is plausible')
assert.equal(payload['fxa-verifiedEmail'], email, 'verifiedEmail is correct')
assert.equal(payload['fxa-tokenVerified'], true, 'tokenVerified is correct')
assert.deepEqual(payload['fxa-amr'].sort(), ['otp', 'pwd'], 'amr values are correct')
assert.equal(payload['fxa-aal'], 2, 'aal value is correct')
})
}
)
it(
'certificate sign requires a verified account',
() => {
var email = server.uniqueEmail()
var password = 'allyourbasearebelongtous'
var client = null
var duration = 1000 * 60 * 60 * 24 // 24 hours
return Client.create(config.publicUrl, email, password)
.then(
function (c) {
client = c
return client.sign(publicKey, duration)
}
)
.then(
function (cert) {
assert(false, 'should not be able to sign with unverified account')
},
function (err) {
assert.equal(err.errno, 104, 'should get an unverifiedAccount error')
}
)
}
)
it(
'/certificate/sign inputs',
() => {
var email = server.uniqueEmail()
var password = '123456'
var client = null
return Client.createAndVerify(config.publicUrl, email, password, server.mailbox)
.then(
function (c) {
client = c
// string as publicKey
return client.sign('tada', 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'string as publicKey')
// empty object as publicKey
return client.sign({}, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'empty object as publicKey')
// undefined duration
return client.sign({ algorithm: 'RS', n: 'x', e: 'y' }, undefined)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'undefined duration')
// missing publicKey arguments (e)
return client.sign({ algorithm: 'RS', n: 'x' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'missing publicKey arguments (e)')
// missing publicKey arguments (n)
return client.sign({ algorithm: 'RS', e: 'x' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'missing publicKey arguments (n)')
// missing publicKey arguments (y)
return client.sign({ algorithm: 'DS', p: 'p', q: 'q', g: 'g' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'missing publicKey arguments (y)')
// missing publicKey arguments (p)
return client.sign({ algorithm: 'DS', y: 'y', q: 'q', g: 'g' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'missing publicKey arguments (p)')
// missing publicKey arguments (q)
return client.sign({ algorithm: 'DS', y: 'y', p: 'p', g: 'g' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'missing publicKey arguments (q)')
// missing publicKey arguments (g)
return client.sign({ algorithm: 'DS', y: 'y', p: 'p', q: 'q' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'missing publicKey arguments (g)')
// invalid algorithm
return client.sign({ algorithm: 'NSA' }, 1000)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.code, 400, 'invalid algorithm')
}
)
}
)
it(
'no payload',
() => {
var email = server.uniqueEmail()
var password = 'allyourbasearebelongtous'
var duration = 1000 * 60 * 60 * 24 // 24 hours
return Client.createAndVerify(config.publicUrl, email, password, server.mailbox)
.then(
function (client) {
client.api.once(
'startRequest',
function hijackPayload(options) {
// we want the payload hash in the auth header
// but no payload in the request body
options.json = true
}
)
return client.api.Token.SessionToken.fromHex(client.sessionToken)
.then(
function (token) {
return client.api.doRequest(
'POST',
client.api.baseURL + '/certificate/sign',
token,
{
publicKey: publicKey,
duration: duration
}
)
}
)
}
)
.then(
() => assert(false),
function (err) {
assert.equal(err.errno, 109, 'Missing payload authentication')
}
)
}
)
after(() => {
return TestServer.stop(server)
})
})