mirror of
https://gitlab.w-hs.de/an14051/backerup-website.git
synced 2026-07-27 17:35:29 +00:00
0d58fafe4e
- Add user management API endpoints for listing and creating users. - Implement login and logout functionality with rate limiting. - Create UI components for login form, logout button, and animated elements. - Add session management with JWT and secure cookie handling. - Seed initial admin user if no users exist. - Introduce utility functions for password hashing and user authentication. - Set up proxy middleware for route protection and security headers. - Create a JSON file for user data storage. - Add links configuration for external resources.
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import crypto from 'crypto'
|
|
|
|
// scrypt params: N=16384 gives ~100ms on modern hardware — deliberate slowdown
|
|
const SCRYPT_N = 16384
|
|
const SCRYPT_R = 8
|
|
const SCRYPT_P = 1
|
|
const KEY_LEN = 64
|
|
|
|
/** Hashes a password using scrypt. Returns the hex hash and a random hex salt. */
|
|
export async function hashPassword(password: string): Promise<{ hash: string; salt: string }> {
|
|
const salt = crypto.randomBytes(16).toString('hex')
|
|
const hash = await deriveKey(password, salt)
|
|
return { hash, salt }
|
|
}
|
|
|
|
/** Constant-time comparison to prevent timing attacks. */
|
|
export async function verifyPassword(
|
|
password: string,
|
|
hash: string,
|
|
salt: string,
|
|
): Promise<boolean> {
|
|
const derived = await deriveKey(password, salt)
|
|
const a = Buffer.from(derived, 'hex')
|
|
const b = Buffer.from(hash, 'hex')
|
|
if (a.length !== b.length) return false
|
|
return crypto.timingSafeEqual(a, b)
|
|
}
|
|
|
|
function deriveKey(password: string, salt: string): Promise<string> {
|
|
return new Promise((resolve, reject) => {
|
|
crypto.scrypt(password, salt, KEY_LEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, key) => {
|
|
if (err) reject(err)
|
|
else resolve(key.toString('hex'))
|
|
})
|
|
})
|
|
}
|