@nexusts/shield 0.9.5 → 0.9.7

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/index.js CHANGED
@@ -9,7 +9,6 @@ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
9
9
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
10
10
  return c > 3 && r && Object.defineProperty(target, key, r), r;
11
11
  };
12
- var __legacyDecorateParamTS = (index, decorator) => (target, key) => decorator(target, key, index);
13
12
  var __legacyMetadataTS = (k, v) => {
14
13
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
15
14
  return Reflect.metadata(k, v);
@@ -269,7 +268,12 @@ class ShieldService {
269
268
  cors;
270
269
  csrf;
271
270
  headers;
272
- constructor(config = {}) {
271
+ _initialized = false;
272
+ init() {
273
+ if (this._initialized)
274
+ return;
275
+ this._initialized = true;
276
+ const config = this._config ?? {};
273
277
  if (config.cors) {
274
278
  this.cors = new CorsGuard(config.cors);
275
279
  }
@@ -279,8 +283,10 @@ class ShieldService {
279
283
  }
280
284
  this.headers = new HeadersGuard(config.hsts ?? false, config.csp ?? false, config.xFrameOptions ?? "SAMEORIGIN", config.xContentTypeOptions ?? true, config.referrerPolicy);
281
285
  }
286
+ constructor() {}
282
287
  middleware() {
283
288
  return async (c, next) => {
289
+ this.init();
284
290
  const requestOrigin = c.req.header("origin") ?? "";
285
291
  const method = c.req.method.toUpperCase();
286
292
  if (this.cors && method === "OPTIONS" && c.req.header("access-control-request-method")) {
@@ -310,6 +316,7 @@ class ShieldService {
310
316
  };
311
317
  }
312
318
  issueToken(headers) {
319
+ this.init();
313
320
  if (!this.csrf)
314
321
  throw new Error("CSRF guard is not enabled");
315
322
  return this.csrf.issue(headers);
@@ -323,12 +330,12 @@ class ShieldService {
323
330
  return null;
324
331
  }
325
332
  }
333
+ __legacyDecorateClassTS([
334
+ Inject("SHIELD_CONFIG")
335
+ ], ShieldService.prototype, "_config", undefined);
326
336
  ShieldService = __legacyDecorateClassTS([
327
337
  Injectable(),
328
- __legacyDecorateParamTS(0, Inject("SHIELD_CONFIG")),
329
- __legacyMetadataTS("design:paramtypes", [
330
- typeof ShieldConfig === "undefined" ? Object : ShieldConfig
331
- ])
338
+ __legacyMetadataTS("design:paramtypes", [])
332
339
  ], ShieldService);
333
340
  // packages/shield/src/shield.module.ts
334
341
  import { Module } from "@nexusts/core";
@@ -370,5 +377,5 @@ export {
370
377
  CorsGuard
371
378
  };
372
379
 
373
- //# debugId=1C7FE289B85891B164756E2164756E21
380
+ //# debugId=8EB126F105C98A1164756E2164756E21
374
381
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -6,10 +6,10 @@
6
6
  "/**\n * CSRF guard — synchronizer token pattern.\n *\n * On `GET` (or any non-mutating request) we ensure a `nexus-csrf` cookie\n * is set. On `POST`/`PUT`/`DELETE`/`PATCH` we read the cookie, then\n * compare it against the `X-CSRF-Token` header (or `_csrf` form field).\n *\n * Both values must match (constant-time compare) for the request to pass.\n */\nimport type { CsrfConfig, CsrfToken } from \"../types.js\";\nimport { ShieldInternals } from \"../types.js\";\n\nexport class CsrfGuard {\n\tprivate config: Required<CsrfConfig>;\n\tprivate secret: string;\n\n\tconstructor(config: CsrfConfig, secret: string) {\n\t\tthis.config = {\n\t\t\tenabled: config.enabled,\n\t\t\tcookieName: config.cookieName ?? \"nexus-csrf\",\n\t\t\theaderName: config.headerName ?? \"x-csrf-token\",\n\t\t\tfieldName: config.fieldName ?? \"_csrf\",\n\t\t\tprotectGet: config.protectGet ?? false,\n\t\t\tcookie: {\n\t\t\t\tsameSite: config.cookie?.sameSite ?? \"Lax\",\n\t\t\t\tsecure: config.cookie?.secure ?? true,\n\t\t\t\thttpOnly: config.cookie?.httpOnly ?? false,\n\t\t\t\tpath: config.cookie?.path ?? \"/\",\n\t\t\t},\n\t\t\tignoreMethods: config.ignoreMethods ?? [\"GET\", \"HEAD\", \"OPTIONS\"],\n\t\t};\n\t\tthis.secret = secret;\n\t}\n\n\t/**\n\t * Issue a CSRF token. Sets the cookie on the response.\n\t */\n\tissue(res: Headers): CsrfToken {\n\t\tconst raw = ShieldInternals.randomToken();\n\t\tconst signed = ShieldInternals.sign(raw, this.secret);\n\t\t// Set the cookie. The unsigned value is stored.\n\t\tconst cookieParts = [\n\t\t\t`${this.config.cookieName}=${raw}`,\n\t\t\t`Path=${this.config.cookie.path}`,\n\t\t\t`SameSite=${this.config.cookie.sameSite}`,\n\t\t];\n\t\tif (this.config.cookie.secure) cookieParts.push(\"Secure\");\n\t\tif (this.config.cookie.httpOnly) cookieParts.push(\"HttpOnly\");\n\t\tres.append(\"Set-Cookie\", cookieParts.join(\"; \"));\n\t\treturn {\n\t\t\ttoken: signed,\n\t\t\thtml: `<meta name=\"csrf-token\" content=\"${signed}\">`,\n\t\t};\n\t}\n\n\t/**\n\t * Verify a request. Returns `true` if the request is allowed.\n\t */\n\tverify(req: { method: string; headers: Headers }): boolean {\n\t\tconst method = req.method.toUpperCase();\n\t\tif (\n\t\t\tthis.config.ignoreMethods.map((m) => m.toUpperCase()).includes(method)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tif (this.config.protectGet) {\n\t\t\t// (no-op; protectGet currently shares ignoreMethods logic)\n\t\t}\n\t\tconst cookieHeader = req.headers.get(\"cookie\") ?? \"\";\n\t\tconst cookieToken = this.extractCookie(\n\t\t\tcookieHeader,\n\t\t\tthis.config.cookieName,\n\t\t);\n\t\tif (!cookieToken) return false;\n\t\t// Header value\n\t\tconst headerToken = req.headers.get(this.config.headerName);\n\t\tif (\n\t\t\theaderToken &&\n\t\t\tShieldInternals.verify(headerToken, this.secret) === cookieToken\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\t// Form field (parsed from x-www-form-urlencoded body or multipart)\n\t\t// For simplicity, we accept a custom header `x-csrf-field` with the value.\n\t\tconst fieldToken = req.headers.get(\"x-csrf-field\");\n\t\tif (\n\t\t\tfieldToken &&\n\t\t\tShieldInternals.verify(fieldToken, this.secret) === cookieToken\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Build a Hono middleware. Sets the cookie on every safe request and\n\t * enforces the check on mutating ones.\n\t */\n\tmiddleware() {\n\t\treturn async (c: any, next: () => Promise<any>) => {\n\t\t\tconst method = (c.req.method as string).toUpperCase();\n\t\t\tif (\n\t\t\t\tthis.config.ignoreMethods.map((m) => m.toUpperCase()).includes(method)\n\t\t\t) {\n\t\t\t\t// Safe method: ensure a cookie is present.\n\t\t\t\tconst cookieHeader = c.req.header(\"cookie\") ?? \"\";\n\t\t\t\tif (!this.extractCookie(cookieHeader, this.config.cookieName)) {\n\t\t\t\t\tthis.issue(c.res.headers);\n\t\t\t\t}\n\t\t\t\treturn next();\n\t\t\t}\n\t\t\tif (!this.verify(c.req.raw)) {\n\t\t\t\treturn c.text(\"Invalid CSRF token\", 403);\n\t\t\t}\n\t\t\treturn next();\n\t\t};\n\t}\n\n\tprivate extractCookie(cookieHeader: string, name: string): string | null {\n\t\tfor (const part of cookieHeader.split(\";\")) {\n\t\t\tconst [k, ...rest] = part.trim().split(\"=\");\n\t\t\tif (k === name) return rest.join(\"=\");\n\t\t}\n\t\treturn null;\n\t}\n}\n",
7
7
  "/**\n * Security headers middleware. Sets HSTS, X-Frame-Options,\n * X-Content-Type-Options, Referrer-Policy, and CSP on every response.\n */\nimport type { CspConfig, HstsConfig } from \"../types.js\";\n\nexport class HeadersGuard {\n\thsts: HstsConfig | false;\n\tcsp: CspConfig | false;\n\txFrameOptions: \"DENY\" | \"SAMEORIGIN\" | false;\n\txContentTypeOptions: boolean;\n\treferrerPolicy: string | undefined;\n\n\tconstructor(\n\t\thsts: HstsConfig | false,\n\t\tcsp: CspConfig | false,\n\t\txFrameOptions: \"DENY\" | \"SAMEORIGIN\" | false,\n\t\txContentTypeOptions: boolean,\n\t\treferrerPolicy: string | undefined,\n\t) {\n\t\tthis.hsts = hsts;\n\t\tthis.csp = csp;\n\t\tthis.xFrameOptions = xFrameOptions;\n\t\tthis.xContentTypeOptions = xContentTypeOptions;\n\t\tthis.referrerPolicy = referrerPolicy;\n\t}\n\n\t/**\n\t * Apply configured headers to the given `Headers` instance in place.\n\t * Useful when you already have a Response and want to enrich it.\n\t */\n\tapply(headers: Headers): void {\n\t\tif (this.hsts) {\n\t\t\tconst h = this.buildHstsHeader(this.hsts);\n\t\t\tif (h) headers.set(\"Strict-Transport-Security\", h);\n\t\t}\n\t\tif (this.csp) {\n\t\t\tconst header = this.buildCspHeader(this.csp);\n\t\t\tconst name = this.csp.reportOnly\n\t\t\t\t? \"Content-Security-Policy-Report-Only\"\n\t\t\t\t: \"Content-Security-Policy\";\n\t\t\theaders.set(name, header);\n\t\t}\n\t\tif (this.xFrameOptions) {\n\t\t\theaders.set(\"X-Frame-Options\", this.xFrameOptions);\n\t\t}\n\t\tif (this.xContentTypeOptions) {\n\t\t\theaders.set(\"X-Content-Type-Options\", \"nosniff\");\n\t\t}\n\t\tif (this.referrerPolicy) {\n\t\t\theaders.set(\"Referrer-Policy\", this.referrerPolicy);\n\t\t}\n\t}\n\n\tmiddleware() {\n\t\treturn async (_c: any, next: () => Promise<any>) => {\n\t\t\t// Apply headers to c.res BEFORE next() so the handler inherits them.\n\t\t\tthis.apply(_c.res.headers as Headers);\n\t\t\treturn next();\n\t\t};\n\t}\n\n\tprivate buildHstsHeader(cfg: HstsConfig): string {\n\t\tlet v = `max-age=${cfg.maxAge}`;\n\t\tif (cfg.includeSubDomains) v += \"; includeSubDomains\";\n\t\tif (cfg.preload) v += \"; preload\";\n\t\treturn v;\n\t}\n\n\tprivate buildCspHeader(cfg: CspConfig): string {\n\t\tconst parts: string[] = [];\n\t\tfor (const [name, values] of Object.entries(cfg.directives)) {\n\t\t\tif (!values || values.length === 0) continue;\n\t\t\tparts.push(`${camelToKebab(name)} ${values.join(\" \")}`);\n\t\t}\n\t\tif (cfg.reportUri) parts.push(`report-uri ${cfg.reportUri}`);\n\t\treturn parts.join(\"; \");\n\t}\n}\n\n/** Convert `defaultSrc` → `default-src`. Already-kebab names pass through. */\nfunction camelToKebab(s: string): string {\n\treturn s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n}\n",
8
8
  "/**\n * CORS guard — handles preflight and sets Access-Control-* headers\n * on every response according to the configured policy.\n */\nimport type { CorsConfig } from \"../types.js\";\n\nexport class CorsGuard {\n\tconstructor(private config: CorsConfig) {}\n\n\t/**\n\t * Resolve the `Access-Control-Allow-Origin` value for a given\n\t * request origin. Returns `null` when the origin is not allowed.\n\t */\n\tresolveOrigin(requestOrigin: string): string | null {\n\t\tconst { origin = \"*\" } = this.config;\n\t\tif (origin === \"*\") return \"*\";\n\t\tif (typeof origin === \"string\")\n\t\t\treturn requestOrigin === origin ? origin : null;\n\t\tif (Array.isArray(origin))\n\t\t\treturn origin.includes(requestOrigin) ? requestOrigin : null;\n\t\tif (typeof origin === \"function\") {\n\t\t\tconst result = origin(requestOrigin);\n\t\t\tif (result === true) return requestOrigin;\n\t\t\tif (typeof result === \"string\") return result;\n\t\t\treturn null;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** Apply CORS response headers (non-preflight). */\n\tapplyHeaders(headers: Headers, requestOrigin: string): void {\n\t\tconst resolved = this.resolveOrigin(requestOrigin);\n\t\tif (!resolved) return;\n\t\theaders.set(\"Access-Control-Allow-Origin\", resolved);\n\t\tif (this.config.credentials) {\n\t\t\theaders.set(\"Access-Control-Allow-Credentials\", \"true\");\n\t\t}\n\t\tif (this.config.exposedHeaders?.length) {\n\t\t\theaders.set(\n\t\t\t\t\"Access-Control-Expose-Headers\",\n\t\t\t\tthis.config.exposedHeaders.join(\", \"),\n\t\t\t);\n\t\t}\n\t\tif (resolved !== \"*\") {\n\t\t\t// Vary so caches don't conflate responses for different origins.\n\t\t\theaders.append(\"Vary\", \"Origin\");\n\t\t}\n\t}\n\n\t/** Apply preflight response headers. Returns false if origin is not allowed. */\n\tapplyPreflightHeaders(headers: Headers, requestOrigin: string): boolean {\n\t\tconst resolved = this.resolveOrigin(requestOrigin);\n\t\tif (!resolved) return false;\n\t\theaders.set(\"Access-Control-Allow-Origin\", resolved);\n\t\tconst methods = (\n\t\t\tthis.config.methods ?? [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\", \"OPTIONS\"]\n\t\t).join(\", \");\n\t\theaders.set(\"Access-Control-Allow-Methods\", methods);\n\t\tif (this.config.allowedHeaders?.length) {\n\t\t\theaders.set(\n\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\tthis.config.allowedHeaders.join(\", \"),\n\t\t\t);\n\t\t}\n\t\tif (this.config.credentials) {\n\t\t\theaders.set(\"Access-Control-Allow-Credentials\", \"true\");\n\t\t}\n\t\tif (this.config.maxAge !== undefined) {\n\t\t\theaders.set(\"Access-Control-Max-Age\", String(this.config.maxAge));\n\t\t}\n\t\tif (resolved !== \"*\") {\n\t\t\theaders.append(\"Vary\", \"Origin\");\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Hono middleware — handles preflight (OPTIONS) and annotates responses. */\n\tmiddleware() {\n\t\treturn async (c: any, next: () => Promise<any>) => {\n\t\t\tconst requestOrigin = (c.req.header(\"origin\") as string) ?? \"\";\n\t\t\tconst method = (c.req.method as string).toUpperCase();\n\n\t\t\t// Preflight: OPTIONS + Access-Control-Request-Method\n\t\t\tif (method === \"OPTIONS\" && c.req.header(\"access-control-request-method\")) {\n\t\t\t\tconst headers = new Headers();\n\t\t\t\tconst allowed = this.applyPreflightHeaders(headers, requestOrigin);\n\t\t\t\treturn new Response(null, { status: allowed ? 204 : 403, headers });\n\t\t\t}\n\n\t\t\t// Regular request: apply CORS headers before the handler.\n\t\t\tthis.applyHeaders(c.res.headers as Headers, requestOrigin);\n\t\t\treturn next();\n\t\t};\n\t}\n}\n",
9
- "/**\n * `ShieldService` — orchestrator. Aggregates the per-feature guards\n * into a single Hono middleware that can be mounted globally.\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport type { CorsConfig, CsrfConfig, ShieldConfig } from \"./types.js\";\nimport { CorsGuard, CsrfGuard, HeadersGuard } from \"./guards/index.js\";\n\n@Injectable()\nexport class ShieldService {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:ShieldService\");\n\n\tcors?: CorsGuard;\n\tcsrf?: CsrfGuard;\n\theaders: HeadersGuard;\n\n\tconstructor(@Inject(\"SHIELD_CONFIG\") config: ShieldConfig = {}) {\n\t\tif (config.cors) {\n\t\t\tthis.cors = new CorsGuard(config.cors as CorsConfig);\n\t\t}\n\t\tif (config.csrf) {\n\t\t\tconst secret =\n\t\t\t\tconfig.secret ??\n\t\t\t\tprocess.env[\"NEXUS_SHIELD_SECRET\"] ??\n\t\t\t\t\"change-me-in-production-please\";\n\t\t\tthis.csrf = new CsrfGuard(config.csrf as CsrfConfig, secret);\n\t\t}\n\t\tthis.headers = new HeadersGuard(\n\t\t\tconfig.hsts ?? false,\n\t\t\tconfig.csp ?? false,\n\t\t\tconfig.xFrameOptions ?? \"SAMEORIGIN\",\n\t\t\tconfig.xContentTypeOptions ?? true,\n\t\t\tconfig.referrerPolicy,\n\t\t);\n\t}\n\n\t/**\n\t * Returns a Hono middleware that applies all configured guards.\n\t *\n\t * Order:\n\t * 1. CSRF check on mutating requests (rejects with 403 + security headers)\n\t * 2. Security headers applied to the final response\n\t */\n\tmiddleware() {\n\t\treturn async (c: any, next: () => Promise<any>) => {\n\t\t\tconst requestOrigin = (c.req.header(\"origin\") as string) ?? \"\";\n\t\t\tconst method = (c.req.method as string).toUpperCase();\n\n\t\t\t// 0. CORS preflight — short-circuit before CSRF so OPTIONS doesn't 403.\n\t\t\tif (this.cors && method === \"OPTIONS\" && c.req.header(\"access-control-request-method\")) {\n\t\t\t\tconst headers = new Headers();\n\t\t\t\tconst allowed = this.cors.applyPreflightHeaders(headers, requestOrigin);\n\t\t\t\treturn new Response(null, { status: allowed ? 204 : 403, headers });\n\t\t\t}\n\n\t\t\t// 0b. Apply CORS headers to regular requests.\n\t\t\tif (this.cors) {\n\t\t\t\tthis.cors.applyHeaders(c.res.headers as Headers, requestOrigin);\n\t\t\t}\n\n\t\t\t// 1. CSRF check — must run before `next()` so we can short-circuit.\n\t\t\tif (this.csrf) {\n\t\t\t\tconst ignoreMethods = (this.csrf as any).config.ignoreMethods as string[];\n\t\t\t\tif (ignoreMethods.map((m) => m.toUpperCase()).includes(method)) {\n\t\t\t\t\t// Safe method: ensure a CSRF cookie is present.\n\t\t\t\t\tconst cookieHeader = c.req.header(\"cookie\") ?? \"\";\n\t\t\t\t\tconst cookieName = (this.csrf as any).config.cookieName as string;\n\t\t\t\t\tif (!this.extractCookie(cookieHeader, cookieName)) {\n\t\t\t\t\t\t(this.csrf as any).issue(c.res.headers);\n\t\t\t\t\t}\n\t\t\t\t} else if (!(this.csrf as any).verify(c.req.raw)) {\n\t\t\t\t\t// 403 — apply security headers and return.\n\t\t\t\t\tconst resp = c.text(\"Invalid CSRF token\", 403);\n\t\t\t\t\tthis.headers.apply(resp.headers as Headers);\n\t\t\t\t\treturn resp;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 2. Apply security headers to c.res BEFORE the handler runs.\n\t\t\t// Hono's c.text()/c.json() etc. create a new Response but\n\t\t\t// inherit existing headers from c.res.headers.\n\t\t\tthis.headers.apply(c.res.headers as Headers);\n\n\t\t\t// 3. Continue to next middleware/handler.\n\t\t\treturn next();\n\t\t};\n\t}\n\n\t/** Generate a CSRF token and set the cookie. Useful for forms. */\n\tissueToken(headers: Headers) {\n\t\tif (!this.csrf) throw new Error(\"CSRF guard is not enabled\");\n\t\treturn this.csrf.issue(headers);\n\t}\n\n\tprivate extractCookie(cookieHeader: string, name: string): string | null {\n\t\tfor (const part of cookieHeader.split(\";\")) {\n\t\t\tconst [k, ...rest] = part.trim().split(\"=\");\n\t\t\tif (k === name) return rest.join(\"=\");\n\t\t}\n\t\treturn null;\n\t}\n}\n",
10
- "/**\n * `ShieldModule` — drop-in security middleware suite.\n *\n * @Module({\n * imports: [\n * ShieldModule.forRoot({\n * csrf: { enabled: true },\n * hsts: { maxAge: 31_536_000, includeSubDomains: true },\n * csp: { directives: { defaultSrc: [\"'self'\"] } },\n * xFrameOptions: 'SAMEORIGIN',\n * xContentTypeOptions: true,\n * referrerPolicy: 'strict-origin-when-cross-origin',\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { ShieldService } from \"./shield.service.js\";\nimport type { ShieldConfig } from \"./types.js\";\nimport { safeGetMeta, safeDefineMeta, safeHasMeta } from \"@nexusts/core/di/safe-reflect\";\n\n@Module({\n\tproviders: [\n\t\tShieldService,\n\t\t{ provide: ShieldService.TOKEN, useExisting: ShieldService },\n\t],\n\texports: [ShieldService, ShieldService.TOKEN],\n})\nexport class ShieldModule {\n\tstatic forRoot(config: ShieldConfig = {}) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tShieldService,\n\t\t\t\t{ provide: ShieldService.TOKEN, useExisting: ShieldService },\n\t\t\t\t{ provide: \"SHIELD_CONFIG\", useValue: config },\n\t\t\t],\n\t\t\texports: [ShieldService, ShieldService.TOKEN],\n\t\t})\n\t\tclass ConfiguredShieldModule {}\n\t\tObject.defineProperty(ConfiguredShieldModule, \"name\", {\n\t\t\tvalue: \"ConfiguredShieldModule\",\n\t\t});\n\t\treturn ConfiguredShieldModule;\n\t}\n}\n"
9
+ "/**\n * `ShieldService` — orchestrator. Aggregates the per-feature guards\n * into a single Hono middleware that can be mounted globally.\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport type { CorsConfig, CsrfConfig, ShieldConfig } from \"./types.js\";\nimport { CorsGuard, CsrfGuard, HeadersGuard } from \"./guards/index.js\";\n\n@Injectable()\nexport class ShieldService {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:ShieldService\");\n\n\t/** Shield config — injected by DI container. */\n\t@Inject(\"SHIELD_CONFIG\") declare private _config: ShieldConfig;\n\n\tcors?: CorsGuard;\n\tcsrf?: CsrfGuard;\n\theaders: HeadersGuard;\n\tprivate _initialized = false;\n\n\tprivate init(): void {\n\t\tif (this._initialized) return;\n\t\tthis._initialized = true;\n\t\tconst config = this._config ?? {};\n\t\tif (config.cors) {\n\t\t\tthis.cors = new CorsGuard(config.cors as CorsConfig);\n\t\t}\n\t\tif (config.csrf) {\n\t\t\tconst secret =\n\t\t\t\tconfig.secret ??\n\t\t\t\tprocess.env[\"NEXUS_SHIELD_SECRET\"] ??\n\t\t\t\t\"change-me-in-production-please\";\n\t\t\tthis.csrf = new CsrfGuard(config.csrf as CsrfConfig, secret);\n\t\t}\n\t\tthis.headers = new HeadersGuard(\n\t\t\tconfig.hsts ?? false,\n\t\t\tconfig.csp ?? false,\n\t\t\tconfig.xFrameOptions ?? \"SAMEORIGIN\",\n\t\t\tconfig.xContentTypeOptions ?? true,\n\t\t\tconfig.referrerPolicy,\n\t\t);\n\t}\n\n\tconstructor() {\n\t\t// DI sets @Inject fields before first use.\n\t}\n\n\t/**\n\t * Returns a Hono middleware that applies all configured guards.\n\t *\n\t * Order:\n\t * 1. CSRF check on mutating requests (rejects with 403 + security headers)\n\t * 2. Security headers applied to the final response\n\t */\n\tmiddleware() {\n\t\treturn async (c: any, next: () => Promise<any>) => {\n\t\t\tthis.init();\n\t\t\tconst requestOrigin = (c.req.header(\"origin\") as string) ?? \"\";\n\t\t\tconst method = (c.req.method as string).toUpperCase();\n\n\t\t\t// 0. CORS preflight — short-circuit before CSRF so OPTIONS doesn't 403.\n\t\t\tif (this.cors && method === \"OPTIONS\" && c.req.header(\"access-control-request-method\")) {\n\t\t\t\tconst headers = new Headers();\n\t\t\t\tconst allowed = this.cors.applyPreflightHeaders(headers, requestOrigin);\n\t\t\t\treturn new Response(null, { status: allowed ? 204 : 403, headers });\n\t\t\t}\n\n\t\t\t// 0b. Apply CORS headers to regular requests.\n\t\t\tif (this.cors) {\n\t\t\t\tthis.cors.applyHeaders(c.res.headers as Headers, requestOrigin);\n\t\t\t}\n\n\t\t\t// 1. CSRF check — must run before `next()` so we can short-circuit.\n\t\t\tif (this.csrf) {\n\t\t\t\tconst ignoreMethods = (this.csrf as any).config.ignoreMethods as string[];\n\t\t\t\tif (ignoreMethods.map((m) => m.toUpperCase()).includes(method)) {\n\t\t\t\t\t// Safe method: ensure a CSRF cookie is present.\n\t\t\t\t\tconst cookieHeader = c.req.header(\"cookie\") ?? \"\";\n\t\t\t\t\tconst cookieName = (this.csrf as any).config.cookieName as string;\n\t\t\t\t\tif (!this.extractCookie(cookieHeader, cookieName)) {\n\t\t\t\t\t\t(this.csrf as any).issue(c.res.headers);\n\t\t\t\t\t}\n\t\t\t\t} else if (!(this.csrf as any).verify(c.req.raw)) {\n\t\t\t\t\t// 403 — apply security headers and return.\n\t\t\t\t\tconst resp = c.text(\"Invalid CSRF token\", 403);\n\t\t\t\t\tthis.headers.apply(resp.headers as Headers);\n\t\t\t\t\treturn resp;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 2. Apply security headers to c.res BEFORE the handler runs.\n\t\t\t// Hono's c.text()/c.json() etc. create a new Response but\n\t\t\t// inherit existing headers from c.res.headers.\n\t\t\tthis.headers.apply(c.res.headers as Headers);\n\n\t\t\t// 3. Continue to next middleware/handler.\n\t\t\treturn next();\n\t\t};\n\t}\n\n\t/** Generate a CSRF token and set the cookie. */\n\tissueToken(headers: Headers) {\n\t\tthis.init();\n\t\tif (!this.csrf) throw new Error(\"CSRF guard is not enabled\");\n\t\treturn this.csrf.issue(headers);\n\t}\n\n\tprivate extractCookie(cookieHeader: string, name: string): string | null {\n\t\tfor (const part of cookieHeader.split(\";\")) {\n\t\t\tconst [k, ...rest] = part.trim().split(\"=\");\n\t\t\tif (k === name) return rest.join(\"=\");\n\t\t}\n\t\treturn null;\n\t}\n}\n",
10
+ "/**\n * `ShieldModule` — drop-in security middleware suite.\n *\n * @Module({\n * imports: [\n * ShieldModule.forRoot({\n * csrf: { enabled: true },\n * hsts: { maxAge: 31_536_000, includeSubDomains: true },\n * csp: { directives: { defaultSrc: [\"'self'\"] } },\n * xFrameOptions: 'SAMEORIGIN',\n * xContentTypeOptions: true,\n * referrerPolicy: 'strict-origin-when-cross-origin',\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { ShieldService } from \"./shield.service.js\";\nimport type { ShieldConfig } from \"./types.js\";\n\n@Module({\n\tproviders: [\n\t\tShieldService,\n\t\t{ provide: ShieldService.TOKEN, useExisting: ShieldService },\n\t],\n\texports: [ShieldService, ShieldService.TOKEN],\n})\nexport class ShieldModule {\n\tstatic forRoot(config: ShieldConfig = {}) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tShieldService,\n\t\t\t\t{ provide: ShieldService.TOKEN, useExisting: ShieldService },\n\t\t\t\t{ provide: \"SHIELD_CONFIG\", useValue: config },\n\t\t\t],\n\t\t\texports: [ShieldService, ShieldService.TOKEN],\n\t\t})\n\t\tclass ConfiguredShieldModule {}\n\t\tObject.defineProperty(ConfiguredShieldModule, \"name\", {\n\t\t\tvalue: \"ConfiguredShieldModule\",\n\t\t});\n\t\treturn ConfiguredShieldModule;\n\t}\n}\n"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "1C7FE289B85891B164756E2164756E21",
12
+ "mappings": "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",
13
+ "debugId": "8EB126F105C98A1164756E2164756E21",
14
14
  "names": []
15
15
  }
@@ -1,12 +1,15 @@
1
- import type { ShieldConfig } from "./types.js";
2
1
  import { CorsGuard, CsrfGuard, HeadersGuard } from "./guards/index.js";
3
2
  export declare class ShieldService {
4
3
  /** DI token. */
5
4
  static readonly TOKEN: unique symbol;
5
+ /** Shield config — injected by DI container. */
6
+ private _config;
6
7
  cors?: CorsGuard;
7
8
  csrf?: CsrfGuard;
8
9
  headers: HeadersGuard;
9
- constructor(config?: ShieldConfig);
10
+ private _initialized;
11
+ private init;
12
+ constructor();
10
13
  /**
11
14
  * Returns a Hono middleware that applies all configured guards.
12
15
  *
@@ -15,7 +18,7 @@ export declare class ShieldService {
15
18
  * 2. Security headers applied to the final response
16
19
  */
17
20
  middleware(): (c: any, next: () => Promise<any>) => Promise<any>;
18
- /** Generate a CSRF token and set the cookie. Useful for forms. */
21
+ /** Generate a CSRF token and set the cookie. */
19
22
  issueToken(headers: Headers): import("./types.js").CsrfToken;
20
23
  private extractCookie;
21
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexusts/shield",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "CSRF / HSTS / CSP security middleware",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
- "@nexusts/core": "^0.9.5"
29
+ "@nexusts/core": "^0.9.7"
30
30
  },
31
31
  "repository": {
32
32
  "type": "git",