@nestjs-kitchen/authz 3.1.0 → 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.
- package/README.md +10 -8
- package/dist/jwt/jwt-authz-als.middleware.d.ts +2 -5
- package/dist/jwt/jwt-authz-als.middleware.js +3 -7
- package/dist/jwt/jwt-authz.guard.d.ts +10 -23
- package/dist/jwt/jwt-authz.guard.js +93 -22
- package/dist/jwt/jwt-authz.module.d.ts +3 -10
- package/dist/jwt/jwt-authz.module.js +2 -17
- package/dist/jwt/jwt-authz.service.d.ts +1 -1
- package/dist/session/session-authz-als.middleware.d.ts +0 -1
- package/dist/session/session-authz-als.middleware.js +0 -1
- package/dist/session/session-authz.guard.d.ts +2 -9
- package/dist/session/session-authz.guard.js +33 -11
- package/dist/session/session-authz.module.d.ts +1 -8
- package/dist/session/session-authz.module.js +0 -13
- package/package.json +1 -7
- package/dist/jwt/jwt-authz.strategy.d.ts +0 -16
- package/dist/jwt/jwt-authz.strategy.js +0 -134
- package/dist/session/session-authz.strategy.d.ts +0 -10
- package/dist/session/session-authz.strategy.js +0 -70
package/README.md
CHANGED
|
@@ -16,27 +16,27 @@ Simplest authentication & authorization module in NextJS.
|
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
|
-
- ✅ JWT
|
|
19
|
+
- ✅ Support JWT authentication
|
|
20
20
|
|
|
21
|
-
- ✅
|
|
21
|
+
- ✅ Support session authentication
|
|
22
22
|
|
|
23
|
-
- ✅
|
|
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
|
|
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
|
|
34
|
+
$ npm install --save @nestjs-kitchen/authz
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
## Platform
|
|
37
|
+
## Platform support
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Below platforms require different dependencies:
|
|
40
40
|
|
|
41
41
|
- For `@nestjs/platform-express`:
|
|
42
42
|
|
|
@@ -50,7 +50,9 @@ Different platforms require different dependencies:
|
|
|
50
50
|
|
|
51
51
|
## Beark change
|
|
52
52
|
|
|
53
|
-
- From
|
|
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:
|
|
54
56
|
|
|
55
57
|
```typescript
|
|
56
58
|
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
|
|
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"
|
|
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
|
|
19
|
+
const createJwtAuthzAlsMiddleware = ([ALS_PROVIDER]) => {
|
|
20
20
|
let JwtAuthzAlsMiddleware = class JwtAuthzAlsMiddleware {
|
|
21
|
-
constructor(als
|
|
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
|
-
|
|
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 {
|
|
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: ([
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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):
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
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
|
|
23
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
|
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 = ([
|
|
110
|
-
let JwtRefreshAuthzGuard = class JwtRefreshAuthzGuard
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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
|
-
|
|
107
|
-
|
|
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" | "
|
|
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
|
|
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)([
|
|
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" | "
|
|
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: ([
|
|
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
|
-
|
|
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 = ([
|
|
23
|
-
let SessionAuthzGuard = class SessionAuthzGuard
|
|
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
|
-
|
|
32
|
-
|
|
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
|
|
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)),
|
|
@@ -93,16 +93,9 @@ export declare const cereateSessionAuthzModule: <P, U, T extends AuthzProviderCl
|
|
|
93
93
|
readonly authzProvider: AuthzProviderClass<unknown, unknown>;
|
|
94
94
|
readonly sessionAuthzOptions: SessionAuthzOptions;
|
|
95
95
|
readonly als: AsyncLocalStorage<SessionAlsType<unknown, unknown>>;
|
|
96
|
-
getAuthenticateOptions(): {
|
|
97
|
-
property: string;
|
|
98
|
-
session: boolean;
|
|
99
|
-
};
|
|
100
96
|
handleRequest<T_1>(_err: unknown, user: T_1, info?: AuthzError): T_1;
|
|
101
97
|
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
102
|
-
|
|
103
|
-
logIn: Function;
|
|
104
|
-
} = any>(request: TRequest): Promise<void>;
|
|
105
|
-
getRequest(context: ExecutionContext): any;
|
|
98
|
+
validate(req: any): Promise<[any, any?]>;
|
|
106
99
|
}, "als" | "reflector" | "authzProvider" | "sessionAuthzOptions">> & {
|
|
107
100
|
/**
|
|
108
101
|
* 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": "
|
|
5
|
+
"version": "4.0.0",
|
|
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": {
|
|
@@ -38,7 +37,6 @@
|
|
|
38
37
|
"@types/jest": "^30.0.0",
|
|
39
38
|
"@types/jsonwebtoken": "^9.0.9",
|
|
40
39
|
"@types/node": "^22.13.9",
|
|
41
|
-
"@types/passport": "^1.0.17",
|
|
42
40
|
"@types/supertest": "^6.0.2",
|
|
43
41
|
"express-session": "^1.18.2",
|
|
44
42
|
"fastify": "^5.5.0",
|
|
@@ -65,8 +63,6 @@
|
|
|
65
63
|
"JWT",
|
|
66
64
|
"NextJS",
|
|
67
65
|
"NodeJS",
|
|
68
|
-
"passport",
|
|
69
|
-
"Passport",
|
|
70
66
|
"Session"
|
|
71
67
|
],
|
|
72
68
|
"optionalDependencies": {
|
|
@@ -81,8 +77,6 @@
|
|
|
81
77
|
"peerDependencies": {
|
|
82
78
|
"@nestjs/common": "^11.0.0",
|
|
83
79
|
"@nestjs/core": "^11.0.0",
|
|
84
|
-
"@nestjs/passport": "^11.0.0",
|
|
85
|
-
"passport": "^0.7.0",
|
|
86
80
|
"reflect-metadata": "^0.2.2",
|
|
87
81
|
"rxjs": "^7.8.2"
|
|
88
82
|
},
|
|
@@ -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;
|