emilsoftware-utilities 2.0.0-dev.73 → 2.0.0-dev.75

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 (45) hide show
  1. package/README.MD +2 -0
  2. package/dist/accessi/resource-server/token.js +62 -18
  3. package/dist/accessi/resource-server/token.js.map +1 -1
  4. package/dist/accessi/resource-server/types.d.ts +22 -0
  5. package/dist/accessi/resource-server/types.js.map +1 -1
  6. package/dist/accessi/server/index.d.ts +1 -1
  7. package/dist/accessi/server/index.js +2 -1
  8. package/dist/accessi/server/index.js.map +1 -1
  9. package/dist/accessi/server/standalone.d.ts +2 -4
  10. package/dist/accessi/server/standalone.js +4 -79
  11. package/dist/accessi/server/standalone.js.map +1 -1
  12. package/dist/accessi-module/AccessiModule.d.ts +12 -3
  13. package/dist/accessi-module/AccessiModule.js.map +1 -1
  14. package/dist/accessi-module/Console/console.js +2 -1
  15. package/dist/accessi-module/Console/wiki.js +2 -1
  16. package/dist/accessi-module/Console/wiki.js.map +1 -1
  17. package/dist/accessi-module/Services/AuthService/AuthService.js +2 -2
  18. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  19. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.d.ts +9 -1
  20. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js +53 -1
  21. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js.map +1 -1
  22. package/dist/accessi-module/health/nest.d.ts +31 -0
  23. package/dist/accessi-module/health/nest.js +89 -0
  24. package/dist/accessi-module/health/nest.js.map +1 -0
  25. package/dist/accessi-module/health/readiness.d.ts +53 -0
  26. package/dist/accessi-module/health/readiness.js +110 -0
  27. package/dist/accessi-module/health/readiness.js.map +1 -0
  28. package/dist/accessi-module/index.d.ts +6 -0
  29. package/dist/accessi-module/index.js +16 -1
  30. package/dist/accessi-module/index.js.map +1 -1
  31. package/dist/accessi-module/jwt/jwt.strategy.js +1 -35
  32. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  33. package/dist/accessi-module/middleware/authenticateGen.js +1 -35
  34. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  35. package/dist/accessi-module/security/jwtTokenOptions.d.ts +44 -9
  36. package/dist/accessi-module/security/jwtTokenOptions.js +118 -7
  37. package/dist/accessi-module/security/jwtTokenOptions.js.map +1 -1
  38. package/dist/accessi-module/security/validateOptions.js +31 -4
  39. package/dist/accessi-module/security/validateOptions.js.map +1 -1
  40. package/dist/emilsoftware-utilities-2.0.0-dev.75.tgz +0 -0
  41. package/docs/jwt-key-rotation.md +143 -0
  42. package/docs/proxy-ip.md +99 -0
  43. package/docs/standalone-service.md +25 -0
  44. package/package.json +5 -3
  45. package/dist/emilsoftware-utilities-2.0.0-dev.73.tgz +0 -0
