better-auth
Version:
The most comprehensive authentication library for TypeScript.
103 lines (95 loc) • 3.35 kB
JavaScript
;
const hash = require('@better-auth/utils/hash');
const chacha = require('@noble/ciphers/chacha');
const utils$2 = require('@noble/ciphers/utils');
const webcrypto = require('@noble/ciphers/webcrypto');
const base64 = require('@better-auth/utils/base64');
const jose = require('jose');
const scrypt = require('@noble/hashes/scrypt');
const utils = require('@better-auth/utils');
const hex = require('@better-auth/utils/hex');
const utils$1 = require('@noble/hashes/utils');
const random = require('../shared/better-auth.CYeOI8C-.cjs');
require('@better-auth/utils/random');
async function signJWT(payload, secret, expiresIn = 3600) {
const jwt = await new jose.SignJWT(payload).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime(Math.floor(Date.now() / 1e3) + expiresIn).sign(new TextEncoder().encode(secret));
return jwt;
}
function constantTimeEqual(a, b) {
const aBuffer = new Uint8Array(a);
const bBuffer = new Uint8Array(b);
if (aBuffer.length !== bBuffer.length) {
return false;
}
let c = 0;
for (let i = 0; i < aBuffer.length; i++) {
c |= aBuffer[i] ^ bBuffer[i];
}
return c === 0;
}
async function hashToBase64(data) {
const buffer = await hash.createHash("SHA-256").digest(data);
return base64.base64.encode(buffer);
}
async function compareHash(data, hash$1) {
const buffer = await hash.createHash("SHA-256").digest(
typeof data === "string" ? new TextEncoder().encode(data) : data
);
const hashBuffer = base64.base64.decode(hash$1);
return constantTimeEqual(buffer, hashBuffer);
}
const config = {
N: 16384,
r: 16,
p: 1,
dkLen: 64
};
async function generateKey(password, salt) {
return await scrypt.scryptAsync(password.normalize("NFKC"), salt, {
N: config.N,
p: config.p,
r: config.r,
dkLen: config.dkLen,
maxmem: 128 * config.N * config.r * 2
});
}
const hashPassword = async (password) => {
const salt = hex.hex.encode(utils.getRandomValues(new Uint8Array(16)));
const key = await generateKey(password, salt);
return `${salt}:${hex.hex.encode(key)}`;
};
const verifyPassword = async ({
hash,
password
}) => {
const [salt, key] = hash.split(":");
const targetKey = await generateKey(password, salt);
return constantTimeEqual(targetKey, utils$1.hexToBytes(key));
};
const symmetricEncrypt = async ({
key,
data
}) => {
const keyAsBytes = await hash.createHash("SHA-256").digest(key);
const dataAsBytes = utils$2.utf8ToBytes(data);
const chacha$1 = webcrypto.managedNonce(chacha.xchacha20poly1305)(new Uint8Array(keyAsBytes));
return utils$2.bytesToHex(chacha$1.encrypt(dataAsBytes));
};
const symmetricDecrypt = async ({
key,
data
}) => {
const keyAsBytes = await hash.createHash("SHA-256").digest(key);
const dataAsBytes = utils$2.hexToBytes(data);
const chacha$1 = webcrypto.managedNonce(chacha.xchacha20poly1305)(new Uint8Array(keyAsBytes));
return new TextDecoder().decode(chacha$1.decrypt(dataAsBytes));
};
exports.generateRandomString = random.generateRandomString;
exports.compareHash = compareHash;
exports.constantTimeEqual = constantTimeEqual;
exports.hashPassword = hashPassword;
exports.hashToBase64 = hashToBase64;
exports.signJWT = signJWT;
exports.symmetricDecrypt = symmetricDecrypt;
exports.symmetricEncrypt = symmetricEncrypt;
exports.verifyPassword = verifyPassword;