Fix production TypeScript builds and add DEPLOY.md so the app can be hosted from this repo. Co-authored-by: Cursor <cursoragent@cursor.com>
48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { describe, it } from 'node:test';
|
|
import { hashPassword, isArgon2idHash, verifyPassword } from '../src/modules/auth/password.js';
|
|
import { generateSessionToken, hashSessionToken } from '../src/modules/auth/sessionToken.js';
|
|
import { redactObject } from '../src/middleware/requestLogger.js';
|
|
|
|
describe('password hashing', () => {
|
|
it('hashes with Argon2id and never stores plaintext', async () => {
|
|
const password = 'correct-horse-battery';
|
|
const hashed = await hashPassword(password);
|
|
|
|
assert.notEqual(hashed, password);
|
|
assert.equal(isArgon2idHash(hashed), true);
|
|
assert.equal(await verifyPassword(password, hashed), true);
|
|
assert.equal(await verifyPassword('wrong-password', hashed), false);
|
|
});
|
|
});
|
|
|
|
describe('session tokens', () => {
|
|
it('hashes opaque tokens with SHA-256', () => {
|
|
const token = generateSessionToken();
|
|
const hashed = hashSessionToken(token);
|
|
|
|
assert.notEqual(hashed, token);
|
|
assert.match(hashed, /^[a-f0-9]{64}$/);
|
|
assert.equal(hashSessionToken(token), hashed);
|
|
});
|
|
});
|
|
|
|
describe('log redaction', () => {
|
|
it('redacts passwords, tokens, and authorization headers', () => {
|
|
const redacted = redactObject({
|
|
password: 'secret',
|
|
passwordHash: 'hash',
|
|
authorization: 'Bearer raw-session-token',
|
|
token: 'raw-session-token',
|
|
email: 'user@example.com',
|
|
});
|
|
|
|
assert.equal(redacted.password, '[REDACTED]');
|
|
assert.equal(redacted.passwordHash, '[REDACTED]');
|
|
assert.equal(redacted.authorization, '[REDACTED]');
|
|
assert.equal(redacted.token, '[REDACTED]');
|
|
assert.equal(redacted.email, 'user@example.com');
|
|
assert.doesNotMatch(JSON.stringify(redacted), /raw-session-token/);
|
|
});
|
|
});
|