umami/lib/crypto.js

79 lines
1.8 KiB
JavaScript
Raw Normal View History

2020-07-23 00:46:05 +02:00
import crypto from 'crypto';
import { v4, v5, validate } from 'uuid';
2021-04-28 11:45:38 +02:00
import bcrypt from 'bcryptjs';
2020-07-23 06:33:17 +02:00
import { JWT, JWE, JWK } from 'jose';
2020-08-21 04:38:20 +02:00
import { startOfMonth } from 'date-fns';
2020-07-23 00:46:05 +02:00
2020-08-09 08:48:43 +02:00
const SALT_ROUNDS = 10;
2022-08-12 20:59:05 +02:00
const KEY = key();
2020-08-21 04:38:20 +02:00
const ROTATING_SALT = hash(startOfMonth(new Date()).toUTCString());
2020-08-15 10:17:15 +02:00
const CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
2020-07-23 00:46:05 +02:00
2022-08-12 20:59:05 +02:00
export function key(value) {
return JWK.asKey(Buffer.from(secret(value)));
}
2020-07-24 04:56:55 +02:00
export function hash(...args) {
return crypto.createHash('sha512').update(args.join('')).digest('hex');
2020-07-23 05:45:09 +02:00
}
2022-08-12 20:59:05 +02:00
export function secret(secret = process.env.HASH_SALT || process.env.DATABASE_URL) {
return hash(secret);
2020-07-23 05:45:09 +02:00
}
2020-07-23 00:46:05 +02:00
2020-08-21 04:38:20 +02:00
export function salt() {
2022-04-13 05:59:17 +02:00
return v5(hash(secret(), ROTATING_SALT), v5.DNS);
2020-08-21 04:38:20 +02:00
}
2020-07-23 05:45:09 +02:00
export function uuid(...args) {
if (!args.length) return v4();
2020-08-21 04:38:20 +02:00
return v5(args.join(''), salt());
2020-07-23 00:46:05 +02:00
}
export function isValidUuid(s) {
return validate(s);
2020-07-23 00:46:05 +02:00
}
2020-08-15 10:17:15 +02:00
export function getRandomChars(n) {
let s = '';
for (let i = 0; i < n; i++) {
s += CHARS[Math.floor(Math.random() * CHARS.length)];
}
return s;
}
export function hashPassword(password) {
2021-04-28 11:45:38 +02:00
return bcrypt.hashSync(password, SALT_ROUNDS);
2020-08-09 08:48:43 +02:00
}
export function checkPassword(password, hash) {
2021-04-28 11:45:38 +02:00
return bcrypt.compareSync(password, hash);
2020-07-23 00:46:05 +02:00
}
2020-07-23 06:33:17 +02:00
export async function createToken(payload) {
return JWT.sign(payload, KEY);
2020-07-23 00:46:05 +02:00
}
2022-08-12 20:59:05 +02:00
export async function parseToken(token, key = KEY) {
try {
2022-08-12 20:59:05 +02:00
return JWT.verify(token, key);
} catch {
return null;
}
2020-07-23 06:33:17 +02:00
}
2022-08-12 20:59:05 +02:00
export async function createSecureToken(payload, key = KEY) {
return JWE.encrypt(await createToken(payload), key);
2020-07-23 06:33:17 +02:00
}
2022-08-12 20:59:05 +02:00
export async function parseSecureToken(token, key = KEY) {
try {
2022-08-12 20:59:05 +02:00
const result = await JWE.decrypt(token, key);
2022-08-12 20:59:05 +02:00
return parseToken(result.toString(), key);
} catch {
return null;
}
2020-07-23 00:46:05 +02:00
}