import { tap, expect } from '@git.zone/tstest/tapbundle'; import { LoginSession } from '../ts/reception/classes.loginsession.js'; import { User } from '../ts/reception/classes.user.js'; import * as plugins from '../ts/plugins.js'; const createTestLoginSession = () => { const loginSession = new LoginSession(); loginSession.id = 'test-session'; loginSession.data.userId = 'test-user'; (loginSession as LoginSession & { save: () => Promise }).save = async () => undefined; return loginSession; }; tap.test('hashes passwords with argon2 and verifies them', async () => { const passwordHash = await User.hashPassword('correct horse battery staple'); expect(passwordHash.startsWith('$argon2')).toBeTrue(); expect(await User.verifyPassword('correct horse battery staple', passwordHash)).toBeTrue(); expect(await User.verifyPassword('wrong password', passwordHash)).toBeFalse(); expect(User.shouldUpgradePasswordHash(passwordHash)).toBeFalse(); }); tap.test('accepts legacy sha256 hashes and marks them for upgrade', async () => { const legacyHash = await plugins.smarthash.sha256FromString('legacy-password'); expect(User.isLegacyPasswordHash(legacyHash)).toBeTrue(); expect(await User.verifyPassword('legacy-password', legacyHash)).toBeTrue(); expect(await User.verifyPassword('different-password', legacyHash)).toBeFalse(); expect(User.shouldUpgradePasswordHash(legacyHash)).toBeTrue(); }); tap.test('rotates refresh tokens and detects reuse', async () => { const loginSession = createTestLoginSession(); const firstRefreshToken = await loginSession.getRefreshToken(); const secondRefreshToken = await loginSession.getRefreshToken(); expect(firstRefreshToken.startsWith('refresh_')).toBeTrue(); expect(secondRefreshToken.startsWith('refresh_')).toBeTrue(); expect(firstRefreshToken).not.toEqual(secondRefreshToken); expect(loginSession.data.refreshToken).toBeNullOrUndefined(); expect(loginSession.data.refreshTokenHash).toBeTruthy(); expect(await loginSession.validateRefreshToken(secondRefreshToken)).toEqual('current'); expect(await loginSession.validateRefreshToken(firstRefreshToken)).toEqual('reused'); await loginSession.invalidate(); expect(await loginSession.validateRefreshToken(secondRefreshToken)).toEqual('invalidated'); }); tap.test('persists transfer tokens as one-time hashes', async () => { const loginSession = createTestLoginSession(); const transferToken = await loginSession.getTransferToken(); expect(transferToken.startsWith('transfer_')).toBeTrue(); expect(loginSession.data.transferTokenHash).toBeTruthy(); expect(await loginSession.validateTransferToken(transferToken)).toBeTrue(); expect(await loginSession.validateTransferToken(transferToken)).toBeFalse(); }); export default tap.start();