emilsoftware-utilities 1.7.2 → 1.7.3
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/dist/accessi-module/AccessiModule.js +7 -4
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/index.d.ts +3 -1
- package/dist/accessi-module/index.js +5 -2
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/accessi-module/middleware/accessiRequirements.d.ts +60 -0
- package/dist/accessi-module/middleware/accessiRequirements.js +106 -0
- package/dist/accessi-module/middleware/accessiRequirements.js.map +1 -0
- package/dist/accessi-module/middleware/authenticateGen.d.ts +9 -7
- package/dist/accessi-module/middleware/authenticateGen.js +150 -37
- package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
- package/dist/emilsoftware-utilities-1.7.3.tgz +0 -0
- package/package.json +1 -1
- package/dist/emilsoftware-utilities-1.7.2.tgz +0 -0
|
@@ -22,6 +22,7 @@ const FiltriController_1 = require("./Controllers/FiltriController");
|
|
|
22
22
|
const ConfiguratorController_1 = require("./Controllers/ConfiguratorController");
|
|
23
23
|
const ConfiguratorService_1 = require("./Services/ConfiguratorService/ConfiguratorService");
|
|
24
24
|
const jwt_strategy_1 = require("./jwt/jwt.strategy");
|
|
25
|
+
const authenticateGen_1 = require("./middleware/authenticateGen");
|
|
25
26
|
let AccessiModule = AccessiModule_1 = class AccessiModule {
|
|
26
27
|
static forRoot(options) {
|
|
27
28
|
return {
|
|
@@ -37,7 +38,8 @@ let AccessiModule = AccessiModule_1 = class AccessiModule {
|
|
|
37
38
|
PermissionService_1.PermissionService,
|
|
38
39
|
FiltriService_1.FiltriService,
|
|
39
40
|
ConfiguratorService_1.ConfiguratorService,
|
|
40
|
-
jwt_strategy_1.JwtSimpleGuard
|
|
41
|
+
jwt_strategy_1.JwtSimpleGuard,
|
|
42
|
+
authenticateGen_1.AuthenticateGenService
|
|
41
43
|
],
|
|
42
44
|
exports: [
|
|
43
45
|
'ACCESSI_OPTIONS',
|
|
@@ -47,7 +49,8 @@ let AccessiModule = AccessiModule_1 = class AccessiModule {
|
|
|
47
49
|
PermissionService_1.PermissionService,
|
|
48
50
|
FiltriService_1.FiltriService,
|
|
49
51
|
ConfiguratorService_1.ConfiguratorService,
|
|
50
|
-
jwt_strategy_1.JwtSimpleGuard
|
|
52
|
+
jwt_strategy_1.JwtSimpleGuard,
|
|
53
|
+
authenticateGen_1.AuthenticateGenService
|
|
51
54
|
],
|
|
52
55
|
};
|
|
53
56
|
}
|
|
@@ -64,8 +67,8 @@ exports.AccessiModule = AccessiModule = AccessiModule_1 = __decorate([
|
|
|
64
67
|
FiltriController_1.FiltriController,
|
|
65
68
|
ConfiguratorController_1.ConfiguratorController
|
|
66
69
|
],
|
|
67
|
-
providers: [AuthService_1.AuthService, UserService_1.UserService, EmailService_1.EmailService, PermissionService_1.PermissionService, FiltriService_1.FiltriService, ConfiguratorService_1.ConfiguratorService, jwt_strategy_1.JwtSimpleGuard],
|
|
68
|
-
exports: [AuthService_1.AuthService, UserService_1.UserService, EmailService_1.EmailService, PermissionService_1.PermissionService, FiltriService_1.FiltriService, ConfiguratorService_1.ConfiguratorService, jwt_strategy_1.JwtSimpleGuard],
|
|
70
|
+
providers: [AuthService_1.AuthService, UserService_1.UserService, EmailService_1.EmailService, PermissionService_1.PermissionService, FiltriService_1.FiltriService, ConfiguratorService_1.ConfiguratorService, jwt_strategy_1.JwtSimpleGuard, authenticateGen_1.AuthenticateGenService],
|
|
71
|
+
exports: [AuthService_1.AuthService, UserService_1.UserService, EmailService_1.EmailService, PermissionService_1.PermissionService, FiltriService_1.FiltriService, ConfiguratorService_1.ConfiguratorService, jwt_strategy_1.JwtSimpleGuard, authenticateGen_1.AuthenticateGenService],
|
|
69
72
|
})
|
|
70
73
|
], AccessiModule);
|
|
71
74
|
//# sourceMappingURL=AccessiModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccessiModule.js","sourceRoot":"","sources":["../../src/accessi-module/AccessiModule.ts"],"names":[],"mappings":";;;;;;;;;;AAOA,2CAA+D;AAC/D,oEAAiE;AACjE,uEAAoE;AACpE,sFAAmF;AACnF,oEAAiE;AACjE,mEAAgE;AAChE,iEAA8D;AAC9D,6EAA0E;AAC1E,iEAA8D;AAC9D,0EAAuE;AACvE,qEAAkE;AAClE,iFAA8E;AAC9E,4FAAyF;AACzF,qDAAoD;
|
|
1
|
+
{"version":3,"file":"AccessiModule.js","sourceRoot":"","sources":["../../src/accessi-module/AccessiModule.ts"],"names":[],"mappings":";;;;;;;;;;AAOA,2CAA+D;AAC/D,oEAAiE;AACjE,uEAAoE;AACpE,sFAAmF;AACnF,oEAAiE;AACjE,mEAAgE;AAChE,iEAA8D;AAC9D,6EAA0E;AAC1E,iEAA8D;AAC9D,0EAAuE;AACvE,qEAAkE;AAClE,iFAA8E;AAC9E,4FAAyF;AACzF,qDAAoD;AACpD,kEAAsE;AAgE/D,IAAM,aAAa,qBAAnB,MAAM,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAAuB;QACpC,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,iBAAiB;oBAC1B,QAAQ,EAAE,OAAO;iBAClB;gBACD,yBAAW;gBACX,yBAAW;gBACX,2BAAY;gBACZ,qCAAiB;gBACjB,6BAAa;gBACb,yCAAmB;gBACnB,6BAAc;gBACd,wCAAsB;aACvB;YACD,OAAO,EAAE;gBACP,iBAAiB;gBACjB,yBAAW;gBACX,yBAAW;gBACX,2BAAY;gBACZ,qCAAiB;gBACjB,6BAAa;gBACb,yCAAmB;gBACnB,6BAAc;gBACd,wCAAsB;aACvB;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA/BY,sCAAa;wBAAb,aAAa;IAbzB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,WAAW,EAAE;YACX,iCAAe;YACf,+BAAc;YACd,2CAAoB;YACpB,+BAAc;YACd,mCAAgB;YAChB,+CAAsB;SACvB;QACD,SAAS,EAAE,CAAC,yBAAW,EAAE,yBAAW,EAAE,2BAAY,EAAE,qCAAiB,EAAE,6BAAa,EAAE,yCAAmB,EAAE,6BAAc,EAAE,wCAAsB,CAAC;QAClJ,OAAO,EAAE,CAAC,yBAAW,EAAE,yBAAW,EAAE,2BAAY,EAAE,qCAAiB,EAAE,6BAAa,EAAE,yCAAmB,EAAE,6BAAc,EAAE,wCAAsB,CAAC;KACjJ,CAAC;GACW,aAAa,CA+BzB","sourcesContent":["/**\n * Modulo che gestisce le operazioni di accesso degli utenti, incluse le rotte, il controller e il modello.\n *\n * @module AccessiModule\n * @author mttdev382\n */\nimport { Options } from 'es-node-firebird';\nimport { DynamicModule, Global, Module } from '@nestjs/common';\nimport { AuthService } from './Services/AuthService/AuthService';\nimport { EmailService } from './Services/EmailService/EmailService';\nimport { PermissionService } from './Services/PermissionService/PermissionService';\nimport { UserService } from './Services/UserService/UserService';\nimport { EmailController } from './Controllers/EmailController';\nimport { AuthController } from './Controllers/AuthController';\nimport { PermissionController } from './Controllers/PermissionController';\nimport { UserController } from './Controllers/UserController';\nimport { FiltriService } from './Services/FiltriService/FiltriService';\nimport { FiltriController } from './Controllers/FiltriController';\nimport { ConfiguratorController } from './Controllers/ConfiguratorController';\nimport { ConfiguratorService } from './Services/ConfiguratorService/ConfiguratorService';\nimport { JwtSimpleGuard } from './jwt/jwt.strategy';\nimport { AuthenticateGenService } from './middleware/authenticateGen';\n\nexport interface JwtOptions {\n secret: string;\n expiresIn: string;\n}\n\nexport interface EmailOptions {\n host: string;\n port: number;\n secure: boolean;\n requireTLS : boolean;\n tls: {\n rejectUnauthorized: boolean,\n }\n from: string;\n auth: {\n user: string;\n pass: string;\n };\n}\n\nexport interface ExtensionFieldsOptions {\n databaseOptions: Options;\n objectKey: string;\n tableName: string;\n tableFields: string[];\n tableJoinFieldName: string;\n}\n\nexport interface AccessiOptions {\n databaseOptions: Options;\n /**\n * Basepath del sito es: 'http://www.il-mio-sito.it/nome-progetto(se c'è)'\n */\n confirmationEmailUrl: string;\n /**\n * Percorso della pagina di reset personalizzata es. http://localhost:4200/#/admin/reset-password\n * N.B si sostituisce al confirmationMailURl\n */\n customResetPage?: string;\n confirmationEmailReturnUrl: string;\n confirmationEmailPrefix?: string;\n encryptionKey: string;\n mockDemoUser: boolean;\n passwordExpiration?: boolean;\n jwtOptions: JwtOptions;\n emailOptions: EmailOptions;\n extensionFieldsOptions?: ExtensionFieldsOptions[];\n}\n\n@Global()\n@Module({\n controllers: [\n EmailController,\n AuthController,\n PermissionController,\n UserController,\n FiltriController,\n ConfiguratorController\n ],\n providers: [AuthService, UserService, EmailService, PermissionService, FiltriService, ConfiguratorService, JwtSimpleGuard, AuthenticateGenService],\n exports: [AuthService, UserService, EmailService, PermissionService, FiltriService, ConfiguratorService, JwtSimpleGuard, AuthenticateGenService],\n})\nexport class AccessiModule {\n static forRoot(options: AccessiOptions): DynamicModule {\n return {\n module: AccessiModule,\n providers: [\n {\n provide: 'ACCESSI_OPTIONS',\n useValue: options,\n },\n AuthService,\n UserService,\n EmailService,\n PermissionService,\n FiltriService,\n ConfiguratorService,\n JwtSimpleGuard,\n AuthenticateGenService\n ],\n exports: [\n 'ACCESSI_OPTIONS',\n AuthService,\n UserService,\n EmailService,\n PermissionService,\n FiltriService,\n ConfiguratorService,\n JwtSimpleGuard,\n AuthenticateGenService\n ],\n };\n }\n}\n"]}
|
|
@@ -3,4 +3,6 @@ import { AccessiOptions } from "./AccessiModule";
|
|
|
3
3
|
export declare function initializeAccessiModule(app: Application, options: AccessiOptions): Promise<void>;
|
|
4
4
|
export { AccessiModule } from "./AccessiModule";
|
|
5
5
|
export * from "./Dtos";
|
|
6
|
-
export { authorizeAccessi, authenticateGen, setAccessiAuthOptions } from "./middleware/authenticateGen";
|
|
6
|
+
export { authorizeAccessi, authenticateGen, setAccessiAuthOptions, setAccessiAuthService } from "./middleware/authenticateGen";
|
|
7
|
+
export { accessiRequirement } from "./middleware/accessiRequirements";
|
|
8
|
+
export type { AccessiAuthorizationOptions, AccessiRequirementNode, AccessiCustomRequirementContext, AccessiCustomRequirementHandler } from "./middleware/accessiRequirements";
|
|
@@ -23,7 +23,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.setAccessiAuthOptions = exports.authenticateGen = exports.authorizeAccessi = exports.AccessiModule = void 0;
|
|
26
|
+
exports.accessiRequirement = exports.setAccessiAuthService = exports.setAccessiAuthOptions = exports.authenticateGen = exports.authorizeAccessi = exports.AccessiModule = void 0;
|
|
27
27
|
exports.initializeAccessiModule = initializeAccessiModule;
|
|
28
28
|
const core_1 = require("@nestjs/core");
|
|
29
29
|
const platform_express_1 = require("@nestjs/platform-express");
|
|
@@ -35,7 +35,6 @@ function initializeAccessiModule(app, options) {
|
|
|
35
35
|
const logger = new Logger_1.Logger("initializeAccessiModule");
|
|
36
36
|
console.log("Accessi initialized");
|
|
37
37
|
try {
|
|
38
|
-
(0, authenticateGen_1.setAccessiAuthOptions)(options);
|
|
39
38
|
// Creiamo un'istanza Express separata per NestJS
|
|
40
39
|
const nestExpressInstance = new platform_express_1.ExpressAdapter(app);
|
|
41
40
|
// Creiamo l'app NestJS attaccata a Express
|
|
@@ -48,6 +47,7 @@ function initializeAccessiModule(app, options) {
|
|
|
48
47
|
});
|
|
49
48
|
// Note: Swagger setup is now handled by the unified module
|
|
50
49
|
yield nestApp.init();
|
|
50
|
+
(0, authenticateGen_1.setAccessiAuthService)(nestApp.get(authenticateGen_1.AuthenticateGenService));
|
|
51
51
|
}
|
|
52
52
|
catch (error) {
|
|
53
53
|
logger.error("Errore in initialize AccessiModule:", error);
|
|
@@ -62,4 +62,7 @@ var authenticateGen_2 = require("./middleware/authenticateGen");
|
|
|
62
62
|
Object.defineProperty(exports, "authorizeAccessi", { enumerable: true, get: function () { return authenticateGen_2.authorizeAccessi; } });
|
|
63
63
|
Object.defineProperty(exports, "authenticateGen", { enumerable: true, get: function () { return authenticateGen_2.authenticateGen; } });
|
|
64
64
|
Object.defineProperty(exports, "setAccessiAuthOptions", { enumerable: true, get: function () { return authenticateGen_2.setAccessiAuthOptions; } });
|
|
65
|
+
Object.defineProperty(exports, "setAccessiAuthService", { enumerable: true, get: function () { return authenticateGen_2.setAccessiAuthService; } });
|
|
66
|
+
var accessiRequirements_1 = require("./middleware/accessiRequirements");
|
|
67
|
+
Object.defineProperty(exports, "accessiRequirement", { enumerable: true, get: function () { return accessiRequirements_1.accessiRequirement; } });
|
|
65
68
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,0DA2BC;AApCD,uCAA2C;AAC3C,+DAA0D;AAC1D,mDAAgE;AAChE,sCAAmC;AACnC,kEAGsC;AAEtC,SAAsB,uBAAuB,CAAC,GAAgB,EAAE,OAAuB;;QACnF,MAAM,MAAM,GAAW,IAAI,eAAM,CAAC,yBAAyB,CAAC,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,IAAI,CAAC;YACD,iDAAiD;YACjD,MAAM,mBAAmB,GAAG,IAAI,iCAAc,CAAC,GAAG,CAAC,CAAC;YAEpD,2CAA2C;YAC3C,MAAM,OAAO,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,6BAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE;gBAC1F,UAAU,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,OAAO,CAAC,UAAU,EAAE,CAAC;YAErB,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE;gBAC3B,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC;aACzC,CAAC,CAAC;YAEH,2DAA2D;YAC3D,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,IAAA,uCAAqB,EAAC,OAAO,CAAC,GAAG,CAAC,wCAAsB,CAAC,CAAC,CAAC;QAE/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;CAAA;AAED,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,yCAAuB;AACvB,gEAKsC;AAJlC,mHAAA,gBAAgB,OAAA;AAChB,kHAAA,eAAe,OAAA;AACf,wHAAA,qBAAqB,OAAA;AACrB,wHAAA,qBAAqB,OAAA;AAEzB,wEAAsE;AAA7D,yHAAA,kBAAkB,OAAA","sourcesContent":["import { Application } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport {\n AuthenticateGenService,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\n\nexport async function initializeAccessiModule(app: Application, options: AccessiOptions) {\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n\n console.log(\"Accessi initialized\");\n try {\n // Creiamo un'istanza Express separata per NestJS\n const nestExpressInstance = new ExpressAdapter(app);\n\n // Creiamo l'app NestJS attaccata a Express\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: true\n });\n\n nestApp.enableCors();\n\n nestApp.setGlobalPrefix('api', {\n exclude: ['/swagger', '/swagger/(.*)']\n });\n\n // Note: Swagger setup is now handled by the unified module\n await nestApp.init();\n setAccessiAuthService(nestApp.get(AuthenticateGenService));\n\n } catch (error) {\n logger.error(\"Errore in initialize AccessiModule:\", error);\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen,\n setAccessiAuthOptions,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\nexport type {\n AccessiAuthorizationOptions,\n AccessiRequirementNode,\n AccessiCustomRequirementContext,\n AccessiCustomRequirementHandler\n} from \"./middleware/accessiRequirements\";\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Request } from "express";
|
|
2
|
+
export type AccessiGrant = {
|
|
3
|
+
codiceMenu: string;
|
|
4
|
+
tipoAbilitazione?: number;
|
|
5
|
+
};
|
|
6
|
+
export type GrantsResult = {
|
|
7
|
+
grants?: AccessiGrant[];
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
export type AccessiPermissionRequirement = {
|
|
11
|
+
type: "permission";
|
|
12
|
+
menuCode: string;
|
|
13
|
+
minPermissionLevel: number;
|
|
14
|
+
};
|
|
15
|
+
export type AccessiAllRequirement = {
|
|
16
|
+
type: "and";
|
|
17
|
+
requirements: AccessiRequirementNode[];
|
|
18
|
+
};
|
|
19
|
+
export type AccessiAnyRequirement = {
|
|
20
|
+
type: "or";
|
|
21
|
+
requirements: AccessiRequirementNode[];
|
|
22
|
+
};
|
|
23
|
+
export type AccessiNotRequirement = {
|
|
24
|
+
type: "not";
|
|
25
|
+
requirement: AccessiRequirementNode;
|
|
26
|
+
};
|
|
27
|
+
export type AccessiCustomRequirement = {
|
|
28
|
+
type: "custom";
|
|
29
|
+
key: string;
|
|
30
|
+
payload?: unknown;
|
|
31
|
+
};
|
|
32
|
+
export type AccessiRequirementNode = AccessiPermissionRequirement | AccessiAllRequirement | AccessiAnyRequirement | AccessiNotRequirement | AccessiCustomRequirement;
|
|
33
|
+
export type AccessiCustomRequirementContext = {
|
|
34
|
+
req: Request;
|
|
35
|
+
decodedToken: any;
|
|
36
|
+
userCode: number;
|
|
37
|
+
getGrantsResult: () => Promise<GrantsResult>;
|
|
38
|
+
};
|
|
39
|
+
export type AccessiCustomRequirementHandler = (context: AccessiCustomRequirementContext, payload?: unknown) => boolean | Promise<boolean>;
|
|
40
|
+
export type AccessiAuthorizationOptions = {
|
|
41
|
+
requirements?: {
|
|
42
|
+
menuCode: string;
|
|
43
|
+
minPermissionLevel: number;
|
|
44
|
+
}[];
|
|
45
|
+
requirementTree?: AccessiRequirementNode;
|
|
46
|
+
customRequirementHandlers?: Record<string, AccessiCustomRequirementHandler>;
|
|
47
|
+
};
|
|
48
|
+
export declare class RequirementEvaluationError extends Error {
|
|
49
|
+
readonly code: string;
|
|
50
|
+
constructor(code: string, message: string);
|
|
51
|
+
}
|
|
52
|
+
export declare const accessiRequirement: {
|
|
53
|
+
permission: (menuCode: string, minPermissionLevel: number) => AccessiPermissionRequirement;
|
|
54
|
+
and: (...requirements: AccessiRequirementNode[]) => AccessiAllRequirement;
|
|
55
|
+
or: (...requirements: AccessiRequirementNode[]) => AccessiAnyRequirement;
|
|
56
|
+
not: (requirement: AccessiRequirementNode) => AccessiNotRequirement;
|
|
57
|
+
custom: (key: string, payload?: unknown) => AccessiCustomRequirement;
|
|
58
|
+
};
|
|
59
|
+
export declare function buildRequirementTree(options?: AccessiAuthorizationOptions): AccessiRequirementNode | undefined;
|
|
60
|
+
export declare function evaluateRequirement(requirement: AccessiRequirementNode, context: AccessiCustomRequirementContext, options?: AccessiAuthorizationOptions): Promise<boolean>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.accessiRequirement = exports.RequirementEvaluationError = void 0;
|
|
13
|
+
exports.buildRequirementTree = buildRequirementTree;
|
|
14
|
+
exports.evaluateRequirement = evaluateRequirement;
|
|
15
|
+
class RequirementEvaluationError extends Error {
|
|
16
|
+
constructor(code, message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.name = "RequirementEvaluationError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.RequirementEvaluationError = RequirementEvaluationError;
|
|
23
|
+
function requirementError(code, message) {
|
|
24
|
+
return new RequirementEvaluationError(code, message);
|
|
25
|
+
}
|
|
26
|
+
exports.accessiRequirement = {
|
|
27
|
+
permission: (menuCode, minPermissionLevel) => ({
|
|
28
|
+
type: "permission",
|
|
29
|
+
menuCode,
|
|
30
|
+
minPermissionLevel,
|
|
31
|
+
}),
|
|
32
|
+
and: (...requirements) => ({
|
|
33
|
+
type: "and",
|
|
34
|
+
requirements,
|
|
35
|
+
}),
|
|
36
|
+
or: (...requirements) => ({
|
|
37
|
+
type: "or",
|
|
38
|
+
requirements,
|
|
39
|
+
}),
|
|
40
|
+
not: (requirement) => ({
|
|
41
|
+
type: "not",
|
|
42
|
+
requirement,
|
|
43
|
+
}),
|
|
44
|
+
custom: (key, payload) => ({
|
|
45
|
+
type: "custom",
|
|
46
|
+
key,
|
|
47
|
+
payload,
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
50
|
+
function buildRequirementTree(options) {
|
|
51
|
+
var _a;
|
|
52
|
+
if (options === null || options === void 0 ? void 0 : options.requirementTree)
|
|
53
|
+
return options.requirementTree;
|
|
54
|
+
const requirements = (_a = options === null || options === void 0 ? void 0 : options.requirements) !== null && _a !== void 0 ? _a : [];
|
|
55
|
+
if (requirements.length === 0)
|
|
56
|
+
return undefined;
|
|
57
|
+
const nodes = requirements.map((requirement) => exports.accessiRequirement.permission(requirement.menuCode, requirement.minPermissionLevel));
|
|
58
|
+
return exports.accessiRequirement.and(...nodes);
|
|
59
|
+
}
|
|
60
|
+
function evaluateRequirement(requirement, context, options) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
switch (requirement.type) {
|
|
64
|
+
case "permission": {
|
|
65
|
+
const grantsResult = yield context.getGrantsResult();
|
|
66
|
+
const grants = (_a = grantsResult.grants) !== null && _a !== void 0 ? _a : [];
|
|
67
|
+
return grants.some((grant) => {
|
|
68
|
+
var _a;
|
|
69
|
+
return grant.codiceMenu == requirement.menuCode &&
|
|
70
|
+
Number((_a = grant.tipoAbilitazione) !== null && _a !== void 0 ? _a : 0) >= requirement.minPermissionLevel;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
case "and":
|
|
74
|
+
if (!requirement.requirements || requirement.requirements.length === 0) {
|
|
75
|
+
throw requirementError("AUTH_REQUIREMENTS_MISCONFIGURED", "AND requirement must contain at least one child requirement");
|
|
76
|
+
}
|
|
77
|
+
for (const child of requirement.requirements) {
|
|
78
|
+
if (!(yield evaluateRequirement(child, context, options)))
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
case "or":
|
|
83
|
+
if (!requirement.requirements || requirement.requirements.length === 0) {
|
|
84
|
+
throw requirementError("AUTH_REQUIREMENTS_MISCONFIGURED", "OR requirement must contain at least one child requirement");
|
|
85
|
+
}
|
|
86
|
+
for (const child of requirement.requirements) {
|
|
87
|
+
if (yield evaluateRequirement(child, context, options))
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
case "not":
|
|
92
|
+
return !(yield evaluateRequirement(requirement.requirement, context, options));
|
|
93
|
+
case "custom": {
|
|
94
|
+
const handlers = (_b = options === null || options === void 0 ? void 0 : options.customRequirementHandlers) !== null && _b !== void 0 ? _b : {};
|
|
95
|
+
const handler = handlers[requirement.key];
|
|
96
|
+
if (!handler) {
|
|
97
|
+
throw requirementError("AUTH_REQUIREMENTS_MISCONFIGURED", `Custom requirement handler "${requirement.key}" not found`);
|
|
98
|
+
}
|
|
99
|
+
return Boolean(yield handler(context, requirement.payload));
|
|
100
|
+
}
|
|
101
|
+
default:
|
|
102
|
+
throw requirementError("AUTH_REQUIREMENTS_MISCONFIGURED", "Unknown requirement node type");
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=accessiRequirements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessiRequirements.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/accessiRequirements.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\n\nexport type AccessiGrant = {\n codiceMenu: string;\n tipoAbilitazione?: number;\n};\n\nexport type GrantsResult = {\n grants?: AccessiGrant[];\n [key: string]: unknown;\n};\n\nexport type AccessiPermissionRequirement = {\n type: \"permission\";\n menuCode: string;\n minPermissionLevel: number;\n};\n\nexport type AccessiAllRequirement = {\n type: \"and\";\n requirements: AccessiRequirementNode[];\n};\n\nexport type AccessiAnyRequirement = {\n type: \"or\";\n requirements: AccessiRequirementNode[];\n};\n\nexport type AccessiNotRequirement = {\n type: \"not\";\n requirement: AccessiRequirementNode;\n};\n\nexport type AccessiCustomRequirement = {\n type: \"custom\";\n key: string;\n payload?: unknown;\n};\n\nexport type AccessiRequirementNode =\n | AccessiPermissionRequirement\n | AccessiAllRequirement\n | AccessiAnyRequirement\n | AccessiNotRequirement\n | AccessiCustomRequirement;\n\nexport type AccessiCustomRequirementContext = {\n req: Request;\n decodedToken: any;\n userCode: number;\n getGrantsResult: () => Promise<GrantsResult>;\n};\n\nexport type AccessiCustomRequirementHandler = (\n context: AccessiCustomRequirementContext,\n payload?: unknown\n) => boolean | Promise<boolean>;\n\nexport type AccessiAuthorizationOptions = {\n requirements?: { menuCode: string; minPermissionLevel: number }[];\n requirementTree?: AccessiRequirementNode;\n customRequirementHandlers?: Record<string, AccessiCustomRequirementHandler>;\n};\n\nexport class RequirementEvaluationError extends Error {\n constructor(public readonly code: string, message: string) {\n super(message);\n this.name = \"RequirementEvaluationError\";\n }\n}\n\nfunction requirementError(code: string, message: string): RequirementEvaluationError {\n return new RequirementEvaluationError(code, message);\n}\n\nexport const accessiRequirement = {\n permission: (\n menuCode: string,\n minPermissionLevel: number\n ): AccessiPermissionRequirement => ({\n type: \"permission\",\n menuCode,\n minPermissionLevel,\n }),\n and: (...requirements: AccessiRequirementNode[]): AccessiAllRequirement => ({\n type: \"and\",\n requirements,\n }),\n or: (...requirements: AccessiRequirementNode[]): AccessiAnyRequirement => ({\n type: \"or\",\n requirements,\n }),\n not: (requirement: AccessiRequirementNode): AccessiNotRequirement => ({\n type: \"not\",\n requirement,\n }),\n custom: (key: string, payload?: unknown): AccessiCustomRequirement => ({\n type: \"custom\",\n key,\n payload,\n }),\n};\n\nexport function buildRequirementTree(\n options?: AccessiAuthorizationOptions\n): AccessiRequirementNode | undefined {\n if (options?.requirementTree) return options.requirementTree;\n\n const requirements = options?.requirements ?? [];\n if (requirements.length === 0) return undefined;\n\n const nodes: AccessiRequirementNode[] = requirements.map((requirement) =>\n accessiRequirement.permission(\n requirement.menuCode,\n requirement.minPermissionLevel\n )\n );\n\n return accessiRequirement.and(...nodes);\n}\n\nexport async function evaluateRequirement(\n requirement: AccessiRequirementNode,\n context: AccessiCustomRequirementContext,\n options?: AccessiAuthorizationOptions\n): Promise<boolean> {\n switch (requirement.type) {\n case \"permission\": {\n const grantsResult = await context.getGrantsResult();\n const grants = grantsResult.grants ?? [];\n return grants.some(\n (grant) =>\n grant.codiceMenu == requirement.menuCode &&\n Number(grant.tipoAbilitazione ?? 0) >= requirement.minPermissionLevel\n );\n }\n case \"and\":\n if (!requirement.requirements || requirement.requirements.length === 0) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"AND requirement must contain at least one child requirement\"\n );\n }\n for (const child of requirement.requirements) {\n if (!(await evaluateRequirement(child, context, options))) return false;\n }\n return true;\n case \"or\":\n if (!requirement.requirements || requirement.requirements.length === 0) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"OR requirement must contain at least one child requirement\"\n );\n }\n for (const child of requirement.requirements) {\n if (await evaluateRequirement(child, context, options)) return true;\n }\n return false;\n case \"not\":\n return !(await evaluateRequirement(requirement.requirement, context, options));\n case \"custom\": {\n const handlers = options?.customRequirementHandlers ?? {};\n const handler = handlers[requirement.key];\n if (!handler) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n `Custom requirement handler \"${requirement.key}\" not found`\n );\n }\n return Boolean(await handler(context, requirement.payload));\n }\n default:\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"Unknown requirement node type\"\n );\n }\n}\n"]}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { NextFunction, Request, Response } from "express";
|
|
2
2
|
import { AccessiOptions } from "../AccessiModule";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
import { PermissionService } from "../Services/PermissionService/PermissionService";
|
|
4
|
+
import { AccessiAuthorizationOptions } from "./accessiRequirements";
|
|
5
|
+
export declare class AuthenticateGenService {
|
|
6
|
+
private readonly accessiOptions;
|
|
7
|
+
private readonly permissionService;
|
|
8
|
+
constructor(accessiOptions: AccessiOptions, permissionService: PermissionService);
|
|
9
|
+
authorize(req: Request, res: Response, next: NextFunction, options?: AccessiAuthorizationOptions): Promise<void | Response<any, Record<string, any>>>;
|
|
10
|
+
}
|
|
11
|
+
export declare function setAccessiAuthService(service: AuthenticateGenService): void;
|
|
10
12
|
export declare function setAccessiAuthOptions(options: AccessiOptions): void;
|
|
11
13
|
export declare function authorizeAccessi(req: Request, res: Response, next: NextFunction, options?: AccessiAuthorizationOptions): Promise<void | Response<any, Record<string, any>>>;
|
|
12
14
|
export declare const authenticateGen: typeof authorizeAccessi;
|
|
@@ -15,6 +15,12 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
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;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
18
24
|
var __importStar = (this && this.__importStar) || (function () {
|
|
19
25
|
var ownKeys = function(o) {
|
|
20
26
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
@@ -32,6 +38,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
38
|
return result;
|
|
33
39
|
};
|
|
34
40
|
})();
|
|
41
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
45
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
46
|
+
};
|
|
35
47
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
48
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
49
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -42,69 +54,170 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
54
|
});
|
|
43
55
|
};
|
|
44
56
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.authenticateGen = void 0;
|
|
57
|
+
exports.authenticateGen = exports.AuthenticateGenService = void 0;
|
|
58
|
+
exports.setAccessiAuthService = setAccessiAuthService;
|
|
46
59
|
exports.setAccessiAuthOptions = setAccessiAuthOptions;
|
|
47
60
|
exports.authorizeAccessi = authorizeAccessi;
|
|
48
61
|
const jwt = __importStar(require("jsonwebtoken"));
|
|
62
|
+
const common_1 = require("@nestjs/common");
|
|
49
63
|
const PermissionService_1 = require("../Services/PermissionService/PermissionService");
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
const Logger_1 = require("../../Logger");
|
|
65
|
+
const accessiRequirements_1 = require("./accessiRequirements");
|
|
66
|
+
const logger = new Logger_1.Logger("AuthenticateGen");
|
|
67
|
+
class AuthMiddlewareError extends Error {
|
|
68
|
+
constructor(status, code, message, details) {
|
|
69
|
+
super(message);
|
|
70
|
+
this.status = status;
|
|
71
|
+
this.code = code;
|
|
72
|
+
this.details = details;
|
|
73
|
+
this.name = "AuthMiddlewareError";
|
|
74
|
+
}
|
|
53
75
|
}
|
|
54
76
|
function resolveCodiceUtente(decoded) {
|
|
55
77
|
var _a, _b, _c, _d, _e;
|
|
56
78
|
return ((_e = (_c = (_b = (_a = decoded === null || decoded === void 0 ? void 0 : decoded.userData) === null || _a === void 0 ? void 0 : _a.utente) === null || _b === void 0 ? void 0 : _b.codiceUtente) !== null && _c !== void 0 ? _c : (_d = decoded === null || decoded === void 0 ? void 0 : decoded.utente) === null || _d === void 0 ? void 0 : _d.codiceUtente) !== null && _e !== void 0 ? _e : decoded === null || decoded === void 0 ? void 0 : decoded.codiceUtente);
|
|
57
79
|
}
|
|
58
|
-
function
|
|
80
|
+
function authError(status, code, message, details) {
|
|
81
|
+
return new AuthMiddlewareError(status, code, message, details);
|
|
82
|
+
}
|
|
83
|
+
function normalizeAuthError(error) {
|
|
84
|
+
if (error instanceof AuthMiddlewareError)
|
|
85
|
+
return error;
|
|
86
|
+
if (error instanceof accessiRequirements_1.RequirementEvaluationError) {
|
|
87
|
+
return authError(500, error.code, error.message);
|
|
88
|
+
}
|
|
89
|
+
if (error instanceof Error) {
|
|
90
|
+
return authError(500, "AUTH_INTERNAL_ERROR", error.message, {
|
|
91
|
+
originalError: error.name,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return authError(500, "AUTH_INTERNAL_ERROR", "Unexpected authentication error");
|
|
95
|
+
}
|
|
96
|
+
function logAuthFailure(req, authErr) {
|
|
97
|
+
var _a;
|
|
98
|
+
const payload = {
|
|
99
|
+
code: authErr.code,
|
|
100
|
+
status: authErr.status,
|
|
101
|
+
message: authErr.message,
|
|
102
|
+
details: authErr.details,
|
|
103
|
+
method: req.method,
|
|
104
|
+
path: (_a = req.originalUrl) !== null && _a !== void 0 ? _a : req.url,
|
|
105
|
+
ip: req.ip,
|
|
106
|
+
};
|
|
107
|
+
if (authErr.status >= 500)
|
|
108
|
+
logger.error("Authentication failure", payload);
|
|
109
|
+
else
|
|
110
|
+
logger.warning("Authentication denied", payload);
|
|
111
|
+
}
|
|
112
|
+
function authorizeWithDependencies(req, res, next, options, accessiOptions, permissionService) {
|
|
59
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
-
var _a, _b
|
|
114
|
+
var _a, _b;
|
|
61
115
|
try {
|
|
62
116
|
const authHeader = req.headers.authorization;
|
|
63
|
-
if (!authHeader)
|
|
64
|
-
throw
|
|
117
|
+
if (!authHeader) {
|
|
118
|
+
throw authError(401, "AUTH_HEADER_MISSING", "Authorization header not found");
|
|
119
|
+
}
|
|
65
120
|
const token = authHeader.split(" ")[1];
|
|
66
|
-
if (!token)
|
|
67
|
-
throw
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
121
|
+
if (!token) {
|
|
122
|
+
throw authError(401, "AUTH_TOKEN_MISSING", "Token not found in Authorization header");
|
|
123
|
+
}
|
|
124
|
+
const secret = (_b = (_a = accessiOptions === null || accessiOptions === void 0 ? void 0 : accessiOptions.jwtOptions) === null || _a === void 0 ? void 0 : _a.secret) !== null && _b !== void 0 ? _b : process.env.ACC_JWT_SECRET;
|
|
125
|
+
if (!secret) {
|
|
126
|
+
throw authError(500, "AUTH_JWT_SECRET_MISSING", "JWT secret not configured");
|
|
127
|
+
}
|
|
71
128
|
let decoded;
|
|
72
129
|
try {
|
|
73
130
|
decoded = jwt.verify(token, secret);
|
|
74
131
|
}
|
|
75
|
-
catch (
|
|
76
|
-
throw
|
|
132
|
+
catch (_c) {
|
|
133
|
+
throw authError(401, "AUTH_TOKEN_INVALID", "Invalid JWT token");
|
|
77
134
|
}
|
|
78
135
|
const codiceUtente = resolveCodiceUtente(decoded);
|
|
79
|
-
if (!codiceUtente)
|
|
80
|
-
throw
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
136
|
+
if (!codiceUtente) {
|
|
137
|
+
throw authError(401, "AUTH_USER_CODE_MISSING", "codiceUtente not found in token payload");
|
|
138
|
+
}
|
|
139
|
+
const requirementTree = (0, accessiRequirements_1.buildRequirementTree)(options);
|
|
140
|
+
if (requirementTree) {
|
|
141
|
+
if (!(accessiOptions === null || accessiOptions === void 0 ? void 0 : accessiOptions.databaseOptions)) {
|
|
142
|
+
throw authError(500, "AUTH_DATABASE_OPTIONS_MISSING", "Database options not configured");
|
|
143
|
+
}
|
|
144
|
+
let grantsResultCache = null;
|
|
145
|
+
const getGrantsResult = () => __awaiter(this, void 0, void 0, function* () {
|
|
146
|
+
if (!grantsResultCache) {
|
|
147
|
+
grantsResultCache = yield permissionService.getUserRolesAndGrants(codiceUtente);
|
|
148
|
+
}
|
|
149
|
+
return grantsResultCache;
|
|
92
150
|
});
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
151
|
+
const requirementContext = {
|
|
152
|
+
req,
|
|
153
|
+
decodedToken: decoded,
|
|
154
|
+
userCode: codiceUtente,
|
|
155
|
+
getGrantsResult,
|
|
156
|
+
};
|
|
157
|
+
const hasPermissions = yield (0, accessiRequirements_1.evaluateRequirement)(requirementTree, requirementContext, options);
|
|
158
|
+
if (!hasPermissions) {
|
|
159
|
+
throw authError(403, "AUTH_INSUFFICIENT_PERMISSIONS", "User does not have required permissions");
|
|
160
|
+
}
|
|
161
|
+
req.userGrants = yield getGrantsResult();
|
|
100
162
|
}
|
|
101
163
|
req.data = decoded;
|
|
102
164
|
return next();
|
|
103
165
|
}
|
|
104
166
|
catch (error) {
|
|
105
|
-
|
|
106
|
-
|
|
167
|
+
const authErr = normalizeAuthError(error);
|
|
168
|
+
logAuthFailure(req, authErr);
|
|
169
|
+
const publicMessage = authErr.status === 403
|
|
170
|
+
? "Forbidden"
|
|
171
|
+
: authErr.status >= 500
|
|
172
|
+
? "Internal server error"
|
|
173
|
+
: "Unauthorized";
|
|
174
|
+
return res
|
|
175
|
+
.status(authErr.status)
|
|
176
|
+
.json({ message: publicMessage, error: authErr.message, code: authErr.code });
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
let AuthenticateGenService = class AuthenticateGenService {
|
|
181
|
+
constructor(accessiOptions, permissionService) {
|
|
182
|
+
this.accessiOptions = accessiOptions;
|
|
183
|
+
this.permissionService = permissionService;
|
|
184
|
+
}
|
|
185
|
+
authorize(req, res, next, options) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
return authorizeWithDependencies(req, res, next, options, this.accessiOptions, this.permissionService);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
exports.AuthenticateGenService = AuthenticateGenService;
|
|
192
|
+
exports.AuthenticateGenService = AuthenticateGenService = __decorate([
|
|
193
|
+
(0, common_1.Injectable)(),
|
|
194
|
+
__param(0, (0, common_1.Inject)("ACCESSI_OPTIONS")),
|
|
195
|
+
__metadata("design:paramtypes", [Object, PermissionService_1.PermissionService])
|
|
196
|
+
], AuthenticateGenService);
|
|
197
|
+
let authenticateGenServiceRef = null;
|
|
198
|
+
let accessiOptionsRef = null;
|
|
199
|
+
function setAccessiAuthService(service) {
|
|
200
|
+
authenticateGenServiceRef = service;
|
|
201
|
+
}
|
|
202
|
+
function setAccessiAuthOptions(options) {
|
|
203
|
+
accessiOptionsRef = options;
|
|
204
|
+
}
|
|
205
|
+
function authorizeAccessi(req, res, next, options) {
|
|
206
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
207
|
+
var _a;
|
|
208
|
+
if (authenticateGenServiceRef) {
|
|
209
|
+
return authenticateGenServiceRef.authorize(req, res, next, options);
|
|
210
|
+
}
|
|
211
|
+
if (!accessiOptionsRef) {
|
|
212
|
+
logger.error("Authentication service not initialized", {
|
|
213
|
+
method: req.method,
|
|
214
|
+
path: (_a = req.originalUrl) !== null && _a !== void 0 ? _a : req.url,
|
|
215
|
+
});
|
|
216
|
+
return res
|
|
217
|
+
.status(500)
|
|
218
|
+
.json({ message: "Accessi authentication service not initialized" });
|
|
107
219
|
}
|
|
220
|
+
return authorizeWithDependencies(req, res, next, options, accessiOptionsRef, new PermissionService_1.PermissionService(accessiOptionsRef));
|
|
108
221
|
});
|
|
109
222
|
}
|
|
110
223
|
exports.authenticateGen = authorizeAccessi;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticateGen.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/authenticateGen.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport * as jwt from \"jsonwebtoken\";\nimport { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\n\nexport type AccessiAuthorizationOptions = {\n requisiti: { codiceMenu: string; tipoAbilitazione: number }[];\n tipoControllo?: \"AND\" | \"OR\";\n};\n\nlet accessiOptionsRef: AccessiOptions | null = null;\n\nexport function setAccessiAuthOptions(options: AccessiOptions) {\n accessiOptionsRef = options;\n}\n\nfunction resolveCodiceUtente(decoded: any): number | undefined {\n return (\n decoded?.userData?.utente?.codiceUtente ??\n decoded?.utente?.codiceUtente ??\n decoded?.codiceUtente\n );\n}\n\nexport async function authorizeAccessi(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n) {\n try {\n const authHeader = req.headers.authorization;\n if (!authHeader) throw new Error(\"Authorization header not found\");\n\n const token = authHeader.split(\" \")[1];\n if (!token) throw new Error(\"Token not found in Authorization header\");\n\n const secret =\n accessiOptionsRef?.jwtOptions?.secret ?? process.env.ACC_JWT_SECRET;\n if (!secret) throw new Error(\"JWT secret not configured\");\n\n let decoded: any;\n try {\n decoded = jwt.verify(token, secret);\n } catch (error) {\n throw new Error(\"Invalid JWT token\");\n }\n\n const codiceUtente = resolveCodiceUtente(decoded);\n if (!codiceUtente) throw new Error(\"codiceUtente not found in token payload\");\n\n const requisiti = options?.requisiti ?? [];\n if (requisiti.length > 0) {\n if (!accessiOptionsRef?.databaseOptions) throw new Error(\"Database options not configured\");\n const permissionService = new PermissionService(accessiOptionsRef);\n const grantsResult = await permissionService.getUserRolesAndGrants(\n codiceUtente\n );\n\n const grants = grantsResult.grants ?? [];\n const hasMenu = (codiceMenu: string, tipoAbilitazione: number) =>\n grants.some(\n (g) =>\n g.codiceMenu == codiceMenu &&\n Number(g.tipoAbilitazione ?? 0) >= tipoAbilitazione\n );\n const requireAll = (options?.tipoControllo ?? \"AND\") === \"AND\";\n const hasAbil = requireAll\n ? requisiti.every((r) => hasMenu(r.codiceMenu, r.tipoAbilitazione))\n : requisiti.some((r) => hasMenu(r.codiceMenu, r.tipoAbilitazione));\n\n if (!hasAbil) throw new Error(\"User does not have required permissions\");\n (req as any).userGrants = grantsResult;\n }\n\n (req as any).data = decoded;\n return next();\n } catch (error) {\n console.error(\"Authentication error:\", error);\n return res.status(401).json({ message: \"Unauthorized\", error: error.message });\n }\n}\n\nexport const authenticateGen = authorizeAccessi;\n"]}
|
|
1
|
+
{"version":3,"file":"authenticateGen.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/authenticateGen.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport * as jwt from \"jsonwebtoken\";\nimport { Inject, Injectable } from \"@nestjs/common\";\nimport { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\nimport { Logger } from \"../../Logger\";\nimport {\n AccessiAuthorizationOptions,\n AccessiCustomRequirementContext,\n GrantsResult,\n RequirementEvaluationError,\n buildRequirementTree,\n evaluateRequirement,\n} from \"./accessiRequirements\";\n\nconst logger = new Logger(\"AuthenticateGen\");\n\nclass AuthMiddlewareError extends Error {\n constructor(\n public readonly status: number,\n public readonly code: string,\n message: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = \"AuthMiddlewareError\";\n }\n}\n\nfunction resolveCodiceUtente(decoded: any): number | undefined {\n return (\n decoded?.userData?.utente?.codiceUtente ??\n decoded?.utente?.codiceUtente ??\n decoded?.codiceUtente\n );\n}\n\nfunction authError(\n status: number,\n code: string,\n message: string,\n details?: Record<string, unknown>\n) {\n return new AuthMiddlewareError(status, code, message, details);\n}\n\nfunction normalizeAuthError(error: unknown): AuthMiddlewareError {\n if (error instanceof AuthMiddlewareError) return error;\n if (error instanceof RequirementEvaluationError) {\n return authError(500, error.code, error.message);\n }\n if (error instanceof Error) {\n return authError(500, \"AUTH_INTERNAL_ERROR\", error.message, {\n originalError: error.name,\n });\n }\n return authError(500, \"AUTH_INTERNAL_ERROR\", \"Unexpected authentication error\");\n}\n\nfunction logAuthFailure(req: Request, authErr: AuthMiddlewareError) {\n const payload = {\n code: authErr.code,\n status: authErr.status,\n message: authErr.message,\n details: authErr.details,\n method: req.method,\n path: req.originalUrl ?? req.url,\n ip: req.ip,\n };\n\n if (authErr.status >= 500) logger.error(\"Authentication failure\", payload);\n else logger.warning(\"Authentication denied\", payload);\n}\n\nasync function authorizeWithDependencies(\n req: Request,\n res: Response,\n next: NextFunction,\n options: AccessiAuthorizationOptions | undefined,\n accessiOptions: AccessiOptions,\n permissionService: PermissionService\n) {\n try {\n const authHeader = req.headers.authorization;\n if (!authHeader) {\n throw authError(401, \"AUTH_HEADER_MISSING\", \"Authorization header not found\");\n }\n\n const token = authHeader.split(\" \")[1];\n if (!token) {\n throw authError(\n 401,\n \"AUTH_TOKEN_MISSING\",\n \"Token not found in Authorization header\"\n );\n }\n\n const secret = accessiOptions?.jwtOptions?.secret ?? process.env.ACC_JWT_SECRET;\n if (!secret) {\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT secret not configured\");\n }\n\n let decoded: any;\n try {\n decoded = jwt.verify(token, secret);\n } catch {\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\n }\n\n const codiceUtente = resolveCodiceUtente(decoded);\n if (!codiceUtente) {\n throw authError(\n 401,\n \"AUTH_USER_CODE_MISSING\",\n \"codiceUtente not found in token payload\"\n );\n }\n\n const requirementTree = buildRequirementTree(options);\n if (requirementTree) {\n if (!accessiOptions?.databaseOptions) {\n throw authError(\n 500,\n \"AUTH_DATABASE_OPTIONS_MISSING\",\n \"Database options not configured\"\n );\n }\n\n let grantsResultCache: GrantsResult | null = null;\n const getGrantsResult = async () => {\n if (!grantsResultCache) {\n grantsResultCache = await permissionService.getUserRolesAndGrants(\n codiceUtente\n );\n }\n return grantsResultCache;\n };\n\n const requirementContext: AccessiCustomRequirementContext = {\n req,\n decodedToken: decoded,\n userCode: codiceUtente,\n getGrantsResult,\n };\n\n const hasPermissions = await evaluateRequirement(\n requirementTree,\n requirementContext,\n options\n );\n\n if (!hasPermissions) {\n throw authError(\n 403,\n \"AUTH_INSUFFICIENT_PERMISSIONS\",\n \"User does not have required permissions\"\n );\n }\n\n (req as any).userGrants = await getGrantsResult();\n }\n\n (req as any).data = decoded;\n return next();\n } catch (error: unknown) {\n const authErr = normalizeAuthError(error);\n logAuthFailure(req, authErr);\n const publicMessage =\n authErr.status === 403\n ? \"Forbidden\"\n : authErr.status >= 500\n ? \"Internal server error\"\n : \"Unauthorized\";\n return res\n .status(authErr.status)\n .json({ message: publicMessage, error: authErr.message, code: authErr.code });\n }\n}\n\n@Injectable()\nexport class AuthenticateGenService {\n constructor(\n @Inject(\"ACCESSI_OPTIONS\")\n private readonly accessiOptions: AccessiOptions,\n private readonly permissionService: PermissionService\n ) {}\n\n async authorize(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n ) {\n return authorizeWithDependencies(\n req,\n res,\n next,\n options,\n this.accessiOptions,\n this.permissionService\n );\n }\n}\n\nlet authenticateGenServiceRef: AuthenticateGenService | null = null;\nlet accessiOptionsRef: AccessiOptions | null = null;\n\nexport function setAccessiAuthService(service: AuthenticateGenService) {\n authenticateGenServiceRef = service;\n}\n\nexport function setAccessiAuthOptions(options: AccessiOptions) {\n accessiOptionsRef = options;\n}\n\nexport async function authorizeAccessi(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n) {\n if (authenticateGenServiceRef) {\n return authenticateGenServiceRef.authorize(req, res, next, options);\n }\n\n if (!accessiOptionsRef) {\n logger.error(\"Authentication service not initialized\", {\n method: req.method,\n path: req.originalUrl ?? req.url,\n });\n return res\n .status(500)\n .json({ message: \"Accessi authentication service not initialized\" });\n }\n\n return authorizeWithDependencies(\n req,\n res,\n next,\n options,\n accessiOptionsRef,\n new PermissionService(accessiOptionsRef)\n );\n}\n\nexport const authenticateGen = authorizeAccessi;\n"]}
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|