Release v2.20.1: migrate authentication to Better Auth
This commit is contained in:
1 parent
e9a53f577c
commit
fba4f99ff7
92 files changed
+5085
-1943
No files matched your search
+56
@@ -5,6 +5,7 @@ const crypto = require('crypto');
|
||||
const PASSWORD_ITERATIONS = 310000;
|
||||
const PASSWORD_KEY_LENGTH = 32;
|
||||
const PASSWORD_DIGEST = 'sha256';
|
||||
const SCRYPT_OPTIONS = { N: 16384, r: 16, p: 1, keyLength: 64, maxmem: 128 * 16384 * 16 * 2 };
|
||||
const SESSION_BYTES = 32;
|
||||
|
||||
function createOneTimeToken() {
|
||||
@@ -71,6 +72,56 @@ function hashPassword(password, salt) {
|
||||
};
|
||||
}
|
||||
|
||||
function encodePasswordRecord(record) {
|
||||
return ['pbkdf2-sha256', Number(record.iterations), record.salt, record.hash].join('$');
|
||||
}
|
||||
|
||||
function verifyEncodedPassword(password, encodedPassword) {
|
||||
const [algorithm, iterations, salt, hash] = String(encodedPassword || '').split('$');
|
||||
if (algorithm !== 'pbkdf2-sha256' || !iterations || !salt || !hash) {
|
||||
return false;
|
||||
}
|
||||
return verifyPassword(password, {
|
||||
password_hash: hash,
|
||||
password_salt: salt,
|
||||
password_iterations: Number(iterations)
|
||||
});
|
||||
}
|
||||
|
||||
function deriveScryptKey(password, salt) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
crypto.scrypt(String(password || '').normalize('NFKC'), salt, SCRYPT_OPTIONS.keyLength, SCRYPT_OPTIONS, function (error, key) {
|
||||
if (error) return reject(error);
|
||||
resolve(key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function hashScryptPassword(password) {
|
||||
const salt = crypto.randomBytes(16).toString('hex');
|
||||
const key = await deriveScryptKey(password, salt);
|
||||
return salt + ':' + key.toString('hex');
|
||||
}
|
||||
|
||||
async function verifyScryptPassword(password, encodedPassword) {
|
||||
const [salt, hash] = String(encodedPassword || '').split(':');
|
||||
if (!/^[a-f0-9]{32}$/i.test(salt || '') || !/^[a-f0-9]{128}$/i.test(hash || '')) return false;
|
||||
const expected = Buffer.from(hash, 'hex');
|
||||
const actual = await deriveScryptKey(password, salt);
|
||||
return crypto.timingSafeEqual(actual, expected);
|
||||
}
|
||||
|
||||
async function verifyCredentialPassword(password, encodedPassword) {
|
||||
if (String(encodedPassword || '').startsWith('pbkdf2-sha256$')) {
|
||||
return verifyEncodedPassword(password, encodedPassword);
|
||||
}
|
||||
try {
|
||||
return await verifyScryptPassword(password, encodedPassword);
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function verifyPassword(password, record) {
|
||||
if (!record || !record.password_salt || !record.password_hash) {
|
||||
return false;
|
||||
@@ -93,6 +144,11 @@ function hashSessionToken(token) {
|
||||
module.exports = {
|
||||
hashPassword,
|
||||
verifyPassword,
|
||||
encodePasswordRecord,
|
||||
verifyEncodedPassword,
|
||||
hashScryptPassword,
|
||||
verifyScryptPassword,
|
||||
verifyCredentialPassword,
|
||||
validatePasswordStrength,
|
||||
createSessionToken,
|
||||
hashSessionToken,
|
||||
|
||||
Reference in new issue
Block a user