@nestjs-kitchen/authz 3.1.0 → 4.0.1

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/README.md CHANGED
@@ -16,41 +16,58 @@ Simplest authentication & authorization module in NextJS.
16
16
 
17
17
  ## Features
18
18
 
19
- - ✅ JWT based authentication
19
+ - ✅ Support JWT authentication
20
20
 
21
- - ✅ Session based authentication
21
+ - ✅ Support session authentication
22
22
 
23
- - ✅ Flexible authorization
23
+ - ✅ Service based authentication/authorization -- Use Nestjs style services to implement authentication/authorization.
24
24
 
25
25
  - ✅ Support Anonymous access
26
26
 
27
- - ✅ Compatible with both `@nestjs/platform-express` and `@nestjs/platform-fastify`
27
+ - ✅ Compatible with `Express` and `Fastify`
28
28
 
29
29
  ## Install
30
30
 
31
31
  Once completed NestJS project setup, install this package and its dependencies:
32
32
 
33
33
  ```bash
34
- $ npm install --save @nestjs/passport passport @nestjs-kitchen/authz
34
+ $ npm install @nestjs-kitchen/authz -D @types/jsonwebtoken
35
35
  ```
36
36
 
37
- ## Platform prerequisite
37
+ ## Platform support
38
38
 
39
- Different platforms require different dependencies:
39
+ This package supports multiple platforms (adapters).
40
+ You only need to install the adapter(s) you plan to use.
40
41
 
41
- - For `@nestjs/platform-express`:
42
+ - `@nestjs/platform-express`:
42
43
 
