@nestjs-kitchen/authz 3.0.1 → 4.0.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.
Files changed (36) hide show
  1. package/README.md +27 -8
  2. package/dist/authz.provider.d.ts +1 -2
  3. package/dist/jwt/jwt-authz-als.middleware.d.ts +5 -9
  4. package/dist/jwt/jwt-authz-als.middleware.js +6 -9
  5. package/dist/jwt/jwt-authz.guard.d.ts +10 -23
  6. package/dist/jwt/jwt-authz.guard.js +93 -22
  7. package/dist/jwt/jwt-authz.module.d.ts +6 -13
  8. package/dist/jwt/jwt-authz.module.js +3 -17
  9. package/dist/jwt/jwt-authz.service.d.ts +3 -3
  10. package/dist/session/session-authz-als.middleware.d.ts +3 -5
  11. package/dist/session/session-authz-als.middleware.js +29 -50
  12. package/dist/session/session-authz.guard.d.ts +3 -10
  13. package/dist/session/session-authz.guard.js +33 -11
  14. package/dist/session/session-authz.module.d.ts +4 -11
  15. package/dist/session/session-authz.module.js +1 -13
  16. package/dist/session/session-authz.service.d.ts +2 -2
  17. package/dist/utils/adapter-shim.d.ts +28 -0
  18. package/dist/utils/adapter-shim.js +174 -0
  19. package/dist/utils/cookie-parsers.d.ts +6 -7
  20. package/dist/utils/cookie-parsers.js +10 -0
  21. package/dist/utils/create-set-cookie-fn.d.ts +2 -3
  22. package/dist/utils/create-set-cookie-fn.js +2 -1
  23. package/dist/utils/generics.d.ts +0 -1
  24. package/dist/utils/generics.js +1 -12
  25. package/dist/utils/get-passport-property.d.ts +1 -1
  26. package/dist/utils/get-passport-property.js +0 -1
  27. package/dist/utils/index.d.ts +2 -0
  28. package/dist/utils/index.js +2 -0
  29. package/dist/utils/safe-clone.d.ts +1 -0
  30. package/dist/utils/safe-clone.js +15 -0
  31. package/dist/utils/types.d.ts +0 -7
  32. package/package.json +24 -10
  33. package/dist/jwt/jwt-authz.strategy.d.ts +0 -17
  34. package/dist/jwt/jwt-authz.strategy.js +0 -134
  35. package/dist/session/session-authz.strategy.d.ts +0 -11
  36. package/dist/session/session-authz.strategy.js +0 -70
package/README.md CHANGED
@@ -16,24 +16,43 @@ Simplest authentication & authorization module in NextJS.
16
16
 
17
17
  ## Features
18
18
 
19
- - JWT based authentication
20
- - Session based authentication
21
- - Customizable authorization
22
- - Simplified setups and APIs
23
- - Anonymous access support
24
- - Simultaneous multiple strategy (JWT/Session) uses
19
+ - ✅ Support JWT authentication
20
+
21
+ - Support session authentication
22
+
23
+ - Service based authentication/authorization -- Use Nestjs style services to implement authentication/authorization.
24
+
25
+ - ✅ Support Anonymous access
26
+
27
+ - ✅ Compatible with `Express` and `Fastify`
25
28
 
26
29
  ## Install
27
30
 
28
31
  Once completed NestJS project setup, install this package and its dependencies:
29
32
 
30
33
  ```bash
31
- $ npm install --save @nestjs/passport passport @nestjs-kitchen/authz
34
+ $ npm install --save @nestjs-kitchen/authz
32
35
  ```
33
36
 
