84 lines
2.7 KiB
TypeScript
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);
|
|
} |