게임 토큰 회수를 Redis에 유지하고 재시작과 알림 누락을 방어한다

This commit is contained in:
2026-10-09 05:59:28 +09:00
parent eeda225429
commit 005f88d7ca
17 changed files with 605 additions and 17 deletions
+24
View File
@@ -1242,6 +1242,30 @@ describe('gateway auth flow', () => {
expect(validated?.user.username).toBe('tester');
});
it('starts token age before the user snapshot so a concurrent role flush can revoke stale identity', async () => {
const { caller, users, sessions } = buildCaller();
const user = await users.createUser({ username: 'role-snapshot-race', password: 'synthetic-password' });
const parent = await sessions.createSession(user);
const issuedAt = new Date().toISOString();
vi.useFakeTimers({ now: new Date(issuedAt) });
const original = users.findById.bind(users);
const find = vi.spyOn(users, 'findById').mockImplementationOnce(async (id) => {
const snapshot = await original(id);
vi.advanceTimersByTime(5000); // admin mutation/flush arrives after the snapshot.
return snapshot;
});
try {
const result = await caller.auth.issueGameSession({
sessionToken: parent.sessionToken,
profile: 'che:default',
});
expect(decryptGameSessionToken(result.gameToken, 'test-secret')?.issuedAt).toBe(issuedAt);
} finally {
find.mockRestore();
vi.useRealTimers();
}
});
it('retains the original issuance instant when logout flush overlaps later identity reads', async () => {
const { caller, users, sessions } = buildCaller();
const user = await users.createUser({ username: 'issue-flush-race', password: 'synthetic-password' });