v0.71.0: admin panel — users table, login/sessions, generic DB CRUD modal
CI / build + unit + e2e (pull_request) Failing after 13m35s
CI / build + unit + e2e (pull_request) Failing after 13m35s
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
import { getGameDb } from '@/lib/db/client';
|
||||
import { createSession } from '@/lib/auth';
|
||||
import { GET } from './route';
|
||||
|
||||
// v0.71.0 — admin guard + table list tests: no/expired session → 401, non-admin → 403,
|
||||
// admin passes and sees every user table (sqlite_% excluded).
|
||||
|
||||
let dir: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
dir = await fs.mkdtemp(path.join(os.tmpdir(), 'flight-admin-tables-'));
|
||||
process.env.FLIGHT_DB_PATH = path.join(dir, 'tables.db');
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
delete process.env.FLIGHT_DB_PATH;
|
||||
await fs.rm(dir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
const get = (sessionId?: string) =>
|
||||
GET(
|
||||
new Request('http://localhost/api/admin/tables', {
|
||||
headers: sessionId ? { 'X-Flight-Session': sessionId } : undefined,
|
||||
}),
|
||||
);
|
||||
|
||||
async function makeUser(username: string, admin: number): Promise<string> {
|
||||
const inst = await getGameDb();
|
||||
const id = `user-${username}`;
|
||||
inst.raw.run(
|
||||
`INSERT INTO users (id, username, password_hash, admin, created_at)
|
||||
SELECT ?, ?, 'aa$bb', ?, ? WHERE NOT EXISTS (SELECT 1 FROM users WHERE id = ?)`,
|
||||
[id, username, admin, Date.now(), id],
|
||||
);
|
||||
return id;
|
||||
}
|
||||
|
||||
describe('GET /api/admin/tables', () => {
|
||||
it('returns 401 without a session header', async () => {
|
||||
const res = await get();
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
|
||||
it('returns 401 for an expired session', async () => {
|
||||
const inst = await getGameDb();
|
||||
inst.raw.run('INSERT INTO sessions (id, user_id, expires_at) VALUES (?, ?, ?)', [
|
||||
'expired-admin-session',
|
||||
'admin-kamilkrzywda',
|
||||
Date.now() - 1000,
|
||||
]);
|
||||
const res = await get('expired-admin-session');
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
|
||||
it('returns 403 for a valid non-admin session', async () => {
|
||||
const userId = await makeUser('tables-nonadmin', 0);
|
||||
const sessionId = await createSession(await getGameDb(), userId);
|
||||
const res = await get(sessionId);
|
||||
expect(res.status).toBe(403);
|
||||
expect(((await res.json()) as { error: string }).error).toMatch(/admin/i);
|
||||
});
|
||||
|
||||
it('lists every user table for an admin, excluding sqlite_% internals', async () => {
|
||||
const sessionId = await createSession(await getGameDb(), 'admin-kamilkrzywda');
|
||||
const res = await get(sessionId);
|
||||
expect(res.status).toBe(200);
|
||||
const names = ((await res.json()) as Array<{ name: string }>).map((t) => t.name);
|
||||
|
||||
for (const expected of ['account', 'packages', 'planes', 'sessions', 'sim_state', 'users']) {
|
||||
expect(names, `missing ${expected}`).toContain(expected);
|
||||
}
|
||||
expect(names.some((n) => n.startsWith('sqlite_'))).toBe(false);
|
||||
// Name-ordered.
|
||||
expect([...names].sort()).toEqual(names);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user