firebase-scrypt
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -25,2 +25,23 @@ 'use strict'; | ||
/** | ||
* base64decode - Decodes a base64 encoded string into a Buffer | ||
* | ||
* The hashes exported via the firebase CLI's auth:export command use the | ||
* standard base64 alphabet with + and / being used in addition to the 62 | ||
* alphanumeric characters. | ||
* | ||
* The hashes exported via the Admin SDK's | ||
* listUsers command use the URL safe base64 alphabet which uses - and _ | ||
* instead. | ||
* | ||
* This function allows this library to be compatible with hashes in either | ||
* format. | ||
* | ||
* @param {string} encoded Base64 encoded string | ||
* @returns {Buffer} decoded | ||
*/ | ||
function base64decode(encoded) { | ||
return Buffer.from(encoded.replace(/-/g, '+').replace(/_/g, '/'), 'base64'); | ||
} | ||
/** | ||
* From https://github.com/firebase/scrypt/issues/2#issuecomment-548203625 | ||
@@ -45,2 +66,27 @@ * 1. Decrypt the User's salt, and Project's base64_signer_key and | ||
constructor({ memCost, rounds, saltSeparator, signerKey }) { | ||
if (memCost === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: memCost parameter missing'); | ||
} | ||
if (typeof memCost !== 'number') { | ||
throw new Error('Error constructing FirebaseScrypt instance: memCost parameter must be a number'); | ||
} | ||
if (rounds === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: rounds parameter missing'); | ||
} | ||
if (typeof rounds !== 'number') { | ||
throw new Error('Error constructing FirebaseScrypt instance: rounds parameter must be a number'); | ||
} | ||
if (saltSeparator === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: saltSeparator parameter missing'); | ||
} | ||
if (typeof saltSeparator !== 'string') { | ||
throw new Error('Error constructing FirebaseScrypt instance: saltSeparator parameter must be a base64 encoded string'); | ||
} | ||
if (signerKey === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: signerKey parameter missing'); | ||
} | ||
if (typeof signerKey !== 'string') { | ||
throw new Error('Error constructing FirebaseScrypt instance: signerKey parameter must be a base64 encoded string'); | ||
} | ||
this.memCost = memCost; | ||
@@ -59,4 +105,7 @@ this.rounds = rounds; | ||
hash(password, salt) { | ||
if (!password) throw new Error('Error hashing password: password parameter missing'); | ||
if (!salt) throw new Error('Error hashing password: salt parameter missing'); | ||
return new _promise2.default((resolve, reject) => { | ||
const bSalt = Buffer.concat([Buffer.from(salt, 'base64'), Buffer.from(this.saltSeparator, 'base64')]); | ||
const bSalt = Buffer.concat([base64decode(salt), base64decode(this.saltSeparator)]); | ||
const iv = Buffer.alloc(IV_LENGTH, 0); | ||
@@ -75,3 +124,3 @@ | ||
const cipher = (0, _crypto.createCipheriv)(ALGORITHM, derivedKey, iv); | ||
resolve(Buffer.concat([cipher.update(Buffer.from(this.signerKey, 'base64')), cipher.final()]).toString('base64')); | ||
resolve(Buffer.concat([cipher.update(base64decode(this.signerKey)), cipher.final()]).toString('base64')); | ||
} catch (error) { | ||
@@ -92,5 +141,9 @@ reject(error); | ||
verify(password, salt, hash) { | ||
if (!password) throw new Error('Error verifying password: password parameter missing'); | ||
if (!salt) throw new Error('Error verifying password: salt parameter missing'); | ||
if (!hash) throw new Error('Error verifying password: hash parameter missing'); | ||
return this.hash(password, salt).then(generatedHash => { | ||
const knownHash = Buffer.from(hash, 'base64'); | ||
const bGeneratedHash = Buffer.from(generatedHash, 'base64'); | ||
const knownHash = base64decode(hash); | ||
const bGeneratedHash = base64decode(generatedHash); | ||
if (bGeneratedHash.length !== knownHash.length) { | ||
@@ -97,0 +150,0 @@ // timingSafeEqual throws when buffer lengths don't match |
{ | ||
"name": "firebase-scrypt", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Nodejs implementation of Firebase's Scrypt modified version.", | ||
@@ -5,0 +5,0 @@ "main": "dist/firebaseScrypt.js", |
@@ -5,6 +5,2 @@ # Node Firebase Scrypt | ||
## Warning | ||
This module work only with users exported with Firebase Tools CLI and the command `auth:export`. Others way to gets users (Admin SDK, etc.) will give you an incompatible hash. | ||
## Table of Contents | ||
@@ -11,0 +7,0 @@ |
@@ -12,2 +12,23 @@ import { createCipheriv, scrypt, timingSafeEqual } from 'crypto' | ||
/** | ||
* base64decode - Decodes a base64 encoded string into a Buffer | ||
* | ||
* The hashes exported via the firebase CLI's auth:export command use the | ||
* standard base64 alphabet with + and / being used in addition to the 62 | ||
* alphanumeric characters. | ||
* | ||
* The hashes exported via the Admin SDK's | ||
* listUsers command use the URL safe base64 alphabet which uses - and _ | ||
* instead. | ||
* | ||
* This function allows this library to be compatible with hashes in either | ||
* format. | ||
* | ||
* @param {string} encoded Base64 encoded string | ||
* @returns {Buffer} decoded | ||
*/ | ||
function base64decode (encoded) { | ||
return Buffer.from(encoded.replace(/-/g, '+').replace(/_/g, '/'), 'base64') | ||
} | ||
/** | ||
* From https://github.com/firebase/scrypt/issues/2#issuecomment-548203625 | ||
@@ -32,2 +53,27 @@ * 1. Decrypt the User's salt, and Project's base64_signer_key and | ||
constructor ({ memCost, rounds, saltSeparator, signerKey }) { | ||
if (memCost === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: memCost parameter missing') | ||
} | ||
if (typeof memCost !== 'number') { | ||
throw new Error('Error constructing FirebaseScrypt instance: memCost parameter must be a number') | ||
} | ||
if (rounds === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: rounds parameter missing') | ||
} | ||
if (typeof rounds !== 'number') { | ||
throw new Error('Error constructing FirebaseScrypt instance: rounds parameter must be a number') | ||
} | ||
if (saltSeparator === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: saltSeparator parameter missing') | ||
} | ||
if (typeof saltSeparator !== 'string') { | ||
throw new Error('Error constructing FirebaseScrypt instance: saltSeparator parameter must be a base64 encoded string') | ||
} | ||
if (signerKey === undefined) { | ||
throw new Error('Error constructing FirebaseScrypt instance: signerKey parameter missing') | ||
} | ||
if (typeof signerKey !== 'string') { | ||
throw new Error('Error constructing FirebaseScrypt instance: signerKey parameter must be a base64 encoded string') | ||
} | ||
this.memCost = memCost | ||
@@ -46,6 +92,9 @@ this.rounds = rounds | ||
hash (password, salt) { | ||
if (!password) throw new Error('Error hashing password: password parameter missing') | ||
if (!salt) throw new Error('Error hashing password: salt parameter missing') | ||
return new Promise((resolve, reject) => { | ||
const bSalt = Buffer.concat([ | ||
Buffer.from(salt, 'base64'), | ||
Buffer.from(this.saltSeparator, 'base64'), | ||
base64decode(salt), | ||
base64decode(this.saltSeparator), | ||
]) | ||
@@ -65,3 +114,3 @@ const iv = Buffer.alloc(IV_LENGTH, 0) | ||
const cipher = createCipheriv(ALGORITHM, derivedKey, iv) | ||
resolve(Buffer.concat([ cipher.update(Buffer.from(this.signerKey, 'base64')), cipher.final() ]).toString('base64')) | ||
resolve(Buffer.concat([ cipher.update(base64decode(this.signerKey)), cipher.final() ]).toString('base64')) | ||
} catch (error) { | ||
@@ -82,5 +131,9 @@ reject(error) | ||
verify (password, salt, hash) { | ||
if (!password) throw new Error('Error verifying password: password parameter missing') | ||
if (!salt) throw new Error('Error verifying password: salt parameter missing') | ||
if (!hash) throw new Error('Error verifying password: hash parameter missing') | ||
return this.hash(password, salt).then(generatedHash => { | ||
const knownHash = Buffer.from(hash, 'base64') | ||
const bGeneratedHash = Buffer.from(generatedHash, 'base64') | ||
const knownHash = base64decode(hash) | ||
const bGeneratedHash = base64decode(generatedHash) | ||
if (bGeneratedHash.length !== knownHash.length) { | ||
@@ -87,0 +140,0 @@ // timingSafeEqual throws when buffer lengths don't match |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20260
426
77