@@ -0,0 +1,53 @@
1
+ import type { AccessiOptions } from '../AccessiModule';
2
+ /**
3
+ * Health e readiness riutilizzabili.
4
+ *
5
+ * Lo stesso contratto e usato da `createAccessiService` (servizio standalone) e
6
+ * da `createAccessiHealthModule` (host Nest con `AccessiModule.forRoot`):
7
+ * `/health/live` risponde sempre se il processo e vivo, `/health/ready` verifica
8
+ * bootstrap, schema del database, store condivisi e check applicativi.
9
+ */
10
+ export interface AccessiReadinessCheck {
11
+ name: string;
12
+ check: () => boolean | Promise<boolean>;
13
+ }
14
+ export interface AccessiHealthCheckResult {
15
+ ok: boolean;
16
+ detail?: string;
17
+ }
18
+ export interface AccessiReadinessReport {
19
+ status: 'ok' | 'error';
20
+ checks: Record<string, AccessiHealthCheckResult>;
21
+ timestamp: string;
22
+ }
23
+ export interface AccessiLiveReport {
24
+ status: 'ok';
25
+ uptimeSeconds: number;
26
+ }
27
+ /** Store condivisi con health check, senza duplicati. */
28
+ export interface AccessiHealthStore {
29
+ name: string;
30
+ store: {
31
+ healthCheck?: () => Promise<boolean>;
32
+ };
33
+ }
34
+ export interface AccessiReadinessDependencies {
35
+ /** Override del check database (usato dai test o da host con pool esterni). */
36
+ databaseVersion?: (options: AccessiOptions) => Promise<string | null | undefined>;
37
+ }
38
+ /** Stato liveness: il processo risponde, nessun accesso a DB o store. */
39
+ export declare function createAccessiLiveReport(): AccessiLiveReport;
40
+ /** Store con health check configurati nelle opzioni Accessi. */
41
+ export declare function collectAccessiHealthStores(options: AccessiOptions): AccessiHealthStore[];
42
+ /** Verifica che lo schema Accessi sia inizializzato e alla versione attesa. */
43
+ export declare function checkAccessiDatabase(options: AccessiOptions, resolveVersion?: AccessiReadinessDependencies['databaseVersion']): Promise<AccessiHealthCheckResult>;
44
+ /**
45
+ * Report di readiness con lo stesso formato del servizio standalone.
46
+ *
47
+ * `bootstrap` e considerato completato: chi chiama questa funzione ha gia
48
+ * inizializzato il modulo. Il servizio standalone mantiene il proprio stato di
49
+ * bootstrap prima di delegare qui.
50
+ */
51
+ export declare function checkAccessiReadiness(options: AccessiOptions, readinessChecks?: AccessiReadinessCheck[], dependencies?: AccessiReadinessDependencies): Promise<AccessiReadinessReport>;
52
+ /** Status HTTP da usare per un report di readiness: 200 o 503. */
53
+ export declare function readinessHttpStatus(report: AccessiReadinessReport): 200 | 503;
@@ -0,0 +1,110 @@
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.createAccessiLiveReport = createAccessiLiveReport;
13
+ exports.collectAccessiHealthStores = collectAccessiHealthStores;
14
+ exports.checkAccessiDatabase = checkAccessiDatabase;
15
+ exports.checkAccessiReadiness = checkAccessiReadiness;
16
+ exports.readinessHttpStatus = readinessHttpStatus;
17
+ const accessiSchema_1 = require("../database-updates/accessiSchema");
18
+ const AccessiDatabaseUpdater_1 = require("../database-updates/AccessiDatabaseUpdater");
19
+ /** Stato liveness: il processo risponde, nessun accesso a DB o store. */
20
+ function createAccessiLiveReport() {
21
+ return { status: 'ok', uptimeSeconds: Math.floor(process.uptime()) };
22
+ }
23
+ /** Store con health check configurati nelle opzioni Accessi. */
24
+ function collectAccessiHealthStores(options) {
25
+ var _a, _b, _c, _d, _e, _f, _g;
26
+ const stores = [];
27
+ const seen = new Set();
28
+ const add = (name, store) => {
29
+ if (!store || seen.has(store) || typeof store.healthCheck !== 'function')
30
+ return;
31
+ seen.add(store);
32
+ stores.push({ name, store });
33
+ };
34
+ add('publicAuthRateLimit', (_a = options.publicAuthRateLimit) === null || _a === void 0 ? void 0 : _a.store);
35
+ add('serviceTokenRateLimit', (_b = options.serviceTokens) === null || _b === void 0 ? void 0 : _b.rateLimitStore);
36
+ add('consoleEntry', (_c = options.consoleEntry) === null || _c === void 0 ? void 0 : _c.store);
37
+ add('edgeRateLimit', (_d = options.edgeRateLimit) === null || _d === void 0 ? void 0 : _d.store);
38
+ add('sessionRevocation', (_e = options.sessionRevocation) === null || _e === void 0 ? void 0 : _e.store);
39
+ add('accessTokenRevocation', (_f = options.accessTokenRevocation) === null || _f === void 0 ? void 0 : _f.store);
40
+ add('refreshTokenRotation', (_g = options.refreshTokenRotation) === null || _g === void 0 ? void 0 : _g.store);
41
+ return stores;
42
+ }
43
+ /** Verifica che lo schema Accessi sia inizializzato e alla versione attesa. */
44
+ function checkAccessiDatabase(options_1) {
45
+ return __awaiter(this, arguments, void 0, function* (options, resolveVersion = (value) => AccessiDatabaseUpdater_1.AccessiDatabaseUpdater.getCurrentVersion(value)) {
46
+ try {
47
+ const version = yield resolveVersion(options);
48
+ if (!version) {
49
+ return { ok: false, detail: 'schema Accessi non inizializzato' };
50
+ }
51
+ return {
52
+ ok: true,
53
+ detail: version === accessiSchema_1.ACCESSI_SCHEMA_VERSION ? version : `${version} (atteso ${accessiSchema_1.ACCESSI_SCHEMA_VERSION})`,
54
+ };
55
+ }
56
+ catch (error) {
57
+ return { ok: false, detail: error instanceof Error ? error.message : String(error) };
58
+ }
59
+ });
60
+ }
61
+ /**
62
+ * Report di readiness con lo stesso formato del servizio standalone.
63
+ *
64
+ * `bootstrap` e considerato completato: chi chiama questa funzione ha gia
65
+ * inizializzato il modulo. Il servizio standalone mantiene il proprio stato di
66
+ * bootstrap prima di delegare qui.
67
+ */
68
+ function checkAccessiReadiness(options_1) {
69
+ return __awaiter(this, arguments, void 0, function* (options, readinessChecks = [], dependencies = {}) {
70
+ const checks = {
71
+ bootstrap: { ok: true },
72
+ database: yield checkAccessiDatabase(options, dependencies.databaseVersion),
73
+ };
74
+ const stores = collectAccessiHealthStores(options);
75
+ yield Promise.all(stores.map((_a) => __awaiter(this, [_a], void 0, function* ({ name, store }) {
76
+ var _b;
77
+ try {
78
+ checks[name] = { ok: Boolean(yield ((_b = store.healthCheck) === null || _b === void 0 ? void 0 : _b.call(store))) };
79
+ }
80
+ catch (error) {
81
+ checks[name] = {
82
+ ok: false,
83
+ detail: error instanceof Error ? error.message : String(error),
84
+ };
85
+ }
86
+ })));
87
+ for (const check of readinessChecks) {
88
+ try {
89
+ checks[check.name] = { ok: Boolean(yield check.check()) };
90
+ }
91
+ catch (error) {
92
+ checks[check.name] = {
93
+ ok: false,
94
+ detail: error instanceof Error ? error.message : String(error),
95
+ };
96
+ }
97
+ }
98
+ const ok = Object.values(checks).every((check) => check.ok);
99
+ return {
100
+ status: ok ? 'ok' : 'error',
101
+ checks,
102
+ timestamp: new Date().toISOString(),
103
+ };
104
+ });
105
+ }
106
+ /** Status HTTP da usare per un report di readiness: 200 o 503. */
107
+ function readinessHttpStatus(report) {
108
+ return report.status === 'ok' ? 200 : 503;
109
+ }
110
+ //# sourceMappingURL=readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../../src/accessi-module/health/readiness.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessiOptions } from '../AccessiModule';\nimport { ACCESSI_SCHEMA_VERSION } from '../database-updates/accessiSchema';\nimport { AccessiDatabaseUpdater } from '../database-updates/AccessiDatabaseUpdater';\n\n/**\n * Health e readiness riutilizzabili.\n *\n * Lo stesso contratto e usato da `createAccessiService` (servizio standalone) e\n * da `createAccessiHealthModule` (host Nest con `AccessiModule.forRoot`):\n * `/health/live` risponde sempre se il processo e vivo, `/health/ready` verifica\n * bootstrap, schema del database, store condivisi e check applicativi.\n */\nexport interface AccessiReadinessCheck {\n name: string;\n check: () => boolean | Promise<boolean>;\n}\n\nexport interface AccessiHealthCheckResult {\n ok: boolean;\n detail?: string;\n}\n\nexport interface AccessiReadinessReport {\n status: 'ok' | 'error';\n checks: Record<string, AccessiHealthCheckResult>;\n timestamp: string;\n}\n\nexport interface AccessiLiveReport {\n status: 'ok';\n uptimeSeconds: number;\n}\n\n/** Store condivisi con health check, senza duplicati. */\nexport interface AccessiHealthStore {\n name: string;\n store: { healthCheck?: () => Promise<boolean> };\n}\n\nexport interface AccessiReadinessDependencies {\n /** Override del check database (usato dai test o da host con pool esterni). */\n databaseVersion?: (options: AccessiOptions) => Promise<string | null | undefined>;\n}\n\n/** Stato liveness: il processo risponde, nessun accesso a DB o store. */\nexport function createAccessiLiveReport(): AccessiLiveReport {\n return { status: 'ok', uptimeSeconds: Math.floor(process.uptime()) };\n}\n\n/** Store con health check configurati nelle opzioni Accessi. */\nexport function collectAccessiHealthStores(options: AccessiOptions): AccessiHealthStore[] {\n const stores: AccessiHealthStore[] = [];\n const seen = new Set<unknown>();\n\n const add = (name: string, store: { healthCheck?: () => Promise<boolean> } | undefined): void => {\n if (!store || seen.has(store) || typeof store.healthCheck !== 'function') return;\n seen.add(store);\n stores.push({ name, store });\n };\n\n add('publicAuthRateLimit', options.publicAuthRateLimit?.store);\n add('serviceTokenRateLimit', options.serviceTokens?.rateLimitStore);\n add('consoleEntry', options.consoleEntry?.store);\n add('edgeRateLimit', options.edgeRateLimit?.store);\n add('sessionRevocation', options.sessionRevocation?.store);\n add('accessTokenRevocation', options.accessTokenRevocation?.store);\n add('refreshTokenRotation', options.refreshTokenRotation?.store);\n return stores;\n}\n\n/** Verifica che lo schema Accessi sia inizializzato e alla versione attesa. */\nexport async function checkAccessiDatabase(\n options: AccessiOptions,\n resolveVersion: AccessiReadinessDependencies['databaseVersion'] = (value) =>\n AccessiDatabaseUpdater.getCurrentVersion(value),\n): Promise<AccessiHealthCheckResult> {\n try {\n const version = await resolveVersion(options);\n if (!version) {\n return { ok: false, detail: 'schema Accessi non inizializzato' };\n }\n return {\n ok: true,\n detail: version === ACCESSI_SCHEMA_VERSION ? version : `${version} (atteso ${ACCESSI_SCHEMA_VERSION})`,\n };\n } catch (error) {\n return { ok: false, detail: error instanceof Error ? error.message : String(error) };\n }\n}\n\n/**\n * Report di readiness con lo stesso formato del servizio standalone.\n *\n * `bootstrap` e considerato completato: chi chiama questa funzione ha gia\n * inizializzato il modulo. Il servizio standalone mantiene il proprio stato di\n * bootstrap prima di delegare qui.\n */\nexport async function checkAccessiReadiness(\n options: AccessiOptions,\n readinessChecks: AccessiReadinessCheck[] = [],\n dependencies: AccessiReadinessDependencies = {},\n): Promise<AccessiReadinessReport> {\n const checks: Record<string, AccessiHealthCheckResult> = {\n bootstrap: { ok: true },\n database: await checkAccessiDatabase(options, dependencies.databaseVersion),\n };\n\n const stores = collectAccessiHealthStores(options);\n await Promise.all(stores.map(async ({ name, store }) => {\n try {\n checks[name] = { ok: Boolean(await store.healthCheck?.()) };\n } catch (error) {\n checks[name] = {\n ok: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n }\n }));\n\n for (const check of readinessChecks) {\n try {\n checks[check.name] = { ok: Boolean(await check.check()) };\n } catch (error) {\n checks[check.name] = {\n ok: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n const ok = Object.values(checks).every((check) => check.ok);\n return {\n status: ok ? 'ok' : 'error',\n checks,\n timestamp: new Date().toISOString(),\n };\n}\n\n/** Status HTTP da usare per un report di readiness: 200 o 503. */\nexport function readinessHttpStatus(report: AccessiReadinessReport): 200 | 503 {\n return report.status === 'ok' ? 200 : 503;\n}\n"]}
@@ -60,6 +60,8 @@ export { assertEmailConfigured, isEmailConfigured, AccessiEmailNotConfiguredErro
60
60
  export { buildLoginAsUrl, LOGIN_AS_QUERY_PARAM } from './security/loginAs';
61
61
  export { buildAccessiJwks, createAccessiJwksHandler, getAccessiJwksPath, setupAccessiJwks } from './security/jwks';
62
62
  export type { AccessiJwksDocument, AccessiJwksKey } from './security/jwks';
63
+ export { getAccessiAccessTokenSigningConfig, getAccessiAccessTokenVerificationConfig, getAccessiRefreshTokenSigningConfig, getAccessiRefreshTokenVerificationConfig, resolveAccessiVerificationKeys, verifyAccessiJwt } from './security/jwtTokenOptions';
64
+ export type { AccessiJwtVerificationConfig, AccessiUnknownKeyIdEvent } from './security/jwtTokenOptions';
63
65
  export { FederatedAuthService } from './federated-auth/FederatedAuthService';
64
66
  export type { FederatedAuthenticationResult, FederatedIdentity, FederatedProvider, VerifiedFederatedIdentity } from './federated-auth/FederatedAuthTypes';
65
67
  export * from "./Dtos";
@@ -68,3 +70,7 @@ export { accessiRequirement } from "./middleware/accessiRequirements";
68
70
  export { registerAccessiModuleServices, getAccessiModuleServices, ACCESSI_MODULE_SERVICES_LOCALS_KEY } from "./accessiRuntime";
69
71
  export type { AccessiModuleServices } from "./accessiRuntime";
70
72
  export type { AccessiAuthorizationOptions, AccessiRequirementNode, AccessiCustomRequirementContext, AccessiCustomRequirementHandler } from "./middleware/accessiRequirements";
73
+ export { checkAccessiReadiness, checkAccessiDatabase, collectAccessiHealthStores, createAccessiLiveReport, readinessHttpStatus } from './health/readiness';
74
+ export type { AccessiHealthCheckResult, AccessiHealthStore, AccessiLiveReport, AccessiReadinessCheck, AccessiReadinessDependencies, AccessiReadinessReport } from './health/readiness';
75
+ export { createAccessiHealthModule } from './health/nest';
76
+ export type { AccessiHealthModuleOptions } from './health/nest';
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.getAccessiServiceToken = exports.RequireServiceTokenScopes = exports.ServiceTokenGuard = exports.isValidAdminBootstrapToken = exports.clearAdminBootstrapToken = exports.getAdminBootstrapToken = exports.getOrCreateAdminBootstrapToken = exports.AdminBootstrapService = exports.SchemaExportService = exports.ServiceTokenService = exports.discoverCatalogScripts = exports.computeCatalogScriptChecksum = exports.leadingStatementKeyword = exports.analyzeCatalogScript = exports.splitSqlStatements = exports.listPendingCatalogScripts = exports.applyCatalogScripts = exports.AccessiCatalogMigrator = exports.revokeAccessiAccessTokenIfConfigured = exports.revokeAccessiAccessToken = exports.isAccessiAccessTokenRevoked = exports.getAccessTokenRevocationStore = exports.createRedisAccessTokenRevocationStore = exports.createMemoryAccessTokenRevocationStore = exports.revokeRefreshTokenFamily = exports.isRefreshTokenFamilyRevoked = exports.getRefreshTokenRotationStore = exports.consumeRefreshToken = exports.createRedisRefreshTokenRotationStore = exports.createMemoryRefreshTokenRotationStore = exports.getSessionRevocationStore = exports.isAccessiTokenRevoked = exports.revokeAccessiUserSessionsIfConfigured = exports.revokeAccessiUserSessions = exports.createRedisSessionRevocationStore = exports.createMemorySessionRevocationStore = exports.auditAccessi = exports.validateAccessiOptions = exports.assertValidAccessiOptions = exports.createAccessiEdgeRateLimitMiddleware = exports.getDefaultRateLimitStore = exports.createRedisRateLimitStore = exports.createMemoryRateLimitStore = exports.getDefaultConsoleEntryStore = exports.createRedisConsoleEntryStore = exports.createMemoryConsoleEntryStore = exports.AccessiDatabaseUpdater = exports.FederatedAuthExchangeController = exports.AccessiIntrospectionController = exports.AccessiModule = void 0;
30
- exports.ACCESSI_MODULE_SERVICES_LOCALS_KEY = exports.getAccessiModuleServices = exports.registerAccessiModuleServices = exports.accessiRequirement = exports.authenticateGen = exports.authorizeAccessi = exports.FederatedAuthService = exports.setupAccessiJwks = exports.getAccessiJwksPath = exports.createAccessiJwksHandler = exports.buildAccessiJwks = exports.LOGIN_AS_QUERY_PARAM = exports.buildLoginAsUrl = exports.ACCESSI_EMAIL_NOT_CONFIGURED = exports.AccessiEmailNotConfiguredError = exports.isEmailConfigured = exports.assertEmailConfigured = void 0;
30
+ exports.createAccessiHealthModule = exports.readinessHttpStatus = exports.createAccessiLiveReport = exports.collectAccessiHealthStores = exports.checkAccessiDatabase = exports.checkAccessiReadiness = exports.ACCESSI_MODULE_SERVICES_LOCALS_KEY = exports.getAccessiModuleServices = exports.registerAccessiModuleServices = exports.accessiRequirement = exports.authenticateGen = exports.authorizeAccessi = exports.FederatedAuthService = exports.verifyAccessiJwt = exports.resolveAccessiVerificationKeys = exports.getAccessiRefreshTokenVerificationConfig = exports.getAccessiRefreshTokenSigningConfig = exports.getAccessiAccessTokenVerificationConfig = exports.getAccessiAccessTokenSigningConfig = exports.setupAccessiJwks = exports.getAccessiJwksPath = exports.createAccessiJwksHandler = exports.buildAccessiJwks = exports.LOGIN_AS_QUERY_PARAM = exports.buildLoginAsUrl = exports.ACCESSI_EMAIL_NOT_CONFIGURED = exports.AccessiEmailNotConfiguredError = exports.isEmailConfigured = exports.assertEmailConfigured = void 0;
31
31
  exports.initializeAccessiModule = initializeAccessiModule;
32
32
  const express_1 = __importDefault(require("express"));
33
33
  const core_1 = require("@nestjs/core");
@@ -232,6 +232,13 @@ Object.defineProperty(exports, "buildAccessiJwks", { enumerable: true, get: func
232
232
  Object.defineProperty(exports, "createAccessiJwksHandler", { enumerable: true, get: function () { return jwks_2.createAccessiJwksHandler; } });
233
233
  Object.defineProperty(exports, "getAccessiJwksPath", { enumerable: true, get: function () { return jwks_2.getAccessiJwksPath; } });
234
234
  Object.defineProperty(exports, "setupAccessiJwks", { enumerable: true, get: function () { return jwks_2.setupAccessiJwks; } });
235
+ var jwtTokenOptions_1 = require("./security/jwtTokenOptions");
236
+ Object.defineProperty(exports, "getAccessiAccessTokenSigningConfig", { enumerable: true, get: function () { return jwtTokenOptions_1.getAccessiAccessTokenSigningConfig; } });
237
+ Object.defineProperty(exports, "getAccessiAccessTokenVerificationConfig", { enumerable: true, get: function () { return jwtTokenOptions_1.getAccessiAccessTokenVerificationConfig; } });
238
+ Object.defineProperty(exports, "getAccessiRefreshTokenSigningConfig", { enumerable: true, get: function () { return jwtTokenOptions_1.getAccessiRefreshTokenSigningConfig; } });
239
+ Object.defineProperty(exports, "getAccessiRefreshTokenVerificationConfig", { enumerable: true, get: function () { return jwtTokenOptions_1.getAccessiRefreshTokenVerificationConfig; } });
240
+ Object.defineProperty(exports, "resolveAccessiVerificationKeys", { enumerable: true, get: function () { return jwtTokenOptions_1.resolveAccessiVerificationKeys; } });
241
+ Object.defineProperty(exports, "verifyAccessiJwt", { enumerable: true, get: function () { return jwtTokenOptions_1.verifyAccessiJwt; } });
235
242
  var FederatedAuthService_1 = require("./federated-auth/FederatedAuthService");
236
243
  Object.defineProperty(exports, "FederatedAuthService", { enumerable: true, get: function () { return FederatedAuthService_1.FederatedAuthService; } });
237
244
  __exportStar(require("./Dtos"), exports);
@@ -244,4 +251,12 @@ var accessiRuntime_2 = require("./accessiRuntime");
244
251
  Object.defineProperty(exports, "registerAccessiModuleServices", { enumerable: true, get: function () { return accessiRuntime_2.registerAccessiModuleServices; } });
245
252
  Object.defineProperty(exports, "getAccessiModuleServices", { enumerable: true, get: function () { return accessiRuntime_2.getAccessiModuleServices; } });
246
253
  Object.defineProperty(exports, "ACCESSI_MODULE_SERVICES_LOCALS_KEY", { enumerable: true, get: function () { return accessiRuntime_2.ACCESSI_MODULE_SERVICES_LOCALS_KEY; } });
254
+ var readiness_1 = require("./health/readiness");
255
+ Object.defineProperty(exports, "checkAccessiReadiness", { enumerable: true, get: function () { return readiness_1.checkAccessiReadiness; } });
256
+ Object.defineProperty(exports, "checkAccessiDatabase", { enumerable: true, get: function () { return readiness_1.checkAccessiDatabase; } });
257
+ Object.defineProperty(exports, "collectAccessiHealthStores", { enumerable: true, get: function () { return readiness_1.collectAccessiHealthStores; } });
258
+ Object.defineProperty(exports, "createAccessiLiveReport", { enumerable: true, get: function () { return readiness_1.createAccessiLiveReport; } });
259
+ Object.defineProperty(exports, "readinessHttpStatus", { enumerable: true, get: function () { return readiness_1.readinessHttpStatus; } });
260
+ var nest_1 = require("./health/nest");
261
+ Object.defineProperty(exports, "createAccessiHealthModule", { enumerable: true, get: function () { return nest_1.createAccessiHealthModule; } });
247
262
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { Application, Request } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport type { INestApplication } from \"@nestjs/common\";\nimport type { OpenAPIObject } from \"@nestjs/swagger\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport { AuthService } from \"./Services/AuthService/AuthService\";\nimport {\n buildOpenApiExcludePaths,\n isOpenApiRequestPath,\n resolveAccessiOpenApiOptions,\n setupOpenApi\n} from \"../openapi/OpenApiConfig\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\nimport { registerAccessiModuleServices } from \"./accessiRuntime\";\nimport { logAccessiStartup } from \"./startupLog\";\nimport { createAccessiValidationPipe } from './security/accessiValidation';\nimport { AccessiHttpExceptionFilter } from './security/AccessiHttpExceptionFilter';\nimport { assertEmailConfigured } from './security/emailConfiguration';\nimport { getAccessiJwksPath, setupAccessiJwks } from './security/jwks';\nimport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\n\n/** Esito del bootstrap Express di Accessi. */\nexport interface AccessiModuleInitializationResult {\n /** Sotto-app Nest che serve `/api/accessi/*` e la documentazione. */\n nestApp: INestApplication;\n /** Documento OpenAPI generato, mergiabile nel documento unico dell'host. */\n document: OpenAPIObject;\n}\n\nfunction describeDatabaseTarget(options: AccessiOptions): string {\n const dbOptions = options.databaseOptions as {\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n };\n\n return `${dbOptions.host ?? \"?\"}:${dbOptions.port ?? \"?\"} -> ${dbOptions.database ?? \"?\"} as ${dbOptions.user ?? \"?\"}`;\n}\n\n/**\n * Monta il modulo Accessi in un'applicazione Express gia esistente.\n *\n * Il bootstrap crea un host Nest isolato per le rotte `/api/accessi`, inizializza la\n * documentazione OpenAPI, validazione ed error handler, quindi rende disponibile\n * `authorizeAccessi` al resto dell'app.\n * Attendere questa Promise prima di aprire la porta HTTP: durante il bootstrap il middleware\n * restituisce `ACCESSI_AUTH_INITIALIZING` invece di autorizzare richieste parzialmente inizializzate.\n *\n * @param app Applicazione Express ospitante. Non viene sostituita ne vengono intercettate rotte estranee ad Accessi.\n * @param options Configurazione riservata del modulo; proviene normalmente da variabili d'ambiente o secret manager.\n * @returns Il sotto-app Nest e il documento OpenAPI generato (utile per il merge nell'host).\n */\nexport async function initializeAccessiModule(\n app: Application,\n options: AccessiOptions\n): Promise<AccessiModuleInitializationResult> {\n // Il servizio email e obbligatorio: reset password, 2FA e creazione utente ne dipendono.\n assertEmailConfigured(options);\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n const startedAt = performance.now();\n const resolvedOpenApi = resolveAccessiOpenApiOptions(options.openapi);\n\n try {\n logger.info(\"Inizializzazione modulo accessi avviata.\");\n logger.info(`Target database accessi: ${describeDatabaseTarget(options)}`);\n logger.info(\n `Configurazione accessi: autoUpdateDatabase=${options.autoUpdateDatabase !== false}, legacyPasswordMigrationOnStartup=${options.legacyPasswordMigrationOnStartup !== false}`\n );\n const nestHostApp = express();\n if (options.http?.trustProxy !== undefined) {\n app.set('trust proxy', options.http.trustProxy);\n nestHostApp.set('trust proxy', options.http.trustProxy);\n }\n const jwksPath = getAccessiJwksPath(options);\n const isAccessiRoute = (path: string) =>\n path === \"/api/accessi\" ||\n path.startsWith(\"/api/accessi/\") ||\n isOpenApiRequestPath(path, resolvedOpenApi) ||\n (jwksPath !== undefined && path === jwksPath);\n const edgeRateLimit = options.edgeRateLimit\n ? createAccessiEdgeRateLimitMiddleware({\n ...options.edgeRateLimit,\n match: options.edgeRateLimit.match ?? ((path) => isAccessiRoute(path)),\n })\n : undefined;\n if (edgeRateLimit) {\n app.use(edgeRateLimit);\n }\n if (options.http?.securityHeaders !== false) {\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n res.setHeader('Referrer-Policy', 'no-referrer');\n res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');\n return next();\n });\n }\n\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n\n return nestHostApp(req, res, next);\n });\n\n setupAccessiJwks(app, options);\n if (jwksPath) {\n logger.info(`JWKS accessi disponibile su: ${jwksPath}`);\n }\n\n const nestExpressInstance = new ExpressAdapter(nestHostApp);\n\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: options.bufferLogs !== false,\n ...(options.logger ? { logger: options.logger } : {})\n });\n logger.info(\"Applicazione Nest accessi creata.\");\n\n if (options.http?.cors !== false) {\n nestApp.enableCors(options.http?.cors ?? { exposedHeaders: ['X-Total-Count'] });\n }\n nestApp.useGlobalPipes(createAccessiValidationPipe());\n nestApp.useGlobalFilters(new AccessiHttpExceptionFilter());\n\n nestApp.setGlobalPrefix('api', {\n exclude: buildOpenApiExcludePaths(resolvedOpenApi)\n });\n\n const document = setupOpenApi(nestApp, resolvedOpenApi);\n logger.info(\"Avvio init del modulo accessi.\");\n await nestApp.init();\n logger.info(\"Init del modulo accessi completata.\");\n if (options.legacyPasswordMigrationOnStartup !== false) {\n logger.info(\"Avvio migrazione password legacy accessi.\");\n const passwordMigrationService = nestApp.get(AuthService);\n await passwordMigrationService.migrateLegacyEncryptedPasswords();\n logger.info(\"Migrazione password legacy accessi completata.\");\n }\n\n const accessiServices = registerAccessiModuleServices(app, nestApp);\n app.locals.accessiAuthService = accessiServices.authenticateGenService;\n setAccessiAuthService(accessiServices.authenticateGenService);\n logAccessiStartup(options, resolvedOpenApi);\n const elapsedMs = performance.now() - startedAt;\n logger.info(`Accessi initialized. Tempo totale bootstrap: ${elapsedMs.toFixed(2)} ms`);\n\n return { nestApp, document };\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\n \"Errore in initialize AccessiModule:\",\n error instanceof Error\n ? { name: error.name, message: error.message, stack: error.stack }\n : { error: String(error) }\n );\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport { AccessiIntrospectionController } from \"./Controllers/AccessiIntrospectionController\";\nexport { FederatedAuthExchangeController } from \"./federated-auth/FederatedAuthExchangeController\";\nexport type { AccessiTokenIntrospectionResult } from \"./Services/AuthService/AuthService\";\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\nexport type { AccessiOptions, EmailOptions, JwtOptions, ExtensionFieldsOptions, PublicAuthRateLimitOptions, PublicAuthRateLimitRuleOptions } from \"./AccessiModule\";\nexport type { PublicRegistrationOptions, FederatedAuthenticationOptions, ServiceTokenOptions } from \"./AccessiModule\";\nexport type { CatalogScriptsOptions, CatalogScriptChecksumPolicy, ConsoleEntryOptions } from \"./AccessiModule\";\nexport {\n createMemoryConsoleEntryStore,\n createRedisConsoleEntryStore,\n getDefaultConsoleEntryStore\n} from './security/consoleEntry';\nexport type {\n ConsoleEntryRedisClient,\n ConsoleEntryRecord,\n ConsoleEntryStore,\n ConsoleEntryTicket,\n MemoryConsoleEntryStore,\n RedisConsoleEntryStoreOptions\n} from './security/consoleEntry';\nexport {\n createMemoryRateLimitStore,\n createRedisRateLimitStore,\n getDefaultRateLimitStore\n} from './security/rateLimitStore';\nexport type {\n MemoryRateLimitStore,\n RateLimitDecision,\n RateLimitRedisClient,\n RateLimitStore,\n RedisRateLimitStoreOptions\n} from './security/rateLimitStore';\nexport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\nexport type {\n AccessiEdgeRateLimitMiddleware,\n AccessiEdgeRateLimitOptions\n} from './security/edgeRateLimit';\nexport {\n assertValidAccessiOptions,\n validateAccessiOptions\n} from './security/validateOptions';\nexport { auditAccessi } from './security/audit';\nexport {\n createMemorySessionRevocationStore,\n createRedisSessionRevocationStore,\n revokeAccessiUserSessions,\n revokeAccessiUserSessionsIfConfigured,\n isAccessiTokenRevoked,\n getSessionRevocationStore\n} from './security/sessionRevocation';\nexport type {\n MemorySessionRevocationStore,\n RedisSessionRevocationStoreOptions,\n SessionRevocationOptions,\n SessionRevocationRedisClient,\n SessionRevocationStore\n} from './security/sessionRevocation';\nexport {\n createMemoryRefreshTokenRotationStore,\n createRedisRefreshTokenRotationStore,\n consumeRefreshToken,\n getRefreshTokenRotationStore,\n isRefreshTokenFamilyRevoked,\n revokeRefreshTokenFamily\n} from './security/refreshTokenRotation';\nexport type {\n MemoryRefreshTokenRotationStore,\n RedisRefreshTokenRotationStoreOptions,\n RefreshTokenConsumeResult,\n RefreshTokenRotationOptions,\n RefreshTokenRotationRedisClient,\n RefreshTokenRotationStore\n} from './security/refreshTokenRotation';\nexport {\n createMemoryAccessTokenRevocationStore,\n createRedisAccessTokenRevocationStore,\n getAccessTokenRevocationStore,\n isAccessiAccessTokenRevoked,\n revokeAccessiAccessToken,\n revokeAccessiAccessTokenIfConfigured\n} from './security/accessTokenRevocation';\nexport type {\n AccessTokenRevocationOptions,\n AccessTokenRevocationRedisClient,\n AccessTokenRevocationStore,\n MemoryAccessTokenRevocationStore,\n RedisAccessTokenRevocationStoreOptions\n} from './security/accessTokenRevocation';\nexport type {\n AccessiOptionsValidationIssue,\n AccessiOptionsValidationResult\n} from './security/validateOptions';\nexport {\n AccessiCatalogMigrator,\n applyCatalogScripts,\n listPendingCatalogScripts,\n splitSqlStatements,\n analyzeCatalogScript,\n leadingStatementKeyword,\n computeCatalogScriptChecksum,\n discoverCatalogScripts\n} from \"./database-updates/AccessiCatalogMigrator\";\nexport type { CatalogMigrationReport, CatalogScriptMigration } from \"./database-updates/AccessiCatalogMigrator\";\nexport { ServiceTokenService } from './Services/ServiceTokenService/ServiceTokenService';\nexport type {\n ServiceTokenMetadata,\n IssuedServiceToken,\n VerifiedServiceToken,\n IssueServiceTokenInput\n} from './Services/ServiceTokenService/ServiceTokenService';\nexport { SchemaExportService } from './Services/SchemaExportService/SchemaExportService';\nexport type { SchemaDdlResult, SchemaDdlSection, SchemaEntitiesResult } from './Services/SchemaExportService/SchemaExportService';\nexport { AdminBootstrapService } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport type { BootstrapAdminResult } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport {\n getOrCreateAdminBootstrapToken,\n getAdminBootstrapToken,\n clearAdminBootstrapToken,\n isValidAdminBootstrapToken\n} from './security/adminBootstrap';\nexport { ServiceTokenGuard, RequireServiceTokenScopes, getAccessiServiceToken } from './security/serviceTokenGuard';\nexport { assertEmailConfigured, isEmailConfigured, AccessiEmailNotConfiguredError, ACCESSI_EMAIL_NOT_CONFIGURED } from './security/emailConfiguration';\nexport { buildLoginAsUrl, LOGIN_AS_QUERY_PARAM } from './security/loginAs';\nexport {\n buildAccessiJwks,\n createAccessiJwksHandler,\n getAccessiJwksPath,\n setupAccessiJwks\n} from './security/jwks';\nexport type { AccessiJwksDocument, AccessiJwksKey } from './security/jwks';\nexport { FederatedAuthService } from './federated-auth/FederatedAuthService';\nexport type { FederatedAuthenticationResult, FederatedIdentity, FederatedProvider, VerifiedFederatedIdentity } from './federated-auth/FederatedAuthTypes';\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\nexport {\n registerAccessiModuleServices,\n getAccessiModuleServices,\n ACCESSI_MODULE_SERVICES_LOCALS_KEY\n} from \"./accessiRuntime\";\nexport type { AccessiModuleServices } from \"./accessiRuntime\";\nexport type {\n AccessiAuthorizationOptions,\n AccessiRequirementNode,\n AccessiCustomRequirementContext,\n AccessiCustomRequirementHandler\n} from \"./middleware/accessiRequirements\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { Application, Request } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport type { INestApplication } from \"@nestjs/common\";\nimport type { OpenAPIObject } from \"@nestjs/swagger\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport { AuthService } from \"./Services/AuthService/AuthService\";\nimport {\n buildOpenApiExcludePaths,\n isOpenApiRequestPath,\n resolveAccessiOpenApiOptions,\n setupOpenApi\n} from \"../openapi/OpenApiConfig\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\nimport { registerAccessiModuleServices } from \"./accessiRuntime\";\nimport { logAccessiStartup } from \"./startupLog\";\nimport { createAccessiValidationPipe } from './security/accessiValidation';\nimport { AccessiHttpExceptionFilter } from './security/AccessiHttpExceptionFilter';\nimport { assertEmailConfigured } from './security/emailConfiguration';\nimport { getAccessiJwksPath, setupAccessiJwks } from './security/jwks';\nimport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\n\n/** Esito del bootstrap Express di Accessi. */\nexport interface AccessiModuleInitializationResult {\n /** Sotto-app Nest che serve `/api/accessi/*` e la documentazione. */\n nestApp: INestApplication;\n /** Documento OpenAPI generato, mergiabile nel documento unico dell'host. */\n document: OpenAPIObject;\n}\n\nfunction describeDatabaseTarget(options: AccessiOptions): string {\n const dbOptions = options.databaseOptions as {\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n };\n\n return `${dbOptions.host ?? \"?\"}:${dbOptions.port ?? \"?\"} -> ${dbOptions.database ?? \"?\"} as ${dbOptions.user ?? \"?\"}`;\n}\n\n/**\n * Monta il modulo Accessi in un'applicazione Express gia esistente.\n *\n * Il bootstrap crea un host Nest isolato per le rotte `/api/accessi`, inizializza la\n * documentazione OpenAPI, validazione ed error handler, quindi rende disponibile\n * `authorizeAccessi` al resto dell'app.\n * Attendere questa Promise prima di aprire la porta HTTP: durante il bootstrap il middleware\n * restituisce `ACCESSI_AUTH_INITIALIZING` invece di autorizzare richieste parzialmente inizializzate.\n *\n * @param app Applicazione Express ospitante. Non viene sostituita ne vengono intercettate rotte estranee ad Accessi.\n * @param options Configurazione riservata del modulo; proviene normalmente da variabili d'ambiente o secret manager.\n * @returns Il sotto-app Nest e il documento OpenAPI generato (utile per il merge nell'host).\n */\nexport async function initializeAccessiModule(\n app: Application,\n options: AccessiOptions\n): Promise<AccessiModuleInitializationResult> {\n // Il servizio email e obbligatorio: reset password, 2FA e creazione utente ne dipendono.\n assertEmailConfigured(options);\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n const startedAt = performance.now();\n const resolvedOpenApi = resolveAccessiOpenApiOptions(options.openapi);\n\n try {\n logger.info(\"Inizializzazione modulo accessi avviata.\");\n logger.info(`Target database accessi: ${describeDatabaseTarget(options)}`);\n logger.info(\n `Configurazione accessi: autoUpdateDatabase=${options.autoUpdateDatabase !== false}, legacyPasswordMigrationOnStartup=${options.legacyPasswordMigrationOnStartup !== false}`\n );\n const nestHostApp = express();\n if (options.http?.trustProxy !== undefined) {\n app.set('trust proxy', options.http.trustProxy);\n nestHostApp.set('trust proxy', options.http.trustProxy);\n }\n const jwksPath = getAccessiJwksPath(options);\n const isAccessiRoute = (path: string) =>\n path === \"/api/accessi\" ||\n path.startsWith(\"/api/accessi/\") ||\n isOpenApiRequestPath(path, resolvedOpenApi) ||\n (jwksPath !== undefined && path === jwksPath);\n const edgeRateLimit = options.edgeRateLimit\n ? createAccessiEdgeRateLimitMiddleware({\n ...options.edgeRateLimit,\n match: options.edgeRateLimit.match ?? ((path) => isAccessiRoute(path)),\n })\n : undefined;\n if (edgeRateLimit) {\n app.use(edgeRateLimit);\n }\n if (options.http?.securityHeaders !== false) {\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n res.setHeader('Referrer-Policy', 'no-referrer');\n res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');\n return next();\n });\n }\n\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n\n return nestHostApp(req, res, next);\n });\n\n setupAccessiJwks(app, options);\n if (jwksPath) {\n logger.info(`JWKS accessi disponibile su: ${jwksPath}`);\n }\n\n const nestExpressInstance = new ExpressAdapter(nestHostApp);\n\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: options.bufferLogs !== false,\n ...(options.logger ? { logger: options.logger } : {})\n });\n logger.info(\"Applicazione Nest accessi creata.\");\n\n if (options.http?.cors !== false) {\n nestApp.enableCors(options.http?.cors ?? { exposedHeaders: ['X-Total-Count'] });\n }\n nestApp.useGlobalPipes(createAccessiValidationPipe());\n nestApp.useGlobalFilters(new AccessiHttpExceptionFilter());\n\n nestApp.setGlobalPrefix('api', {\n exclude: buildOpenApiExcludePaths(resolvedOpenApi)\n });\n\n const document = setupOpenApi(nestApp, resolvedOpenApi);\n logger.info(\"Avvio init del modulo accessi.\");\n await nestApp.init();\n logger.info(\"Init del modulo accessi completata.\");\n if (options.legacyPasswordMigrationOnStartup !== false) {\n logger.info(\"Avvio migrazione password legacy accessi.\");\n const passwordMigrationService = nestApp.get(AuthService);\n await passwordMigrationService.migrateLegacyEncryptedPasswords();\n logger.info(\"Migrazione password legacy accessi completata.\");\n }\n\n const accessiServices = registerAccessiModuleServices(app, nestApp);\n app.locals.accessiAuthService = accessiServices.authenticateGenService;\n setAccessiAuthService(accessiServices.authenticateGenService);\n logAccessiStartup(options, resolvedOpenApi);\n const elapsedMs = performance.now() - startedAt;\n logger.info(`Accessi initialized. Tempo totale bootstrap: ${elapsedMs.toFixed(2)} ms`);\n\n return { nestApp, document };\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\n \"Errore in initialize AccessiModule:\",\n error instanceof Error\n ? { name: error.name, message: error.message, stack: error.stack }\n : { error: String(error) }\n );\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport { AccessiIntrospectionController } from \"./Controllers/AccessiIntrospectionController\";\nexport { FederatedAuthExchangeController } from \"./federated-auth/FederatedAuthExchangeController\";\nexport type { AccessiTokenIntrospectionResult } from \"./Services/AuthService/AuthService\";\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\nexport type { AccessiOptions, EmailOptions, JwtOptions, ExtensionFieldsOptions, PublicAuthRateLimitOptions, PublicAuthRateLimitRuleOptions } from \"./AccessiModule\";\nexport type { PublicRegistrationOptions, FederatedAuthenticationOptions, ServiceTokenOptions } from \"./AccessiModule\";\nexport type { CatalogScriptsOptions, CatalogScriptChecksumPolicy, ConsoleEntryOptions } from \"./AccessiModule\";\nexport {\n createMemoryConsoleEntryStore,\n createRedisConsoleEntryStore,\n getDefaultConsoleEntryStore\n} from './security/consoleEntry';\nexport type {\n ConsoleEntryRedisClient,\n ConsoleEntryRecord,\n ConsoleEntryStore,\n ConsoleEntryTicket,\n MemoryConsoleEntryStore,\n RedisConsoleEntryStoreOptions\n} from './security/consoleEntry';\nexport {\n createMemoryRateLimitStore,\n createRedisRateLimitStore,\n getDefaultRateLimitStore\n} from './security/rateLimitStore';\nexport type {\n MemoryRateLimitStore,\n RateLimitDecision,\n RateLimitRedisClient,\n RateLimitStore,\n RedisRateLimitStoreOptions\n} from './security/rateLimitStore';\nexport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\nexport type {\n AccessiEdgeRateLimitMiddleware,\n AccessiEdgeRateLimitOptions\n} from './security/edgeRateLimit';\nexport {\n assertValidAccessiOptions,\n validateAccessiOptions\n} from './security/validateOptions';\nexport { auditAccessi } from './security/audit';\nexport {\n createMemorySessionRevocationStore,\n createRedisSessionRevocationStore,\n revokeAccessiUserSessions,\n revokeAccessiUserSessionsIfConfigured,\n isAccessiTokenRevoked,\n getSessionRevocationStore\n} from './security/sessionRevocation';\nexport type {\n MemorySessionRevocationStore,\n RedisSessionRevocationStoreOptions,\n SessionRevocationOptions,\n SessionRevocationRedisClient,\n SessionRevocationStore\n} from './security/sessionRevocation';\nexport {\n createMemoryRefreshTokenRotationStore,\n createRedisRefreshTokenRotationStore,\n consumeRefreshToken,\n getRefreshTokenRotationStore,\n isRefreshTokenFamilyRevoked,\n revokeRefreshTokenFamily\n} from './security/refreshTokenRotation';\nexport type {\n MemoryRefreshTokenRotationStore,\n RedisRefreshTokenRotationStoreOptions,\n RefreshTokenConsumeResult,\n RefreshTokenRotationOptions,\n RefreshTokenRotationRedisClient,\n RefreshTokenRotationStore\n} from './security/refreshTokenRotation';\nexport {\n createMemoryAccessTokenRevocationStore,\n createRedisAccessTokenRevocationStore,\n getAccessTokenRevocationStore,\n isAccessiAccessTokenRevoked,\n revokeAccessiAccessToken,\n revokeAccessiAccessTokenIfConfigured\n} from './security/accessTokenRevocation';\nexport type {\n AccessTokenRevocationOptions,\n AccessTokenRevocationRedisClient,\n AccessTokenRevocationStore,\n MemoryAccessTokenRevocationStore,\n RedisAccessTokenRevocationStoreOptions\n} from './security/accessTokenRevocation';\nexport type {\n AccessiOptionsValidationIssue,\n AccessiOptionsValidationResult\n} from './security/validateOptions';\nexport {\n AccessiCatalogMigrator,\n applyCatalogScripts,\n listPendingCatalogScripts,\n splitSqlStatements,\n analyzeCatalogScript,\n leadingStatementKeyword,\n computeCatalogScriptChecksum,\n discoverCatalogScripts\n} from \"./database-updates/AccessiCatalogMigrator\";\nexport type { CatalogMigrationReport, CatalogScriptMigration } from \"./database-updates/AccessiCatalogMigrator\";\nexport { ServiceTokenService } from './Services/ServiceTokenService/ServiceTokenService';\nexport type {\n ServiceTokenMetadata,\n IssuedServiceToken,\n VerifiedServiceToken,\n IssueServiceTokenInput\n} from './Services/ServiceTokenService/ServiceTokenService';\nexport { SchemaExportService } from './Services/SchemaExportService/SchemaExportService';\nexport type { SchemaDdlResult, SchemaDdlSection, SchemaEntitiesResult } from './Services/SchemaExportService/SchemaExportService';\nexport { AdminBootstrapService } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport type { BootstrapAdminResult } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport {\n getOrCreateAdminBootstrapToken,\n getAdminBootstrapToken,\n clearAdminBootstrapToken,\n isValidAdminBootstrapToken\n} from './security/adminBootstrap';\nexport { ServiceTokenGuard, RequireServiceTokenScopes, getAccessiServiceToken } from './security/serviceTokenGuard';\nexport { assertEmailConfigured, isEmailConfigured, AccessiEmailNotConfiguredError, ACCESSI_EMAIL_NOT_CONFIGURED } from './security/emailConfiguration';\nexport { buildLoginAsUrl, LOGIN_AS_QUERY_PARAM } from './security/loginAs';\nexport {\n buildAccessiJwks,\n createAccessiJwksHandler,\n getAccessiJwksPath,\n setupAccessiJwks\n} from './security/jwks';\nexport type { AccessiJwksDocument, AccessiJwksKey } from './security/jwks';\nexport {\n getAccessiAccessTokenSigningConfig,\n getAccessiAccessTokenVerificationConfig,\n getAccessiRefreshTokenSigningConfig,\n getAccessiRefreshTokenVerificationConfig,\n resolveAccessiVerificationKeys,\n verifyAccessiJwt\n} from './security/jwtTokenOptions';\nexport type {\n AccessiJwtVerificationConfig,\n AccessiUnknownKeyIdEvent\n} from './security/jwtTokenOptions';\nexport { FederatedAuthService } from './federated-auth/FederatedAuthService';\nexport type { FederatedAuthenticationResult, FederatedIdentity, FederatedProvider, VerifiedFederatedIdentity } from './federated-auth/FederatedAuthTypes';\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\nexport {\n registerAccessiModuleServices,\n getAccessiModuleServices,\n ACCESSI_MODULE_SERVICES_LOCALS_KEY\n} from \"./accessiRuntime\";\nexport type { AccessiModuleServices } from \"./accessiRuntime\";\nexport type {\n AccessiAuthorizationOptions,\n AccessiRequirementNode,\n AccessiCustomRequirementContext,\n AccessiCustomRequirementHandler\n} from \"./middleware/accessiRequirements\";\n\nexport {\n checkAccessiReadiness,\n checkAccessiDatabase,\n collectAccessiHealthStores,\n createAccessiLiveReport,\n readinessHttpStatus\n} from './health/readiness';\nexport type {\n AccessiHealthCheckResult,\n AccessiHealthStore,\n AccessiLiveReport,\n AccessiReadinessCheck,\n AccessiReadinessDependencies,\n AccessiReadinessReport\n} from './health/readiness';\nexport { createAccessiHealthModule } from './health/nest';\nexport type { AccessiHealthModuleOptions } from './health/nest';\n\n"]}
@@ -1,43 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
2
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
3
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
4
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
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;
22
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
23
7
  };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
