Last active
July 3, 2019 22:43
-
-
Save kimsible/cf57e18764b154c9e45ce33daa45b595 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const crypto = require('crypto') | |
const path = require('path') | |
const mudb = require('mudb') | |
const { STORAGE, SALT } = process.env | |
let db | |
async function load () { | |
const authList = path.resolve(STORAGE || process.cwd(), './auth.json') | |
db = await mudb.open(authList) | |
} | |
const encrypt = (string, salt = SALT) => { | |
if (salt) { | |
return new Promise((resolve, reject) => { | |
crypto.pbkdf2(string, salt, 100000, 32, 'sha512', (error, data) => { | |
if (error) { | |
return reject(error) | |
} | |
return resolve(data.toString('base64')) | |
}) | |
}) | |
} else { | |
return string | |
} | |
} | |
const credentials = req => { | |
const { authorization } = req.headers | |
try { | |
const [, base64Credentials] = (authorization || '').match(/^Basic (.+)$/) | |
return Buffer.from(base64Credentials, 'base64').toString('ascii').split(':') | |
} catch { | |
return [] | |
} | |
} | |
const access = async req => { | |
const [email, id] = credentials(req) | |
if (db.get({ email: await encrypt(email), id: await encrypt(id) }).length === 0) { | |
throw new Error('Unauthorized Error') | |
} | |
} | |
const get = async id => { | |
if (db.get({ id: await encrypt(id) }).length === 0) { | |
throw new Error('Unauthorized Error') | |
} | |
} | |
const create = async email => { | |
const id = crypto.randomBytes(3 * 8).toString('base64') | |
const encryptedEmail = await encrypt(email) | |
if (db.get({ email: encryptedEmail }).length > 0) { | |
db.del({ email: encryptedEmail }) | |
} | |
db.add({ email: encryptedEmail, id: await encrypt(id) }).save() | |
return id | |
} | |
const remove = async email => { | |
db.del({ email: await encrypt(email) }).save() | |
} | |
module.exports = { | |
load, | |
encrypt, | |
credentials, | |
access, | |
get, | |
create, | |
remove | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
import test from 'ava' | |
import auth from './auth' | |
test('auth/encrypt - no salt / no encryption', authEncryptTest, 'email@provider.com') | |
test('auth/encrypt - with salt', authEncryptTest, 'email@provider.com', 'salt') | |
async function authEncryptTest (t, input, salt) { | |
const encrypted = await auth.encrypt(input, salt) | |
if (salt) { | |
t.not(encrypted, input) | |
} else { | |
t.is(encrypted, input) | |
} | |
} | |
test('auth/credentials - OK', authCredentialsTest, `Basic ${Buffer.from('user@provider.com:GwJexPcIEeAnPTtH091ynxodjXCo86/j').toString('base64')}`, { email: 'user@provider.com', id: 'GwJexPcIEeAnPTtH091ynxodjXCo86/j' }) | |
test('auth/credentials - wrong header', authCredentialsTest, `${Buffer.from('user@provider.com:GwJexPcIEeAnPTtH091ynxodjXCo86/j').toString('base64')}`, { email: undefined, id: undefined }) | |
function authCredentialsTest (t, input, output) { | |
const [email, id] = auth.credentials({ | |
headers: { | |
authorization: input | |
} | |
}) | |
t.is(email, output.email) | |
t.is(id, output.id) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment