@nauth-toolkit/nestjs 0.1.18 → 0.1.22

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.
Files changed (39) hide show
  1. package/dist/auth.module.d.ts.map +1 -1
  2. package/dist/auth.module.js +29 -14
  3. package/dist/auth.module.js.map +1 -1
  4. package/dist/factories/storage-adapter.factory.d.ts.map +1 -1
  5. package/dist/factories/storage-adapter.factory.js +204 -63
  6. package/dist/factories/storage-adapter.factory.js.map +1 -1
  7. package/dist/guards/auth.guard.d.ts +3 -4
  8. package/dist/guards/auth.guard.d.ts.map +1 -1
  9. package/dist/guards/auth.guard.js +49 -60
  10. package/dist/guards/auth.guard.js.map +1 -1
  11. package/dist/guards/nauth-context.guard.d.ts +44 -0
  12. package/dist/guards/nauth-context.guard.d.ts.map +1 -0
  13. package/dist/guards/nauth-context.guard.js +140 -0
  14. package/dist/guards/nauth-context.guard.js.map +1 -0
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/interceptors/cookie-token.interceptor.d.ts +3 -7
  20. package/dist/interceptors/cookie-token.interceptor.d.ts.map +1 -1
  21. package/dist/interceptors/cookie-token.interceptor.js +25 -139
  22. package/dist/interceptors/cookie-token.interceptor.js.map +1 -1
  23. package/dist/interceptors/index.d.ts +1 -1
  24. package/dist/interceptors/index.d.ts.map +1 -1
  25. package/dist/interceptors/index.js +1 -1
  26. package/dist/interceptors/index.js.map +1 -1
  27. package/dist/interceptors/nauth-context.interceptor.d.ts +27 -0
  28. package/dist/interceptors/nauth-context.interceptor.d.ts.map +1 -0
  29. package/dist/interceptors/nauth-context.interceptor.js +64 -0
  30. package/dist/interceptors/nauth-context.interceptor.js.map +1 -0
  31. package/dist/services/token-delivery-http.service.d.ts +68 -0
  32. package/dist/services/token-delivery-http.service.d.ts.map +1 -0
  33. package/dist/services/token-delivery-http.service.js +194 -0
  34. package/dist/services/token-delivery-http.service.js.map +1 -0
  35. package/package.json +2 -2
  36. package/dist/interceptors/client-info.interceptor.d.ts +0 -50
  37. package/dist/interceptors/client-info.interceptor.d.ts.map +0 -1
  38. package/dist/interceptors/client-info.interceptor.js +0 -196
  39. package/dist/interceptors/client-info.interceptor.js.map +0 -1
