슈퍼어드민 디스코드 ID를 저장소에서 제거: 서버 deploy/.env의 SUPERADMIN_DISCORD_IDS에만 둔다
- config: 기본값 삭제(설정이 없으면 슈퍼어드민 없음) - 테스트·E2E: 만든 ID(900000000000000001/2) 사용 - 문서·README·.env.example·관리자 화면 입력 예시에서 실제 ID 삭제 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/** Admin site tests (docs/14-admin.md §9). */
|
||||
import { afterEach, describe, expect, test } from 'bun:test';
|
||||
import { Client, api, boot, guest, sleep } from './test-utils';
|
||||
import { Client, TEST_SUPERADMINS, api, boot, guest, sleep } from './test-utils';
|
||||
|
||||
const SUPER = '293719842274541579';
|
||||
const [SUPER, SUPER2] = TEST_SUPERADMINS;
|
||||
type Booted = ReturnType<typeof boot>;
|
||||
const running: Booted[] = [];
|
||||
const clients: Client[] = [];
|
||||
@@ -47,7 +47,7 @@ describe('roles', () => {
|
||||
const me = await api(s.base, '/api/admin/me', { cookie: sup.cookie });
|
||||
expect(me.body.role).toBe('superadmin');
|
||||
expect((await api(s.base, '/api/me', { cookie: sup.cookie })).body.role).toBe('superadmin');
|
||||
const sup2 = await discordLogin(s, '1352267557213573160');
|
||||
const sup2 = await discordLogin(s, SUPER2);
|
||||
expect((await api(s.base, '/api/admin/me', { cookie: sup2.cookie })).body.role).toBe('superadmin');
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ describe('roles', () => {
|
||||
// Pre-register before the person ever logged in.
|
||||
const add = await api(s.base, '/api/admin/admins', { method: 'POST', cookie: sup.cookie, body: JSON.stringify({ discordId: adminDiscord, note: '친구1' }) });
|
||||
expect(add.res.status).toBe(200);
|
||||
expect(add.body.admins.map((a: any) => a.discordId)).toEqual([SUPER, '1352267557213573160', adminDiscord]);
|
||||
expect(add.body.admins.map((a: any) => a.discordId)).toEqual([SUPER, SUPER2, adminDiscord]);
|
||||
const adm = await discordLogin(s, adminDiscord);
|
||||
expect((await api(s.base, '/api/admin/me', { cookie: adm.cookie })).body.role).toBe('admin');
|
||||
expect((await api(s.base, '/api/admin/users', { cookie: adm.cookie })).res.status).toBe(403);
|
||||
|
||||
@@ -14,9 +14,6 @@ export interface Config {
|
||||
loadTestNoHttpLimits: boolean;
|
||||
}
|
||||
|
||||
/** Superadmin Discord IDs, comma-separated (docs/14-admin.md §2). */
|
||||
export const DEFAULT_SUPERADMIN = '293719842274541579,1352267557213573160';
|
||||
|
||||
export function loadConfig(env: Record<string, string | undefined> = process.env): Config {
|
||||
const publicOrigin = (env.PUBLIC_ORIGIN ?? 'http://localhost:5173').replace(/\/$/, '');
|
||||
const extra = (env.ALLOWED_ORIGINS ?? '').split(',').map((s) => s.trim()).filter(Boolean);
|
||||
@@ -36,6 +33,7 @@ export function loadConfig(env: Record<string, string | undefined> = process.env
|
||||
secureCookies: publicOrigin.startsWith('https://'),
|
||||
trustProxy: env.TRUST_PROXY === '1',
|
||||
loadTestNoHttpLimits: env.LOADTEST_NO_HTTP_LIMITS === '1' && !publicOrigin.startsWith('https://'),
|
||||
superadminDiscordIds: (env.SUPERADMIN_DISCORD_IDS ?? DEFAULT_SUPERADMIN).split(',').map((s) => s.trim()).filter(Boolean),
|
||||
/** Superadmin Discord IDs, comma-separated (docs/14-admin.md §2). Only in deploy/.env, never in the repo. */
|
||||
superadminDiscordIds: (env.SUPERADMIN_DISCORD_IDS ?? '').split(',').map((s) => s.trim()).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import { loadConfig } from './config';
|
||||
import { startServer, type StartOptions } from './server';
|
||||
|
||||
export const ORIGIN = 'http://localhost:5173';
|
||||
/** Made-up superadmin Discord IDs for tests (the real ones live only in deploy/.env). */
|
||||
export const TEST_SUPERADMINS = ['900000000000000001', '900000000000000002'] as const;
|
||||
|
||||
export function tempDbPath(): string {
|
||||
const dir = mkdtempSync(join(process.env.TMPDIR ?? tmpdir(), 'bg-test-'));
|
||||
@@ -14,7 +16,7 @@ export function tempDbPath(): string {
|
||||
}
|
||||
|
||||
export function boot(dbPath = tempDbPath(), extra: Partial<StartOptions> = {}) {
|
||||
const config = loadConfig({ PORT: '0', DB_PATH: dbPath, PUBLIC_ORIGIN: ORIGIN });
|
||||
const config = loadConfig({ PORT: '0', DB_PATH: dbPath, PUBLIC_ORIGIN: ORIGIN, SUPERADMIN_DISCORD_IDS: TEST_SUPERADMINS.join(',') });
|
||||
const app = startServer({ config, log: () => {}, staticDir: null, stopWaitMs: 50, ...extra });
|
||||
const base = `http://localhost:${app.server.port}`;
|
||||
return { ...app, base, dbPath, config };
|
||||
|
||||
@@ -577,7 +577,7 @@ function Admins() {
|
||||
<h2>어드민 추가</h2>
|
||||
<label className="field">
|
||||
디스코드 ID(숫자)
|
||||
<input className="input" inputMode="numeric" value={discordId} onChange={(e) => setDiscordId(e.target.value)} placeholder="예: 293719842274541579" />
|
||||
<input className="input" inputMode="numeric" value={discordId} onChange={(e) => setDiscordId(e.target.value)} placeholder="디스코드 ID (숫자 17~20자리)" />
|
||||
</label>
|
||||
<label className="field">
|
||||
메모(선택)
|
||||
|
||||
Reference in New Issue
Block a user