import assert from 'node:assert/strict'; import test from 'node:test'; import { JwtService } from '@nestjs/jwt'; import { AuthConfigService } from '../../src/common/config/auth-config.service'; import { TokenService } from '../../src/auth/services/token.service'; function config(): AuthConfigService { return { accessTokenSecret: 'a'.repeat(64), refreshTokenPepper: 'b'.repeat(64), accessTokenTtlSeconds: 900, refreshTokenTtlSeconds: 604800, maxLoginAttempts: 5, lockoutSeconds: 900, webOrigin: 'https://dhv2.korexlabs.com', accessCookieName: 'dhv2_access', refreshCookieName: 'dhv2_refresh', csrfCookieName: 'dhv2_csrf', } as AuthConfigService; } test('TokenService issues and verifies access tokens', async () => { const service = new TokenService(new JwtService(), config()); const token = await service.issueAccessToken({ userId: 'b6f6b10e-434a-4d72-9ec9-3520212dd290', sessionId: '1bab61ac-65d1-40e6-816b-63d90131a795', username: 'admin', }); const payload = await service.verifyAccessToken(token); assert.equal(payload.sub, 'b6f6b10e-434a-4d72-9ec9-3520212dd290'); assert.equal(payload.sid, '1bab61ac-65d1-40e6-816b-63d90131a795'); assert.equal(payload.typ, 'access'); }); test('TokenService rotates opaque refresh credentials without storing plaintext', () => { const service = new TokenService(new JwtService(), config()); const issued = service.issueRefreshToken(); assert.deepEqual(service.parseRefreshToken(issued.token), { sessionId: issued.sessionId, }); assert.equal(service.verifyRefreshToken(issued.token, issued.tokenHash), true); const replacement = issued.token.endsWith('x') ? 'y' : 'x'; assert.equal( service.verifyRefreshToken( `${issued.token.slice(0, -1)}${replacement}`, issued.tokenHash, ), false, ); assert.equal(issued.tokenHash.includes(issued.token), false); });