Initial LisgloSIPS V2 implementation

This commit is contained in:
hectorzhao
2026-06-22 10:56:38 +08:00
commit 5fa1bd35e9
303 changed files with 35644 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
import { describe, expect, it } from 'vitest';
import crypto from 'node:crypto';
import {
hashPasswordArgon2id,
randomToken,
sha256Token,
signAccessToken,
verifyAccessToken,
verifyPasswordArgon2id
} from './index.js';
describe('auth primitives', () => {
it('hashes and verifies Argon2id passwords with PHC metadata', async () => {
const secret = crypto.randomUUID();
const hash = await hashPasswordArgon2id(secret, {
salt: Buffer.alloc(16, 7),
memoryKiB: 1024,
passes: 1
});
expect(hash).toMatch(/^\$argon2id\$v=19\$m=1024,t=1,p=1\$/);
await expect(verifyPasswordArgon2id(secret, hash)).resolves.toBe(true);
await expect(verifyPasswordArgon2id(crypto.randomUUID(), hash)).resolves.toBe(false);
});
it('hashes refresh tokens without retaining token material', () => {
const token = randomToken();
const digest = sha256Token(token);
expect(token).not.toContain(digest);
expect(digest).toMatch(/^[a-f0-9]{64}$/);
});
it('signs and verifies expiring access tokens', () => {
const secret = 'test-only-access-token-secret-min-32-bytes';
const token = signAccessToken(
{
sub: 'usr_test',
username: 'operator',
roles: ['admin'],
typ: 'access'
},
{
secret,
issuer: 'lisglosips-api',
audience: 'lisglosips-web',
ttlSeconds: 60,
now: new Date('2026-06-21T00:00:00.000Z')
}
);
expect(
verifyAccessToken(token, {
secret,
issuer: 'lisglosips-api',
audience: 'lisglosips-web',
now: new Date('2026-06-21T00:00:30.000Z')
})?.sub
).toBe('usr_test');
expect(
verifyAccessToken(token, {
secret,
issuer: 'lisglosips-api',
audience: 'lisglosips-web',
now: new Date('2026-06-21T00:02:00.000Z')
})
).toBeNull();
});
});