a134c47152
Gate a new /api/admin/* route set (register/list/update/delete servers) behind a single shared MCMAPPER_ADMIN_TOKEN header, and add a /admin frontend page (Alpine) to unlock, register new servers, and edit authMode/anonymousChatAllowed/waypointFormat per server — these columns already existed but were only editable via direct DB edit until now. Written test-first per the project's TDD workflow: admin.ts's domain logic, the index.ts route wiring, and a new e2e/tests/admin.spec.ts covering the token gate and register/edit/delete round trip through the real browser UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015tKdPZt78zbPUZMXWzKEKt
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
// Shared constants between global-setup.ts, global-teardown.ts, playwright.config.ts, and the
|
|
// proxy process — kept in one place deliberately (see region-select.js's MAX_EXPORT_CHUNKS
|
|
// comment for why hand-synced duplicate constants across files are worth avoiding when a single
|
|
// source is this easy).
|
|
import { readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
export const ROOT = join(import.meta.dirname, "..");
|
|
export const API_DIR = join(ROOT, "api");
|
|
export const FRONTEND_DIR = join(ROOT, "frontend");
|
|
|
|
// Distinct container names/ports from the README's `bun test` throwaway infra (mcmapper-test-*
|
|
// on 15432/16379/19000) so an e2e run and a `bun test` run can happen at the same time without
|
|
// colliding.
|
|
export const PG_CONTAINER = "mcmapper-e2e-pg";
|
|
export const REDIS_CONTAINER = "mcmapper-e2e-redis";
|
|
export const MINIO_CONTAINER = "mcmapper-e2e-minio";
|
|
|
|
export const PG_PORT = 15433;
|
|
export const REDIS_PORT = 16380;
|
|
export const MINIO_PORT = 19002;
|
|
|
|
export const API_PORT = 13010;
|
|
export const FRONTEND_PORT = 13011;
|
|
export const PROXY_PORT = 14010;
|
|
|
|
export const DATABASE_URL = `postgres://mcmapper:mcmapper@localhost:${PG_PORT}/mcmapper`;
|
|
export const REDIS_URL = `redis://localhost:${REDIS_PORT}`;
|
|
export const MINIO_ACCESS_KEY = "mcmapper";
|
|
export const MINIO_SECRET_KEY = "mcmapper-e2e-only";
|
|
|
|
export const PROXY_ORIGIN = `http://localhost:${PROXY_PORT}`;
|
|
|
|
// Fixed, not random: admin.spec.ts needs to know it up front, and this only ever gates the
|
|
// throwaway e2e api instance.
|
|
export const ADMIN_TOKEN = "e2e-admin-token";
|
|
|
|
export const STATE_FILE = join(import.meta.dirname, ".e2e-state.json");
|
|
|
|
export type E2eState = {
|
|
pids: number[];
|
|
containers: string[];
|
|
baseURL: string;
|
|
serverId: string;
|
|
serverToken: string;
|
|
sessionToken: string;
|
|
accountId: string;
|
|
adminToken: string;
|
|
};
|
|
|
|
// Read by spec files — by the time tests run, global-setup.ts has already written this.
|
|
export function readE2eState(): E2eState {
|
|
return JSON.parse(readFileSync(STATE_FILE, "utf-8"));
|
|
}
|