8
  var __metadata = (this && this.__metadata) || function (k, v) {
42
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
10
  };
@@ -56,7 +23,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
56
23
  Object.defineProperty(exports, "__esModule", { value: true });
57
24
  exports.JwtSimpleGuard = void 0;
58
25
  const common_1 = require("@nestjs/common");
59
- const jwt = __importStar(require("jsonwebtoken"));
60
26
  const UserService_1 = require("../Services/UserService/UserService");
61
27
  const authenticatedToken_1 = require("../security/authenticatedToken");
62
28
  const jwtTokenOptions_1 = require("../security/jwtTokenOptions");
@@ -85,7 +51,7 @@ let JwtSimpleGuard = class JwtSimpleGuard {
85
51
  }
86
52
  let payload;
87
53
  try {
88
- payload = jwt.verify(token, verification.key, verification.verifyOptions);
54
+ payload = (0, jwtTokenOptions_1.verifyAccessiJwt)(token, verification);
89
55
  }
90
56
  catch (_b) {
91
57
  throw new common_1.UnauthorizedException('Token non valido o scaduto.');
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../../src/accessi-module/jwt/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAOwB;AACxB,kDAAoC;AAEpC,qEAAkE;AAClE,uEAMwC;AACxC,iEAAsF;AACtF,qEAAsE;AAG/D,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAC8C,cAA8B,EACzD,WAAwB;QADG,mBAAc,GAAd,cAAc,CAAgB;QACzD,gBAAW,GAAX,WAAW,CAAa;IACxC,CAAC;IAEE,WAAW,CAAC,OAAyB;;YACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YAEpD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,8BAAqB,CAAC,iBAAiB,CAAC,CAAC;YAEpE,MAAM,KAAK,GAAG,IAAA,8CAAyB,EAAC,UAAU,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;YAEzE,IAAI,CAAC;gBACH,IAAI,YAAwE,CAAC;gBAC7E,IAAI,CAAC;oBACH,YAAY,GAAG,IAAA,yDAAuC,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC9E,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,qCAA4B,CAAC,6BAA6B,CAAC,CAAC;gBACxE,CAAC;gBACD,IAAI,OAAgC,CAAC;gBACrC,IAAI,CAAC;oBACH,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC;gBAC5E,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBACD,MAAM,YAAY,GAAG,IAAA,wDAAmC,EAAC,OAAO,CAAC,CAAC;gBAClE,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,IAAI,8BAAqB,CAAC,kCAAkC,CAAC,CAAC;gBACtE,CAAC;gBACD,IAAI,MAAM,IAAA,yCAAqB,EAAC,IAAI,CAAC,cAAc,EAAE,OAAkC,EAAE,YAAY,CAAC,EAAE,CAAC;oBACvG,MAAM,IAAI,8BAAqB,CAAC,oBAAoB,CAAC,CAAC;gBACxD,CAAC;gBAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,IAAA,qDAAgC,EAAC,WAAW,CAAC,IAAI,CAAC,IAAA,iDAA4B,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC1G,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBAED,OAAO,CAAC,IAAI,GAAG,IAAA,mDAA8B,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBACpE,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,qCAA4B,IAAI,KAAK,YAAY,8BAAqB,EAAE,CAAC;oBAC5F,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,qCAA4B,CAAC,yCAAyC,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;KAAA;CACF,CAAA;AAlDY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CACI,yBAAW;GAHhC,cAAc,CAkD1B","sourcesContent":["import {\n CanActivate,\n ExecutionContext,\n Inject,\n Injectable,\n InternalServerErrorException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport * as jwt from 'jsonwebtoken';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { UserService } from '../Services/UserService/UserService';\nimport {\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from '../security/authenticatedToken';\nimport { getAccessiAccessTokenVerificationConfig } from '../security/jwtTokenOptions';\nimport { isAccessiTokenRevoked } from '../security/sessionRevocation';\n\n@Injectable()\nexport class JwtSimpleGuard implements CanActivate {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly userService: UserService,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest();\n\n const authHeader = request.headers['authorization'];\n if (!authHeader) throw new UnauthorizedException('Token mancante.');\n\n const token = extractAccessiBearerToken(authHeader);\n if (!token) throw new UnauthorizedException('Formato token non valido.');\n\n try {\n let verification: ReturnType<typeof getAccessiAccessTokenVerificationConfig>;\n try {\n verification = getAccessiAccessTokenVerificationConfig(this.accessiOptions);\n } catch {\n throw new InternalServerErrorException('Chiave JWT non configurata.');\n }\n let payload: jwt.JwtPayload | string;\n try {\n payload = jwt.verify(token, verification.key, verification.verifyOptions);\n } catch {\n throw new UnauthorizedException('Token non valido o scaduto.');\n }\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(payload);\n if (!codiceUtente) {\n throw new UnauthorizedException('Token privo di un utente valido.');\n }\n if (await isAccessiTokenRevoked(this.accessiOptions, payload as Record<string, unknown>, codiceUtente)) {\n throw new UnauthorizedException('Sessione revocata.');\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(payload, currentUser)) {\n throw new UnauthorizedException('Utente non piu autorizzato.');\n }\n\n request.user = buildAuthenticatedTokenPayload(payload, currentUser);\n return true;\n } catch (error) {\n if (error instanceof InternalServerErrorException || error instanceof UnauthorizedException) {\n throw error;\n }\n throw new InternalServerErrorException('Errore durante la verifica dell utente.');\n }\n }\n}\n"]}
1
+ {"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../../src/accessi-module/jwt/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAOwB;AAExB,qEAAkE;AAClE,uEAMwC;AACxC,iEAAwG;AACxG,qEAAsE;AAG/D,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAC8C,cAA8B,EACzD,WAAwB;QADG,mBAAc,GAAd,cAAc,CAAgB;QACzD,gBAAW,GAAX,WAAW,CAAa;IACxC,CAAC;IAEE,WAAW,CAAC,OAAyB;;YACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YAEpD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,8BAAqB,CAAC,iBAAiB,CAAC,CAAC;YAEpE,MAAM,KAAK,GAAG,IAAA,8CAAyB,EAAC,UAAU,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;YAEzE,IAAI,CAAC;gBACH,IAAI,YAAwE,CAAC;gBAC7E,IAAI,CAAC;oBACH,YAAY,GAAG,IAAA,yDAAuC,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC9E,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,qCAA4B,CAAC,6BAA6B,CAAC,CAAC;gBACxE,CAAC;gBACD,IAAI,OAAgB,CAAC;gBACrB,IAAI,CAAC;oBACH,OAAO,GAAG,IAAA,kCAAgB,EAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBAClD,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBACD,MAAM,YAAY,GAAG,IAAA,wDAAmC,EAAC,OAAO,CAAC,CAAC;gBAClE,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,IAAI,8BAAqB,CAAC,kCAAkC,CAAC,CAAC;gBACtE,CAAC;gBACD,IAAI,MAAM,IAAA,yCAAqB,EAAC,IAAI,CAAC,cAAc,EAAE,OAAkC,EAAE,YAAY,CAAC,EAAE,CAAC;oBACvG,MAAM,IAAI,8BAAqB,CAAC,oBAAoB,CAAC,CAAC;gBACxD,CAAC;gBAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,IAAA,qDAAgC,EAAC,WAAW,CAAC,IAAI,CAAC,IAAA,iDAA4B,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC1G,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBAED,OAAO,CAAC,IAAI,GAAG,IAAA,mDAA8B,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBACpE,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,qCAA4B,IAAI,KAAK,YAAY,8BAAqB,EAAE,CAAC;oBAC5F,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,qCAA4B,CAAC,yCAAyC,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;KAAA;CACF,CAAA;AAlDY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CACI,yBAAW;GAHhC,cAAc,CAkD1B","sourcesContent":["import {\n CanActivate,\n ExecutionContext,\n Inject,\n Injectable,\n InternalServerErrorException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { UserService } from '../Services/UserService/UserService';\nimport {\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from '../security/authenticatedToken';\nimport { getAccessiAccessTokenVerificationConfig, verifyAccessiJwt } from '../security/jwtTokenOptions';\nimport { isAccessiTokenRevoked } from '../security/sessionRevocation';\n\n@Injectable()\nexport class JwtSimpleGuard implements CanActivate {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly userService: UserService,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest();\n\n const authHeader = request.headers['authorization'];\n if (!authHeader) throw new UnauthorizedException('Token mancante.');\n\n const token = extractAccessiBearerToken(authHeader);\n if (!token) throw new UnauthorizedException('Formato token non valido.');\n\n try {\n let verification: ReturnType<typeof getAccessiAccessTokenVerificationConfig>;\n try {\n verification = getAccessiAccessTokenVerificationConfig(this.accessiOptions);\n } catch {\n throw new InternalServerErrorException('Chiave JWT non configurata.');\n }\n let payload: unknown;\n try {\n payload = verifyAccessiJwt(token, verification);\n } catch {\n throw new UnauthorizedException('Token non valido o scaduto.');\n }\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(payload);\n if (!codiceUtente) {\n throw new UnauthorizedException('Token privo di un utente valido.');\n }\n if (await isAccessiTokenRevoked(this.accessiOptions, payload as Record<string, unknown>, codiceUtente)) {\n throw new UnauthorizedException('Sessione revocata.');\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(payload, currentUser)) {\n throw new UnauthorizedException('Utente non piu autorizzato.');\n }\n\n request.user = buildAuthenticatedTokenPayload(payload, currentUser);\n return true;\n } catch (error) {\n if (error instanceof InternalServerErrorException || error instanceof UnauthorizedException) {\n throw error;\n }\n throw new InternalServerErrorException('Errore durante la verifica dell utente.');\n }\n }\n}\n"]}
@@ -1,43 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
2
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
3
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
4
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
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;
22
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
23
7
  };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
8
  var __metadata = (this && this.__metadata) || function (k, v) {
42
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
10
  };
@@ -59,7 +26,6 @@ exports.beginAccessiAuthInitialization = beginAccessiAuthInitialization;
59
26
  exports.setAccessiAuthService = setAccessiAuthService;
60
27
  exports.failAccessiAuthInitialization = failAccessiAuthInitialization;
61
28
  exports.authorizeAccessi = authorizeAccessi;
62
- const jwt = __importStar(require("jsonwebtoken"));
63
29
  const common_1 = require("@nestjs/common");
64
30
  const PermissionService_1 = require("../Services/PermissionService/PermissionService");
65
31
  const UserService_1 = require("../Services/UserService/UserService");
@@ -152,7 +118,7 @@ function authorizeWithDependencies(req, res, next, options, accessiOptions, perm
152
118
  }
153
119
  let decoded;
154
120
  try {
155
- decoded = jwt.verify(token, verification.key, verification.verifyOptions);
121
+ decoded = (0, jwtTokenOptions_1.verifyAccessiJwt)(token, verification);
156
122
  }
157
123
  catch (_b) {
158
124
  throw authError(401, "AUTH_TOKEN_INVALID", "Invalid JWT token");
@@ -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 { Inject, Injectable } from \"@nestjs/common\";\nimport type { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\nimport { UserService } from \"../Services/UserService/UserService\";\nimport { Logger } from \"../../Logger\";\nimport {\n AccessiAuthorizationOptions,\n AccessiCustomRequirementContext,\n GrantsResult,\n RequirementEvaluationError,\n buildRequirementTree,\n evaluateRequirement,\n} from \"./accessiRequirements\";\nimport {\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../security/authenticatedToken\";\nimport { getAccessiAccessTokenVerificationConfig } from \"../security/jwtTokenOptions\";\nimport { isAccessiTokenRevoked } from \"../security/sessionRevocation\";\n\nconst logger = new Logger(\"AuthenticateGen\");\nconst ACCESSI_AUTH_SERVICE_LOCALS_KEY = \"accessiAuthService\";\nconst ACCESSI_AUTH_SERVICE_GLOBAL_KEY = Symbol.for(\"emilsoftware.accessiAuthService\");\nconst ACCESSI_AUTH_SERVICE_WAIT_MS = 15000;\n\ntype Deferred<T> = {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (reason?: unknown) => void;\n};\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 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 const message = `${authErr.status >= 500 ? \"Authentication failure\" : \"Authentication denied\"} ${JSON.stringify(payload)}`;\n if (authErr.status >= 500) logger.error(message);\n else logger.warning(message);\n}\n\n/** Sends the documented Accessi error contract from Express middleware. */\nfunction sendAuthenticationError(res: Response, authErr: AuthMiddlewareError): Response {\n const message =\n authErr.status === 403\n ? 'Operazione non autorizzata.'\n : authErr.status >= 500\n ? 'Errore interno del modulo Accessi.'\n : 'Autenticazione non valida o scaduta.';\n\n return res.status(authErr.status).json({\n severity: 'error',\n status: authErr.status,\n statusCode: 2,\n code: authErr.code,\n // Kept for callers of older versions which already inspected `error`.\n error: authErr.code,\n message,\n });\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 userService: UserService\n) {\n type AuthenticatedRequest = Request & {\n userGrants?: unknown;\n user?: unknown;\n data?: unknown;\n };\n const authenticatedRequest = req as AuthenticatedRequest;\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 = extractAccessiBearerToken(authHeader);\n if (!token) {\n throw authError(\n 401,\n \"AUTH_TOKEN_MISSING\",\n \"Token not found in Authorization header\"\n );\n }\n\n let verification: ReturnType<typeof getAccessiAccessTokenVerificationConfig>;\n try {\n verification = getAccessiAccessTokenVerificationConfig(accessiOptions);\n } catch {\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT signing key not configured\");\n }\n\n let decoded: unknown;\n try {\n decoded = jwt.verify(token, verification.key, verification.verifyOptions);\n } catch {\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n if (!codiceUtente) {\n throw authError(\n 401,\n \"AUTH_USER_CODE_MISSING\",\n \"codiceUtente not found in token payload\"\n );\n }\n if (await isAccessiTokenRevoked(accessiOptions, decoded as Record<string, unknown>, codiceUtente)) {\n throw authError(401, \"AUTH_TOKEN_REVOKED\", \"Session revoked\");\n }\n\n const currentUser = await userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw authError(\n 401,\n \"AUTH_USER_DISABLED\",\n \"User is no longer authorized\"\n );\n }\n\n const authenticatedPayload = buildAuthenticatedTokenPayload(decoded, currentUser);\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: authenticatedPayload,\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 authenticatedRequest.userGrants = await getGrantsResult();\n }\n\n authenticatedRequest.user = authenticatedPayload;\n authenticatedRequest.data = authenticatedPayload;\n return next();\n } catch (error: unknown) {\n const authErr = normalizeAuthError(error);\n logAuthFailure(req, authErr);\n return sendAuthenticationError(res, authErr);\n }\n}\n\n@Injectable()\n/** Nest service behind the Express-compatible `authorizeAccessi` middleware. */\nexport class AuthenticateGenService {\n constructor(\n @Inject(\"ACCESSI_OPTIONS\")\n private readonly accessiOptions: AccessiOptions,\n private readonly permissionService: PermissionService,\n private readonly userService: UserService\n ) { }\n\n /**\n * Verifica JWT, stato corrente dell'utente e policy opzionale, poi popola `req.user` e `req.data`.\n * Se una policy richiede grant, popola anche `req.userGrants`; non chiamarlo direttamente fuori da test o adapter.\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 this.userService\n );\n }\n}\n\nlet authenticateGenServiceRef: AuthenticateGenService | null = null;\nlet authServiceBootstrapDeferred: Deferred<AuthenticateGenService> | null = null;\n\nfunction createDeferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (reason?: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\nfunction isAuthenticateGenService(value: unknown): value is AuthenticateGenService {\n return Boolean(\n value &&\n typeof (value as { authorize?: unknown }).authorize === \"function\"\n );\n}\n\n/** Segnala al middleware che il bootstrap e in corso, consentendo una risposta 503 temporanea invece di un 500. */\nexport function beginAccessiAuthInitialization() {\n if (!authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred = createDeferred<AuthenticateGenService>();\n }\n}\n\n/** Registra il servizio costruito da Nest nel bridge usato dalle rotte Express dell'app ospitante. */\nexport function setAccessiAuthService(service: AuthenticateGenService) {\n authenticateGenServiceRef = service;\n (globalThis as Record<symbol, unknown>)[ACCESSI_AUTH_SERVICE_GLOBAL_KEY] = service;\n if (authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred.resolve(service);\n authServiceBootstrapDeferred = null;\n }\n}\n\n/** Propaga il fallimento del bootstrap alle richieste che stavano attendendo il bridge di autorizzazione. */\nexport function failAccessiAuthInitialization(error: unknown) {\n if (authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred.reject(error);\n authServiceBootstrapDeferred = null;\n }\n}\n\nfunction getAccessiAuthServiceFromRequest(req: Request): AuthenticateGenService | null {\n const appLocalsService = (req.app?.locals as Record<string, unknown> | undefined)?.[\n ACCESSI_AUTH_SERVICE_LOCALS_KEY\n ];\n\n if (isAuthenticateGenService(appLocalsService)) {\n return appLocalsService as AuthenticateGenService;\n }\n\n const globalService = (globalThis as Record<symbol, unknown>)[\n ACCESSI_AUTH_SERVICE_GLOBAL_KEY\n ];\n if (isAuthenticateGenService(globalService)) {\n return globalService as AuthenticateGenService;\n }\n\n return authenticateGenServiceRef;\n}\n\nasync function waitForBootstrappedService(): Promise<AuthenticateGenService | null> {\n if (!authServiceBootstrapDeferred) {\n return null;\n }\n\n const bootstrapPromise = authServiceBootstrapDeferred.promise;\n const timeoutPromise = new Promise<null>((resolve) => {\n setTimeout(() => resolve(null), ACCESSI_AUTH_SERVICE_WAIT_MS);\n });\n\n try {\n const resolved = await Promise.race([bootstrapPromise, timeoutPromise]);\n return isAuthenticateGenService(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\nasync function resolveAccessiAuthService(req: Request): Promise<AuthenticateGenService | null> {\n const immediateService = getAccessiAuthServiceFromRequest(req);\n if (immediateService) {\n return immediateService;\n }\n\n const bootstrappedService = await waitForBootstrappedService();\n if (bootstrappedService) {\n return bootstrappedService;\n }\n\n return getAccessiAuthServiceFromRequest(req);\n}\n\n/**\n * Middleware Express pubblico di Accessi.\n *\n * Applicarlo dopo `initializeAccessiModule`: legge `Authorization: Bearer <jwt>`, verifica l'utente corrente\n * e applica eventuali requisiti. Su successo valorizza `req.user` e continua; su errore risponde direttamente\n * con il contratto Accessi, quindi il chiamante non deve aggiungere un proprio `next(error)`.\n */\nexport async function authorizeAccessi(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n) {\n const authService = await resolveAccessiAuthService(req);\n\n if (!authService) {\n const status = authServiceBootstrapDeferred ? 503 : 500;\n const code = authServiceBootstrapDeferred\n ? 'ACCESSI_AUTH_INITIALIZING'\n : 'ACCESSI_AUTH_NOT_INITIALIZED';\n logger.error(\n `Authentication service not initialized ${JSON.stringify({\n method: req.method,\n path: req.originalUrl ?? req.url,\n status,\n })}`\n );\n return res.status(status).json({\n severity: 'error',\n status,\n statusCode: 2,\n code,\n error: code,\n message: status === 503\n ? 'Il modulo Accessi e in inizializzazione. Riprova tra poco.'\n : 'Il modulo Accessi non e disponibile.',\n });\n }\n\n return authService.authorize(req, res, next, options);\n}\n\n/** Alias storico di `authorizeAccessi`, mantenuto per retrocompatibilita. Preferire il nome esplicito nelle nuove integrazioni. */\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 { Inject, Injectable } from \"@nestjs/common\";\nimport type { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\nimport { UserService } from \"../Services/UserService/UserService\";\nimport { Logger } from \"../../Logger\";\nimport {\n AccessiAuthorizationOptions,\n AccessiCustomRequirementContext,\n GrantsResult,\n RequirementEvaluationError,\n buildRequirementTree,\n evaluateRequirement,\n} from \"./accessiRequirements\";\nimport {\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../security/authenticatedToken\";\nimport { getAccessiAccessTokenVerificationConfig, verifyAccessiJwt } from \"../security/jwtTokenOptions\";\nimport { isAccessiTokenRevoked } from \"../security/sessionRevocation\";\n\nconst logger = new Logger(\"AuthenticateGen\");\nconst ACCESSI_AUTH_SERVICE_LOCALS_KEY = \"accessiAuthService\";\nconst ACCESSI_AUTH_SERVICE_GLOBAL_KEY = Symbol.for(\"emilsoftware.accessiAuthService\");\nconst ACCESSI_AUTH_SERVICE_WAIT_MS = 15000;\n\ntype Deferred<T> = {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (reason?: unknown) => void;\n};\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 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 const message = `${authErr.status >= 500 ? \"Authentication failure\" : \"Authentication denied\"} ${JSON.stringify(payload)}`;\n if (authErr.status >= 500) logger.error(message);\n else logger.warning(message);\n}\n\n/** Sends the documented Accessi error contract from Express middleware. */\nfunction sendAuthenticationError(res: Response, authErr: AuthMiddlewareError): Response {\n const message =\n authErr.status === 403\n ? 'Operazione non autorizzata.'\n : authErr.status >= 500\n ? 'Errore interno del modulo Accessi.'\n : 'Autenticazione non valida o scaduta.';\n\n return res.status(authErr.status).json({\n severity: 'error',\n status: authErr.status,\n statusCode: 2,\n code: authErr.code,\n // Kept for callers of older versions which already inspected `error`.\n error: authErr.code,\n message,\n });\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 userService: UserService\n) {\n type AuthenticatedRequest = Request & {\n userGrants?: unknown;\n user?: unknown;\n data?: unknown;\n };\n const authenticatedRequest = req as AuthenticatedRequest;\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 = extractAccessiBearerToken(authHeader);\n if (!token) {\n throw authError(\n 401,\n \"AUTH_TOKEN_MISSING\",\n \"Token not found in Authorization header\"\n );\n }\n\n let verification: ReturnType<typeof getAccessiAccessTokenVerificationConfig>;\n try {\n verification = getAccessiAccessTokenVerificationConfig(accessiOptions);\n } catch {\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT signing key not configured\");\n }\n\n let decoded: unknown;\n try {\n decoded = verifyAccessiJwt(token, verification);\n } catch {\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n if (!codiceUtente) {\n throw authError(\n 401,\n \"AUTH_USER_CODE_MISSING\",\n \"codiceUtente not found in token payload\"\n );\n }\n if (await isAccessiTokenRevoked(accessiOptions, decoded as Record<string, unknown>, codiceUtente)) {\n throw authError(401, \"AUTH_TOKEN_REVOKED\", \"Session revoked\");\n }\n\n const currentUser = await userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw authError(\n 401,\n \"AUTH_USER_DISABLED\",\n \"User is no longer authorized\"\n );\n }\n\n const authenticatedPayload = buildAuthenticatedTokenPayload(decoded, currentUser);\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: authenticatedPayload,\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 authenticatedRequest.userGrants = await getGrantsResult();\n }\n\n authenticatedRequest.user = authenticatedPayload;\n authenticatedRequest.data = authenticatedPayload;\n return next();\n } catch (error: unknown) {\n const authErr = normalizeAuthError(error);\n logAuthFailure(req, authErr);\n return sendAuthenticationError(res, authErr);\n }\n}\n\n@Injectable()\n/** Nest service behind the Express-compatible `authorizeAccessi` middleware. */\nexport class AuthenticateGenService {\n constructor(\n @Inject(\"ACCESSI_OPTIONS\")\n private readonly accessiOptions: AccessiOptions,\n private readonly permissionService: PermissionService,\n private readonly userService: UserService\n ) { }\n\n /**\n * Verifica JWT, stato corrente dell'utente e policy opzionale, poi popola `req.user` e `req.data`.\n * Se una policy richiede grant, popola anche `req.userGrants`; non chiamarlo direttamente fuori da test o adapter.\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 this.userService\n );\n }\n}\n\nlet authenticateGenServiceRef: AuthenticateGenService | null = null;\nlet authServiceBootstrapDeferred: Deferred<AuthenticateGenService> | null = null;\n\nfunction createDeferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (reason?: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\nfunction isAuthenticateGenService(value: unknown): value is AuthenticateGenService {\n return Boolean(\n value &&\n typeof (value as { authorize?: unknown }).authorize === \"function\"\n );\n}\n\n/** Segnala al middleware che il bootstrap e in corso, consentendo una risposta 503 temporanea invece di un 500. */\nexport function beginAccessiAuthInitialization() {\n if (!authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred = createDeferred<AuthenticateGenService>();\n }\n}\n\n/** Registra il servizio costruito da Nest nel bridge usato dalle rotte Express dell'app ospitante. */\nexport function setAccessiAuthService(service: AuthenticateGenService) {\n authenticateGenServiceRef = service;\n (globalThis as Record<symbol, unknown>)[ACCESSI_AUTH_SERVICE_GLOBAL_KEY] = service;\n if (authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred.resolve(service);\n authServiceBootstrapDeferred = null;\n }\n}\n\n/** Propaga il fallimento del bootstrap alle richieste che stavano attendendo il bridge di autorizzazione. */\nexport function failAccessiAuthInitialization(error: unknown) {\n if (authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred.reject(error);\n authServiceBootstrapDeferred = null;\n }\n}\n\nfunction getAccessiAuthServiceFromRequest(req: Request): AuthenticateGenService | null {\n const appLocalsService = (req.app?.locals as Record<string, unknown> | undefined)?.[\n ACCESSI_AUTH_SERVICE_LOCALS_KEY\n ];\n\n if (isAuthenticateGenService(appLocalsService)) {\n return appLocalsService as AuthenticateGenService;\n }\n\n const globalService = (globalThis as Record<symbol, unknown>)[\n ACCESSI_AUTH_SERVICE_GLOBAL_KEY\n ];\n if (isAuthenticateGenService(globalService)) {\n return globalService as AuthenticateGenService;\n }\n\n return authenticateGenServiceRef;\n}\n\nasync function waitForBootstrappedService(): Promise<AuthenticateGenService | null> {\n if (!authServiceBootstrapDeferred) {\n return null;\n }\n\n const bootstrapPromise = authServiceBootstrapDeferred.promise;\n const timeoutPromise = new Promise<null>((resolve) => {\n setTimeout(() => resolve(null), ACCESSI_AUTH_SERVICE_WAIT_MS);\n });\n\n try {\n const resolved = await Promise.race([bootstrapPromise, timeoutPromise]);\n return isAuthenticateGenService(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\nasync function resolveAccessiAuthService(req: Request): Promise<AuthenticateGenService | null> {\n const immediateService = getAccessiAuthServiceFromRequest(req);\n if (immediateService) {\n return immediateService;\n }\n\n const bootstrappedService = await waitForBootstrappedService();\n if (bootstrappedService) {\n return bootstrappedService;\n }\n\n return getAccessiAuthServiceFromRequest(req);\n}\n\n/**\n * Middleware Express pubblico di Accessi.\n *\n * Applicarlo dopo `initializeAccessiModule`: legge `Authorization: Bearer <jwt>`, verifica l'utente corrente\n * e applica eventuali requisiti. Su successo valorizza `req.user` e continua; su errore risponde direttamente\n * con il contratto Accessi, quindi il chiamante non deve aggiungere un proprio `next(error)`.\n */\nexport async function authorizeAccessi(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n) {\n const authService = await resolveAccessiAuthService(req);\n\n if (!authService) {\n const status = authServiceBootstrapDeferred ? 503 : 500;\n const code = authServiceBootstrapDeferred\n ? 'ACCESSI_AUTH_INITIALIZING'\n : 'ACCESSI_AUTH_NOT_INITIALIZED';\n logger.error(\n `Authentication service not initialized ${JSON.stringify({\n method: req.method,\n path: req.originalUrl ?? req.url,\n status,\n })}`\n );\n return res.status(status).json({\n severity: 'error',\n status,\n statusCode: 2,\n code,\n error: code,\n message: status === 503\n ? 'Il modulo Accessi e in inizializzazione. Riprova tra poco.'\n : 'Il modulo Accessi non e disponibile.',\n });\n }\n\n return authService.authorize(req, res, next, options);\n}\n\n/** Alias storico di `authorizeAccessi`, mantenuto per retrocompatibilita. Preferire il nome esplicito nelle nuove integrazioni. */\nexport const authenticateGen = authorizeAccessi;\n"]}