@nestjs-kitchen/authz 3.0.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +27 -8
  2. package/dist/authz.provider.d.ts +1 -2
  3. package/dist/jwt/jwt-authz-als.middleware.d.ts +5 -9
  4. package/dist/jwt/jwt-authz-als.middleware.js +6 -9
  5. package/dist/jwt/jwt-authz.guard.d.ts +10 -23
  6. package/dist/jwt/jwt-authz.guard.js +93 -22
  7. package/dist/jwt/jwt-authz.module.d.ts +6 -13
  8. package/dist/jwt/jwt-authz.module.js +3 -17
  9. package/dist/jwt/jwt-authz.service.d.ts +3 -3
  10. package/dist/session/session-authz-als.middleware.d.ts +3 -5
  11. package/dist/session/session-authz-als.middleware.js +29 -50
  12. package/dist/session/session-authz.guard.d.ts +3 -10
  13. package/dist/session/session-authz.guard.js +33 -11
  14. package/dist/session/session-authz.module.d.ts +4 -11
  15. package/dist/session/session-authz.module.js +1 -13
  16. package/dist/session/session-authz.service.d.ts +2 -2
  17. package/dist/utils/adapter-shim.d.ts +28 -0
  18. package/dist/utils/adapter-shim.js +174 -0
  19. package/dist/utils/cookie-parsers.d.ts +6 -7
  20. package/dist/utils/cookie-parsers.js +10 -0
  21. package/dist/utils/create-set-cookie-fn.d.ts +2 -3
  22. package/dist/utils/create-set-cookie-fn.js +2 -1
  23. package/dist/utils/generics.d.ts +0 -1
  24. package/dist/utils/generics.js +1 -12
  25. package/dist/utils/get-passport-property.d.ts +1 -1
  26. package/dist/utils/get-passport-property.js +0 -1
  27. package/dist/utils/index.d.ts +2 -0
  28. package/dist/utils/index.js +2 -0
  29. package/dist/utils/safe-clone.d.ts +1 -0
  30. package/dist/utils/safe-clone.js +15 -0
  31. package/dist/utils/types.d.ts +0 -7
  32. package/package.json +24 -10
  33. package/dist/jwt/jwt-authz.strategy.d.ts +0 -17
  34. package/dist/jwt/jwt-authz.strategy.js +0 -134
  35. package/dist/session/session-authz.strategy.d.ts +0 -11
  36. package/dist/session/session-authz.strategy.js +0 -70
@@ -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,9 +1,9 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { type ConfigurableModuleAsyncOptions, DynamicModule, type ExecutionContext, MiddlewareConsumer, type Type } from '@nestjs/common';
3
- import type { Reflector } from '@nestjs/core';
3
+ import { type Reflector } from '@nestjs/core';
4
4
  import { AuthzProviderClass } from '../authz.provider';
5
5
  import { AuthzError } from '../errors';
6
- import { type AbstractConstructor, type ApplyDecorators, type AuthzDecoParams, type AuthzModuleBaseOptions, type AuthzModuleRoutesOptions, type CookieOptionsWithSecret, type DeepReadonly, type MethodParameters, type RoutesOptions } from '../utils';
6
+ import { type AbstractConstructor, type ApplyDecorators, type AuthzDecoParams, type AuthzModuleBaseOptions, type AuthzModuleRoutesOptions, type DeepReadonly, type MethodParameters, type RoutesOptions } from '../utils';
7
7
  import { type 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
- logIn<TRequest extends {
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?: CookieOptionsWithSecret | undefined): void;
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 CookieOptionsWithSecret, type DeepReadonly } from '../utils';
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?: CookieOptionsWithSecret | undefined): void;
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
- import type { Request } from 'express';
2
- export declare const normalCookieParser: (req: Request, _secrets?: string[], decode?: (str: string) => string | undefined) => {
3
- cookies: Record<string, any>;
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: Request, secrets?: string[], decode?: (str: string) => string | undefined) => {
7
- cookies: Record<string, any>;
8
- signedCookies: Record<string, any>;
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 { Request, Response } from 'express';
2
- import type { CookieOptionsWithSecret } from './types';
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.cookie(name, value, {
19
+ res.shims.setCookie(name, value, {
19
20
  signed,
20
21
  ...restOpts
21
22
  });
@@ -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;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.merge = exports.normalizedObject = exports.normalizedArray = exports.isNotFalsy = void 0;
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: Express.Request) => T;
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;
@@ -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';
@@ -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;
@@ -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": "3.0.1",
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.1",
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.1",
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": "^10.0.0 || ^11.0.0",
62
- "@nestjs/core": "^10.0.0 || ^11.0.0",
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">>;