@@ -8,18 +8,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
- var __param = (this && this.__param) || function (paramIndex, decorator) {
12
- return function (target, key) { decorator(target, key, paramIndex); }
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.CookieTokenInterceptor = void 0;
16
13
  const common_1 = require("@nestjs/common");
17
14
  const core_1 = require("@nestjs/core");
18
15
  const operators_1 = require("rxjs/operators");
19
- const core_2 = require("@nauth-toolkit/core");
20
- const internal_1 = require("@nauth-toolkit/core/internal");
21
16
  const token_delivery_decorator_1 = require("../decorators/token-delivery.decorator");
22
- const csrf_service_1 = require("../services/csrf.service");
17
+ const token_delivery_http_service_1 = require("../services/token-delivery-http.service");
23
18
  /**
24
19
  * Cookie Token Interceptor
25
20
  *
@@ -37,56 +32,33 @@ const csrf_service_1 = require("../services/csrf.service");
37
32
  * It does nothing in other contexts (e.g., WebSocket, GraphQL).
38
33
  */
39
34
  let CookieTokenInterceptor = class CookieTokenInterceptor {
40
- config;
41
- jwtService;
35
+ tokenDeliveryHttp;
42
36
  reflector;
43
- csrfService;
44
- constructor(config, jwtService, reflector, csrfService) {
45
- this.config = config;
46
- this.jwtService = jwtService;
37
+ constructor(tokenDeliveryHttp, reflector) {
38
+ this.tokenDeliveryHttp = tokenDeliveryHttp;
47
39
  this.reflector = reflector;
48
- this.csrfService = csrfService;
49
40
  }
50
41
  intercept(context, next) {
51
42
  // Only operate in HTTP context
52
43
  if (context.getType() !== 'http') {
53
44
  return next.handle();
54
45
  }
55
- const deliveryConfig = this.config.tokenDelivery;
56
46
  const http = context.switchToHttp();
57
47
  const req = http.getRequest();
58
48
  const res = http.getResponse();
59
49
  // Determine effective delivery for this request
60
50
  const routeMode = this.reflector.get(token_delivery_decorator_1.TOKEN_DELIVERY_KEY, context.getHandler());
61
- const method = deliveryConfig?.method || 'json';
62
- // Validate route-level delivery mode against global configuration
63
- if (routeMode === 'cookies') {
64
- // Route requests cookies - config must allow cookies (cookies or hybrid)
65
- if (method === 'json') {
66
- throw new core_2.NAuthException(core_2.AuthErrorCode.COOKIES_NOT_ALLOWED, "Route-level cookie delivery requested, but tokenDelivery.method is 'json' (cookies disabled)");
67
- }
68
- // method === 'cookies' or 'hybrid' - both allow cookies, so OK
69
- }
70
- else if (routeMode === 'json') {
71
- // Route requests JSON - config must allow JSON (json or hybrid)
72
- if (method === 'cookies') {
73
- throw new core_2.NAuthException(core_2.AuthErrorCode.BEARER_NOT_ALLOWED, "Route-level JSON delivery requested, but tokenDelivery.method is 'cookies' (JSON/Bearer tokens disabled)");
74
- }
75
- // method === 'json' or 'hybrid' - both allow JSON, so OK
76
- }
77
- let effective = 'json';
78
- if (routeMode) {
79
- effective = routeMode;
80
- }
81
- else if (method === 'hybrid') {
82
- effective = (0, core_2.resolveDeliveryForRequest)(req, deliveryConfig?.hybridPolicy);
83
- }
84
- else if (method === 'cookies') {
85
- effective = 'cookies';
86
- }
87
- else {
88
- effective = 'json';
89
- }
51
+ const effective = this.tokenDeliveryHttp.resolveEffectiveDelivery(req, routeMode);
52
+ // ============================================================================
53
+ // Expose route-level delivery decision to downstream handlers
54
+ // ============================================================================
55
+ // Social redirect endpoints (and other framework-neutral handlers) may need to
56
+ // know the route-level delivery override in hybrid deployments. Provider callbacks
57
+ // often omit `Origin`, so the only deterministic signal is the route itself.
58
+ //
59
+ // We store it on the request object using a non-enumerable-ish private-ish key.
60
+ // Frameworks tolerate extra properties on the request object (Express/Fastify).
61
+ req.__nauthRouteDelivery = routeMode;
90
62
  return next.handle().pipe((0, operators_1.map)((data) => {
91
63
  // ============================================================================
92
64
  // Safety: Only process object responses
@@ -105,102 +77,18 @@ let CookieTokenInterceptor = class CookieTokenInterceptor {
105
77
  if (!hasAccessToken && !hasDeviceTokenOnly) {
106
78
  return responseData;
107
79
  }
108
- // Smart default cookie options
109
- const opt = deliveryConfig?.cookieOptions;
110
- // Cookie domain handling:
111
- // - undefined: Cookie set for exact host:port (e.g., localhost:3000)
112
- // For cross-port requests (localhost:4200 → localhost:3000), cookies work IF:
113
- // - Frontend sends withCredentials: true
114
- // - Backend CORS allows credentials
115
- // - SameSite allows cross-site requests (e.g., 'lax' or 'none')
116
- //
117
- // - 'localhost' or '.localhost': Some browsers accept this, others reject it
118
- // Modern browsers generally allow 'localhost' without domain attribute
119
- //
120
- // - '.example.com': For production cross-subdomain sharing
121
- // Allows cookies set by api.example.com to be sent from app.example.com
122
- const cookieOptions = {
123
- httpOnly: true,
124
- secure: opt?.secure !== false, // default true
125
- sameSite: (opt?.sameSite || 'strict'),
126
- path: opt?.path || '/',
127
- };
128
- // Include domain if provided (browsers handle localhost differently - some accept, some reject)
129
- // For cross-port testing (like Cognito), omitting domain works with sameSite: 'lax' or 'none'
130
- if (opt?.domain) {
131
- cookieOptions.domain = opt.domain;
132
- }
133
- // Derive expiry strictly from JWT claims (no fallback)
134
- // We decode here (signature already trusted as tokens are freshly issued);
135
- // full validation and blacklist checks happen in the AuthGuard on subsequent requests.
136
- let accessTokenMaxAgeMs = 0;
137
- if (hasAccessToken && responseData.accessToken) {
138
- const accessPayload = this.jwtService.decodeToken(responseData.accessToken);
139
- if (!accessPayload?.exp) {
140
- throw new core_2.NAuthException(core_2.AuthErrorCode.TOKEN_INVALID, 'Access token missing or invalid exp claim; refusing to set cookies');
141
- }
142
- const accessExpSeconds = accessPayload.exp;
143
- accessTokenMaxAgeMs = Math.max(0, accessExpSeconds * 1000 - Date.now());
144
- if (accessTokenMaxAgeMs <= 0) {
145
- throw new core_2.NAuthException(core_2.AuthErrorCode.TOKEN_INVALID, 'Access token already expired; refusing to set cookies');
146
- }
147
- }
148
- const setCookie = (name, value, options) => {
149
- if (res && typeof res.cookie === 'function') {
150
- res.cookie(name, value, options);
151
- }
152
- else if (res && typeof res.setCookie === 'function') {
153
- res.setCookie(name, value, options);
154
- }
155
- };
156
80
  // Set cookies only when effective is 'cookies'
157
81
  if (effective === 'cookies' && hasAccessToken && responseData.accessToken) {
158
- const accessTokenCookieName = (0, core_2.getAccessTokenCookieName)(this.config);
159
- setCookie(accessTokenCookieName, responseData.accessToken, {
160
- ...cookieOptions,
161
- maxAge: accessTokenMaxAgeMs,
82
+ this.tokenDeliveryHttp.setAuthCookies(res, {
83
+ accessToken: responseData.accessToken,
84
+ refreshToken: typeof responseData.refreshToken === 'string' ? responseData.refreshToken : undefined,
85
+ deviceToken: typeof responseData.deviceToken === 'string' ? responseData.deviceToken : undefined,
162
86
  });
87
+ this.tokenDeliveryHttp.setCsrfCookie(res, responseData.accessToken);
163
88
  }
164
- if (typeof responseData.refreshToken === 'string' && responseData.refreshToken && effective === 'cookies') {
165
- const refreshPayload = this.jwtService.decodeToken(responseData.refreshToken);
166
- if (!refreshPayload?.exp) {
167
- throw new core_2.NAuthException(core_2.AuthErrorCode.TOKEN_INVALID, 'Refresh token missing or invalid exp claim; refusing to set cookies');
168
- }
169
- const refreshExpSeconds = refreshPayload.exp;
170
- const refreshTokenMaxAgeMs = Math.max(0, refreshExpSeconds * 1000 - Date.now());
171
- if (refreshTokenMaxAgeMs <= 0) {
172
- throw new core_2.NAuthException(core_2.AuthErrorCode.TOKEN_INVALID, 'Refresh token already expired; refusing to set cookies');
173
- }
174
- const refreshTokenCookieName = (0, core_2.getRefreshTokenCookieName)(this.config);
175
- setCookie(refreshTokenCookieName, responseData.refreshToken, {
176
- ...cookieOptions,
177
- maxAge: refreshTokenMaxAgeMs,
178
- });
179
- }
180
- // Set device token cookie for trusted device feature (web)
181
- // Only set cookie when deviceToken is present and effective is cookies
182
- // (hybrid mode may resolve to cookies for web origins)
183
- if (typeof responseData.deviceToken === 'string' && responseData.deviceToken && effective === 'cookies') {
184
- const rememberDeviceDays = this.config.mfa?.rememberDeviceDays || 30;
185
- const deviceTokenMaxAgeMs = rememberDeviceDays * 24 * 60 * 60 * 1000; // Convert days to milliseconds
186
- const deviceTokenCookieName = (0, core_2.getDeviceTokenCookieName)(this.config);
187
- setCookie(deviceTokenCookieName, responseData.deviceToken, {
188
- ...cookieOptions,
189
- maxAge: deviceTokenMaxAgeMs,
190
- });
191
- }
192
- // Set CSRF token cookie when using cookie-based token delivery
193
- // CSRF token is required for state-changing requests to prevent CSRF attacks
194
- if (effective === 'cookies' && this.csrfService && this.config.security?.csrf) {
195
- const csrfToken = this.csrfService.generateToken();
196
- const csrfCookieName = this.csrfService.getCookieName();
197
- const csrfCookieOptions = this.csrfService.getCookieOptions();
198
- // Use same max age as access token for CSRF cookie
199
- // This ensures CSRF token expires when access token expires
200
- setCookie(csrfCookieName, csrfToken, {
201
- ...csrfCookieOptions,
202
- maxAge: accessTokenMaxAgeMs > 0 ? accessTokenMaxAgeMs : undefined,
203
- });
89
+ else if (effective === 'cookies' && hasDeviceTokenOnly && responseData.deviceToken) {
90
+ // trust-device endpoint: cookie only
91
+ this.tokenDeliveryHttp.setDeviceTokenCookie(res, responseData.deviceToken);
204
92
  }
205
93
  // Strip tokens, deviceToken, and expiration fields only when effective is cookies (strict web path)
206
94
  // Expiration is managed by cookie maxAge, so these fields are not needed
@@ -220,9 +108,7 @@ let CookieTokenInterceptor = class CookieTokenInterceptor {
220
108
  exports.CookieTokenInterceptor = CookieTokenInterceptor;
221
109
  exports.CookieTokenInterceptor = CookieTokenInterceptor = __decorate([
222
110
  (0, common_1.Injectable)(),
223
- __param(0, (0, common_1.Inject)('NAUTH_CONFIG')),
224
- __metadata("design:paramtypes", [Object, internal_1.JwtService,
225
- core_1.Reflector,
226
- csrf_service_1.CsrfService])
111
+ __metadata("design:paramtypes", [token_delivery_http_service_1.TokenDeliveryHttpService,
112
+ core_1.Reflector])
227
113
  ], CookieTokenInterceptor);
228
114
  //# sourceMappingURL=cookie-token.interceptor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookie-token.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/cookie-token.interceptor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cookie-token.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/cookie-token.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4F;AAC5F,uCAAyC;AAEzC,8CAAqC;AAErC,qFAA2F;AAC3F,yFAAmF;AAEnF;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAEd;IACA;IAFnB,YACmB,iBAA2C,EAC3C,SAAoB;QADpB,sBAAiB,GAAjB,iBAAiB,CAA0B;QAC3C,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,+BAA+B;QAC/B,IAAI,OAAO,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAGpC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAkB,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAmB,CAAC;QAEhD,gDAAgD;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAgB,6CAAkB,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAElF,+EAA+E;QAC/E,8DAA8D;QAC9D,+EAA+E;QAC/E,+EAA+E;QAC/E,mFAAmF;QACnF,6EAA6E;QAC7E,EAAE;QACF,gFAAgF;QAChF,gFAAgF;QAC/E,GAA+B,CAAC,oBAAoB,GAAG,SAAS,CAAC;QAElE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,IAAa,EAAE,EAAE;YACpB,+EAA+E;YAC/E,wCAAwC;YACxC,+EAA+E;YAC/E,8EAA8E;YAC9E,2EAA2E;YAC3E,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC;YACd,CAAC;YAGD,MAAM,YAAY,GAAG,IAAwB,CAAC;YAC9C,MAAM,MAAM,GAAG,IAA+B,CAAC;YAE/C,8DAA8D;YAC9D,MAAM,kBAAkB,GACtB,aAAa,IAAI,MAAM,IAAI,CAAC,CAAC,aAAa,IAAI,MAAM,CAAC,IAAI,OAAO,YAAY,CAAC,WAAW,KAAK,QAAQ,CAAC;YACxG,MAAM,cAAc,GAClB,aAAa,IAAI,MAAM,IAAI,OAAO,YAAY,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC;YAExG,4DAA4D;YAC5D,IAAI,CAAC,cAAc,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC3C,OAAO,YAAY,CAAC;YACtB,CAAC;YAED,+CAA+C;YAC/C,IAAI,SAAS,KAAK,SAAS,IAAI,cAAc,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;gBAC1E,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EAAE;oBACzC,WAAW,EAAE,YAAY,CAAC,WAAW;oBACrC,YAAY,EAAE,OAAO,YAAY,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;oBACnG,WAAW,EAAE,OAAO,YAAY,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;iBACjG,CAAC,CAAC;gBACH,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;YACtE,CAAC;iBAAM,IAAI,SAAS,KAAK,SAAS,IAAI,kBAAkB,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;gBACrF,qCAAqC;gBACrC,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;YAC7E,CAAC;YAED,oGAAoG;YACpG,yEAAyE;YACzE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,IAAI,kBAAkB,EAAE,CAAC;oBACvB,6EAA6E;oBAC7E,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,MAAM,QAAQ,GAAG,YAA+B,CAAC;gBACjD,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAAE,GACzG,QAAQ,CAAC;gBACX,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAxFY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAG2B,sDAAwB;QAChC,gBAAS;GAH5B,sBAAsB,CAwFlC"}
@@ -1,3 +1,3 @@
1
- export * from './client-info.interceptor';
1
+ export * from './nauth-context.interceptor';
2
2
  export * from './cookie-token.interceptor';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interceptors/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interceptors/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC"}
@@ -14,6 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./client-info.interceptor"), exports);
17
+ __exportStar(require("./nauth-context.interceptor"), exports);
18
18
  __exportStar(require("./cookie-token.interceptor"), exports);
19
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interceptors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C;AAC1C,6DAA2C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interceptors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,6DAA2C"}
@@ -0,0 +1,27 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { Observable } from 'rxjs';
3
+ /**
4
+ * NAuth Context Interceptor
5
+ *
6
+ * Re-enters the AsyncLocalStorage context that was initialized by NAuthContextGuard.
7
+ * This ensures controllers and services run inside the same request-scoped context.
8
+ *
9
+ * **Why This is Needed:**
10
+ * - Guards and interceptors run in separate execution contexts
11
+ * - AsyncLocalStorage context from the guard is not automatically available to controllers
12
+ * - This interceptor restores the context using `ContextStorage.enterStore()`
13
+ *
14
+ * **Pattern:**
15
+ * - Mirrors the core FastifyAdapter pattern for context restoration
16
+ * - Works with both Express and Fastify adapters
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Registered globally in AuthModule as APP_INTERCEPTOR
21
+ * // No manual usage required - runs automatically for all HTTP requests
22
+ * ```
23
+ */
24
+ export declare class NAuthContextInterceptor implements NestInterceptor {
25
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
26
+ }
27
+ //# sourceMappingURL=nauth-context.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nauth-context.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/nauth-context.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIlC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,uBAAwB,YAAW,eAAe;IAC7D,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;CA2B7E"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.NAuthContextInterceptor = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const rxjs_1 = require("rxjs");
12
+ const core_1 = require("@nauth-toolkit/core");
13
+ const nauth_context_guard_1 = require("../guards/nauth-context.guard");
14
+ /**
15
+ * NAuth Context Interceptor
16
+ *
17
+ * Re-enters the AsyncLocalStorage context that was initialized by NAuthContextGuard.
18
+ * This ensures controllers and services run inside the same request-scoped context.
19
+ *
20
+ * **Why This is Needed:**
21
+ * - Guards and interceptors run in separate execution contexts
22
+ * - AsyncLocalStorage context from the guard is not automatically available to controllers
23
+ * - This interceptor restores the context using `ContextStorage.enterStore()`
24
+ *
25
+ * **Pattern:**
26
+ * - Mirrors the core FastifyAdapter pattern for context restoration
27
+ * - Works with both Express and Fastify adapters
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Registered globally in AuthModule as APP_INTERCEPTOR
32
+ * // No manual usage required - runs automatically for all HTTP requests
33
+ * ```
34
+ */
35
+ let NAuthContextInterceptor = class NAuthContextInterceptor {
36
+ intercept(context, next) {
37
+ // Only operate in HTTP context
38
+ if (context.getType() !== 'http') {
39
+ return next.handle();
40
+ }
41
+ const request = context.switchToHttp().getRequest();
42
+ // Get the context store that was created by NAuthContextGuard
43
+ const store = (0, nauth_context_guard_1.getNAuthContextStore)(request);
44
+ if (!store) {
45
+ // No context available - continue without context (shouldn't happen with proper setup)
46
+ return next.handle();
47
+ }
48
+ // Re-enter the context store so controllers/services have access to it
49
+ return new rxjs_1.Observable((subscriber) => {
50
+ core_1.ContextStorage.enterStore(store, () => {
51
+ next.handle().subscribe({
52
+ next: (value) => subscriber.next(value),
53
+ error: (err) => subscriber.error(err),
54
+ complete: () => subscriber.complete(),
55
+ });
56
+ });
57
+ });
58
+ }
59
+ };
60
+ exports.NAuthContextInterceptor = NAuthContextInterceptor;
61
+ exports.NAuthContextInterceptor = NAuthContextInterceptor = __decorate([
62
+ (0, common_1.Injectable)()
63
+ ], NAuthContextInterceptor);
64
+ //# sourceMappingURL=nauth-context.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nauth-context.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/nauth-context.interceptor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4F;AAC5F,+BAAkC;AAClC,8CAAqD;AACrD,uEAAqE;AAErE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAClC,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,+BAA+B;QAC/B,IAAI,OAAO,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAEpD,8DAA8D;QAC9D,MAAM,KAAK,GAAG,IAAA,0CAAoB,EAAC,OAAO,CAAC,CAAC;QAE5C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,uFAAuF;YACvF,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC;QAED,uEAAuE;QACvE,OAAO,IAAI,iBAAU,CAAC,CAAC,UAAU,EAAE,EAAE;YACnC,qBAAc,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE;gBACpC,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC;oBACtB,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;oBACvC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;oBACrC,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;iBACtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AA5BY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAU,GAAE;GACA,uBAAuB,CA4BnC"}
@@ -0,0 +1,68 @@
1
+ import { NAuthConfig } from '@nauth-toolkit/core';
2
+ import { JwtService } from '@nauth-toolkit/core/internal';
3
+ import { CsrfService } from './csrf.service';
4
+ import type { RouteDelivery } from '../decorators/token-delivery.decorator';
5
+ /**
6
+ * Token delivery helper for HTTP controllers/interceptors (NestJS)
7
+ *
8
+ * Centralizes logic for:
9
+ * - determining effective token delivery ('cookies' | 'json') in hybrid mode
10
+ * - setting httpOnly auth cookies (and device token cookie) consistently
11
+ * - setting CSRF cookie when using cookie-based delivery
12
+ *
13
+ * This keeps consumer applications lightweight by letting toolkit controllers
14
+ * (like social redirect/callback) reuse the same cookie semantics as interceptors.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const effective = service.resolveEffectiveDelivery(req, undefined);
19
+ * if (effective === 'cookies') {
20
+ * service.setAuthCookies(res, { accessToken, refreshToken });
21
+ * service.setCsrfCookie(res, accessToken);
22
+ * }
23
+ * ```
24
+ */
25
+ export declare class TokenDeliveryHttpService {
26
+ private readonly config;
27
+ private readonly jwtService;
28
+ private readonly csrfService?;
29
+ constructor(config: NAuthConfig, jwtService: JwtService, csrfService?: CsrfService | undefined);
30
+ /**
31
+ * Resolve the effective delivery mode for the current request.
32
+ *
33
+ * @param req - Framework request object (only `headers.origin` is used in hybrid mode)
34
+ * @param routeMode - Optional route-level override ('cookies' | 'json')
35
+ * @returns Effective delivery mode
36
+ * @throws {NAuthException} If route requests a mode not allowed by global config
37
+ */
38
+ resolveEffectiveDelivery(req: unknown, routeMode?: RouteDelivery): 'cookies' | 'json';
39
+ /**
40
+ * Set auth cookies on the response.
41
+ *
42
+ * @param res - HTTP response object (FastifyReply or Express response)
43
+ * @param tokens - Tokens to set
44
+ * @throws {NAuthException} If token exp claims are missing/invalid
45
+ */
46
+ setAuthCookies(res: unknown, tokens: {
47
+ accessToken: string;
48
+ refreshToken?: string;
49
+ deviceToken?: string;
50
+ }): void;
51
+ /**
52
+ * Set only the device token cookie (used by trust-device endpoint).
53
+ *
54
+ * @param res - HTTP response
55
+ * @param deviceToken - Device token to persist as cookie
56
+ */
57
+ setDeviceTokenCookie(res: unknown, deviceToken: string): void;
58
+ /**
59
+ * Set CSRF cookie for cookie-based delivery.
60
+ *
61
+ * @param res - HTTP response
62
+ * @param accessToken - Access token used to align CSRF cookie lifetime
63
+ */
64
+ setCsrfCookie(res: unknown, accessToken: string): void;
65
+ private buildCookieOptions;
66
+ private getSetCookieFn;
67
+ }
68
+ //# sourceMappingURL=token-delivery-http.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-delivery-http.service.d.ts","sourceRoot":"","sources":["../../src/services/token-delivery-http.service.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,EAMZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,wBAAwB;IAGjC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAFZ,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,UAAU,EACtB,WAAW,CAAC,EAAE,WAAW,YAAA;IAG5C;;;;;;;OAOG;IACH,wBAAwB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM;IA0BrF;;;;;;OAMG;IACH,cAAc,CACZ,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3E,IAAI;IAuCP;;;;;OAKG;IACH,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAe7D;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IA0BtD,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,cAAc;CAmBvB"}
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.TokenDeliveryHttpService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const core_1 = require("@nauth-toolkit/core");
18
+ const internal_1 = require("@nauth-toolkit/core/internal");
19
+ const csrf_service_1 = require("./csrf.service");
20
+ /**
21
+ * Token delivery helper for HTTP controllers/interceptors (NestJS)
22
+ *
23
+ * Centralizes logic for:
24
+ * - determining effective token delivery ('cookies' | 'json') in hybrid mode
25
+ * - setting httpOnly auth cookies (and device token cookie) consistently
26
+ * - setting CSRF cookie when using cookie-based delivery
27
+ *
28
+ * This keeps consumer applications lightweight by letting toolkit controllers
29
+ * (like social redirect/callback) reuse the same cookie semantics as interceptors.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const effective = service.resolveEffectiveDelivery(req, undefined);
34
+ * if (effective === 'cookies') {
35
+ * service.setAuthCookies(res, { accessToken, refreshToken });
36
+ * service.setCsrfCookie(res, accessToken);
37
+ * }
38
+ * ```
39
+ */
40
+ let TokenDeliveryHttpService = class TokenDeliveryHttpService {
41
+ config;
42
+ jwtService;
43
+ csrfService;
44
+ constructor(config, jwtService, csrfService) {
45
+ this.config = config;
46
+ this.jwtService = jwtService;
47
+ this.csrfService = csrfService;
48
+ }
49
+ /**
50
+ * Resolve the effective delivery mode for the current request.
51
+ *
52
+ * @param req - Framework request object (only `headers.origin` is used in hybrid mode)
53
+ * @param routeMode - Optional route-level override ('cookies' | 'json')
54
+ * @returns Effective delivery mode
55
+ * @throws {NAuthException} If route requests a mode not allowed by global config
56
+ */
57
+ resolveEffectiveDelivery(req, routeMode) {
58
+ const method = this.config.tokenDelivery?.method || 'json';
59
+ // Validate route override against global configuration
60
+ if (routeMode === 'cookies' && method === 'json') {
61
+ throw new core_1.NAuthException(core_1.AuthErrorCode.COOKIES_NOT_ALLOWED, "Route-level cookie delivery requested, but tokenDelivery.method is 'json' (cookies disabled)");
62
+ }
63
+ if (routeMode === 'json' && method === 'cookies') {
64
+ throw new core_1.NAuthException(core_1.AuthErrorCode.BEARER_NOT_ALLOWED, "Route-level JSON delivery requested, but tokenDelivery.method is 'cookies' (JSON/Bearer tokens disabled)");
65
+ }
66
+ if (routeMode) {
67
+ return routeMode;
68
+ }
69
+ if (method === 'hybrid') {
70
+ return (0, core_1.resolveDeliveryForRequest)(req, this.config.tokenDelivery?.hybridPolicy);
71
+ }
72
+ return method === 'cookies' ? 'cookies' : 'json';
73
+ }
74
+ /**
75
+ * Set auth cookies on the response.
76
+ *
77
+ * @param res - HTTP response object (FastifyReply or Express response)
78
+ * @param tokens - Tokens to set
79
+ * @throws {NAuthException} If token exp claims are missing/invalid
80
+ */
81
+ setAuthCookies(res, tokens) {
82
+ const deliveryConfig = this.config.tokenDelivery;
83
+ const opt = deliveryConfig?.cookieOptions;
84
+ const cookieOptions = this.buildCookieOptions();
85
+ const setCookie = this.getSetCookieFn(res);
86
+ // Derive expiry from JWT exp claims (strict)
87
+ const accessPayload = this.jwtService.decodeToken(tokens.accessToken);
88
+ if (!accessPayload?.exp) {
89
+ throw new core_1.NAuthException(core_1.AuthErrorCode.TOKEN_INVALID, 'Access token missing exp claim; refusing to set cookies');
90
+ }
91
+ const accessMaxAgeMs = Math.max(0, accessPayload.exp * 1000 - Date.now());
92
+ if (accessMaxAgeMs <= 0) {
93
+ throw new core_1.NAuthException(core_1.AuthErrorCode.TOKEN_INVALID, 'Access token already expired; refusing to set cookies');
94
+ }
95
+ const accessTokenCookieName = (0, core_1.getAccessTokenCookieName)(this.config);
96
+ setCookie(accessTokenCookieName, tokens.accessToken, { ...cookieOptions, maxAge: accessMaxAgeMs });
97
+ if (typeof tokens.refreshToken === 'string' && tokens.refreshToken) {
98
+ const refreshPayload = this.jwtService.decodeToken(tokens.refreshToken);
99
+ if (!refreshPayload?.exp) {
100
+ throw new core_1.NAuthException(core_1.AuthErrorCode.TOKEN_INVALID, 'Refresh token missing exp claim; refusing to set cookies');
101
+ }
102
+ const refreshMaxAgeMs = Math.max(0, refreshPayload.exp * 1000 - Date.now());
103
+ if (refreshMaxAgeMs <= 0) {
104
+ throw new core_1.NAuthException(core_1.AuthErrorCode.TOKEN_INVALID, 'Refresh token already expired; refusing to set cookies');
105
+ }
106
+ const refreshTokenCookieName = (0, core_1.getRefreshTokenCookieName)(this.config);
107
+ setCookie(refreshTokenCookieName, tokens.refreshToken, { ...cookieOptions, maxAge: refreshMaxAgeMs });
108
+ }
109
+ // Trusted device cookie (optional)
110
+ if (typeof tokens.deviceToken === 'string' && tokens.deviceToken) {
111
+ this.setDeviceTokenCookie(res, tokens.deviceToken);
112
+ }
113
+ }
114
+ /**
115
+ * Set only the device token cookie (used by trust-device endpoint).
116
+ *
117
+ * @param res - HTTP response
118
+ * @param deviceToken - Device token to persist as cookie
119
+ */
120
+ setDeviceTokenCookie(res, deviceToken) {
121
+ const token = typeof deviceToken === 'string' ? deviceToken : '';
122
+ if (!token) {
123
+ throw new core_1.NAuthException(core_1.AuthErrorCode.VALIDATION_FAILED, 'deviceToken is required', { field: 'deviceToken' });
124
+ }
125
+ const cookieOptions = this.buildCookieOptions();
126
+ const setCookie = this.getSetCookieFn(res);
127
+ const rememberDeviceDays = this.config.mfa?.rememberDeviceDays || 30;
128
+ const deviceTokenMaxAgeMs = rememberDeviceDays * 24 * 60 * 60 * 1000;
129
+ const deviceTokenCookieName = (0, core_1.getDeviceTokenCookieName)(this.config);
130
+ setCookie(deviceTokenCookieName, token, { ...cookieOptions, maxAge: deviceTokenMaxAgeMs });
131
+ }
132
+ /**
133
+ * Set CSRF cookie for cookie-based delivery.
134
+ *
135
+ * @param res - HTTP response
136
+ * @param accessToken - Access token used to align CSRF cookie lifetime
137
+ */
138
+ setCsrfCookie(res, accessToken) {
139
+ if (!this.csrfService || !this.config.security?.csrf) {
140
+ return;
141
+ }
142
+ const accessPayload = this.jwtService.decodeToken(accessToken);
143
+ if (!accessPayload?.exp) {
144
+ throw new core_1.NAuthException(core_1.AuthErrorCode.TOKEN_INVALID, 'Access token missing exp claim; refusing to set CSRF cookie');
145
+ }
146
+ const accessMaxAgeMs = Math.max(0, accessPayload.exp * 1000 - Date.now());
147
+ const csrfToken = this.csrfService.generateToken();
148
+ const csrfCookieName = this.csrfService.getCookieName();
149
+ const csrfCookieOptions = this.csrfService.getCookieOptions();
150
+ const setCookie = this.getSetCookieFn(res);
151
+ setCookie(csrfCookieName, csrfToken, {
152
+ ...csrfCookieOptions,
153
+ maxAge: accessMaxAgeMs > 0 ? accessMaxAgeMs : undefined,
154
+ });
155
+ }
156
+ // ============================================================================
157
+ // Private helpers
158
+ // ============================================================================
159
+ buildCookieOptions() {
160
+ const opt = this.config.tokenDelivery?.cookieOptions;
161
+ const cookieOptions = {
162
+ httpOnly: true,
163
+ secure: opt?.secure !== false,
164
+ sameSite: (opt?.sameSite || 'strict'),
165
+ path: opt?.path || '/',
166
+ };
167
+ if (opt?.domain) {
168
+ cookieOptions.domain = opt.domain;
169
+ }
170
+ return cookieOptions;
171
+ }
172
+ getSetCookieFn(res) {
173
+ return (name, value, options) => {
174
+ const r = res;
175
+ if (typeof r.cookie === 'function') {
176
+ r.cookie(name, value, options);
177
+ return;
178
+ }
179
+ if (typeof r.setCookie === 'function') {
180
+ r.setCookie(name, value, options);
181
+ return;
182
+ }
183
+ throw new core_1.NAuthException(core_1.AuthErrorCode.INTERNAL_ERROR, 'Response does not support setting cookies');
184
+ };
185
+ }
186
+ };
187
+ exports.TokenDeliveryHttpService = TokenDeliveryHttpService;
188
+ exports.TokenDeliveryHttpService = TokenDeliveryHttpService = __decorate([
189
+ (0, common_1.Injectable)(),
190
+ __param(0, (0, common_1.Inject)('NAUTH_CONFIG')),
191
+ __metadata("design:paramtypes", [Object, internal_1.JwtService,
192
+ csrf_service_1.CsrfService])
193
+ ], TokenDeliveryHttpService);
194
+ //# sourceMappingURL=token-delivery-http.service.js.map