@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.
- package/README.md +27 -8
- package/dist/authz.provider.d.ts +1 -2
- package/dist/jwt/jwt-authz-als.middleware.d.ts +5 -9
- package/dist/jwt/jwt-authz-als.middleware.js +6 -9
- 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 +6 -13
- package/dist/jwt/jwt-authz.module.js +3 -17
- package/dist/jwt/jwt-authz.service.d.ts +3 -3
- package/dist/session/session-authz-als.middleware.d.ts +3 -5
- package/dist/session/session-authz-als.middleware.js +29 -50
- package/dist/session/session-authz.guard.d.ts +3 -10
- package/dist/session/session-authz.guard.js +33 -11
- package/dist/session/session-authz.module.d.ts +4 -11
- package/dist/session/session-authz.module.js +1 -13
- package/dist/session/session-authz.service.d.ts +2 -2
- package/dist/utils/adapter-shim.d.ts +28 -0
- package/dist/utils/adapter-shim.js +174 -0
- package/dist/utils/cookie-parsers.d.ts +6 -7
- package/dist/utils/cookie-parsers.js +10 -0
- package/dist/utils/create-set-cookie-fn.d.ts +2 -3
- package/dist/utils/create-set-cookie-fn.js +2 -1
- package/dist/utils/generics.d.ts +0 -1
- package/dist/utils/generics.js +1 -12
- package/dist/utils/get-passport-property.d.ts +1 -1
- package/dist/utils/get-passport-property.js +0 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/safe-clone.d.ts +1 -0
- package/dist/utils/safe-clone.js +15 -0
- package/dist/utils/types.d.ts +0 -7
- package/package.json +24 -10
- package/dist/jwt/jwt-authz.strategy.d.ts +0 -17
- package/dist/jwt/jwt-authz.strategy.js +0 -134
- package/dist/session/session-authz.strategy.d.ts +0 -11
- package/dist/session/session-authz.strategy.js +0 -70
|
@@ -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)),
|
|
@@ -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
|
|
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
|
|
6
|
+
import { type AbstractConstructor, type ApplyDecorators, type AuthzDecoParams, type AuthzModuleBaseOptions, type AuthzModuleRoutesOptions, type DeepReadonly, type MethodParameters, type RoutesOptions } from '../utils';
|
|
7
7
|
import { type SessionAuthzModuleOptions, type SessionAuthzOptions } from './session-authz.interface';
|
|
8
8
|
import { type SessionAlsType } from './session-authz-als.middleware';
|
|
9
9
|
declare const ASYNC_OPTIONS_TYPE: ConfigurableModuleAsyncOptions<SessionAuthzModuleOptions, "createSessionAuthzModuleOptions"> & Partial<{
|
|
@@ -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.
|
|
@@ -166,7 +159,7 @@ export declare const cereateSessionAuthzModule: <P, U, T extends AuthzProviderCl
|
|
|
166
159
|
readonly als: AsyncLocalStorage<SessionAlsType<P, U>>;
|
|
167
160
|
logIn(user: U): Promise<void>;
|
|
168
161
|
logOut(): Promise<void>;
|
|
169
|
-
setCookie(name: string, value: string, options?:
|
|
162
|
+
setCookie(name: string, value: string, options?: Record<string, any> | undefined): void;
|
|
170
163
|
getUser(): DeepReadonly<U> | undefined;
|
|
171
164
|
}, "als" | "authzProvider">>;
|
|
172
165
|
};
|
|
@@ -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
|
|
@@ -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: {
|
|
@@ -75,28 +75,18 @@ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, ASYNC_OPTIONS_TYPE, OPTIO
|
|
|
75
75
|
*/
|
|
76
76
|
const cereateSessionAuthzModule = (authzProvider) => {
|
|
77
77
|
const id = `${constants_1.PREFIX}${(0, uid_1.uid)()}`;
|
|
78
|
-
// strategy tokens
|
|
79
|
-
const SESSION_STRATEGY = `${id}_SESSION_STRATEGY`;
|
|
80
78
|
// provider tokens
|
|
81
79
|
const AUTHZ_PROVIDER = `${id}_AUTHZ_PROVIDER`;
|
|
82
80
|
const ALS_PROVIDER = `${id}_ALS_PROVIDER`;
|
|
83
81
|
const SESSION_AUTHZ_OPTIONS = `${id}_SESSION_AUTHZ_OPTIONS`;
|
|
84
82
|
// meta keys
|
|
85
83
|
const SESSION_META_KEY = `${id}_SESSION_META_KEY`;
|
|
86
|
-
// strategies
|
|
87
|
-
const SessionAuthzStrategy = (0, session_authz_strategy_1.createSessionAuthzStrategy)([SESSION_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]);
|
|
88
84
|
// providers
|
|
89
85
|
const SessionAuthzService = (0, session_authz_service_1.createSessionAuthzService)([AUTHZ_PROVIDER, ALS_PROVIDER]);
|
|
90
86
|
const SessionAuthzAlsMiddleware = (0, session_authz_als_middleware_1.createSessionAuthzAlsMiddleware)([ALS_PROVIDER, SESSION_AUTHZ_OPTIONS]);
|
|
91
87
|
const als = new node_async_hooks_1.AsyncLocalStorage();
|
|
92
|
-
// each strategy can be only registered once in passport.
|
|
93
|
-
// no need to provide multiple times as
|
|
94
|
-
// 1. they use the same ALS and authzProvider instance.
|
|
95
|
-
// 2. guard use strategy through passport via strategy name.
|
|
96
|
-
let isStrategyInited = false;
|
|
97
88
|
// guards
|
|
98
89
|
const SessionAuthzGuard = (0, session_authz_guard_1.createSessionAuthzGuard)([
|
|
99
|
-
SESSION_STRATEGY,
|
|
100
90
|
AUTHZ_PROVIDER,
|
|
101
91
|
SESSION_AUTHZ_OPTIONS,
|
|
102
92
|
ALS_PROVIDER,
|
|
@@ -125,12 +115,10 @@ const cereateSessionAuthzModule = (authzProvider) => {
|
|
|
125
115
|
provide: ALS_PROVIDER,
|
|
126
116
|
useValue: als
|
|
127
117
|
},
|
|
128
|
-
...(!isStrategyInited ? [SessionAuthzStrategy] : []),
|
|
129
118
|
SessionAuthzService
|
|
130
119
|
],
|
|
131
120
|
exports: [AUTHZ_PROVIDER, ALS_PROVIDER, SESSION_AUTHZ_OPTIONS, SessionAuthzService]
|
|
132
121
|
};
|
|
133
|
-
isStrategyInited = true;
|
|
134
122
|
return configs;
|
|
135
123
|
};
|
|
136
124
|
let SessionAuthzModule = class SessionAuthzModule 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
|
|
4
|
+
import { type DeepReadonly } from '../utils';
|
|
5
5
|
import type { SessionAlsType } from './session-authz-als.middleware';
|
|
6
6
|
export declare const createSessionAuthzService: <P = unknown, U = unknown>([AUTHZ_PROVIDER, ALS_PROVIDER]: [any, any]) => Type<Omit<{
|
|
7
7
|
readonly authzProvider: AuthzProviderClass<P, U>;
|
|
@@ -19,7 +19,7 @@ export declare const createSessionAuthzService: <P = unknown, U = unknown>([AUTH
|
|
|
19
19
|
/**
|
|
20
20
|
* Sets a secure HTTP cookie with the given name, value, and optional cookie options.
|
|
21
21
|
*/
|
|
22
|
-
setCookie(name: string, value: string, options?:
|
|
22
|
+
setCookie(name: string, value: string, options?: Record<string, any> | undefined): void;
|
|
23
23
|
/**
|
|
24
24
|
* Retrieves the current user associated with the request, if available.
|
|
25
25
|
*/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CanActivate, ExecutionContext, type OnModuleInit, type Provider } from '@nestjs/common';
|
|
2
|
+
import { HttpAdapterHost } from '@nestjs/core';
|
|
3
|
+
export type RawRequestWithShims = {
|
|
4
|
+
shims: {
|
|
5
|
+
getSession(key?: string): any;
|
|
6
|
+
getAllSession(): any;
|
|
7
|
+
setSession(key: string, value: any): void;
|
|
8
|
+
deleteSession(key: string): void;
|
|
9
|
+
sessionContains(key: string): boolean;
|
|
10
|
+
regenerateSession(): Promise<void>;
|
|
11
|
+
saveSession(): Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
};
|
|
15
|
+
export type RawResponseWithShims = {
|
|
16
|
+
shims: {
|
|
17
|
+
setCookie(key: string, value: string, options?: Record<string, any>): void;
|
|
18
|
+
};
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
};
|
|
21
|
+
export declare class AdapterShim implements CanActivate, OnModuleInit {
|
|
22
|
+
private httpAdapterHost;
|
|
23
|
+
private addShims;
|
|
24
|
+
constructor(httpAdapterHost: HttpAdapterHost);
|
|
25
|
+
onModuleInit(): void;
|
|
26
|
+
canActivate(context: ExecutionContext): boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare const createOnceAdapterShimProvider: () => Provider[];
|
|
@@ -0,0 +1,174 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createOnceAdapterShimProvider = exports.AdapterShim = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const core_1 = require("@nestjs/core");
|
|
15
|
+
const errors_1 = require("../errors");
|
|
16
|
+
const safe_clone_1 = require("./safe-clone");
|
|
17
|
+
const addExpressShims = (req, res) => {
|
|
18
|
+
const reqShims = {
|
|
19
|
+
getSession(key) {
|
|
20
|
+
return req.session?.[key];
|
|
21
|
+
},
|
|
22
|
+
getAllSession() {
|
|
23
|
+
return (0, safe_clone_1.safeClone)(req.session);
|
|
24
|
+
},
|
|
25
|
+
setSession(key, value) {
|
|
26
|
+
req.session[key] = value;
|
|
27
|
+
},
|
|
28
|
+
deleteSession(key) {
|
|
29
|
+
delete req.session?.[key];
|
|
30
|
+
},
|
|
31
|
+
sessionContains(key) {
|
|
32
|
+
if (!req.session) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return key in req.session;
|
|
36
|
+
},
|
|
37
|
+
async regenerateSession() {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
req.session.regenerate((err) => {
|
|
40
|
+
if (err)
|
|
41
|
+
return reject(err);
|
|
42
|
+
resolve();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
async saveSession() {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
req.session.save((err) => {
|
|
49
|
+
if (err)
|
|
50
|
+
return reject(err);
|
|
51
|
+
resolve();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const resShims = {
|
|
57
|
+
setCookie(key, value, options) {
|
|
58
|
+
res.cookie(key, value, options);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
req.shims = reqShims;
|
|
62
|
+
res.shims = resShims;
|
|
63
|
+
};
|
|
64
|
+
const addFastifyShims = (req, res) => {
|
|
65
|
+
const reqShims = {
|
|
66
|
+
getSession(key) {
|
|
67
|
+
return req.session.get(key);
|
|
68
|
+
},
|
|
69
|
+
getAllSession() {
|
|
70
|
+
const cloned = (0, safe_clone_1.safeClone)(req.session);
|
|
71
|
+
// exclude cookie in @fastify/session
|
|
72
|
+
if (req.session?.cookie?.constructor?.name === 'Cookie') {
|
|
73
|
+
delete cloned.cookie;
|
|
74
|
+
}
|
|
75
|
+
// exclude built-in props in @fastify/secure-session
|
|
76
|
+
if (req.session?.constructor?.name === 'Session') {
|
|
77
|
+
delete cloned.changed;
|
|
78
|
+
delete cloned.deleted;
|
|
79
|
+
}
|
|
80
|
+
return cloned;
|
|
81
|
+
},
|
|
82
|
+
setSession(key, value) {
|
|
83
|
+
req.session.set(key, value);
|
|
84
|
+
},
|
|
85
|
+
deleteSession(key) {
|
|
86
|
+
req.session[key] = undefined;
|
|
87
|
+
},
|
|
88
|
+
sessionContains(key) {
|
|
89
|
+
if (!req.session) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
// fastify-session
|
|
93
|
+
if (key in req.session) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
// fastify-secure-session
|
|
97
|
+
return req.session.get(key) !== undefined;
|
|
98
|
+
},
|
|
99
|
+
async regenerateSession() {
|
|
100
|
+
if (typeof req.session.save === 'function') {
|
|
101
|
+
// fastify-session
|
|
102
|
+
return req.session.regenerate();
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// fastify-secure-session
|
|
106
|
+
try {
|
|
107
|
+
req.session.regenerate();
|
|
108
|
+
return Promise.resolve();
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
return Promise.reject(err);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
async saveSession() {
|
|
116
|
+
if (typeof req.session.save === 'function') {
|
|
117
|
+
// fastify-session
|
|
118
|
+
return req.session.save();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// fastify-secure-session does not have save method
|
|
122
|
+
return Promise.resolve();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const resShims = {
|
|
127
|
+
setCookie(key, value, options) {
|
|
128
|
+
res.setCookie(key, value, options);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
req.raw.shims = reqShims;
|
|
132
|
+
res.raw.shims = resShims;
|
|
133
|
+
};
|
|
134
|
+
const getShimsFactory = (adapter) => {
|
|
135
|
+
switch (adapter) {
|
|
136
|
+
case 'ExpressAdapter':
|
|
137
|
+
return addExpressShims;
|
|
138
|
+
case 'FastifyAdapter':
|
|
139
|
+
return addFastifyShims;
|
|
140
|
+
}
|
|
141
|
+
throw new errors_1.AuthzError(`Cannot find shims factory for adapter "${adapter}".`);
|
|
142
|
+
};
|
|
143
|
+
let AdapterShim = class AdapterShim {
|
|
144
|
+
constructor(httpAdapterHost) {
|
|
145
|
+
this.httpAdapterHost = httpAdapterHost;
|
|
146
|
+
}
|
|
147
|
+
onModuleInit() {
|
|
148
|
+
const adapter = this.httpAdapterHost?.httpAdapter?.constructor?.name;
|
|
149
|
+
this.addShims = getShimsFactory(adapter);
|
|
150
|
+
}
|
|
151
|
+
canActivate(context) {
|
|
152
|
+
this.addShims(context.switchToHttp().getRequest(), context.switchToHttp().getResponse());
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
exports.AdapterShim = AdapterShim;
|
|
157
|
+
exports.AdapterShim = AdapterShim = __decorate([
|
|
158
|
+
(0, common_1.Injectable)(),
|
|
159
|
+
__metadata("design:paramtypes", [core_1.HttpAdapterHost])
|
|
160
|
+
], AdapterShim);
|
|
161
|
+
let guardRegistered = false;
|
|
162
|
+
const createOnceAdapterShimProvider = () => {
|
|
163
|
+
if (guardRegistered) {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
guardRegistered = true;
|
|
167
|
+
return [
|
|
168
|
+
{
|
|
169
|
+
provide: core_1.APP_GUARD,
|
|
170
|
+
useClass: AdapterShim
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
};
|
|
174
|
+
exports.createOnceAdapterShimProvider = createOnceAdapterShimProvider;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
signedCookies: Record<string, any>;
|
|
1
|
+
export declare const normalCookieParser: (req: any, _secrets?: string[], decode?: (str: string) => string | undefined) => {
|
|
2
|
+
cookies: any;
|
|
3
|
+
signedCookies: any;
|
|
5
4
|
};
|
|
6
|
-
export declare const customCookieParser: (req:
|
|
7
|
-
cookies:
|
|
8
|
-
signedCookies:
|
|
5
|
+
export declare const customCookieParser: (req: any, secrets?: string[], decode?: (str: string) => string | undefined) => {
|
|
6
|
+
cookies: {};
|
|
7
|
+
signedCookies: {};
|
|
9
8
|
};
|
|
@@ -42,8 +42,18 @@ const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
|
42
42
|
const normalCookieParser = (req, _secrets = [], decode) => {
|
|
43
43
|
let cookies = req.cookies || {};
|
|
44
44
|
let signedCookies = req.signedCookies || {};
|
|
45
|
+
// compatible to @fastify/cookie
|
|
46
|
+
if (typeof req.unsignCookie === 'function') {
|
|
47
|
+
for (const [key, value] of Object.entries(cookies)) {
|
|
48
|
+
const unsigned = req.unsignCookie(value);
|
|
49
|
+
if (unsigned.valid) {
|
|
50
|
+
signedCookies[key] = unsigned.value;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
45
54
|
if (!req.cookies && req.headers.cookie) {
|
|
46
55
|
const parsedCookies = cookie.parse(req.headers.cookie, { decode });
|
|
56
|
+
// cookie-parser uses req.secret to decrypt cookies
|
|
47
57
|
if (req.secret) {
|
|
48
58
|
signedCookies = cookie_parser_1.default.JSONCookies(cookie_parser_1.default.signedCookies(parsedCookies, [req.secret]));
|
|
49
59
|
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const createSetCookieFn: (req: Request, res: Response) => (name: string, value: string, options?: CookieOptionsWithSecret) => void;
|
|
1
|
+
import type { RawRequestWithShims, RawResponseWithShims } from './adapter-shim';
|
|
2
|
+
export declare const createSetCookieFn: (req: RawRequestWithShims, res: RawResponseWithShims) => (name: string, value: string, options?: Record<string, any>) => void;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createSetCookieFn = void 0;
|
|
4
4
|
const generics_1 = require("./generics");
|
|
5
|
+
// @fastify/cookie does not use req.secret to encrypted.
|
|
5
6
|
const createSetCookieFn = (req, res) => (name, value, options = {}) => {
|
|
6
7
|
const { secret, signed: optSigned, ...restOpts } = options;
|
|
7
8
|
const secrets = (0, generics_1.normalizedArray)(secret) ?? [];
|
|
@@ -15,7 +16,7 @@ const createSetCookieFn = (req, res) => (name, value, options = {}) => {
|
|
|
15
16
|
else {
|
|
16
17
|
req.secret = undefined;
|
|
17
18
|
}
|
|
18
|
-
res.
|
|
19
|
+
res.shims.setCookie(name, value, {
|
|
19
20
|
signed,
|
|
20
21
|
...restOpts
|
|
21
22
|
});
|
package/dist/utils/generics.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export declare const isNotFalsy: <T>(val: T) => val is T;
|
|
2
2
|
export declare const normalizedArray: <T>(val?: T | T[]) => undefined extends T ? T[] | undefined : NonNullable<T>[];
|
|
3
3
|
export declare const normalizedObject: <T extends Record<string, any>>(obj?: T) => T | undefined;
|
|
4
|
-
export declare const merge: <T extends Record<string, any>, U extends Record<string, any>>(obj1: T, obj2?: U) => T & U;
|
package/dist/utils/generics.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.normalizedObject = exports.normalizedArray = exports.isNotFalsy = void 0;
|
|
4
4
|
const isNotFalsy = (val) => {
|
|
5
5
|
return val !== undefined && val !== null && !Number.isNaN(val);
|
|
6
6
|
};
|
|
@@ -27,14 +27,3 @@ const normalizedObject = (obj) => {
|
|
|
27
27
|
return Object.fromEntries(filtered);
|
|
28
28
|
};
|
|
29
29
|
exports.normalizedObject = normalizedObject;
|
|
30
|
-
// ref: https://github.com/jaredhanson/utils-merge/blob/master/index.js
|
|
31
|
-
const merge = (obj1, obj2) => {
|
|
32
|
-
if (obj1 && obj2) {
|
|
33
|
-
for (var key in obj2) {
|
|
34
|
-
// @ts-ignore
|
|
35
|
-
obj1[key] = obj2[key];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return obj1;
|
|
39
|
-
};
|
|
40
|
-
exports.merge = merge;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const getPassportProperty: <T>(request:
|
|
1
|
+
export declare const getPassportProperty: <T>(request: any) => T;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getPassportProperty = void 0;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const getPassportProperty = (request) => {
|
|
6
|
-
// @ts-ignore
|
|
7
6
|
return request[request[constants_1.PASSPORT_PROPERTY]];
|
|
8
7
|
};
|
|
9
8
|
exports.getPassportProperty = getPassportProperty;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './adapter-shim';
|
|
1
2
|
export * from './cookie-parsers';
|
|
2
3
|
export * from './create-authz-decorator-factory';
|
|
3
4
|
export * from './create-set-cookie-fn';
|
|
@@ -8,4 +9,5 @@ export * from './get-context-authz-meta-params-list';
|
|
|
8
9
|
export * from './get-passport-property';
|
|
9
10
|
export * from './merge-dynamic-module-configs';
|
|
10
11
|
export * from './msgpackrs';
|
|
12
|
+
export * from './safe-clone';
|
|
11
13
|
export * from './types';
|
package/dist/utils/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./adapter-shim"), exports);
|
|
17
18
|
__exportStar(require("./cookie-parsers"), exports);
|
|
18
19
|
__exportStar(require("./create-authz-decorator-factory"), exports);
|
|
19
20
|
__exportStar(require("./create-set-cookie-fn"), exports);
|
|
@@ -24,4 +25,5 @@ __exportStar(require("./get-context-authz-meta-params-list"), exports);
|
|
|
24
25
|
__exportStar(require("./get-passport-property"), exports);
|
|
25
26
|
__exportStar(require("./merge-dynamic-module-configs"), exports);
|
|
26
27
|
__exportStar(require("./msgpackrs"), exports);
|
|
28
|
+
__exportStar(require("./safe-clone"), exports);
|
|
27
29
|
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const safeClone: (obj: any) => any;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.safeClone = void 0;
|
|
4
|
+
const safeClone = (obj) => {
|
|
5
|
+
if (!obj) {
|
|
6
|
+
return {};
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(JSON.stringify(obj));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
exports.safeClone = safeClone;
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { applyDecorators } from '@nestjs/common';
|
|
2
2
|
import type { RouteInfo, Type } from '@nestjs/common/interfaces';
|
|
3
|
-
import type { CookieOptions } from 'express';
|
|
4
3
|
import type { AuthzProviderClass } from '../authz.provider';
|
|
5
4
|
export type OmitClassInstance<T extends abstract new (...args: any) => any, K extends keyof any> = Type<Omit<InstanceType<T>, K>>;
|
|
6
5
|
export type SetRequired<T, K extends keyof T> = T & {
|
|
@@ -12,12 +11,6 @@ export type IsUnknown<T> = unknown extends T ? IsNull<T> extends false ? true :
|
|
|
12
11
|
export type DeepReadonly<T> = {
|
|
13
12
|
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
|
|
14
13
|
};
|
|
15
|
-
export type CookieOptionsWithSecret = CookieOptions & {
|
|
16
|
-
/**
|
|
17
|
-
* a string or array used to sign cookies.
|
|
18
|
-
*/
|
|
19
|
-
secret?: string | string[];
|
|
20
|
-
};
|
|
21
14
|
export interface AuthzDecoBaseOptions {
|
|
22
15
|
/**
|
|
23
16
|
* When set, overrides the previous metadatas during the authorization, instead of inheriting.
|
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,20 +22,24 @@
|
|
|
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": {
|
|
28
|
+
"@fastify/cookie": "^11.0.2",
|
|
29
|
+
"@fastify/secure-session": "^8.2.0",
|
|
30
|
+
"@fastify/session": "^11.1.0",
|
|
31
|
+
"@nestjs/platform-express": "^11.0.0",
|
|
32
|
+
"@nestjs/platform-fastify": "^11.0.0",
|
|
29
33
|
"@nestjs/testing": "^11.0.0",
|
|
30
34
|
"@types/cookie-parser": "^1.4.8",
|
|
31
35
|
"@types/express": "^5.0.1",
|
|
32
|
-
"@types/express-session": "^1.18.
|
|
36
|
+
"@types/express-session": "^1.18.2",
|
|
33
37
|
"@types/jest": "^30.0.0",
|
|
34
38
|
"@types/jsonwebtoken": "^9.0.9",
|
|
35
39
|
"@types/node": "^22.13.9",
|
|
36
|
-
"@types/passport": "^1.0.17",
|
|
37
40
|
"@types/supertest": "^6.0.2",
|
|
38
|
-
"express-session": "^1.18.
|
|
41
|
+
"express-session": "^1.18.2",
|
|
42
|
+
"fastify": "^5.5.0",
|
|
39
43
|
"jest": "^30.0.5",
|
|
40
44
|
"rimraf": "^6.0.1",
|
|
41
45
|
"supertest": "^7.1.0",
|
|
@@ -52,17 +56,27 @@
|
|
|
52
56
|
"authentication",
|
|
53
57
|
"authorization",
|
|
54
58
|
"authz",
|
|
59
|
+
"express",
|
|
60
|
+
"Express",
|
|
61
|
+
"fastify",
|
|
62
|
+
"Fastify",
|
|
55
63
|
"JWT",
|
|
56
64
|
"NextJS",
|
|
57
65
|
"NodeJS",
|
|
58
66
|
"Session"
|
|
59
67
|
],
|
|
68
|
+
"optionalDependencies": {
|
|
69
|
+
"@fastify/cookie": "^11.0.2",
|
|
70
|
+
"@fastify/secure-session": "^8.2.0",
|
|
71
|
+
"@fastify/session": "^11.1.0",
|
|
72
|
+
"@nestjs/platform-express": "^11.0.0",
|
|
73
|
+
"@nestjs/platform-fastify": "^11.0.0",
|
|
74
|
+
"@types/express-session": "^1.18.2",
|
|
75
|
+
"express-session": "^1.18.2"
|
|
76
|
+
},
|
|
60
77
|
"peerDependencies": {
|
|
61
|
-
"@nestjs/common": "^
|
|
62
|
-
"@nestjs/core": "^
|
|
63
|
-
"@nestjs/passport": "^10.0.0 || ^11.0.0",
|
|
64
|
-
"@nestjs/platform-express": "^10.0.0 || ^11.0.0",
|
|
65
|
-
"passport": "^0.7.0",
|
|
78
|
+
"@nestjs/common": "^11.0.0",
|
|
79
|
+
"@nestjs/core": "^11.0.0",
|
|
66
80
|
"reflect-metadata": "^0.2.2",
|
|
67
81
|
"rxjs": "^7.8.2"
|
|
68
82
|
},
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { type Type } from '@nestjs/common';
|
|
3
|
-
import type { Request } from 'express';
|
|
4
|
-
import { AuthzProviderClass } from '../authz.provider';
|
|
5
|
-
import type { JwtAlsType } from './jwt-authz-als.middleware';
|
|
6
|
-
export declare const createJwtStrategy: ([JWT_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]: [string, any, any]) => Type<Omit<{
|
|
7
|
-
readonly authzProvider: AuthzProviderClass<unknown, unknown>;
|
|
8
|
-
readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
|
|
9
|
-
validate(req: Request): Promise<{}>;
|
|
10
|
-
authenticate(req: Request, options?: any): any;
|
|
11
|
-
}, "als" | "authzProvider">>;
|
|
12
|
-
export declare const createRefreshStrategy: ([JWT_REFRESH_STRATEGY, AUTHZ_PROVIDER, ALS_PROVIDER]: [string, any, any]) => Type<Omit<{
|
|
13
|
-
readonly authzProvider: AuthzProviderClass<unknown, unknown>;
|
|
14
|
-
readonly als: AsyncLocalStorage<JwtAlsType<unknown>>;
|
|
15
|
-
validate(req: Request): Promise<{}>;
|
|
16
|
-
authenticate(req: Request, options?: any): any;
|
|
17
|
-
}, "als" | "authzProvider">>;
|