feat(unblock): change unblock codes to base32 (#1529) r=vladikoff
Closes #1497
This commit is contained in:
Родитель
89ef512c68
Коммит
f82db02c40
|
@ -36,7 +36,7 @@ function main() {
|
|||
var error = require('../lib/error')
|
||||
var Token = require('../lib/tokens')(log, config)
|
||||
var Password = require('../lib/crypto/password')(log, config)
|
||||
var UnblockCode = require('../lib/crypto/base36')(config.signinUnblock.codeLength)
|
||||
var UnblockCode = require('../lib/crypto/base32')(config.signinUnblock.codeLength)
|
||||
|
||||
var signer = require('../lib/signer')(config.secretKeyFile, config.domain)
|
||||
var serverPublicKeys = {
|
||||
|
|
|
@ -501,7 +501,7 @@ var conf = convict({
|
|||
},
|
||||
signinUnblock: {
|
||||
codeLength: {
|
||||
doc: 'Number of base36 digits to make up an unblockCode',
|
||||
doc: 'Number of alphanumeric digits to make up an unblockCode',
|
||||
default: 8,
|
||||
env: 'SIGNIN_UNBLOCK_CODE_LENGTH'
|
||||
},
|
||||
|
|
|
@ -319,7 +319,7 @@ ___Parameters___
|
|||
* authPW - the PBKDF2/HKDF stretched password as a hex string
|
||||
* service - (optional) opaque alphanumeric token to be included in verification links
|
||||
* reason - (optional) alphanumeric string indicating the reason for establishing a new session; may be "login" (the default) or "reconnect"
|
||||
* unblockCode - (optional) base36 code used to unblock certain rate-limitings
|
||||
* unblockCode - (optional) alphanumeric code used to unblock certain rate-limitings
|
||||
|
||||
### Request
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* 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('assert')
|
||||
const crypto = require('crypto')
|
||||
|
||||
const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
|
||||
|
||||
// some sanity checks, hard to test, private to this mdoule
|
||||
assert.equal(ALPHABET.length, 32, 'ALPHABET is 32 characters')
|
||||
assert.equal(ALPHABET.indexOf('I'), -1, 'should not contain I')
|
||||
assert.equal(ALPHABET.indexOf('L'), -1, 'should not contain L')
|
||||
assert.equal(ALPHABET.indexOf('O'), -1, 'should not contain O')
|
||||
assert.equal(ALPHABET.indexOf('U'), -1, 'should not contain U')
|
||||
|
||||
function base32(len) {
|
||||
const out = []
|
||||
const bytes = crypto.randomBytes(len)
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
out.push(ALPHABET[bytes[i] % 32])
|
||||
}
|
||||
|
||||
return out.join('')
|
||||
}
|
||||
|
||||
module.exports = (len) => {
|
||||
return () => {
|
||||
return base32(len)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict'
|
||||
|
||||
const crypto = require('crypto')
|
||||
|
||||
function base36(len) {
|
||||
let out = []
|
||||
while (out.length < len) {
|
||||
let rand = crypto.randomBytes(len)
|
||||
let randLen = rand.length
|
||||
for (let i = 0; i < randLen; i++) {
|
||||
let b = rand[i]
|
||||
// 252-256 skews the base36 distribution, so skip those bytes
|
||||
if (b < 252) {
|
||||
out.push((b % 36).toString(36))
|
||||
if (out.length === len) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out.join('').toUpperCase()
|
||||
}
|
||||
|
||||
module.exports = (len) => {
|
||||
return () => {
|
||||
return base36(len)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* 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/. */
|
||||
|
||||
const test = require('tap').test
|
||||
const base32 = require('../../lib/crypto/base32')
|
||||
|
||||
test('base32 takes 1 integer argument, returns a function', (t) => {
|
||||
t.equal(typeof base32, 'function')
|
||||
t.equal(base32.length, 1)
|
||||
const gen = base32(10)
|
||||
t.equal(typeof gen, 'function')
|
||||
t.equal(gen.length, 0)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('base32 output', (t) => {
|
||||
const gen = base32(10)
|
||||
const code = gen()
|
||||
t.equal(code.length, 10, 'matches length')
|
||||
t.ok(/^[0-9A-Z]+$/.test(code), 'no lowercase letters')
|
||||
t.equal(code.indexOf('I'), -1, 'no I')
|
||||
t.equal(code.indexOf('L'), -1, 'no L')
|
||||
t.equal(code.indexOf('O'), -1, 'no O')
|
||||
t.equal(code.indexOf('U'), -1, 'no U')
|
||||
t.end()
|
||||
})
|
Загрузка…
Ссылка в новой задаче