37
+ ## Platform support
38
+
39
+ Below platforms require different dependencies:
40
+
41
+ - For `@nestjs/platform-express`:
42
+
43
+ It requires [`express-session`](https://www.npmjs.com/package/express-session).
44
+
45
+ - For `@nestjs/platform-fastify`:
46
+
47
+ It requires [`@fastify/cookie`](https://www.npmjs.com/package/@fastify/cookie) and [`@fastify/session`](https://www.npmjs.com/package/@fastify/session).
48
+
49
+ Or [`@fastify/secure-session`](https://www.npmjs.com/package/@fastify/secure-session) instead.
50
+
34
51
  ## Beark change
35
52
 
36
- - From `@nestjs-kitchen/authz` **v3**, [`express-session`](https://www.npmjs.com/package/express-session) had been removed from dependency. Please setup session manually:
53
+ - From **v4**, `Passport.js` is moved out without any api changes.
54
+
55
+ - From **v3**, [`express-session`](https://www.npmjs.com/package/express-session) had been removed from dependency. Please setup session manually:
37
56
 
38
57
  ```typescript
39
58
  import * as session from 'express-session';
@@ -1,4 +1,3 @@
1
- import type { Request } from 'express';
2
1
  /**
3
2
  * Abstract base class for implementing custom authorization logic.
4
3
  *
@@ -26,7 +25,7 @@ export declare abstract class AuthzProviderClass<Payload, User> {
26
25
  * @param {Payload} payload - The payload to authenticate.
27
26
  * @returns {User | Promise<User>} The authenticated user, or a promise resolving to the user.
28
27
  */
29
- abstract authenticate(payload: Payload, req?: Request): User | Promise<User>;
28
+ abstract authenticate(payload: Payload, req?: any): User | Promise<User>;
30
29
  /**
31
30
  * (**Optional**: Implement this method only if authorization is required.)
32
31
  *
@@ -1,19 +1,15 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { type Type } from '@nestjs/common';
3
- import type { NextFunction, Request, Response } from 'express';
4
3
  import { JwtValidationType } from '../constants';
5
- import { type CookieOptionsWithSecret } from '../utils';
6
- import type { JwtAuthzOptions } from './jwt-authz.interface';
4
+ import { type RawRequestWithShims, type RawResponseWithShims } from '../utils';
7
5
  export interface JwtAlsType<U> {
8
6
  user?: U;
9
7
  jwtVerifiedBy?: JwtValidationType;
10
8
  allowAnonymous?: boolean;
11
9
  guardResult?: boolean;
12
- authOptions: JwtAuthzOptions;
13
- setCookie: (name: string, value: string, options?: CookieOptionsWithSecret) => void;
10
+ setCookie: (name: string, value: string, options?: Record<string, any>) => void;
14
11
  }
15
- export declare const createJwtAuthzAlsMiddleware: ([ALS_PROVIDER, JWT_AUTHZ_OPTIONS]: [any, any]) => Type<Omit<{
12
+ export declare const createJwtAuthzAlsMiddleware: ([ALS_PROVIDER]: [any]) => Type<Omit<{
16
13
  readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
17
- readonly jwtAuthzOptions: JwtAuthzOptions;
18
- use(req: Request, res: Response, next: NextFunction): void;
19
- }, "als" | "jwtAuthzOptions">>;
14
+ use(req: RawRequestWithShims, res: RawResponseWithShims, next: Function): void;
15
+ }, "als">>;
@@ -16,30 +16,27 @@ exports.createJwtAuthzAlsMiddleware = void 0;
16
16
  const node_async_hooks_1 = require("node:async_hooks");
17
17
  const common_1 = require("@nestjs/common");
18
18
  const utils_1 = require("../utils");
19
- const createJwtAuthzAlsMiddleware = ([ALS_PROVIDER, JWT_AUTHZ_OPTIONS]) => {
19
+ const createJwtAuthzAlsMiddleware = ([ALS_PROVIDER]) => {
20
20
  let JwtAuthzAlsMiddleware = class JwtAuthzAlsMiddleware {
21
- constructor(als, jwtAuthzOptions) {
21
+ constructor(als) {
22
22
  this.als = als;
23
- this.jwtAuthzOptions = jwtAuthzOptions;
24
23
  }
25
24
  use(req, res, next) {
26
- this.als.run({
25
+ const store = {
27
26
  user: undefined,
28
27
  jwtVerifiedBy: undefined,
29
28
  allowAnonymous: undefined,
30
29
  guardResult: undefined,
31
- // a workaround to pass jwtAuthzOptions to passport strategy.
32
- authOptions: this.jwtAuthzOptions,
33
30
  setCookie: (0, utils_1.createSetCookieFn)(req, res)
34
- }, () => {
31
+ };
32
+ this.als.run(store, () => {
35
33
  next();
36
34
  });
37
35
  }
38
36
  };
39
37
  JwtAuthzAlsMiddleware = __decorate([
40
38
  __param(0, (0, common_1.Inject)(ALS_PROVIDER)),
41
- __param(1, (0, common_1.Inject)(JWT_AUTHZ_OPTIONS)),
42
- __metadata("design:paramtypes", [node_async_hooks_1.AsyncLocalStorage, Object])
39
+ __metadata("design:paramtypes", [node_async_hooks_1.AsyncLocalStorage])
43
40
  ], JwtAuthzAlsMiddleware);
44
41
  return (0, common_1.mixin)(JwtAuthzAlsMiddleware);
45
42
  };
@@ -1,20 +1,15 @@
1
1
  import type { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { ExecutionContext, type Type } from '@nestjs/common';
3
3
  import { Reflector } from '@nestjs/core';
4
- import type { Observable } from 'rxjs';
5
4
  import { AuthzProviderClass } from '../authz.provider';
6
- import { type AuthzError } from '../errors';
5
+ import { AuthzError } from '../errors';
7
6
  import type { JwtAuthzOptions } from './jwt-authz.interface';
8
7
  import type { JwtAlsType } from './jwt-authz-als.middleware';
9
- export declare const createJwtAuthzGuard: ([JWT_STRATEGY, AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER, JWT_META_KEY, JWT_REFRESH_META_KEY]: [string, any, any, any, any, any]) => Type<Omit<{
8
+ export declare const createJwtAuthzGuard: ([AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER, JWT_META_KEY, JWT_REFRESH_META_KEY]: [any, any, any, any, any]) => Type<Omit<{
10
9
  readonly reflector: Reflector;
11
10
  readonly authzProvider: AuthzProviderClass<unknown, unknown>;
12
11
  readonly jwtAuthzOptions: JwtAuthzOptions;
13
12
  readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
14
- getAuthenticateOptions(): {
15
- property: string;
16
- session: boolean;
17
- };
18
13
  /**
19
14
  *
20
15
  * recives err, user, info from JwtStrategy.validate
@@ -28,21 +23,13 @@ export declare const createJwtAuthzGuard: ([JWT_STRATEGY, AUTHZ_PROVIDER, JWT_AU
28
23
  */
29
24
  handleRequest<T>(_err: unknown, user: T, info?: AuthzError): T;
30
25
  canActivate(context: ExecutionContext): Promise<boolean>;
31
- logIn<TRequest extends {
32
- logIn: Function;
33
- } = any>(request: TRequest): Promise<void>;
34
- getRequest(context: ExecutionContext): any;
35
- }, "als" | "jwtAuthzOptions" | "reflector" | "authzProvider">>;
36
- export declare const createJwtRefreshAuthzGuard: ([JWT_REFRESH_STRATEGY, JWT_AUTHZ_OPTIONS]: [string, any]) => Type<Omit<{
26
+ validate(req: any): Promise<[any, any?]>;
27
+ }, "als" | "reflector" | "authzProvider" | "jwtAuthzOptions">>;
28
+ export declare const createJwtRefreshAuthzGuard: ([JWT_AUTHZ_OPTIONS, AUTHZ_PROVIDER, ALS_PROVIDER]: [any, any, any]) => Type<Omit<{
37
29
  readonly jwtAuthzOptions: JwtAuthzOptions;
38
- getAuthenticateOptions(): {
39
- property: string;
40
- session: boolean;
41
- };
30
+ readonly authzProvider: AuthzProviderClass<unknown, unknown>;
31
+ readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
42
32
  handleRequest<T>(_err: unknown, user: T, info?: AuthzError): T;
43
- canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean>;
44
- logIn<TRequest extends {
45
- logIn: Function;
46
- } = any>(request: TRequest): Promise<void>;
47
- getRequest(context: ExecutionContext): any;
48
- }, "jwtAuthzOptions">>;
33
+ canActivate(context: ExecutionContext): Promise<boolean>;
34
+ validate(req: any): Promise<[any, any?]>;
35
+ }, "als" | "authzProvider" | "jwtAuthzOptions">>;
@@ -11,28 +11,29 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
14
17
  Object.defineProperty(exports, "__esModule", { value: true });
15
18
  exports.createJwtRefreshAuthzGuard = exports.createJwtAuthzGuard = void 0;
16
19
  const common_1 = require("@nestjs/common");
17
20
  const core_1 = require("@nestjs/core");
18
- const passport_1 = require("@nestjs/passport");
21
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
19
22
  const authz_provider_1 = require("../authz.provider");
23
+ const constants_1 = require("../constants");
20
24
  const errors_1 = require("../errors");
21
25
  const utils_1 = require("../utils");
22
- const createJwtAuthzGuard = ([JWT_STRATEGY, AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER, JWT_META_KEY, JWT_REFRESH_META_KEY]) => {
23
- let JwtAuthzGuard = class JwtAuthzGuard extends (0, passport_1.AuthGuard)(JWT_STRATEGY) {
26
+ const extract_jwt_1 = require("./extract-jwt");
27
+ const createJwtAuthzGuard = ([AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER, JWT_META_KEY, JWT_REFRESH_META_KEY]) => {
28
+ let JwtAuthzGuard = class JwtAuthzGuard {
24
29
  constructor(reflector, authzProvider, jwtAuthzOptions, als) {
25
- super();
26
30
  this.reflector = reflector;
27
31
  this.authzProvider = authzProvider;
28
32
  this.jwtAuthzOptions = jwtAuthzOptions;
29
33
  this.als = als;
30
- }
31
- getAuthenticateOptions() {
32
- return {
33
- property: this.jwtAuthzOptions.passportProperty,
34
- session: false
35
- };
34
+ if (typeof this.authzProvider.authenticate !== 'function') {
35
+ throw new errors_1.AuthzError(`InternalError: Method 'authenticate' from abstract class 'AuthzProvider' must be implemented.`);
36
+ }
36
37
  }
37
38
  /**
38
39
  *
@@ -82,7 +83,7 @@ const createJwtAuthzGuard = ([JWT_STRATEGY, AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, A
82
83
  store.allowAnonymous = (0, utils_1.getAllowAnonymous)(contextParamsList, {
83
84
  defaultAllowAnonymous: this.jwtAuthzOptions.defaultAllowAnonymous
84
85
  });
85
- await super.canActivate(context);
86
+ req[this.jwtAuthzOptions.passportProperty] = this.handleRequest(undefined, ...(await this.validate(req)));
86
87
  // will be null if allowAnonymous=true.
87
88
  const user = (0, utils_1.getPassportProperty)(req);
88
89
  if (store.allowAnonymous && !user) {
@@ -95,6 +96,38 @@ const createJwtAuthzGuard = ([JWT_STRATEGY, AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, A
95
96
  }
96
97
  return true;
97
98
  }
99
+ async validate(req) {
100
+ const store = (0, utils_1.getAlsStore)(this.als);
101
+ const authOptions = this.jwtAuthzOptions;
102
+ if (!authOptions.jwt.verify) {
103
+ return [null, new errors_1.AuthzError(`InternalError: Refresh verify options must be implemented.`)];
104
+ }
105
+ const extractor = extract_jwt_1.ExtractJwt.fromExtractors(authOptions.jwt.jwtFromRequest);
106
+ req[constants_1.PASSPORT_PROPERTY] = authOptions.passportProperty;
107
+ const token = extractor(req);
108
+ if (!token) {
109
+ return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find token.')];
110
+ }
111
+ let user = undefined;
112
+ try {
113
+ const payload = jsonwebtoken_1.default.verify(token, authOptions.jwt.secretOrPublicKey, authOptions.jwt.verify);
114
+ user = await this.authzProvider.authenticate(payload, req);
115
+ }
116
+ catch (error) {
117
+ return [
118
+ null,
119
+ error instanceof Error
120
+ ? new errors_1.AuthzVerificationError(`${error.name}: ${error.message}`, error)
121
+ : new errors_1.AuthzVerificationError(`${error}`)
122
+ ];
123
+ }
124
+ store.user = user;
125
+ store.jwtVerifiedBy = constants_1.JwtValidationType.JWT;
126
+ if (!user) {
127
+ return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find user.')];
128
+ }
129
+ return [user];
130
+ }
98
131
  };
99
132
  JwtAuthzGuard = __decorate([
100
133
  __param(1, (0, common_1.Inject)(AUTHZ_PROVIDER)),
@@ -106,17 +139,15 @@ const createJwtAuthzGuard = ([JWT_STRATEGY, AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, A
106
139
  return (0, common_1.mixin)(JwtAuthzGuard);
107
140
  };
108
141
  exports.createJwtAuthzGuard = createJwtAuthzGuard;
109
- const createJwtRefreshAuthzGuard = ([JWT_REFRESH_STRATEGY, JWT_AUTHZ_OPTIONS]) => {
110
- let JwtRefreshAuthzGuard = class JwtRefreshAuthzGuard extends (0, passport_1.AuthGuard)(JWT_REFRESH_STRATEGY) {
111
- constructor(jwtAuthzOptions) {
112
- super();
142
+ const createJwtRefreshAuthzGuard = ([JWT_AUTHZ_OPTIONS, AUTHZ_PROVIDER, ALS_PROVIDER]) => {
143
+ let JwtRefreshAuthzGuard = class JwtRefreshAuthzGuard {
144
+ constructor(jwtAuthzOptions, authzProvider, als) {
113
145
  this.jwtAuthzOptions = jwtAuthzOptions;
114
- }
115
- getAuthenticateOptions() {
116
- return {
117
- property: this.jwtAuthzOptions.passportProperty,
118
- session: false
119
- };
146
+ this.authzProvider = authzProvider;
147
+ this.als = als;
148
+ if (typeof this.authzProvider.authenticate !== 'function') {
149
+ throw new errors_1.AuthzError(`InternalError: Method 'authenticate' from abstract class 'AuthzProvider' must be implemented.`);
150
+ }
120
151
  }
121
152
  handleRequest(_err, user, info) {
122
153
  if (info) {
@@ -124,10 +155,50 @@ const createJwtRefreshAuthzGuard = ([JWT_REFRESH_STRATEGY, JWT_AUTHZ_OPTIONS]) =
124
155
  }
125
156
  return user;
126
157
  }
158
+ async canActivate(context) {
159
+ const req = context.switchToHttp().getRequest();
160
+ req[this.jwtAuthzOptions.passportProperty] = this.handleRequest(undefined, ...(await this.validate(req)));
161
+ return true;
162
+ }
163
+ async validate(req) {
164
+ const store = (0, utils_1.getAlsStore)(this.als);
165
+ const authOptions = this.jwtAuthzOptions;
166
+ if (!authOptions.refresh.verify) {
167
+ return [null, new errors_1.AuthzError(`InternalError: Refresh verify options must be implemented.`)];
168
+ }
169
+ const extractor = extract_jwt_1.ExtractJwt.fromExtractors(authOptions.refresh.jwtFromRequest);
170
+ req[constants_1.PASSPORT_PROPERTY] = authOptions.passportProperty;
171
+ const token = extractor(req);
172
+ if (!token) {
173
+ return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find token.')];
174
+ }
175
+ let user = undefined;
176
+ try {
177
+ const payload = jsonwebtoken_1.default.verify(token, authOptions.refresh.secretOrPublicKey, authOptions.refresh.verify);
178
+ const decodePayload = (0, utils_1.decodeMsgpackrString)(payload.data);
179
+ user = await this.authzProvider.authenticate(decodePayload, req);
180
+ }
181
+ catch (error) {
182
+ return [
183
+ null,
184
+ error instanceof Error
185
+ ? new errors_1.AuthzVerificationError(`${error.name}: ${error.message}`, error)
186
+ : new errors_1.AuthzVerificationError(`${error}`)
187
+ ];
188
+ }
189
+ store.user = user;
190
+ store.jwtVerifiedBy = constants_1.JwtValidationType.REFRESH;
191
+ if (!user) {
192
+ return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find user.')];
193
+ }
194
+ return [user];
195
+ }
127
196
  };
128
197
  JwtRefreshAuthzGuard = __decorate([
129
198
  __param(0, (0, common_1.Inject)(JWT_AUTHZ_OPTIONS)),
130
- __metadata("design:paramtypes", [Object])
199
+ __param(1, (0, common_1.Inject)(AUTHZ_PROVIDER)),
200
+ __param(2, (0, common_1.Inject)(ALS_PROVIDER)),
201
+ __metadata("design:paramtypes", [Object, authz_provider_1.AuthzProviderClass, Function])
131
202
  ], JwtRefreshAuthzGuard);
132
203
  return (0, common_1.mixin)(JwtRefreshAuthzGuard);
133
204
  };
@@ -1,9 +1,9 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { type ConfigurableModuleAsyncOptions, DynamicModule, type ExecutionContext, MiddlewareConsumer, type Type } from '@nestjs/common';
3
- import type { Reflector } from '@nestjs/core';
3
+ import { type Reflector } from '@nestjs/core';
4
4
  import { AuthzProviderClass } from '../authz.provider';
5
5
  import { AuthzError } from '../errors';
6
- import { type AbstractConstructor, type ApplyDecorators, type AuthzDecoParams, type AuthzModuleBaseOptions, type AuthzModuleRoutesOptions, type CookieOptionsWithSecret, type DeepReadonly, type MethodParameters, type RoutesOptions } from '../utils';
6
+ import { type AbstractConstructor, type ApplyDecorators, type AuthzDecoParams, type AuthzModuleBaseOptions, type AuthzModuleRoutesOptions, type DeepReadonly, type MethodParameters, type RoutesOptions } from '../utils';
7
7
  import { type JwtAuthzModuleOptions, type JwtAuthzOptions, type JwtOptions } from './jwt-authz.interface';
8
8
  import { type JwtAlsType } from './jwt-authz-als.middleware';
9
9
  declare const ASYNC_OPTIONS_TYPE: ConfigurableModuleAsyncOptions<JwtAuthzModuleOptions, "createJwtAuthzModuleOptions"> & Partial<{
@@ -97,17 +97,10 @@ export declare const createJwtAuthzModule: <P, U, T extends AuthzProviderClass<P
97
97
  readonly authzProvider: AuthzProviderClass<unknown, unknown>;
98
98
  readonly jwtAuthzOptions: JwtAuthzOptions;
99
99
  readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
100
- getAuthenticateOptions(): {
101
- property: string;
102
- session: boolean;
103
- };
104
100
  handleRequest<T_1>(_err: unknown, user: T_1, info?: AuthzError): T_1;
105
101
  canActivate(context: ExecutionContext): Promise<boolean>;
106
- logIn<TRequest extends {
107
- logIn: Function;
108
- } = any>(request: TRequest): Promise<void>;
109
- getRequest(context: ExecutionContext): any;
110
- }, "als" | "jwtAuthzOptions" | "reflector" | "authzProvider">> & {
102
+ validate(req: any): Promise<[any, any?]>;
103
+ }, "als" | "reflector" | "authzProvider" | "jwtAuthzOptions">> & {
111
104
  /**
112
105
  * Verifies the user's authorization for specific meta data.
113
106
  *
@@ -197,8 +190,8 @@ export declare const createJwtAuthzModule: <P, U, T extends AuthzProviderClass<P
197
190
  refresh(user?: U | undefined): Promise<{
198
191
  token: string;
199
192
  } | undefined>;
200
- setCookie(name: string, value: string, options?: CookieOptionsWithSecret | undefined): void;
193
+ setCookie(name: string, value: string, options?: Record<string, any> | undefined): void;
201
194
  getUser(): DeepReadonly<U> | undefined;
202
- }, "als" | "jwtAuthzOptions" | "authzProvider">>;
195
+ }, "als" | "authzProvider" | "jwtAuthzOptions">>;
203
196
  };
204
197
  export {};
@@ -22,7 +22,6 @@ const utils_1 = require("../utils");
22
22
  const jwt_authz_guard_1 = require("./jwt-authz.guard");
23
23
  const jwt_authz_interface_1 = require("./jwt-authz.interface");
24
24
  const jwt_authz_service_1 = require("./jwt-authz.service");
25
- const jwt_authz_strategy_1 = require("./jwt-authz.strategy");
26
25
  const jwt_authz_als_middleware_1 = require("./jwt-authz-als.middleware");
27
26
  const store = {
28
27
  globalInited: 0
@@ -53,6 +52,7 @@ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, ASYNC_OPTIONS_TYPE, OPTIO
53
52
  return (0, utils_1.mergeDynamicModuleConfigs)(definition, {
54
53
  global,
55
54
  providers: [
55
+ ...(0, utils_1.createOnceAdapterShimProvider)(),
56
56
  {
57
57
  provide: constants_1.ROUTES_OPTIONS,
58
58
  useValue: {
@@ -76,9 +76,6 @@ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, ASYNC_OPTIONS_TYPE, OPTIO
76
76
  const createJwtAuthzModule = (authzProvider) => {
77
77
  // prevent token overriding
78
78
  const id = `${constants_1.PREFIX}${(0, uid_1.uid)()}`;
79
- // strategy tokens
80
- const JWT_STRATEGY = `${id}_JWT_STRATEGY`;
81
- const JWT_REFRESH_STRATEGY = `${id}_REFRESH_STRATEGY`;
82
79
  // provider tokens
83
80
  const AUTHZ_PROVIDER = `${id}_AUTHZ_PROVIDER`;
84
81
  const ALS_PROVIDER = `${id}_ALS_PROVIDER`;
@@ -88,20 +85,11 @@ const createJwtAuthzModule = (authzProvider) => {
88
85
  const JWT_REFRESH_META_KEY = `${id}_REFRESH_META_KEY`;
89
86
  // providers
90
87
  const JwtAuthzService = (0, jwt_authz_service_1.createJwtAuthzService)([AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER]);
91
- const JwtAuthzAlsMiddleware = (0, jwt_authz_als_middleware_1.createJwtAuthzAlsMiddleware)([ALS_PROVIDER, JWT_AUTHZ_OPTIONS]);
88
+ const JwtAuthzAlsMiddleware = (0, jwt_authz_als_middleware_1.createJwtAuthzAlsMiddleware)([ALS_PROVIDER]);
92
89
  const als = new node_async_hooks_1.AsyncLocalStorage();
93
- // strategy
94
- const JwtStrategy = (0, jwt_authz_strategy_1.createJwtStrategy)([JWT_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]);
95
- const RefreshStrategy = (0, jwt_authz_strategy_1.createRefreshStrategy)([JWT_REFRESH_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]);
96
- // each strategy can be only registered once in passport.
97
- // no need to provide multiple times as
98
- // 1. they use the same ALS and authzProvider instance.
99
- // 2. guard use strategy through passport via strategy name.
100
- let isStrategyInited = false;
101
90
  // guards
102
- const RefreshAuthzGuard = (0, jwt_authz_guard_1.createJwtRefreshAuthzGuard)([JWT_REFRESH_STRATEGY, JWT_AUTHZ_OPTIONS]);
91
+ const RefreshAuthzGuard = (0, jwt_authz_guard_1.createJwtRefreshAuthzGuard)([JWT_AUTHZ_OPTIONS, AUTHZ_PROVIDER, ALS_PROVIDER]);
103
92
  const JwtAuthzGuard = (0, jwt_authz_guard_1.createJwtAuthzGuard)([
104
- JWT_STRATEGY,
105
93
  AUTHZ_PROVIDER,
106
94
  JWT_AUTHZ_OPTIONS,
107
95
  ALS_PROVIDER,
@@ -135,12 +123,10 @@ const createJwtAuthzModule = (authzProvider) => {
135
123
  provide: ALS_PROVIDER,
136
124
  useValue: als
137
125
  },
138
- ...(!isStrategyInited ? [JwtStrategy, RefreshStrategy] : []),
139
126
  JwtAuthzService
140
127
  ],
141
128
  exports: [AUTHZ_PROVIDER, ALS_PROVIDER, JWT_AUTHZ_OPTIONS, JwtAuthzService]
142
129
  };
143
- isStrategyInited = true;
144
130
  return configs;
145
131
  };
146
132
  let JwtAuthzModule = class JwtAuthzModule extends ConfigurableModuleClass {
@@ -1,7 +1,7 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { type Type } from '@nestjs/common';
3
3
  import { AuthzProviderClass } from '../authz.provider';
4
- import { type CookieOptionsWithSecret, type DeepReadonly } from '../utils';
4
+ import { type DeepReadonly } from '../utils';
5
5
  import type { JwtAuthzOptions } from './jwt-authz.interface';
6
6
  import type { JwtAlsType } from './jwt-authz-als.middleware';
7
7
  export declare const createJwtAuthzService: <P = unknown, U = unknown>([AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER]: [any, any, any]) => Type<Omit<{
@@ -36,9 +36,9 @@ export declare const createJwtAuthzService: <P = unknown, U = unknown>([AUTHZ_PR
36
36
  /**
37
37
  * Sets a secure HTTP cookie with the given name, value, and optional cookie options.
38
38
  */
39
- setCookie(name: string, value: string, options?: CookieOptionsWithSecret | undefined): void;
39
+ setCookie(name: string, value: string, options?: Record<string, any> | undefined): void;
40
40
  /**
41
41
  * Retrieves the current user associated with the request, if available.
42
42
  */
43
43
  getUser(): DeepReadonly<U> | undefined;
44
- }, "als" | "jwtAuthzOptions" | "authzProvider">>;
44
+ }, "als" | "authzProvider" | "jwtAuthzOptions">>;
@@ -1,19 +1,17 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { type Type } from '@nestjs/common';
3
- import type { NextFunction, Request, Response } from 'express';
4
- import { type CookieOptionsWithSecret } from '../utils';
3
+ import { type RawRequestWithShims, type RawResponseWithShims } from '../utils';
5
4
  import type { SessionAuthzOptions } from './session-authz.interface';
6
5
  export interface SessionAlsType<P, U> {
7
6
  user?: U;
8
7
  allowAnonymous?: boolean;
9
8
  guardResult?: boolean;
10
- authOptions: SessionAuthzOptions;
11
9
  logIn: (user: P) => Promise<void>;
12
10
  logOut: () => Promise<void>;
13
- setCookie: (name: string, value: string, options?: CookieOptionsWithSecret) => void;
11
+ setCookie: (name: string, value: string, options?: Record<string, any>) => void;
14
12
  }
15
13
  export declare const createSessionAuthzAlsMiddleware: ([ALS_PROVIDER, SESSION_AUTHZ_OPTIONS]: [any, any]) => Type<Omit<{
16
14
  readonly als: AsyncLocalStorage<SessionAlsType<unknown, unknown>>;
17
15
  readonly sessionAuthzOptions: SessionAuthzOptions;
18
- use(req: Request, res: Response, next: NextFunction): void;
16
+ use(req: RawRequestWithShims, res: RawResponseWithShims, next: Function): void;
19
17
  }, "als" | "sessionAuthzOptions">>;
@@ -16,7 +16,6 @@ exports.createSessionAuthzAlsMiddleware = void 0;
16
16
  const node_async_hooks_1 = require("node:async_hooks");
17
17
  const common_1 = require("@nestjs/common");
18
18
  const constants_1 = require("../constants");
19
- const errors_1 = require("../errors");
20
19
  const utils_1 = require("../utils");
21
20
  const createSessionAuthzAlsMiddleware = ([ALS_PROVIDER, SESSION_AUTHZ_OPTIONS]) => {
22
21
  let SessionAuthzAlsMiddleware = class SessionAuthzAlsMiddleware {
@@ -26,64 +25,44 @@ const createSessionAuthzAlsMiddleware = ([ALS_PROVIDER, SESSION_AUTHZ_OPTIONS])
26
25
  }
27
26
  use(req, res, next) {
28
27
  const keepSessionInfo = Boolean(this.sessionAuthzOptions.keepSessionInfo);
29
- if (!req.session) {
30
- return next(new errors_1.AuthzError('Login sessions require session support. Did you forget to use `express-session` middleware?'));
31
- }
32
- const prevSession = req.session;
33
28
  const store = {
34
29
  user: undefined,
35
30
  allowAnonymous: undefined,
36
31
  guardResult: undefined,
37
- authOptions: this.sessionAuthzOptions,
38
32
  // ref: https://github.com/jaredhanson/passport/blob/217018dbc46dcd4118dd6f2c60c8d97010c587f8/lib/sessionmanager.js#L14
39
- logIn: (user) => {
40
- return new Promise((resolve, reject) => {
41
- req.session.regenerate(function (err) {
42
- if (err) {
43
- return reject(err);
33
+ logIn: async (user) => {
34
+ const prevSession = req.shims.getAllSession();
35
+ await req.shims.regenerateSession();
36
+ if (keepSessionInfo) {
37
+ for (const key in prevSession) {
38
+ if (req.shims.sessionContains(key)) {
39
+ req.shims.setSession(key, prevSession[key]);
44
40
  }
45
- if (keepSessionInfo) {
46
- (0, utils_1.merge)(req.session, prevSession);
47
- }
48
- // @ts-ignore
49
- if (!req.session[constants_1.SESSION_PASSPORT_KEY]) {
50
- // @ts-ignore
51
- req.session[constants_1.SESSION_PASSPORT_KEY] = {};
52
- }
53
- // @ts-ignore
54
- req.session[constants_1.SESSION_PASSPORT_KEY].user = user;
55
- req.session.save(function (err) {
56
- if (err) {
57
- return reject(err);
58
- }
59
- resolve();
60
- });
61
- });
62
- });
41
+ }
42
+ }
43
+ const passportSession = req.shims.getSession(constants_1.SESSION_PASSPORT_KEY) ?? {};
44
+ passportSession.user = user;
45
+ req.shims.setSession(constants_1.SESSION_PASSPORT_KEY, passportSession);
46
+ await req.shims.saveSession();
47
+ return;
63
48
  },
64
49
  // ref: https://github.com/jaredhanson/passport/blob/217018dbc46dcd4118dd6f2c60c8d97010c587f8/lib/sessionmanager.js#L57
65
- logOut: () => {
66
- return new Promise((resolve, reject) => {
67
- // @ts-ignore
68
- if (req.session[constants_1.SESSION_PASSPORT_KEY]) {
69
- // @ts-ignore
70
- delete req.session[constants_1.SESSION_PASSPORT_KEY].user;
71
- }
72
- req.session.save(function (err) {
73
- if (err) {
74
- return reject(err);
50
+ logOut: async () => {
51
+ if (req.shims.sessionContains(constants_1.SESSION_PASSPORT_KEY)) {
52
+ const passportSession = req.shims.getSession(constants_1.SESSION_PASSPORT_KEY);
53
+ delete passportSession.user;
54
+ req.shims.setSession(constants_1.SESSION_PASSPORT_KEY, passportSession);
55
+ }
56
+ const prevSession = req.shims.getAllSession();
57
+ await req.shims.saveSession();
58
+ await req.shims.regenerateSession();
59
+ if (keepSessionInfo) {
60
+ for (const key in prevSession) {
61
+ if (req.shims.sessionContains(key)) {
62
+ req.shims.setSession(key, prevSession[key]);
75
63
  }
76
- req.session.regenerate(function (err) {
77
- if (err) {
78
- return reject(err);
79
- }
80
- if (keepSessionInfo) {
81
- (0, utils_1.merge)(req.session, prevSession);
82
- }
83
- resolve();
84
- });
85
- });
86
- });
64
+ }
65
+ }
87
66
  },
88
67
  setCookie: (0, utils_1.createSetCookieFn)(req, res)
89
68
  };
@@ -2,18 +2,14 @@ import { ExecutionContext, type Type } from '@nestjs/common';
2
2
  import { Reflector } from '@nestjs/core';
3
3
  import type { AsyncLocalStorage } from 'async_hooks';
4
4
  import { AuthzProviderClass } from '../authz.provider';
5
- import { type AuthzError } from '../errors';
5
+ import { AuthzError } from '../errors';
6
6
  import type { SessionAuthzOptions } from './session-authz.interface';
7
7
  import type { SessionAlsType } from './session-authz-als.middleware';
8
- export declare const createSessionAuthzGuard: ([SESSION_STRATEGY, AUTHZ_PROVIDER, SESSION_AUTHZ_OPTIONS, ALS_PROVIDER, SESSION_META_KEY]: [string, any, any, any, any]) => Type<Omit<{
8
+ export declare const createSessionAuthzGuard: ([AUTHZ_PROVIDER, SESSION_AUTHZ_OPTIONS, ALS_PROVIDER, SESSION_META_KEY]: [any, any, any, any]) => Type<Omit<{
9
9
  readonly reflector: Reflector;
10
10
  readonly authzProvider: AuthzProviderClass<unknown, unknown>;
11
11
  readonly sessionAuthzOptions: SessionAuthzOptions;
12
12
  readonly als: AsyncLocalStorage<SessionAlsType<unknown, unknown>>;
13
- getAuthenticateOptions(): {
14
- property: string;
15
- session: boolean;
16
- };
17
13
  /**
18
14
  *
19
15
  * recives err, user, info from JwtStrategy.validate
@@ -27,8 +23,5 @@ export declare const createSessionAuthzGuard: ([SESSION_STRATEGY, AUTHZ_PROVIDER
27
23
  */
28
24
  handleRequest<T>(_err: unknown, user: T, info?: AuthzError): T;
29
25
  canActivate(context: ExecutionContext): Promise<boolean>;
30
- logIn<TRequest extends {
31
- logIn: Function;
32
- } = any>(request: TRequest): Promise<void>;
33
- getRequest(context: ExecutionContext): any;
26
+ validate(req: any): Promise<[any, any?]>;
34
27
  }, "als" | "reflector" | "authzProvider" | "sessionAuthzOptions">>;