43
- It requires [`express-session`](https://www.npmjs.com/package/express-session).
44
+ Requires [`express-session`](https://www.npmjs.com/package/express-session):
44
45
 
45
- - For `@nestjs/platform-fastify`:
46
+ ```bash
47
+ $ npm install express-session -D @types/express-session
48
+ ```
46
49
 
47
- It requires [`@fastify/cookie`](https://www.npmjs.com/package/@fastify/cookie) and [`@fastify/session`](https://www.npmjs.com/package/@fastify/session).
50
+ - `@nestjs/platform-fastify`:
48
51
 
49
- Or [`@fastify/secure-session`](https://www.npmjs.com/package/@fastify/secure-session) instead.
52
+ Requires either:
53
+
54
+ 1. [`@fastify/cookie`](https://www.npmjs.com/package/@fastify/cookie) with [`@fastify/session`](https://www.npmjs.com/package/@fastify/session):
55
+
56
+ ```bash
57
+ $ npm install @fastify/cookie @fastify/session
58
+ ```
59
+
60
+ 2. Or [`@fastify/secure-session`](https://www.npmjs.com/package/@fastify/secure-session) instead:
61
+
62
+ ```bash
63
+ $ npm install @fastify/secure-session
64
+ ```
50
65
 
51
66
  ## Beark change
52
67
 
53
- - From `@nestjs-kitchen/authz` **v3**, [`express-session`](https://www.npmjs.com/package/express-session) had been removed from dependency. Please setup session manually:
68
+ - From **v4**, `Passport.js` is moved out without any api changes.
69
+
70
+ - From **v3**, [`express-session`](https://www.npmjs.com/package/express-session) had been removed from dependency. Please setup session manually:
54
71
 
55
72
  ```typescript
56
73
  import * as session from 'express-session';
@@ -2,17 +2,14 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { type Type } from '@nestjs/common';
3
3
  import { JwtValidationType } from '../constants';
4
4
  import { type RawRequestWithShims, type RawResponseWithShims } from '../utils';
5
- import type { JwtAuthzOptions } from './jwt-authz.interface';
6
5
  export interface JwtAlsType<U> {
7
6
  user?: U;
8
7
  jwtVerifiedBy?: JwtValidationType;
9
8
  allowAnonymous?: boolean;
10
9
  guardResult?: boolean;
11
- authOptions: JwtAuthzOptions;
12
10
  setCookie: (name: string, value: string, options?: Record<string, any>) => void;
13
11
  }
14
- export declare const createJwtAuthzAlsMiddleware: ([ALS_PROVIDER, JWT_AUTHZ_OPTIONS]: [any, any]) => Type<Omit<{
12
+ export declare const createJwtAuthzAlsMiddleware: ([ALS_PROVIDER]: [any]) => Type<Omit<{
15
13
  readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
16
- readonly jwtAuthzOptions: JwtAuthzOptions;
17
14
  use(req: RawRequestWithShims, res: RawResponseWithShims, next: Function): void;
18
- }, "als" | "jwtAuthzOptions">>;
15
+ }, "als">>;
@@ -16,11 +16,10 @@ 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
25
  const store = {
@@ -28,8 +27,6 @@ const createJwtAuthzAlsMiddleware = ([ALS_PROVIDER, JWT_AUTHZ_OPTIONS]) => {
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
  };
35
32
  this.als.run(store, () => {
@@ -39,8 +36,7 @@ const createJwtAuthzAlsMiddleware = ([ALS_PROVIDER, JWT_AUTHZ_OPTIONS]) => {
39
36
  };
40
37
  JwtAuthzAlsMiddleware = __decorate([
41
38
  __param(0, (0, common_1.Inject)(ALS_PROVIDER)),
42
- __param(1, (0, common_1.Inject)(JWT_AUTHZ_OPTIONS)),
43
- __metadata("design:paramtypes", [node_async_hooks_1.AsyncLocalStorage, Object])
39
+ __metadata("design:paramtypes", [node_async_hooks_1.AsyncLocalStorage])
44
40
  ], JwtAuthzAlsMiddleware);
45
41
  return (0, common_1.mixin)(JwtAuthzAlsMiddleware);
46
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
  };
@@ -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
  *
@@ -199,6 +192,6 @@ export declare const createJwtAuthzModule: <P, U, T extends AuthzProviderClass<P
199
192
  } | undefined>;
200
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
@@ -77,9 +76,6 @@ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, ASYNC_OPTIONS_TYPE, OPTIO
77
76
  const createJwtAuthzModule = (authzProvider) => {
78
77
  // prevent token overriding
79
78
  const id = `${constants_1.PREFIX}${(0, uid_1.uid)()}`;
80
- // strategy tokens
81
- const JWT_STRATEGY = `${id}_JWT_STRATEGY`;
82
- const JWT_REFRESH_STRATEGY = `${id}_REFRESH_STRATEGY`;
83
79
  // provider tokens
84
80
  const AUTHZ_PROVIDER = `${id}_AUTHZ_PROVIDER`;
85
81
  const ALS_PROVIDER = `${id}_ALS_PROVIDER`;
@@ -89,20 +85,11 @@ const createJwtAuthzModule = (authzProvider) => {
89
85
  const JWT_REFRESH_META_KEY = `${id}_REFRESH_META_KEY`;
90
86
  // providers
91
87
  const JwtAuthzService = (0, jwt_authz_service_1.createJwtAuthzService)([AUTHZ_PROVIDER, JWT_AUTHZ_OPTIONS, ALS_PROVIDER]);
92
- 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]);
93
89
  const als = new node_async_hooks_1.AsyncLocalStorage();
94
- // strategy
95
- const JwtStrategy = (0, jwt_authz_strategy_1.createJwtStrategy)([JWT_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]);
96
- const RefreshStrategy = (0, jwt_authz_strategy_1.createRefreshStrategy)([JWT_REFRESH_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]);
97
- // each strategy can be only registered once in passport.
98
- // no need to provide multiple times as
99
- // 1. they use the same ALS and authzProvider instance.
100
- // 2. guard use strategy through passport via strategy name.
101
- let isStrategyInited = false;
102
90
  // guards
103
- 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]);
104
92
  const JwtAuthzGuard = (0, jwt_authz_guard_1.createJwtAuthzGuard)([
105
- JWT_STRATEGY,
106
93
  AUTHZ_PROVIDER,
107
94
  JWT_AUTHZ_OPTIONS,
108
95
  ALS_PROVIDER,
@@ -136,12 +123,10 @@ const createJwtAuthzModule = (authzProvider) => {
136
123
  provide: ALS_PROVIDER,
137
124
  useValue: als
138
125
  },
139
- ...(!isStrategyInited ? [JwtStrategy, RefreshStrategy] : []),
140
126
  JwtAuthzService
141
127
  ],
142
128
  exports: [AUTHZ_PROVIDER, ALS_PROVIDER, JWT_AUTHZ_OPTIONS, JwtAuthzService]
143
129
  };
144
- isStrategyInited = true;
145
130
  return configs;
146
131
  };
147
132
  let JwtAuthzModule = class JwtAuthzModule extends ConfigurableModuleClass {
@@ -41,4 +41,4 @@ export declare const createJwtAuthzService: <P = unknown, U = unknown>([AUTHZ_PR
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">>;
@@ -6,7 +6,6 @@ export interface SessionAlsType<P, U> {
6
6
  user?: U;
7
7
  allowAnonymous?: boolean;
8
8
  guardResult?: boolean;
9
- authOptions: SessionAuthzOptions;
10
9
  logIn: (user: P) => Promise<void>;
11
10
  logOut: () => Promise<void>;
12
11
  setCookie: (name: string, value: string, options?: Record<string, any>) => void;
@@ -29,7 +29,6 @@ const createSessionAuthzAlsMiddleware = ([ALS_PROVIDER, SESSION_AUTHZ_OPTIONS])
29
29
  user: undefined,
30
30
  allowAnonymous: undefined,
31
31
  guardResult: undefined,
32
- authOptions: this.sessionAuthzOptions,
33
32
  // ref: https://github.com/jaredhanson/passport/blob/217018dbc46dcd4118dd6f2c60c8d97010c587f8/lib/sessionmanager.js#L14
34
33
  logIn: async (user) => {
35
34
  const prevSession = req.shims.getAllSession();
@@ -5,15 +5,11 @@ import { AuthzProviderClass } from '../authz.provider';
5
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">>;
@@ -15,24 +15,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.createSessionAuthzGuard = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
17
  const core_1 = require("@nestjs/core");
18
- const passport_1 = require("@nestjs/passport");
19
18
  const authz_provider_1 = require("../authz.provider");
19
+ const constants_1 = require("../constants");
20
20
  const errors_1 = require("../errors");
21
21
  const utils_1 = require("../utils");
22
- const createSessionAuthzGuard = ([SESSION_STRATEGY, AUTHZ_PROVIDER, SESSION_AUTHZ_OPTIONS, ALS_PROVIDER, SESSION_META_KEY]) => {
23
- let SessionAuthzGuard = class SessionAuthzGuard extends (0, passport_1.AuthGuard)(SESSION_STRATEGY) {
22
+ const createSessionAuthzGuard = ([AUTHZ_PROVIDER, SESSION_AUTHZ_OPTIONS, ALS_PROVIDER, SESSION_META_KEY]) => {
23
+ let SessionAuthzGuard = class SessionAuthzGuard {
24
24
  constructor(reflector, authzProvider, sessionAuthzOptions, als) {
25
- super();
26
25
  this.reflector = reflector;
27
26
  this.authzProvider = authzProvider;
28
27
  this.sessionAuthzOptions = sessionAuthzOptions;
29
28
  this.als = als;
30
- }
31
- getAuthenticateOptions() {
32
- return {
33
- property: this.sessionAuthzOptions.passportProperty,
34
- session: false
35
- };
29
+ if (typeof this.authzProvider.authenticate !== 'function') {
30
+ throw new errors_1.AuthzError(`InternalError: Method 'authenticate' from abstract class 'AuthzProvider' must be implemented.`);
31
+ }
36
32
  }
37
33
  /**
38
34
  *
@@ -76,7 +72,7 @@ const createSessionAuthzGuard = ([SESSION_STRATEGY, AUTHZ_PROVIDER, SESSION_AUTH
76
72
  store.allowAnonymous = (0, utils_1.getAllowAnonymous)(contextParamsList, {
77
73
  defaultAllowAnonymous: this.sessionAuthzOptions.defaultAllowAnonymous
78
74
  });
79
- await super.canActivate(context);
75
+ req[this.sessionAuthzOptions.passportProperty] = this.handleRequest(undefined, ...(await this.validate(req)));
80
76
  // will be null if allowAnonymous=true.
81
77
  const user = (0, utils_1.getPassportProperty)(req);
82
78
  if (store.allowAnonymous && !user) {
@@ -89,6 +85,32 @@ const createSessionAuthzGuard = ([SESSION_STRATEGY, AUTHZ_PROVIDER, SESSION_AUTH
89
85
  }
90
86
  return true;
91
87
  }
88
+ async validate(req) {
89
+ const store = (0, utils_1.getAlsStore)(this.als);
90
+ const authOptions = this.sessionAuthzOptions;
91
+ req[constants_1.PASSPORT_PROPERTY] = authOptions.passportProperty;
92
+ const payload = req?.session?.[constants_1.SESSION_PASSPORT_KEY]?.user;
93
+ if (!payload) {
94
+ return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find session.')];
95
+ }
96
+ let user = undefined;
97
+ try {
98
+ user = await this.authzProvider.authenticate(payload, req);
99
+ }
100
+ catch (error) {
101
+ return [
102
+ null,
103
+ error instanceof Error
104
+ ? new errors_1.AuthzVerificationError(`${error.name}: ${error.message}`, error)
105
+ : new errors_1.AuthzVerificationError(`${error}`)
106
+ ];
107
+ }
108
+ store.user = user;
109
+ if (!user) {
110
+ return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find user.')];
111
+ }
112
+ return [user];
113
+ }
92
114
  };
93
115
  SessionAuthzGuard = __decorate([
94
116
  __param(1, (0, common_1.Inject)(AUTHZ_PROVIDER)),
@@ -1,14 +1,16 @@
1
1
  import type { AuthzModuleBaseOptions } from '../utils';
2
- export type SessionAuthzModuleOptions = Partial<AuthzModuleBaseOptions> & {
2
+ export type ExtraSessionOptions = {
3
+ /**
4
+ * Option to keep session information after regenerating.
5
+ */
3
6
  session?: {
4
7
  /**
5
- * Option to keep session information after regenerating.
6
- *
7
8
  * Same as `passportjs` [keepSessionInfo](https://github.com/jaredhanson/passport/blob/217018dbc46dcd4118dd6f2c60c8d97010c587f8/CHANGELOG.md#L18).
8
9
  */
9
10
  keepSessionInfo?: boolean;
10
11
  };
11
12
  };
13
+ export type SessionAuthzModuleOptions = Partial<AuthzModuleBaseOptions> & ExtraSessionOptions;
12
14
  export declare const normalizedSessionAuthzModuleOptions: (options?: Partial<SessionAuthzModuleOptions>) => {
13
15
  defaultOverride: boolean;
14
16
  passportProperty: string;
@@ -8,11 +8,7 @@ import { type SessionAuthzModuleOptions, type SessionAuthzOptions } from './sess
8
8
  import { type SessionAlsType } from './session-authz-als.middleware';
9
9
  declare const ASYNC_OPTIONS_TYPE: ConfigurableModuleAsyncOptions<SessionAuthzModuleOptions, "createSessionAuthzModuleOptions"> & Partial<{
10
10
  authzProvider?: Type<AuthzProviderClass<unknown, unknown>>;
11
- } & AuthzModuleRoutesOptions>, OPTIONS_TYPE: Partial<AuthzModuleBaseOptions> & {
12
- session?: {
13
- keepSessionInfo?: boolean;
14
- };
15
- } & Partial<{
11
+ } & AuthzModuleRoutesOptions>, OPTIONS_TYPE: Partial<AuthzModuleBaseOptions> & import("./session-authz.interface").ExtraSessionOptions & Partial<{
16
12
  authzProvider?: Type<AuthzProviderClass<unknown, unknown>>;
17
13
  } & AuthzModuleRoutesOptions>;
18
14
  /**
@@ -93,16 +89,9 @@ export declare const cereateSessionAuthzModule: <P, U, T extends AuthzProviderCl
93
89
  readonly authzProvider: AuthzProviderClass<unknown, unknown>;
94
90
  readonly sessionAuthzOptions: SessionAuthzOptions;
95
91
  readonly als: AsyncLocalStorage<SessionAlsType<unknown, unknown>>;
96
- getAuthenticateOptions(): {
97
- property: string;
98
- session: boolean;
99
- };
100
92
  handleRequest<T_1>(_err: unknown, user: T_1, info?: AuthzError): T_1;
101
93
  canActivate(context: ExecutionContext): Promise<boolean>;
102
- logIn<TRequest extends {
103
- logIn: Function;
104
- } = any>(request: TRequest): Promise<void>;
105
- getRequest(context: ExecutionContext): any;
94
+ validate(req: any): Promise<[any, any?]>;
106
95
  }, "als" | "reflector" | "authzProvider" | "sessionAuthzOptions">> & {
107
96
  /**
108
97
  * Verifies the user's authorization for specific meta data.
@@ -22,7 +22,6 @@ const utils_1 = require("../utils");
22
22
  const session_authz_guard_1 = require("./session-authz.guard");
23
23
  const session_authz_interface_1 = require("./session-authz.interface");
24
24
  const session_authz_service_1 = require("./session-authz.service");
25
- const session_authz_strategy_1 = require("./session-authz.strategy");
26
25
  const session_authz_als_middleware_1 = require("./session-authz-als.middleware");
27
26
  const store = {
28
27
  globalInited: 0
@@ -76,28 +75,18 @@ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, ASYNC_OPTIONS_TYPE, OPTIO
76
75
  */
77
76
  const cereateSessionAuthzModule = (authzProvider) => {
78
77
  const id = `${constants_1.PREFIX}${(0, uid_1.uid)()}`;
79
- // strategy tokens
80
- const SESSION_STRATEGY = `${id}_SESSION_STRATEGY`;
81
78
  // provider tokens
82
79
  const AUTHZ_PROVIDER = `${id}_AUTHZ_PROVIDER`;
83
80
  const ALS_PROVIDER = `${id}_ALS_PROVIDER`;
84
81
  const SESSION_AUTHZ_OPTIONS = `${id}_SESSION_AUTHZ_OPTIONS`;
85
82
  // meta keys
86
83
  const SESSION_META_KEY = `${id}_SESSION_META_KEY`;
87
- // strategies
88
- const SessionAuthzStrategy = (0, session_authz_strategy_1.createSessionAuthzStrategy)([SESSION_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]);
89
84
  // providers
90
85
  const SessionAuthzService = (0, session_authz_service_1.createSessionAuthzService)([AUTHZ_PROVIDER, ALS_PROVIDER]);
91
86
  const SessionAuthzAlsMiddleware = (0, session_authz_als_middleware_1.createSessionAuthzAlsMiddleware)([ALS_PROVIDER, SESSION_AUTHZ_OPTIONS]);
92
87
  const als = new node_async_hooks_1.AsyncLocalStorage();
93
- // each strategy can be only registered once in passport.
94
- // no need to provide multiple times as
95
- // 1. they use the same ALS and authzProvider instance.
96
- // 2. guard use strategy through passport via strategy name.
97
- let isStrategyInited = false;
98
88
  // guards
99
89
  const SessionAuthzGuard = (0, session_authz_guard_1.createSessionAuthzGuard)([
100
- SESSION_STRATEGY,
101
90
  AUTHZ_PROVIDER,
102
91
  SESSION_AUTHZ_OPTIONS,
103
92
  ALS_PROVIDER,
@@ -126,12 +115,10 @@ const cereateSessionAuthzModule = (authzProvider) => {
126
115
  provide: ALS_PROVIDER,
127
116
  useValue: als
128
117
  },
129
- ...(!isStrategyInited ? [SessionAuthzStrategy] : []),
130
118
  SessionAuthzService
131
119
  ],
132
120
  exports: [AUTHZ_PROVIDER, ALS_PROVIDER, SESSION_AUTHZ_OPTIONS, SessionAuthzService]
133
121
  };
134
- isStrategyInited = true;
135
122
  return configs;
136
123
  };
137
124
  let SessionAuthzModule = class SessionAuthzModule extends ConfigurableModuleClass {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@nestjs-kitchen/authz",
3
3
  "private": false,
4
4
  "description": "Simplest authentication & authorization module in NextJS",
5
- "version": "3.1.0",
5
+ "version": "4.0.1",
6
6
  "homepage": "https://github.com/yikenman/nestjs-kitchen",
7
7
  "repository": "https://github.com/yikenman/nestjs-kitchen",
8
8
  "author": "yikenman",
@@ -22,7 +22,6 @@
22
22
  "cookie-parser": "^1.4.7",
23
23
  "jsonwebtoken": "^9.0.2",
24
24
  "msgpackr": "^1.11.2",
25
- "passport-custom": "^1.1.1",
26
25
  "uid": "^2.0.2"
27
26
  },
28
27
  "devDependencies": {
@@ -36,9 +35,7 @@
36
35
  "@types/express": "^5.0.1",
37
36
  "@types/express-session": "^1.18.2",
38
37
  "@types/jest": "^30.0.0",
39
- "@types/jsonwebtoken": "^9.0.9",
40
38
  "@types/node": "^22.13.9",
41
- "@types/passport": "^1.0.17",
42
39
  "@types/supertest": "^6.0.2",
43
40
  "express-session": "^1.18.2",
44
41
  "fastify": "^5.5.0",
@@ -65,27 +62,20 @@
65
62
  "JWT",
66
63
  "NextJS",
67
64
  "NodeJS",
68
- "passport",
69
- "Passport",
70
65
  "Session"
71
66
  ],
72
- "optionalDependencies": {
73
- "@fastify/cookie": "^11.0.2",
74
- "@fastify/secure-session": "^8.2.0",
75
- "@fastify/session": "^11.1.0",
76
- "@nestjs/platform-express": "^11.0.0",
77
- "@nestjs/platform-fastify": "^11.0.0",
78
- "@types/express-session": "^1.18.2",
79
- "express-session": "^1.18.2"
80
- },
81
67
  "peerDependencies": {
82
68
  "@nestjs/common": "^11.0.0",
83
69
  "@nestjs/core": "^11.0.0",
84
- "@nestjs/passport": "^11.0.0",
85
- "passport": "^0.7.0",
70
+ "@types/jsonwebtoken": "^9.0.9",
86
71
  "reflect-metadata": "^0.2.2",
87
72
  "rxjs": "^7.8.2"
88
73
  },
74
+ "peerDependenciesMeta": {
75
+ "@types/jsonwebtoken": {
76
+ "optional": true
77
+ }
78
+ },
89
79
  "scripts": {
90
80
  "build": "rimraf dist && tsc -p tsconfig.build.json",
91
81
  "dev": "rimraf dist && tsc -p tsconfig.build.json --watch",
@@ -1,16 +0,0 @@
1
- import { AsyncLocalStorage } from 'node:async_hooks';
2
- import { type Type } from '@nestjs/common';
3
- import { AuthzProviderClass } from '../authz.provider';
4
- import type { JwtAlsType } from './jwt-authz-als.middleware';
5
- export declare const createJwtStrategy: ([JWT_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]: [string, any, any]) => Type<Omit<{
6
- readonly authzProvider: AuthzProviderClass<unknown, unknown>;
7
- readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
8
- validate(req: any): Promise<{}>;
9
- authenticate(req: import("express").Request, options?: any): any;
10
- }, "als" | "authzProvider">>;
11
- export declare const createRefreshStrategy: ([JWT_REFRESH_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]: [string, any, any]) => Type<Omit<{
12
- readonly authzProvider: AuthzProviderClass<unknown, unknown>;
13
- readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
14
- validate(req: any): Promise<{}>;
15
- authenticate(req: import("express").Request, options?: any): any;
16
- }, "als" | "authzProvider">>;
@@ -1,134 +0,0 @@
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
- var __importDefault = (this && this.__importDefault) || function (mod) {
15
- return (mod && mod.__esModule) ? mod : { "default": mod };
16
- };
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.createRefreshStrategy = exports.createJwtStrategy = void 0;
19
- const node_async_hooks_1 = require("node:async_hooks");
20
- const common_1 = require("@nestjs/common");
21
- const passport_1 = require("@nestjs/passport");
22
- const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
23
- const passport_custom_1 = require("passport-custom");
24
- const authz_provider_1 = require("../authz.provider");
25
- const constants_1 = require("../constants");
26
- const errors_1 = require("../errors");
27
- const utils_1 = require("../utils");
28
- const extract_jwt_1 = require("./extract-jwt");
29
- const createJwtStrategy = ([JWT_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]) => {
30
- let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(passport_custom_1.Strategy, JWT_STRATEGY) {
31
- constructor(authzProvider, als) {
32
- super();
33
- this.authzProvider = authzProvider;
34
- this.als = als;
35
- if (typeof this.authzProvider.authenticate !== 'function') {
36
- throw new errors_1.AuthzError(`InternalError: Method 'authenticate' from abstract class 'AuthzProvider' must be implemented.`);
37
- }
38
- }
39
- async validate(req) {
40
- const store = (0, utils_1.getAlsStore)(this.als);
41
- const authOptions = store.authOptions;
42
- if (!authOptions.jwt.verify) {
43
- return [null, new errors_1.AuthzError(`InternalError: Refresh verify options must be implemented.`)];
44
- }
45
- const extractor = extract_jwt_1.ExtractJwt.fromExtractors(authOptions.jwt.jwtFromRequest);
46
- req[constants_1.PASSPORT_PROPERTY] = authOptions.passportProperty;
47
- const token = extractor(req);
48
- if (!token) {
49
- return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find token.')];
50
- }
51
- let user = undefined;
52
- try {
53
- const payload = jsonwebtoken_1.default.verify(token, authOptions.jwt.secretOrPublicKey, authOptions.jwt.verify);
54
- user = await this.authzProvider.authenticate(payload, req);
55
- }
56
- catch (error) {
57
- return [
58
- null,
59
- error instanceof Error
60
- ? new errors_1.AuthzVerificationError(`${error.name}: ${error.message}`, error)
61
- : new errors_1.AuthzVerificationError(`${error}`)
62
- ];
63
- }
64
- store.user = user;
65
- store.jwtVerifiedBy = constants_1.JwtValidationType.JWT;
66
- if (!user) {
67
- return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find user.')];
68
- }
69
- return user;
70
- }
71
- };
72
- JwtStrategy = __decorate([
73
- __param(0, (0, common_1.Inject)(AUTHZ_PROVIDER)),
74
- __param(1, (0, common_1.Inject)(ALS_PROVIDER)),
75
- __metadata("design:paramtypes", [authz_provider_1.AuthzProviderClass,
76
- node_async_hooks_1.AsyncLocalStorage])
77
- ], JwtStrategy);
78
- return (0, common_1.mixin)(JwtStrategy);
79
- };
80
- exports.createJwtStrategy = createJwtStrategy;
81
- const createRefreshStrategy = ([JWT_REFRESH_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]) => {
82
- let RefreshStrategy = class RefreshStrategy extends (0, passport_1.PassportStrategy)(passport_custom_1.Strategy, JWT_REFRESH_STRATEGY) {
83
- constructor(authzProvider, als) {
84
- super();
85
- this.authzProvider = authzProvider;
86
- this.als = als;
87
- if (typeof this.authzProvider.authenticate !== 'function') {
88
- throw new errors_1.AuthzError(`InternalError: Method 'authenticate' from abstract class 'AuthzProvider' must be implemented.`);
89
- }
90
- }
91
- async validate(req) {
92
- const store = (0, utils_1.getAlsStore)(this.als);
93
- const authOptions = store.authOptions;
94
- if (!authOptions.refresh.verify) {
95
- return [null, new errors_1.AuthzError(`InternalError: Refresh verify options must be implemented.`)];
96
- }
97
- const extractor = extract_jwt_1.ExtractJwt.fromExtractors(authOptions.refresh.jwtFromRequest);
98
- req[constants_1.PASSPORT_PROPERTY] = authOptions.passportProperty;
99
- const token = extractor(req);
100
- if (!token) {
101
- return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find token.')];
102
- }
103
- let user = undefined;
104
- try {
105
- const payload = jsonwebtoken_1.default.verify(token, authOptions.refresh.secretOrPublicKey, authOptions.refresh.verify);
106
- const decodePayload = (0, utils_1.decodeMsgpackrString)(payload.data);
107
- user = await this.authzProvider.authenticate(decodePayload, req);
108
- }
109
- catch (error) {
110
- return [
111
- null,
112
- error instanceof Error
113
- ? new errors_1.AuthzVerificationError(`${error.name}: ${error.message}`, error)
114
- : new errors_1.AuthzVerificationError(`${error}`)
115
- ];
116
- }
117
- store.user = user;
118
- store.jwtVerifiedBy = constants_1.JwtValidationType.REFRESH;
119
- if (!user) {
120
- return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find user.')];
121
- }
122
- return user;
123
- }
124
- };
125
- RefreshStrategy = __decorate([
126
- (0, common_1.Injectable)(),
127
- __param(0, (0, common_1.Inject)(AUTHZ_PROVIDER)),
128
- __param(1, (0, common_1.Inject)(ALS_PROVIDER)),
129
- __metadata("design:paramtypes", [authz_provider_1.AuthzProviderClass,
130
- node_async_hooks_1.AsyncLocalStorage])
131
- ], RefreshStrategy);
132
- return (0, common_1.mixin)(RefreshStrategy);
133
- };
134
- exports.createRefreshStrategy = createRefreshStrategy;
@@ -1,10 +0,0 @@
1
- import { AsyncLocalStorage } from 'node:async_hooks';
2
- import { type Type } from '@nestjs/common';
3
- import { AuthzProviderClass } from '../authz.provider';
4
- import type { SessionAlsType } from './session-authz-als.middleware';
5
- export declare const createSessionAuthzStrategy: ([SESSION_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]: [string, any, any]) => Type<Omit<{
6
- readonly authzProvider: AuthzProviderClass<unknown, unknown>;
7
- readonly als: AsyncLocalStorage<SessionAlsType<unknown, unknown>>;
8
- validate(req: any): Promise<{}>;
9
- authenticate(req: import("express").Request, options?: any): any;
10
- }, "als" | "authzProvider">>;
@@ -1,70 +0,0 @@
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.createSessionAuthzStrategy = void 0;
16
- const node_async_hooks_1 = require("node:async_hooks");
17
- const common_1 = require("@nestjs/common");
18
- const passport_1 = require("@nestjs/passport");
19
- const passport_custom_1 = require("passport-custom");
20
- const authz_provider_1 = require("../authz.provider");
21
- const constants_1 = require("../constants");
22
- const errors_1 = require("../errors");
23
- const utils_1 = require("../utils");
24
- const createSessionAuthzStrategy = ([SESSION_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]) => {
25
- let SessionAuthzStrategy = class SessionAuthzStrategy extends (0, passport_1.PassportStrategy)(passport_custom_1.Strategy, SESSION_STRATEGY) {
26
- constructor(authzProvider, als) {
27
- super();
28
- this.authzProvider = authzProvider;
29
- this.als = als;
30
- if (typeof this.authzProvider.authenticate !== 'function') {
31
- throw new errors_1.AuthzError(`InternalError: Method 'authenticate' from abstract class 'AuthzProvider' must be implemented.`);
32
- }
33
- }
34
- async validate(req) {
35
- const store = (0, utils_1.getAlsStore)(this.als);
36
- const authOptions = store.authOptions;
37
- // @ts-ignore
38
- req[constants_1.PASSPORT_PROPERTY] = authOptions.passportProperty;
39
- const payload = req?.session?.[constants_1.SESSION_PASSPORT_KEY]?.user;
40
- if (!payload) {
41
- return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find session.')];
42
- }
43
- let user = undefined;
44
- try {
45
- user = await this.authzProvider.authenticate(payload, req);
46
- }
47
- catch (error) {
48
- return [
49
- null,
50
- error instanceof Error
51
- ? new errors_1.AuthzVerificationError(`${error.name}: ${error.message}`, error)
52
- : new errors_1.AuthzVerificationError(`${error}`)
53
- ];
54
- }
55
- store.user = user;
56
- if (!user) {
57
- return [null, new errors_1.AuthzAnonymousError('AnonymousError: Cannnot find user.')];
58
- }
59
- return user;
60
- }
61
- };
62
- SessionAuthzStrategy = __decorate([
63
- __param(0, (0, common_1.Inject)(AUTHZ_PROVIDER)),
64
- __param(1, (0, common_1.Inject)(ALS_PROVIDER)),
65
- __metadata("design:paramtypes", [authz_provider_1.AuthzProviderClass,
66
- node_async_hooks_1.AsyncLocalStorage])
67
- ], SessionAuthzStrategy);
68
- return (0, common_1.mixin)(SessionAuthzStrategy);
69
- };
70
- exports.createSessionAuthzStrategy = createSessionAuthzStrategy;