Use authenticated Redis key on logout

This commit is contained in:
Mike Cao
2026-06-02 17:46:08 -07:00
parent a9beebf1a9
commit fded75f940
2 changed files with 71 additions and 5 deletions
+68
View File
@@ -0,0 +1,68 @@
import { beforeEach, expect, test, vi } from 'vitest';
import redis from '@/lib/redis';
import { parseRequest } from '@/lib/request';
import { POST } from './route';
vi.mock('@/lib/redis', () => ({
default: {
enabled: true,
client: {
del: vi.fn(),
},
},
}));
vi.mock('@/lib/request', () => ({
parseRequest: vi.fn(),
}));
vi.mock('@/lib/response', () => ({
ok: () => new Response(null, { status: 200 }),
}));
const redisMock = redis as {
enabled: boolean;
client: {
del: ReturnType<typeof vi.fn>;
};
};
const parseRequestMock = vi.mocked(parseRequest);
beforeEach(() => {
redisMock.enabled = true;
redisMock.client.del.mockReset();
parseRequestMock.mockReset();
});
test('POST deletes the authenticated Redis auth key', async () => {
parseRequestMock.mockResolvedValue({
auth: { authKey: 'auth:session-key' },
error: undefined,
});
const response = await POST(
new Request('http://localhost/api/auth/logout', {
method: 'POST',
headers: {
authorization: 'Bearer secure-token',
},
}),
);
expect(redisMock.client.del).toHaveBeenCalledTimes(1);
expect(redisMock.client.del).toHaveBeenCalledWith('auth:session-key');
expect(redisMock.client.del).not.toHaveBeenCalledWith('secure-token');
expect(response.status).toBe(200);
});
test('POST does not delete a key when auth fails', async () => {
parseRequestMock.mockResolvedValue({
auth: null,
error: () => new Response(null, { status: 401 }),
});
const response = await POST(new Request('http://localhost/api/auth/logout', { method: 'POST' }));
expect(redisMock.client.del).not.toHaveBeenCalled();
expect(response.status).toBe(401);
});
+3 -5
View File
@@ -3,16 +3,14 @@ import { parseRequest } from '@/lib/request';
import { ok } from '@/lib/response'; import { ok } from '@/lib/response';
export async function POST(request: Request) { export async function POST(request: Request) {
const { error } = await parseRequest(request); const { auth, error } = await parseRequest(request);
if (error) { if (error) {
return error(); return error();
} }
if (redis.enabled) { if (redis.enabled && auth?.authKey) {
const token = request.headers.get('authorization')?.split(' ')?.[1]; await redis.client.del(auth.authKey);
await redis.client.del(token);
} }
return ok(); return ok();