@gaonjs/config 0.17.6 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -133,6 +133,13 @@ export interface AppSessionConfig {
133
133
  readonly cookieName?: string;
134
134
  /** 세션 TTL(초). 생략 시 배터리 기본. */
135
135
  readonly ttlSeconds?: number;
136
+ /**
137
+ * CSRF 토큰 검증 토글(결정 271 · 규칙 8). 생략 시 켬(보안 기본값). `false` 로만
138
+ * 끈다 — security-checklist 가 안내하는 `session: { csrf: false }` 가 이 필드다.
139
+ * wire.ts 가 SessionOptions.csrf 로 그대로 전달한다(이전엔 타입에 없어 문서대로
140
+ * 쓴 defineAppConfig 리터럴이 excess-property 컴파일 에러였다).
141
+ */
142
+ readonly csrf?: boolean;
136
143
  }
137
144
  /**
138
145
  * 앱별 설정 — apps/<app>/app.config.ts (v0.16 §3.3).
@@ -142,7 +149,11 @@ export interface AppSessionConfig {
142
149
  * - hosts: 이 앱이 응답할 도메인 목록. 생략 시 URL 프리픽스 관례만 사용.
143
150
  * - session: 세션 옵션(secret · 쿠키 이름 등).
144
151
  * - auth: 인증 이음새(loadUser · loginRedirect — 결정 59).
145
- * - prefix: URL 프리픽스 관례를 명시적으로 덮어쓴다(고급).
152
+ *
153
+ * URL 프리픽스는 **앱 폴더명**이 정한다(§3.3 · web→'/', 그 외→'/<name>') — The One
154
+ * Way. 별도 override 는 두지 않는다(결정 271: 예전 `prefix` 필드는 serving 도, api()
155
+ * 매니페스트 생성기도 배선하지 않은 no-op 이라 제거 · 다른 프리픽스가 필요하면 앱
156
+ * 폴더명을 바꾼다).
146
157
  *
147
158
  * 개발 모드에서는 `<앱이름>.localhost` 로도 접근된다(v0.11 · §3.3) —
148
159
  * hosts 를 비워도 이 로컬 관례는 자동으로 성립한다.
@@ -159,8 +170,6 @@ export interface AppConfig {
159
170
  * requireAuth/this.auth.user 가 로그인 후에도 영구 null 로 파손된다.
160
171
  */
161
172
  readonly auth?: AuthOptions | JwtAuthOptions;
162
- /** URL 프리픽스 명시 덮어쓰기. 생략 시 관례: web→'/', 그 외→'/<name>'. */
163
- readonly prefix?: string;
164
173
  /**
165
174
  * 선택 플러그인 @gaonjs/seal 토글(결정 121). `true` 면 이 앱의 wire(요청/응답 JSON + 최초 문서
166
175
  * data-page)를 봉인한다. `{ except: ['/webhooks/*'] }` 로 특정 경로를 평문 통과. 정적 자산·헬스체크·
package/dist/wire.js CHANGED
@@ -306,7 +306,17 @@ async function assembleApp(config, root, domain, redis, nats) {
306
306
  if (typeof ac?.sharedProps === 'function') {
307
307
  spec = { ...spec, sharedProps: ac.sharedProps };
308
308
  }
309
- if (ac?.session?.secret && redis) {
309
+ if (ac?.session?.secret) {
310
+ // 결정 263: 세션이 구성됐는데(session.secret) Redis 가 없으면 fail-loud 한다.
311
+ // 세션 저장소는 Redis 가 필수인데(redisSessionStore), 이전엔 `&& redis` 게이팅으로
312
+ // config.redis 부재 시 세션 배선을 **조용히 통째로 스킵**했다 — 부팅은 green,
313
+ // 로그인은 영구 실패, CSRF 무방비(부팅 green·런타임 파손 클래스 · 결정 59 동형).
314
+ // DB(250/252)·PORT(240) 와 대칭으로 무효 설정은 부팅 전에 멈춘다(§7.5.3).
315
+ if (!redis) {
316
+ throw new Error(`apps/${a.name}: 세션이 구성됐지만(app.config 의 session.secret) Redis 가 없습니다 — 세션 저장소는 Redis 가 필수입니다.\n` +
317
+ ` → gaon.config 에 redis 를 설정하세요: defineConfig({ redis: { url: env('REDIS_URL') }, ... })\n` +
318
+ ` → 또는 apps/${a.name}/app.config.ts 의 session 설정을 제거하세요(세션 비활성).`);
319
+ }
310
320
  spec = {
311
321
  ...spec,
312
322
  session: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gaonjs/config",
3
- "version": "0.17.6",
3
+ "version": "0.18.0",
4
4
  "description": "Gaon 루트 설정 로더·자동 배선 (gaon.config.ts)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,13 +25,13 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "ioredis": "^5.4.1",
28
- "@gaonjs/async": "0.15.2",
29
28
  "@gaonjs/core": "0.2.4",
30
- "@gaonjs/mail": "0.3.1",
31
- "@gaonjs/data": "0.17.1",
32
- "@gaonjs/storage": "0.1.5",
33
- "@gaonjs/web": "0.20.1",
34
- "@gaonjs/i18n": "0.2.3"
29
+ "@gaonjs/async": "0.15.3",
30
+ "@gaonjs/data": "0.17.3",
31
+ "@gaonjs/mail": "0.3.3",
32
+ "@gaonjs/i18n": "0.2.4",
33
+ "@gaonjs/web": "0.20.4",
34
+ "@gaonjs/storage": "0.1.5"
35
35
  },
36
36
  "devDependencies": {
37
37
  "fastify": "^5.0.0"