This repository has been archived on 2026-03-26. You can view files and clone it, but cannot push or open issues or pull requests.

84 lines
2.7 KiB
TypeScript

import {Express} from "express";
import * as crypto from "node:crypto";
/**
* @desc Print the endpoints loaded into the express application.
* @param app {Express} Express application
*/
export function printEndpoints(app: Express): void {
function traverse(stack: any[], basePath = ''): void {
stack.forEach((layer: any) => {
if (layer.route) {
const methods = layer.route.methods;
if (methods) {
Object.keys(methods).forEach((method) => {
console.log(`${method.toUpperCase()} ${basePath}${layer.route.path}`);
});
}
} else if (layer.name === 'router' && layer.handle.stack) {
const routerBasePath = layer.regexp
? basePath + layer.regexp.source.replace('\\/?(?=\\/|$)', '').replace('\\/', '/')
: basePath;
traverse(layer.handle.stack, routerBasePath);
}
});
}
traverse(app._router.stack);
}
/**
* Hash a string.
* @param s {string} Target string
* @return {string} Target string hash
*/
export function hashString(s: string): string {
// Generate a random salt if not provided
const salt = crypto.randomBytes(16).toString('hex');
// Parameters for scrypt
const keylen = 64; // Length of the derived key (hash)
const cost = 16384; // CPU/memory cost parameter (N)
const blockSize = 8; // Block size parameter (r)
const parallelization = 1; // Parallelization parameter (p)
// Derive the key (hash)
const derivedKey = crypto.scryptSync(
s,
salt,
keylen,
{cost, blockSize, parallelization}
);
// Store the salt and hash together (e.g., as a colon-separated string)
return `${salt}:${derivedKey.toString('hex')}`;
}
/**
* Validate a string and a hash for a match
* @param s Target string
* @param hash Target hash
* @return {boolean} Valid
*/
export function validateHash(s: string, hash: string): boolean {
// Split the stored hash into salt and derived key
const [salt, storedDerivedKeyHex] = hash.split(':');
const storedDerivedKey = Buffer.from(storedDerivedKeyHex, 'hex');
// Parameters for scrypt (must match the hashing parameters)
const keylen = 64;
const cost = 16384;
const blockSize = 8;
const parallelization = 1;
// Derive the key from the provided password and stored salt
const derivedKey = crypto.scryptSync(
s,
salt,
keylen,
{cost, blockSize, parallelization}
);
// Compare the derived key with the stored derived key
return crypto.timingSafeEqual(derivedKey, storedDerivedKey);
}