Initial Commit

This commit is contained in:
jb
2026-09-18 23:15:05 -04:00
commit fdcc4863f5
118 changed files with 16868 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
import { describe, expect, test } from 'bun:test';
import { randomBytes } from 'node:crypto';
import { generateKeyPair, exportPKCS8, jwtVerify } from 'jose';
import { TokenCipher, randomSecret, hashSecret, pkceChallenge, applicationJwt, assertSameOrigin, assertOAuthSessionBinding } from '../src/lib/server/security';
describe('server credential boundaries', () => {
test('authenticated encryption binds purpose and detects tampering', async () => {
const cipher = new TokenCipher(randomBytes(32).toString('base64'));
const envelope = await cipher.seal({ refresh: 'never-in-browser' }, 'character:123');
expect(envelope).not.toContain('never-in-browser');
expect(await cipher.open<{ refresh: string }>(envelope, 'character:123')).toEqual({ refresh: 'never-in-browser' });
await expect(cipher.open(envelope, 'character:456')).rejects.toThrow();
const parts = envelope.split('.');
parts[2] = (parts[2]![0] === 'A' ? 'B' : 'A') + parts[2]!.slice(1);
await expect(cipher.open(parts.join('.'), 'character:123')).rejects.toThrow();
expect(() => new TokenCipher('short')).toThrow();
});
test('opaque secrets and PKCE S256 vector', () => {
expect(randomSecret()).not.toBe(randomSecret());
expect(hashSecret(randomSecret())).toHaveLength(64);
expect(pkceChallenge('dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')).toBe('E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM');
});
test('application token audience is distinct from EVE and is short-lived', async () => {
const { privateKey, publicKey } = await generateKeyPair('RS256', { extractable: true });
const token = await applicationJwt({ userId: 'u1', sessionId: 's1', issuer: 'https://app.example', privateKey: Buffer.from(await exportPKCS8(privateKey)).toString('base64') });
const { payload } = await jwtVerify(token, publicKey, { issuer: 'https://app.example', audience: 'eve-intelligence' });
expect(payload.sub).toBe('u1'); expect(payload.sid).toBe('s1');
expect(payload.exp! - payload.iat!).toBe(300);
await expect(jwtVerify(token, publicKey, { audience: 'EVE Online' })).rejects.toThrow();
});
test('OAuth linking cannot switch user or browser session during the round-trip', () => {
const cookie = randomSecret();
const binding = { expectedUserId: 'user1', expectedSessionHash: hashSecret(cookie), currentUserId: 'user1', currentCookie: cookie };
assertOAuthSessionBinding(binding);
expect(() => assertOAuthSessionBinding({ ...binding, currentUserId: 'user2' })).toThrow();
expect(() => assertOAuthSessionBinding({ ...binding, currentCookie: randomSecret() })).toThrow();
expect(() => assertOAuthSessionBinding({ ...binding, currentUserId: null })).toThrow();
expect(() => assertOAuthSessionBinding({ expectedSessionHash: null, currentUserId: 'unexpected-login' })).toThrow();
assertOAuthSessionBinding({ expectedSessionHash: null, currentUserId: null });
});
test('state-changing browser actions reject missing/foreign origins', () => {
expect(() => assertSameOrigin(new Request('https://app.example/api', { method: 'POST' }), 'https://app.example')).toThrow();
expect(() => assertSameOrigin(new Request('https://app.example/api', { headers: { origin: 'https://evil.example' } }), 'https://app.example')).toThrow();
assertSameOrigin(new Request('https://app.example/api', { headers: { origin: 'https://app.example' } }), 'https://app.example');
});
});