M1 기반: 모노레포, 공통 엔진, 공용 프로토콜, 오목 엔진, 서버 골격
- packages/engine: 시드 RNG(sfc32), GameDefinition 타입, 무작위 대국·정보 유출 테스트 도구 - packages/shared: WS 프로토콜 스키마, 닉네임·방 코드 규칙, 게임 카탈로그 - packages/games/omok: 한국식·렌주·자유룰, 재귀 금수 판정, 무르기·무승부·시계 (테스트 27개) - apps/server: SQLite 스키마, 게스트·디스코드 로그인, 세션, 방 관리(저장·복구·타이머·재접속), WS 게이트웨이, HTTP API Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
30
apps/server/src/config.ts
Normal file
30
apps/server/src/config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export interface Config {
|
||||
port: number;
|
||||
publicOrigin: string;
|
||||
/** Extra origins accepted for WS/CSRF checks (e.g. Vite dev server). */
|
||||
allowedOrigins: string[];
|
||||
dbPath: string;
|
||||
discord: { clientId: string; clientSecret: string } | null;
|
||||
sessionSecret: string;
|
||||
secureCookies: boolean;
|
||||
}
|
||||
|
||||
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);
|
||||
const clientId = env.DISCORD_CLIENT_ID;
|
||||
const clientSecret = env.DISCORD_CLIENT_SECRET;
|
||||
const sessionSecret = env.SESSION_SECRET ?? '';
|
||||
if (publicOrigin.startsWith('https://') && sessionSecret.length < 32) {
|
||||
throw new Error('SESSION_SECRET must be at least 32 characters in production');
|
||||
}
|
||||
return {
|
||||
port: Number(env.PORT ?? 3000),
|
||||
publicOrigin,
|
||||
allowedOrigins: [publicOrigin, ...extra],
|
||||
dbPath: env.DB_PATH ?? './data/app.db',
|
||||
discord: clientId && clientSecret ? { clientId, clientSecret } : null,
|
||||
sessionSecret: sessionSecret || 'dev-only-insecure-session-secret-change-me',
|
||||
secureCookies: publicOrigin.startsWith('https://'),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user