emilsoftware-utilities 1.8.0-dev.2 → 2.0.0-dev.1

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 (67) hide show
  1. package/README.MD +4 -0
  2. package/dist/Utilities.d.ts +18 -0
  3. package/dist/Utilities.js +90 -1
  4. package/dist/Utilities.js.map +1 -1
  5. package/dist/accessi-module/AccessiModule.d.ts +15 -0
  6. package/dist/accessi-module/AccessiModule.js.map +1 -1
  7. package/dist/accessi-module/Controllers/AuthController.d.ts +4 -4
  8. package/dist/accessi-module/Controllers/AuthController.js +36 -21
  9. package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
  10. package/dist/accessi-module/Controllers/EmailController.d.ts +3 -3
  11. package/dist/accessi-module/Controllers/EmailController.js +15 -15
  12. package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
  13. package/dist/accessi-module/Controllers/FiltriController.d.ts +3 -3
  14. package/dist/accessi-module/Controllers/FiltriController.js +32 -15
  15. package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
  16. package/dist/accessi-module/Controllers/PermissionController.d.ts +12 -17
  17. package/dist/accessi-module/Controllers/PermissionController.js +140 -124
  18. package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
  19. package/dist/accessi-module/Controllers/UserController.d.ts +12 -11
  20. package/dist/accessi-module/Controllers/UserController.js +112 -79
  21. package/dist/accessi-module/Controllers/UserController.js.map +1 -1
  22. package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js +6 -0
  23. package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js.map +1 -1
  24. package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js +6 -0
  25. package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
  26. package/dist/accessi-module/Dtos/Permission.js +5 -0
  27. package/dist/accessi-module/Dtos/Permission.js.map +1 -1
  28. package/dist/accessi-module/Dtos/RegisterRequest.js +37 -1
  29. package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
  30. package/dist/accessi-module/Dtos/Role.js +13 -2
  31. package/dist/accessi-module/Dtos/Role.js.map +1 -1
  32. package/dist/accessi-module/Dtos/SetStatoRegistrazione.js +6 -0
  33. package/dist/accessi-module/Dtos/SetStatoRegistrazione.js.map +1 -1
  34. package/dist/accessi-module/Dtos/UserDto.js +59 -1
  35. package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
  36. package/dist/accessi-module/Services/AuthService/AuthService.d.ts +7 -3
  37. package/dist/accessi-module/Services/AuthService/AuthService.js +147 -25
  38. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  39. package/dist/accessi-module/Services/EmailService/EmailService.js +33 -10
  40. package/dist/accessi-module/Services/EmailService/EmailService.js.map +1 -1
  41. package/dist/accessi-module/Services/UserService/UserService.d.ts +15 -6
  42. package/dist/accessi-module/Services/UserService/UserService.js +110 -84
  43. package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
  44. package/dist/accessi-module/Views/reset-password.html +39 -21
  45. package/dist/accessi-module/index.js +17 -3
  46. package/dist/accessi-module/index.js.map +1 -1
  47. package/dist/accessi-module/jwt/jwt.strategy.d.ts +4 -2
  48. package/dist/accessi-module/jwt/jwt.strategy.js +47 -19
  49. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  50. package/dist/accessi-module/middleware/authenticateGen.d.ts +3 -1
  51. package/dist/accessi-module/middleware/authenticateGen.js +17 -11
  52. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  53. package/dist/accessi-module/security/accessControl.d.ts +17 -0
  54. package/dist/accessi-module/security/accessControl.js +44 -0
  55. package/dist/accessi-module/security/accessControl.js.map +1 -0
  56. package/dist/accessi-module/security/authenticatedToken.d.ts +11 -0
  57. package/dist/accessi-module/security/authenticatedToken.js +39 -0
  58. package/dist/accessi-module/security/authenticatedToken.js.map +1 -0
  59. package/dist/accessi-module/security/passwordResetToken.d.ts +8 -0
  60. package/dist/accessi-module/security/passwordResetToken.js +73 -0
  61. package/dist/accessi-module/security/passwordResetToken.js.map +1 -0
  62. package/dist/accessi-module/security/publicAuthRateLimit.d.ts +10 -0
  63. package/dist/accessi-module/security/publicAuthRateLimit.js +105 -0
  64. package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -0
  65. package/dist/emilsoftware-utilities-2.0.0-dev.1.tgz +0 -0
  66. package/package.json +1 -1
  67. package/dist/emilsoftware-utilities-1.8.0-dev.2.tgz +0 -0
@@ -109,7 +109,7 @@
109
109
  <div class="form-group">
110
110
  <label for="password">Nuova Password:</label>
111
111
  <input type="password" id="password" required>
112
- <p class="error" id="passwordError">La password deve avere almeno 6 caratteri.</p>
112
+ <p class="error" id="passwordError">La password deve avere almeno 8 caratteri.</p>
113
113
  </div>
114
114
 
115
115
  <div class="form-group">
@@ -124,21 +124,46 @@
124
124
 
125
125
  <script>
126
126
  document.addEventListener("DOMContentLoaded", function () {
127
- const urlParams = new URLSearchParams(window.location.search);
128
- const token = window.location.pathname.split("/").pop();
129
- const returnUrl = urlParams.get("returnUrl") || "/";
130
- let prefix = urlParams.get("prefix") || "";
127
+ function resolveSafeReturnUrl(rawReturnUrl) {
128
+ if (!rawReturnUrl) {
129
+ return "/";
130
+ }
131
+
132
+ if (rawReturnUrl.startsWith("/")) {
133
+ return rawReturnUrl;
134
+ }
135
+
136
+ try {
137
+ const parsed = new URL(rawReturnUrl, window.location.origin);
138
+ if (parsed.origin === window.location.origin) {
139
+ return `${parsed.pathname}${parsed.search}${parsed.hash}`;
140
+ }
141
+ } catch (error) {}
131
142
 
132
- if (prefix !== "") {
133
- if (!prefix.startsWith("/")) {
134
- prefix = "/" + prefix;
143
+ return "/";
144
+ }
145
+
146
+ function resolveSafePrefix(rawPrefix) {
147
+ if (!rawPrefix) {
148
+ return "";
149
+ }
150
+
151
+ let normalizedPrefix = rawPrefix.trim();
152
+ if (!normalizedPrefix.startsWith("/")) {
153
+ normalizedPrefix = "/" + normalizedPrefix;
135
154
  }
136
155
 
137
- if(prefix.endsWith("/")) {
138
- prefix = prefix.slice(0, -1);
156
+ if (normalizedPrefix.endsWith("/")) {
157
+ normalizedPrefix = normalizedPrefix.slice(0, -1);
139
158
  }
159
+
160
+ return /^\/[A-Za-z0-9/_-]*$/.test(normalizedPrefix) ? normalizedPrefix : "";
140
161
  }
141
162
 
163
+ const urlParams = new URLSearchParams(window.location.search);
164
+ const token = window.location.pathname.split("/").pop();
165
+ const returnUrl = resolveSafeReturnUrl(urlParams.get("returnUrl"));
166
+ const prefix = resolveSafePrefix(urlParams.get("prefix"));
142
167
 
143
168
  document.getElementById("token").value = token;
144
169
  document.getElementById("returnUrl").value = returnUrl;
@@ -151,12 +176,10 @@
151
176
  const passwordError = document.getElementById("passwordError");
152
177
  const confirmError = document.getElementById("confirmError");
153
178
 
154
- // Reset messaggi di errore
155
179
  passwordError.style.display = "none";
156
180
  confirmError.style.display = "none";
157
181
 
158
- // Validazioni
159
- if (password.length < 6) {
182
+ if (password.length < 8) {
160
183
  passwordError.style.display = "block";
161
184
  return;
162
185
  }
@@ -166,7 +189,6 @@
166
189
  return;
167
190
  }
168
191
 
169
- // Effettua la richiesta API
170
192
  try {
171
193
  const response = await fetch(`${prefix}/api/accessi/auth/confirm-reset-password/${token}`, {
172
194
  method: "POST",
@@ -177,14 +199,10 @@
177
199
  const data = await response.json();
178
200
  alert(data.message || "Password aggiornata con successo!");
179
201
  } catch (error) {
180
- alert("Errore nel reset della password. Riprova più tardi.");
202
+ alert("Errore nel reset della password. Riprova piu tardi.");
181
203
  } finally {
182
204
  setTimeout(() => {
183
- if (returnUrl.startsWith("https://") || returnUrl.startsWith("http://")) {
184
- window.location.href = returnUrl;
185
- } else {
186
- window.location.href = "https://" + returnUrl;
187
- }
205
+ window.location.href = returnUrl;
188
206
  }, 500);
189
207
  }
190
208
  });
@@ -192,4 +210,4 @@
192
210
  </script>
193
211
  </body>
194
212
 
195
- </html>
213
+ </html>
@@ -25,10 +25,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.accessiRequirement = exports.authenticateGen = exports.authorizeAccessi = exports.AccessiDatabaseUpdater = exports.AccessiModule = void 0;
27
27
  exports.initializeAccessiModule = initializeAccessiModule;
28
+ const common_1 = require("@nestjs/common");
28
29
  const core_1 = require("@nestjs/core");
29
30
  const platform_express_1 = require("@nestjs/platform-express");
30
31
  const AccessiModule_1 = require("./AccessiModule");
31
32
  const Logger_1 = require("../Logger");
33
+ const AuthService_1 = require("./Services/AuthService/AuthService");
32
34
  const authenticateGen_1 = require("./middleware/authenticateGen");
33
35
  function initializeAccessiModule(app, options) {
34
36
  return __awaiter(this, void 0, void 0, function* () {
@@ -43,14 +45,26 @@ function initializeAccessiModule(app, options) {
43
45
  bufferLogs: true
44
46
  });
45
47
  nestApp.enableCors();
48
+ nestApp.useGlobalPipes(new common_1.ValidationPipe({
49
+ whitelist: true,
50
+ forbidNonWhitelisted: true,
51
+ transform: true,
52
+ transformOptions: {
53
+ enableImplicitConversion: true,
54
+ },
55
+ }));
46
56
  nestApp.setGlobalPrefix('api', {
47
57
  exclude: ['/swagger', '/swagger/(.*)']
48
58
  });
49
59
  // Note: Swagger setup is now handled by the unified module
50
60
  yield nestApp.init();
51
- const authService = nestApp.get(authenticateGen_1.AuthenticateGenService);
52
- app.locals.accessiAuthService = authService;
53
- (0, authenticateGen_1.setAccessiAuthService)(authService);
61
+ if (options.legacyPasswordMigrationOnStartup !== false) {
62
+ const passwordMigrationService = nestApp.get(AuthService_1.AuthService);
63
+ yield passwordMigrationService.migrateLegacyEncryptedPasswords();
64
+ }
65
+ const accessiAuthService = nestApp.get(authenticateGen_1.AuthenticateGenService);
66
+ app.locals.accessiAuthService = accessiAuthService;
67
+ (0, authenticateGen_1.setAccessiAuthService)(accessiAuthService);
54
68
  }
55
69
  catch (error) {
56
70
  (0, authenticateGen_1.failAccessiAuthInitialization)(error);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,0DA+BC;AA1CD,uCAA2C;AAC3C,+DAA0D;AAC1D,mDAAgE;AAChE,sCAAmC;AACnC,kEAKsC;AAEtC,SAAsB,uBAAuB,CAAC,GAAgB,EAAE,OAAuB;;QACnF,MAAM,MAAM,GAAW,IAAI,eAAM,CAAC,yBAAyB,CAAC,CAAC;QAC7D,IAAA,gDAA8B,GAAE,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,IAAI,CAAC;YACD,iDAAiD;YACjD,MAAM,mBAAmB,GAAG,IAAI,iCAAc,CAAC,GAAG,CAAC,CAAC;YAEpD,2CAA2C;YAC3C,MAAM,OAAO,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,6BAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE;gBAC1F,UAAU,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,OAAO,CAAC,UAAU,EAAE,CAAC;YAErB,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE;gBAC3B,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC;aACzC,CAAC,CAAC;YAEH,2DAA2D;YAC3D,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,wCAAsB,CAAC,CAAC;YACxD,GAAG,CAAC,MAAM,CAAC,kBAAkB,GAAG,WAAW,CAAC;YAC5C,IAAA,uCAAqB,EAAC,WAAW,CAAC,CAAC;QAEvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAA,+CAA6B,EAAC,KAAK,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;CAAA;AAED,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,oFAAmF;AAA1E,gIAAA,sBAAsB,OAAA;AAC/B,yCAAuB;AACvB,gEAGsC;AAFlC,mHAAA,gBAAgB,OAAA;AAChB,kHAAA,eAAe,OAAA;AAEnB,wEAAsE;AAA7D,yHAAA,kBAAkB,OAAA","sourcesContent":["import { Application } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n AuthenticateGenService,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\n\nexport async function initializeAccessiModule(app: Application, options: AccessiOptions) {\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n\n console.log(\"Accessi initialized\");\n try {\n // Creiamo un'istanza Express separata per NestJS\n const nestExpressInstance = new ExpressAdapter(app);\n\n // Creiamo l'app NestJS attaccata a Express\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: true\n });\n\n nestApp.enableCors();\n\n nestApp.setGlobalPrefix('api', {\n exclude: ['/swagger', '/swagger/(.*)']\n });\n\n // Note: Swagger setup is now handled by the unified module\n await nestApp.init();\n const authService = nestApp.get(AuthenticateGenService);\n app.locals.accessiAuthService = authService;\n setAccessiAuthService(authService);\n\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\"Errore in initialize AccessiModule:\", error);\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\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":";;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,0DA8CC;AA3DD,2CAAgD;AAChD,uCAA2C;AAC3C,+DAA0D;AAC1D,mDAAgE;AAChE,sCAAmC;AACnC,oEAAiE;AACjE,kEAKsC;AAEtC,SAAsB,uBAAuB,CAAC,GAAgB,EAAE,OAAuB;;QACnF,MAAM,MAAM,GAAW,IAAI,eAAM,CAAC,yBAAyB,CAAC,CAAC;QAC7D,IAAA,gDAA8B,GAAE,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,IAAI,CAAC;YACD,iDAAiD;YACjD,MAAM,mBAAmB,GAAG,IAAI,iCAAc,CAAC,GAAG,CAAC,CAAC;YAEpD,2CAA2C;YAC3C,MAAM,OAAO,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,6BAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE;gBAC1F,UAAU,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,OAAO,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,cAAc,CAClB,IAAI,uBAAc,CAAC;gBACf,SAAS,EAAE,IAAI;gBACf,oBAAoB,EAAE,IAAI;gBAC1B,SAAS,EAAE,IAAI;gBACf,gBAAgB,EAAE;oBACd,wBAAwB,EAAE,IAAI;iBACjC;aACJ,CAAC,CACL,CAAC;YAEF,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE;gBAC3B,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC;aACzC,CAAC,CAAC;YAEH,2DAA2D;YAC3D,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,IAAI,OAAO,CAAC,gCAAgC,KAAK,KAAK,EAAE,CAAC;gBACrD,MAAM,wBAAwB,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAW,CAAC,CAAC;gBAC1D,MAAM,wBAAwB,CAAC,+BAA+B,EAAE,CAAC;YACrE,CAAC;YAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,wCAAsB,CAAC,CAAC;YAC/D,GAAG,CAAC,MAAM,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;YACnD,IAAA,uCAAqB,EAAC,kBAAkB,CAAC,CAAC;QAE9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAA,+CAA6B,EAAC,KAAK,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;CAAA;AAED,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,oFAAmF;AAA1E,gIAAA,sBAAsB,OAAA;AAC/B,yCAAuB;AACvB,gEAGsC;AAFlC,mHAAA,gBAAgB,OAAA;AAChB,kHAAA,eAAe,OAAA;AAEnB,wEAAsE;AAA7D,yHAAA,kBAAkB,OAAA","sourcesContent":["import { Application } from \"express\";\nimport { ValidationPipe } from \"@nestjs/common\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport { AuthService } from \"./Services/AuthService/AuthService\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n AuthenticateGenService,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\n\nexport async function initializeAccessiModule(app: Application, options: AccessiOptions) {\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n\n console.log(\"Accessi initialized\");\n try {\n // Creiamo un'istanza Express separata per NestJS\n const nestExpressInstance = new ExpressAdapter(app);\n\n // Creiamo l'app NestJS attaccata a Express\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: true\n });\n\n nestApp.enableCors();\n nestApp.useGlobalPipes(\n new ValidationPipe({\n whitelist: true,\n forbidNonWhitelisted: true,\n transform: true,\n transformOptions: {\n enableImplicitConversion: true,\n },\n }),\n );\n\n nestApp.setGlobalPrefix('api', {\n exclude: ['/swagger', '/swagger/(.*)']\n });\n\n // Note: Swagger setup is now handled by the unified module\n await nestApp.init();\n if (options.legacyPasswordMigrationOnStartup !== false) {\n const passwordMigrationService = nestApp.get(AuthService);\n await passwordMigrationService.migrateLegacyEncryptedPasswords();\n }\n\n const accessiAuthService = nestApp.get(AuthenticateGenService);\n app.locals.accessiAuthService = accessiAuthService;\n setAccessiAuthService(accessiAuthService);\n\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\"Errore in initialize AccessiModule:\", error);\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\nexport type {\n AccessiAuthorizationOptions,\n AccessiRequirementNode,\n AccessiCustomRequirementContext,\n AccessiCustomRequirementHandler\n} from \"./middleware/accessiRequirements\";\n"]}
@@ -1,7 +1,9 @@
1
1
  import { CanActivate, ExecutionContext } from '@nestjs/common';
2
2
  import { AccessiOptions } from '../AccessiModule';
3
+ import { UserService } from '../Services/UserService/UserService';
3
4
  export declare class JwtSimpleGuard implements CanActivate {
4
5
  private readonly accessiOptions;
5
- constructor(accessiOptions: AccessiOptions);
6
- canActivate(context: ExecutionContext): boolean;
6
+ private readonly userService;
7
+ constructor(accessiOptions: AccessiOptions, userService: UserService);
8
+ canActivate(context: ExecutionContext): Promise<boolean>;
7
9
  }
@@ -44,38 +44,66 @@ var __metadata = (this && this.__metadata) || function (k, v) {
44
44
  var __param = (this && this.__param) || function (paramIndex, decorator) {
45
45
  return function (target, key) { decorator(target, key, paramIndex); }
46
46
  };
47
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
48
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
49
+ return new (P || (P = Promise))(function (resolve, reject) {
50
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
51
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
52
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
53
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
54
+ });
55
+ };
47
56
  Object.defineProperty(exports, "__esModule", { value: true });
48
57
  exports.JwtSimpleGuard = void 0;
49
58
  const common_1 = require("@nestjs/common");
50
59
  const jwt = __importStar(require("jsonwebtoken"));
60
+ const UserService_1 = require("../Services/UserService/UserService");
61
+ const authenticatedToken_1 = require("../security/authenticatedToken");
51
62
  let JwtSimpleGuard = class JwtSimpleGuard {
52
- constructor(accessiOptions) {
63
+ constructor(accessiOptions, userService) {
53
64
  this.accessiOptions = accessiOptions;
65
+ this.userService = userService;
54
66
  }
55
67
  canActivate(context) {
56
- var _a, _b;
57
- const request = context.switchToHttp().getRequest();
58
- const authHeader = request.headers['authorization'];
59
- if (!authHeader)
60
- throw new common_1.UnauthorizedException('Token mancante.');
61
- const token = authHeader.split(' ')[1];
62
- if (!token)
63
- throw new common_1.UnauthorizedException('Formato token non valido.');
64
- try {
65
- const secret = ((_b = (_a = this.accessiOptions) === null || _a === void 0 ? void 0 : _a.jwtOptions) === null || _b === void 0 ? void 0 : _b.secret) || process.env.ACC_JWT_SECRET || 'super-secret';
66
- const payload = jwt.verify(token, secret);
67
- request.user = payload;
68
- return true;
69
- }
70
- catch (error) {
71
- throw new common_1.UnauthorizedException('Token non valido o scaduto.');
72
- }
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ var _a, _b;
70
+ const request = context.switchToHttp().getRequest();
71
+ const authHeader = request.headers['authorization'];
72
+ if (!authHeader)
73
+ throw new common_1.UnauthorizedException('Token mancante.');
74
+ const token = authHeader.split(' ')[1];
75
+ if (!token)
76
+ throw new common_1.UnauthorizedException('Formato token non valido.');
77
+ try {
78
+ const secret = ((_b = (_a = this.accessiOptions) === null || _a === void 0 ? void 0 : _a.jwtOptions) === null || _b === void 0 ? void 0 : _b.secret) || process.env.ACC_JWT_SECRET;
79
+ if (!secret) {
80
+ throw new common_1.InternalServerErrorException('JWT secret non configurato.');
81
+ }
82
+ const payload = jwt.verify(token, secret);
83
+ const codiceUtente = (0, authenticatedToken_1.resolveCodiceUtenteFromTokenPayload)(payload);
84
+ if (!codiceUtente) {
85
+ throw new common_1.UnauthorizedException('Token privo di un utente valido.');
86
+ }
87
+ const currentUser = yield this.userService.getAuthenticatedUserSnapshot(codiceUtente);
88
+ if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(currentUser)) {
89
+ throw new common_1.UnauthorizedException('Utente non piu autorizzato.');
90
+ }
91
+ request.user = (0, authenticatedToken_1.buildAuthenticatedTokenPayload)(payload, currentUser);
92
+ return true;
93
+ }
94
+ catch (error) {
95
+ if (error instanceof common_1.InternalServerErrorException || error instanceof common_1.UnauthorizedException) {
96
+ throw error;
97
+ }
98
+ throw new common_1.UnauthorizedException('Token non valido o scaduto.');
99
+ }
100
+ });
73
101
  }
74
102
  };
75
103
  exports.JwtSimpleGuard = JwtSimpleGuard;
76
104
  exports.JwtSimpleGuard = JwtSimpleGuard = __decorate([
77
105
  (0, common_1.Injectable)(),
78
106
  __param(0, (0, common_1.Inject)('ACCESSI_OPTIONS')),
79
- __metadata("design:paramtypes", [Object])
107
+ __metadata("design:paramtypes", [Object, UserService_1.UserService])
80
108
  ], JwtSimpleGuard);
81
109
  //# sourceMappingURL=jwt.strategy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../../src/accessi-module/jwt/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA0G;AAC1G,kDAAoC;AAI7B,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAAwD,cAA8B;QAA9B,mBAAc,GAAd,cAAc,CAAgB;IAAG,CAAC;IAE1F,WAAW,CAAC,OAAyB;;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAEpD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,8BAAqB,CAAC,iBAAiB,CAAC,CAAC;QAEpE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;QAEzE,IAAI,CAAC;YACH,MAAM,MAAM,GACV,CAAA,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,UAAU,0CAAE,MAAM,KAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,cAAc,CAAC;YAC1F,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;CACF,CAAA;AAtBY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;;GAD3B,cAAc,CAsB1B","sourcesContent":["import { CanActivate, ExecutionContext, Inject, Injectable, UnauthorizedException } from '@nestjs/common';\nimport * as jwt from 'jsonwebtoken';\nimport { AccessiOptions } from '../AccessiModule';\n\n@Injectable()\nexport class JwtSimpleGuard implements CanActivate {\n constructor(@Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions) {}\n\n canActivate(context: ExecutionContext): 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 = authHeader.split(' ')[1];\n if (!token) throw new UnauthorizedException('Formato token non valido.');\n\n try {\n const secret =\n this.accessiOptions?.jwtOptions?.secret || process.env.ACC_JWT_SECRET || 'super-secret';\n const payload = jwt.verify(token, secret);\n request.user = payload;\n return true;\n } catch (error) {\n throw new UnauthorizedException('Token non valido o scaduto.');\n }\n }\n}\n"]}
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,uEAIwC;AAGjC,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,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;YAEzE,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,CAAA,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,UAAU,0CAAE,MAAM,KAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;gBACrF,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,IAAI,qCAA4B,CAAC,6BAA6B,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC1C,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;gBAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,IAAA,qDAAgC,EAAC,WAAW,CAAC,EAAE,CAAC;oBACnD,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,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;KAAA;CACF,CAAA;AAxCY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CACI,yBAAW;GAHhC,cAAc,CAwC1B","sourcesContent":["import {\n CanActivate,\n ExecutionContext,\n Inject,\n Injectable,\n InternalServerErrorException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport * as jwt from 'jsonwebtoken';\nimport { AccessiOptions } from '../AccessiModule';\nimport { UserService } from '../Services/UserService/UserService';\nimport {\n buildAuthenticatedTokenPayload,\n isAuthenticatedUserEnabledForJwt,\n resolveCodiceUtenteFromTokenPayload,\n} from '../security/authenticatedToken';\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 = authHeader.split(' ')[1];\n if (!token) throw new UnauthorizedException('Formato token non valido.');\n\n try {\n const secret = this.accessiOptions?.jwtOptions?.secret || process.env.ACC_JWT_SECRET;\n if (!secret) {\n throw new InternalServerErrorException('JWT secret non configurato.');\n }\n const payload = jwt.verify(token, secret);\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(payload);\n if (!codiceUtente) {\n throw new UnauthorizedException('Token privo di un utente valido.');\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(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 UnauthorizedException('Token non valido o scaduto.');\n }\n }\n}\n"]}
@@ -1,11 +1,13 @@
1
1
  import { NextFunction, Request, Response } from "express";
2
2
  import { AccessiOptions } from "../AccessiModule";
3
3
  import { PermissionService } from "../Services/PermissionService/PermissionService";
4
+ import { UserService } from "../Services/UserService/UserService";
4
5
  import { AccessiAuthorizationOptions } from "./accessiRequirements";
5
6
  export declare class AuthenticateGenService {
6
7
  private readonly accessiOptions;
7
8
  private readonly permissionService;
8
- constructor(accessiOptions: AccessiOptions, permissionService: PermissionService);
9
+ private readonly userService;
10
+ constructor(accessiOptions: AccessiOptions, permissionService: PermissionService, userService: UserService);
9
11
  authorize(req: Request, res: Response, next: NextFunction, options?: AccessiAuthorizationOptions): Promise<void | Response<any, Record<string, any>>>;
10
12
  }
11
13
  export declare function beginAccessiAuthInitialization(): void;
@@ -62,8 +62,10 @@ exports.authorizeAccessi = authorizeAccessi;
62
62
  const jwt = __importStar(require("jsonwebtoken"));
63
63
  const common_1 = require("@nestjs/common");
64
64
  const PermissionService_1 = require("../Services/PermissionService/PermissionService");
65
+ const UserService_1 = require("../Services/UserService/UserService");
65
66
  const Logger_1 = require("../../Logger");
66
67
  const accessiRequirements_1 = require("./accessiRequirements");
68
+ const authenticatedToken_1 = require("../security/authenticatedToken");
67
69
  const logger = new Logger_1.Logger("AuthenticateGen");
68
70
  const ACCESSI_AUTH_SERVICE_LOCALS_KEY = "accessiAuthService";
69
71
  const ACCESSI_AUTH_SERVICE_GLOBAL_KEY = Symbol.for("emilsoftware.accessiAuthService");
@@ -77,10 +79,6 @@ class AuthMiddlewareError extends Error {
77
79
  this.name = "AuthMiddlewareError";
78
80
  }
79
81
  }
80
- function resolveCodiceUtente(decoded) {
81
- var _a, _b, _c, _d, _e;
82
- return ((_e = (_c = (_b = (_a = decoded === null || decoded === void 0 ? void 0 : decoded.userData) === null || _a === void 0 ? void 0 : _a.utente) === null || _b === void 0 ? void 0 : _b.codiceUtente) !== null && _c !== void 0 ? _c : (_d = decoded === null || decoded === void 0 ? void 0 : decoded.utente) === null || _d === void 0 ? void 0 : _d.codiceUtente) !== null && _e !== void 0 ? _e : decoded === null || decoded === void 0 ? void 0 : decoded.codiceUtente);
83
- }
84
82
  function authError(status, code, message, details) {
85
83
  return new AuthMiddlewareError(status, code, message, details);
86
84
  }
@@ -114,7 +112,7 @@ function logAuthFailure(req, authErr) {
114
112
  else
115
113
  logger.warning(message);
116
114
  }
117
- function authorizeWithDependencies(req, res, next, options, accessiOptions, permissionService) {
115
+ function authorizeWithDependencies(req, res, next, options, accessiOptions, permissionService, userService) {
118
116
  return __awaiter(this, void 0, void 0, function* () {
119
117
  var _a, _b;
120
118
  try {
@@ -137,10 +135,15 @@ function authorizeWithDependencies(req, res, next, options, accessiOptions, perm
137
135
  catch (_c) {
138
136
  throw authError(401, "AUTH_TOKEN_INVALID", "Invalid JWT token");
139
137
  }
140
- const codiceUtente = resolveCodiceUtente(decoded);
138
+ const codiceUtente = (0, authenticatedToken_1.resolveCodiceUtenteFromTokenPayload)(decoded);
141
139
  if (!codiceUtente) {
142
140
  throw authError(401, "AUTH_USER_CODE_MISSING", "codiceUtente not found in token payload");
143
141
  }
142
+ const currentUser = yield userService.getAuthenticatedUserSnapshot(codiceUtente);
143
+ if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(currentUser)) {
144
+ throw authError(401, "AUTH_USER_DISABLED", "User is no longer authorized");
145
+ }
146
+ const authenticatedPayload = (0, authenticatedToken_1.buildAuthenticatedTokenPayload)(decoded, currentUser);
144
147
  const requirementTree = (0, accessiRequirements_1.buildRequirementTree)(options);
145
148
  if (requirementTree) {
146
149
  if (!(accessiOptions === null || accessiOptions === void 0 ? void 0 : accessiOptions.databaseOptions)) {
@@ -155,7 +158,7 @@ function authorizeWithDependencies(req, res, next, options, accessiOptions, perm
155
158
  });
156
159
  const requirementContext = {
157
160
  req,
158
- decodedToken: decoded,
161
+ decodedToken: authenticatedPayload,
159
162
  userCode: codiceUtente,
160
163
  getGrantsResult,
161
164
  };
@@ -165,7 +168,8 @@ function authorizeWithDependencies(req, res, next, options, accessiOptions, perm
165
168
  }
166
169
  req.userGrants = yield getGrantsResult();
167
170
  }
168
- req.data = decoded;
171
+ req.user = authenticatedPayload;
172
+ req.data = authenticatedPayload;
169
173
  return next();
170
174
  }
171
175
  catch (error) {
@@ -183,13 +187,14 @@ function authorizeWithDependencies(req, res, next, options, accessiOptions, perm
183
187
  });
184
188
  }
185
189
  let AuthenticateGenService = class AuthenticateGenService {
186
- constructor(accessiOptions, permissionService) {
190
+ constructor(accessiOptions, permissionService, userService) {
187
191
  this.accessiOptions = accessiOptions;
188
192
  this.permissionService = permissionService;
193
+ this.userService = userService;
189
194
  }
190
195
  authorize(req, res, next, options) {
191
196
  return __awaiter(this, void 0, void 0, function* () {
192
- return authorizeWithDependencies(req, res, next, options, this.accessiOptions, this.permissionService);
197
+ return authorizeWithDependencies(req, res, next, options, this.accessiOptions, this.permissionService, this.userService);
193
198
  });
194
199
  }
195
200
  };
@@ -197,7 +202,8 @@ exports.AuthenticateGenService = AuthenticateGenService;
197
202
  exports.AuthenticateGenService = AuthenticateGenService = __decorate([
198
203
  (0, common_1.Injectable)(),
199
204
  __param(0, (0, common_1.Inject)("ACCESSI_OPTIONS")),
200
- __metadata("design:paramtypes", [Object, PermissionService_1.PermissionService])
205
+ __metadata("design:paramtypes", [Object, PermissionService_1.PermissionService,
206
+ UserService_1.UserService])
201
207
  ], AuthenticateGenService);
202
208
  let authenticateGenServiceRef = null;
203
209
  let authServiceBootstrapDeferred = null;
@@ -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 { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\nimport { Logger } from \"../../Logger\";\nimport {\n AccessiAuthorizationOptions,\n AccessiCustomRequirementContext,\n GrantsResult,\n RequirementEvaluationError,\n buildRequirementTree,\n evaluateRequirement,\n} from \"./accessiRequirements\";\n\nconst logger = new Logger(\"AuthenticateGen\");\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 resolveCodiceUtente(decoded: any): number | undefined {\n return (\n decoded?.userData?.utente?.codiceUtente ??\n decoded?.utente?.codiceUtente ??\n decoded?.codiceUtente\n );\n}\n\nfunction authError(\n status: number,\n code: string,\n message: string,\n details?: Record<string, unknown>\n) {\n return new AuthMiddlewareError(status, code, message, details);\n}\n\nfunction normalizeAuthError(error: unknown): AuthMiddlewareError {\n if (error instanceof AuthMiddlewareError) return error;\n if (error instanceof RequirementEvaluationError) {\n return authError(500, error.code, error.message);\n }\n if (error instanceof Error) {\n return authError(500, \"AUTH_INTERNAL_ERROR\", error.message, {\n originalError: error.name,\n });\n }\n return authError(500, \"AUTH_INTERNAL_ERROR\", \"Unexpected authentication error\");\n}\n\nfunction logAuthFailure(req: Request, authErr: AuthMiddlewareError) {\n const payload = {\n code: authErr.code,\n status: authErr.status,\n message: authErr.message,\n details: authErr.details,\n method: req.method,\n path: req.originalUrl ?? req.url,\n ip: req.ip,\n };\n\n 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\nasync function authorizeWithDependencies(\n req: Request,\n res: Response,\n next: NextFunction,\n options: AccessiAuthorizationOptions | undefined,\n accessiOptions: AccessiOptions,\n permissionService: PermissionService\n) {\n try {\n const authHeader = req.headers.authorization;\n if (!authHeader) {\n throw authError(401, \"AUTH_HEADER_MISSING\", \"Authorization header not found\");\n }\n\n const token = authHeader.split(\" \")[1];\n if (!token) {\n throw authError(\n 401,\n \"AUTH_TOKEN_MISSING\",\n \"Token not found in Authorization header\"\n );\n }\n\n const secret = accessiOptions?.jwtOptions?.secret ?? process.env.ACC_JWT_SECRET;\n if (!secret) {\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT secret not configured\");\n }\n\n let decoded: any;\n try {\n decoded = jwt.verify(token, secret);\n } catch {\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\n }\n\n const codiceUtente = resolveCodiceUtente(decoded);\n if (!codiceUtente) {\n throw authError(\n 401,\n \"AUTH_USER_CODE_MISSING\",\n \"codiceUtente not found in token payload\"\n );\n }\n\n const requirementTree = buildRequirementTree(options);\n if (requirementTree) {\n if (!accessiOptions?.databaseOptions) {\n throw authError(\n 500,\n \"AUTH_DATABASE_OPTIONS_MISSING\",\n \"Database options not configured\"\n );\n }\n\n let grantsResultCache: GrantsResult | null = null;\n const getGrantsResult = async () => {\n if (!grantsResultCache) {\n grantsResultCache = await permissionService.getUserRolesAndGrants(\n codiceUtente\n );\n }\n return grantsResultCache;\n };\n\n const requirementContext: AccessiCustomRequirementContext = {\n req,\n decodedToken: decoded,\n userCode: codiceUtente,\n getGrantsResult,\n };\n\n const hasPermissions = await evaluateRequirement(\n requirementTree,\n requirementContext,\n options\n );\n\n if (!hasPermissions) {\n throw authError(\n 403,\n \"AUTH_INSUFFICIENT_PERMISSIONS\",\n \"User does not have required permissions\"\n );\n }\n\n (req as any).userGrants = await getGrantsResult();\n }\n\n (req as any).data = decoded;\n return next();\n } catch (error: unknown) {\n const authErr = normalizeAuthError(error);\n logAuthFailure(req, authErr);\n const publicMessage =\n authErr.status === 403\n ? \"Forbidden\"\n : authErr.status >= 500\n ? \"Internal server error\"\n : \"Unauthorized\";\n return res\n .status(authErr.status)\n .json({ message: publicMessage, error: authErr.message, code: authErr.code });\n }\n}\n\n@Injectable()\nexport class AuthenticateGenService {\n constructor(\n @Inject(\"ACCESSI_OPTIONS\")\n private readonly accessiOptions: AccessiOptions,\n private readonly permissionService: PermissionService\n ) { }\n\n async authorize(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n ) {\n return authorizeWithDependencies(\n req,\n res,\n next,\n options,\n this.accessiOptions,\n this.permissionService\n );\n }\n}\n\nlet authenticateGenServiceRef: AuthenticateGenService | null = null;\nlet 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\nexport function beginAccessiAuthInitialization() {\n if (!authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred = createDeferred<AuthenticateGenService>();\n }\n}\n\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\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\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 message = authServiceBootstrapDeferred\n ? \"Accessi authentication service is still initializing\"\n : \"Accessi authentication service 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\n .status(status)\n .json({ message });\n }\n\n return authService.authorize(req, res, next, options);\n}\n\nexport const authenticateGen = authorizeAccessi;\n"]}
1
+ {"version":3,"file":"authenticateGen.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/authenticateGen.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuPA,wEAIC;AAED,sDAOC;AAED,sEAKC;AAqDD,4CA0BC;AAzVD,kDAAoC;AACpC,2CAAoD;AAEpD,uFAAoF;AACpF,qEAAkE;AAClE,yCAAsC;AACtC,+DAO+B;AAC/B,uEAIwC;AAExC,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAiB,CAAC,CAAC;AAC7C,MAAM,+BAA+B,GAAG,oBAAoB,CAAC;AAC7D,MAAM,+BAA+B,GAAG,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AACtF,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAQ3C,MAAM,mBAAoB,SAAQ,KAAK;IACrC,YACkB,MAAc,EACd,IAAY,EAC5B,OAAe,EACC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;QAEZ,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,SAAS,SAAS,CAChB,MAAc,EACd,IAAY,EACZ,OAAe,EACf,OAAiC;IAEjC,OAAO,IAAI,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,mBAAmB;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,KAAK,YAAY,gDAA0B,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC,GAAG,EAAE,qBAAqB,EAAE,KAAK,CAAC,OAAO,EAAE;YAC1D,aAAa,EAAE,KAAK,CAAC,IAAI;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,SAAS,CAAC,GAAG,EAAE,qBAAqB,EAAE,iCAAiC,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,cAAc,CAAC,GAAY,EAAE,OAA4B;;IAChE,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,MAAA,GAAG,CAAC,WAAW,mCAAI,GAAG,CAAC,GAAG;QAChC,EAAE,EAAE,GAAG,CAAC,EAAE;KACX,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,uBAAuB,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3H,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG;QAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;;QAC5C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,SAAe,yBAAyB,CACtC,GAAY,EACZ,GAAa,EACb,IAAkB,EAClB,OAAgD,EAChD,cAA8B,EAC9B,iBAAoC,EACpC,WAAwB;;;QAExB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;YAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,SAAS,CAAC,GAAG,EAAE,qBAAqB,EAAE,gCAAgC,CAAC,CAAC;YAChF,CAAC;YAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,SAAS,CACb,GAAG,EACH,oBAAoB,EACpB,yCAAyC,CAC1C,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,MAAA,MAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU,0CAAE,MAAM,mCAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAChF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,SAAS,CAAC,GAAG,EAAE,yBAAyB,EAAE,2BAA2B,CAAC,CAAC;YAC/E,CAAC;YAED,IAAI,OAAY,CAAC;YACjB,IAAI,CAAC;gBACH,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC;YAAC,WAAM,CAAC;gBACP,MAAM,SAAS,CAAC,GAAG,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,YAAY,GAAG,IAAA,wDAAmC,EAAC,OAAO,CAAC,CAAC;YAClE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,SAAS,CACb,GAAG,EACH,wBAAwB,EACxB,yCAAyC,CAC1C,CAAC;YACJ,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;YACjF,IAAI,CAAC,IAAA,qDAAgC,EAAC,WAAW,CAAC,EAAE,CAAC;gBACnD,MAAM,SAAS,CACb,GAAG,EACH,oBAAoB,EACpB,8BAA8B,CAC/B,CAAC;YACJ,CAAC;YAED,MAAM,oBAAoB,GAAG,IAAA,mDAA8B,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAElF,MAAM,eAAe,GAAG,IAAA,0CAAoB,EAAC,OAAO,CAAC,CAAC;YACtD,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,eAAe,CAAA,EAAE,CAAC;oBACrC,MAAM,SAAS,CACb,GAAG,EACH,+BAA+B,EAC/B,iCAAiC,CAClC,CAAC;gBACJ,CAAC;gBAED,IAAI,iBAAiB,GAAwB,IAAI,CAAC;gBAClD,MAAM,eAAe,GAAG,GAAS,EAAE;oBACjC,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBACvB,iBAAiB,GAAG,MAAM,iBAAiB,CAAC,qBAAqB,CAC/D,YAAY,CACb,CAAC;oBACJ,CAAC;oBACD,OAAO,iBAAiB,CAAC;gBAC3B,CAAC,CAAA,CAAC;gBAEF,MAAM,kBAAkB,GAAoC;oBAC1D,GAAG;oBACH,YAAY,EAAE,oBAAoB;oBAClC,QAAQ,EAAE,YAAY;oBACtB,eAAe;iBAChB,CAAC;gBAEF,MAAM,cAAc,GAAG,MAAM,IAAA,yCAAmB,EAC9C,eAAe,EACf,kBAAkB,EAClB,OAAO,CACR,CAAC;gBAEF,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,MAAM,SAAS,CACb,GAAG,EACH,+BAA+B,EAC/B,yCAAyC,CAC1C,CAAC;gBACJ,CAAC;gBAEA,GAAW,CAAC,UAAU,GAAG,MAAM,eAAe,EAAE,CAAC;YACpD,CAAC;YAEA,GAAW,CAAC,IAAI,GAAG,oBAAoB,CAAC;YACxC,GAAW,CAAC,IAAI,GAAG,oBAAoB,CAAC;YACzC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC1C,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC7B,MAAM,aAAa,GACjB,OAAO,CAAC,MAAM,KAAK,GAAG;gBACpB,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG;oBACrB,CAAC,CAAC,uBAAuB;oBACzB,CAAC,CAAC,cAAc,CAAC;YACvB,OAAO,GAAG;iBACP,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;iBACtB,IAAI,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;CAAA;AAGM,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IACjC,YAEmB,cAA8B,EAC9B,iBAAoC,EACpC,WAAwB;QAFxB,mBAAc,GAAd,cAAc,CAAgB;QAC9B,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,gBAAW,GAAX,WAAW,CAAa;IACvC,CAAC;IAEC,SAAS,CACb,GAAY,EACZ,GAAa,EACb,IAAkB,EAClB,OAAqC;;YAErC,OAAO,yBAAyB,CAC9B,GAAG,EACH,GAAG,EACH,IAAI,EACJ,OAAO,EACP,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,WAAW,CACjB,CAAC;QACJ,CAAC;KAAA;CACF,CAAA;AAxBY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CAEU,qCAAiB;QACvB,yBAAW;GALhC,sBAAsB,CAwBlC;AAED,IAAI,yBAAyB,GAAkC,IAAI,CAAC;AACpE,IAAI,4BAA4B,GAA4C,IAAI,CAAC;AAEjF,SAAS,cAAc;IACrB,IAAI,OAA4B,CAAC;IACjC,IAAI,MAAmC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1C,OAAO,GAAG,GAAG,CAAC;QACd,MAAM,GAAG,GAAG,CAAC;IACf,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAc;IAC9C,OAAO,OAAO,CACZ,KAAK;QACL,OAAQ,KAAiC,CAAC,SAAS,KAAK,UAAU,CACnE,CAAC;AACJ,CAAC;AAED,SAAgB,8BAA8B;IAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;QAClC,4BAA4B,GAAG,cAAc,EAA0B,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAA+B;IACnE,yBAAyB,GAAG,OAAO,CAAC;IACnC,UAAsC,CAAC,+BAA+B,CAAC,GAAG,OAAO,CAAC;IACnF,IAAI,4BAA4B,EAAE,CAAC;QACjC,4BAA4B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,4BAA4B,GAAG,IAAI,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAgB,6BAA6B,CAAC,KAAc;IAC1D,IAAI,4BAA4B,EAAE,CAAC;QACjC,4BAA4B,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3C,4BAA4B,GAAG,IAAI,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAS,gCAAgC,CAAC,GAAY;;IACpD,MAAM,gBAAgB,GAAG,MAAC,MAAA,GAAG,CAAC,GAAG,0CAAE,MAA8C,0CAC/E,+BAA+B,CAChC,CAAC;IAEF,IAAI,wBAAwB,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC/C,OAAO,gBAA0C,CAAC;IACpD,CAAC;IAED,MAAM,aAAa,GAAI,UAAsC,CAC3D,+BAA+B,CAChC,CAAC;IACF,IAAI,wBAAwB,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5C,OAAO,aAAuC,CAAC;IACjD,CAAC;IAED,OAAO,yBAAyB,CAAC;AACnC,CAAC;AAED,SAAe,0BAA0B;;QACvC,IAAI,CAAC,4BAA4B,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,OAAO,CAAC;QAC9D,MAAM,cAAc,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnD,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,4BAA4B,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAC;YACxE,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CAAA;AAED,SAAe,yBAAyB,CAAC,GAAY;;QACnD,MAAM,gBAAgB,GAAG,gCAAgC,CAAC,GAAG,CAAC,CAAC;QAC/D,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAED,MAAM,mBAAmB,GAAG,MAAM,0BAA0B,EAAE,CAAC;QAC/D,IAAI,mBAAmB,EAAE,CAAC;YACxB,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QAED,OAAO,gCAAgC,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;CAAA;AAED,SAAsB,gBAAgB,CACpC,GAAY,EACZ,GAAa,EACb,IAAkB,EAClB,OAAqC;;;QAErC,MAAM,WAAW,GAAG,MAAM,yBAAyB,CAAC,GAAG,CAAC,CAAC;QAEzD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,4BAA4B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACxD,MAAM,OAAO,GAAG,4BAA4B;gBAC1C,CAAC,CAAC,sDAAsD;gBACxD,CAAC,CAAC,gDAAgD,CAAC;YACrD,MAAM,CAAC,KAAK,CACV,0CAA0C,IAAI,CAAC,SAAS,CAAC;gBACvD,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,MAAA,GAAG,CAAC,WAAW,mCAAI,GAAG,CAAC,GAAG;gBAChC,MAAM;aACP,CAAC,EAAE,CACL,CAAC;YACF,OAAO,GAAG;iBACP,MAAM,CAAC,MAAM,CAAC;iBACd,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;CAAA;AAEY,QAAA,eAAe,GAAG,gBAAgB,CAAC","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport * as jwt from \"jsonwebtoken\";\nimport { Inject, Injectable } from \"@nestjs/common\";\nimport { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\nimport { 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 isAuthenticatedUserEnabledForJwt,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../security/authenticatedToken\";\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\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 try {\n const authHeader = req.headers.authorization;\n if (!authHeader) {\n throw authError(401, \"AUTH_HEADER_MISSING\", \"Authorization header not found\");\n }\n\n const token = authHeader.split(\" \")[1];\n if (!token) {\n throw authError(\n 401,\n \"AUTH_TOKEN_MISSING\",\n \"Token not found in Authorization header\"\n );\n }\n\n const secret = accessiOptions?.jwtOptions?.secret ?? process.env.ACC_JWT_SECRET;\n if (!secret) {\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT secret not configured\");\n }\n\n let decoded: any;\n try {\n decoded = jwt.verify(token, secret);\n } catch {\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\n }\n\n const codiceUtente = 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\n const currentUser = await userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(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 (req as any).userGrants = await getGrantsResult();\n }\n\n (req as any).user = authenticatedPayload;\n (req as any).data = authenticatedPayload;\n return next();\n } catch (error: unknown) {\n const authErr = normalizeAuthError(error);\n logAuthFailure(req, authErr);\n const publicMessage =\n authErr.status === 403\n ? \"Forbidden\"\n : authErr.status >= 500\n ? \"Internal server error\"\n : \"Unauthorized\";\n return res\n .status(authErr.status)\n .json({ message: publicMessage, error: authErr.message, code: authErr.code });\n }\n}\n\n@Injectable()\nexport class AuthenticateGenService {\n constructor(\n @Inject(\"ACCESSI_OPTIONS\")\n private readonly accessiOptions: AccessiOptions,\n private readonly permissionService: PermissionService,\n private readonly userService: UserService\n ) { }\n\n async authorize(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n ) {\n return authorizeWithDependencies(\n req,\n res,\n next,\n options,\n this.accessiOptions,\n this.permissionService,\n 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\nexport function beginAccessiAuthInitialization() {\n if (!authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred = createDeferred<AuthenticateGenService>();\n }\n}\n\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\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\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 message = authServiceBootstrapDeferred\n ? \"Accessi authentication service is still initializing\"\n : \"Accessi authentication service 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\n .status(status)\n .json({ message });\n }\n\n return authService.authorize(req, res, next, options);\n}\n\nexport const authenticateGen = authorizeAccessi;\n"]}
@@ -0,0 +1,17 @@
1
+ import { Request } from 'express';
2
+ export interface AuthenticatedAccessiUser {
3
+ codiceUtente: number;
4
+ email?: string;
5
+ flagSuper: boolean;
6
+ flagAdminConfigurator: boolean;
7
+ }
8
+ export declare function getAuthenticatedAccessiUser(req: Request): AuthenticatedAccessiUser;
9
+ export declare function ensureSuperUser(user: AuthenticatedAccessiUser, message?: string): void;
10
+ export declare function ensureSelfOrSuperUser(user: AuthenticatedAccessiUser, targetUserCode: number, message?: string): void;
11
+ export declare function hasPrivilegedUserChanges(user: {
12
+ statoRegistrazione?: unknown;
13
+ flagSuper?: unknown;
14
+ flagAdminConfigurator?: unknown;
15
+ roles?: unknown;
16
+ permissions?: unknown;
17
+ }): boolean;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAuthenticatedAccessiUser = getAuthenticatedAccessiUser;
4
+ exports.ensureSuperUser = ensureSuperUser;
5
+ exports.ensureSelfOrSuperUser = ensureSelfOrSuperUser;
6
+ exports.hasPrivilegedUserChanges = hasPrivilegedUserChanges;
7
+ const common_1 = require("@nestjs/common");
8
+ function normalizeBooleanFlag(value) {
9
+ return value === true || value === 1 || value === '1';
10
+ }
11
+ function getAuthenticatedAccessiUser(req) {
12
+ var _a, _b, _c;
13
+ const payload = req === null || req === void 0 ? void 0 : req.user;
14
+ const utente = (_c = (_a = payload === null || payload === void 0 ? void 0 : payload.utente) !== null && _a !== void 0 ? _a : (_b = payload === null || payload === void 0 ? void 0 : payload.userData) === null || _b === void 0 ? void 0 : _b.utente) !== null && _c !== void 0 ? _c : payload;
15
+ const codiceUtente = Number(utente === null || utente === void 0 ? void 0 : utente.codiceUtente);
16
+ if (!codiceUtente) {
17
+ throw new common_1.UnauthorizedException('Utente non autenticato.');
18
+ }
19
+ return {
20
+ codiceUtente,
21
+ email: typeof (utente === null || utente === void 0 ? void 0 : utente.email) === 'string' ? utente.email : undefined,
22
+ flagSuper: normalizeBooleanFlag(utente === null || utente === void 0 ? void 0 : utente.flagSuper),
23
+ flagAdminConfigurator: normalizeBooleanFlag(utente === null || utente === void 0 ? void 0 : utente.flagAdminConfigurator),
24
+ };
25
+ }
26
+ function ensureSuperUser(user, message = 'Operazione riservata agli amministratori.') {
27
+ if (!user.flagSuper) {
28
+ throw new common_1.ForbiddenException(message);
29
+ }
30
+ }
31
+ function ensureSelfOrSuperUser(user, targetUserCode, message = 'Operazione non autorizzata su questo utente.') {
32
+ if (user.flagSuper || user.codiceUtente === targetUserCode) {
33
+ return;
34
+ }
35
+ throw new common_1.ForbiddenException(message);
36
+ }
37
+ function hasPrivilegedUserChanges(user) {
38
+ return (user.statoRegistrazione !== undefined ||
39
+ user.flagSuper !== undefined ||
40
+ user.flagAdminConfigurator !== undefined ||
41
+ user.roles !== undefined ||
42
+ user.permissions !== undefined);
43
+ }
44
+ //# sourceMappingURL=accessControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessControl.js","sourceRoot":"","sources":["../../../src/accessi-module/security/accessControl.ts"],"names":[],"mappings":";;AAcA,kEAeC;AAED,0CAOC;AAED,sDAUC;AAED,4DAcC;AAlED,2CAA2E;AAU3E,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC;AACxD,CAAC;AAED,SAAgB,2BAA2B,CAAC,GAAY;;IACtD,MAAM,OAAO,GAAI,GAAW,aAAX,GAAG,uBAAH,GAAG,CAAU,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,mCAAI,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,0CAAE,MAAM,mCAAI,OAAO,CAAC;IACvE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,YAAY,CAAC,CAAC;IAElD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,8BAAqB,CAAC,yBAAyB,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACnE,SAAS,EAAE,oBAAoB,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS,CAAC;QAClD,qBAAqB,EAAE,oBAAoB,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,qBAAqB,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAC7B,IAA8B,EAC9B,OAAO,GAAG,2CAA2C;IAErD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,2BAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,SAAgB,qBAAqB,CACnC,IAA8B,EAC9B,cAAsB,EACtB,OAAO,GAAG,8CAA8C;IAExD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;QAC3D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,2BAAkB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,wBAAwB,CAAC,IAMxC;IACC,OAAO,CACL,IAAI,CAAC,kBAAkB,KAAK,SAAS;QACrC,IAAI,CAAC,SAAS,KAAK,SAAS;QAC5B,IAAI,CAAC,qBAAqB,KAAK,SAAS;QACxC,IAAI,CAAC,KAAK,KAAK,SAAS;QACxB,IAAI,CAAC,WAAW,KAAK,SAAS,CAC/B,CAAC;AACJ,CAAC","sourcesContent":["import { ForbiddenException, UnauthorizedException } from '@nestjs/common';\nimport { Request } from 'express';\n\nexport interface AuthenticatedAccessiUser {\n codiceUtente: number;\n email?: string;\n flagSuper: boolean;\n flagAdminConfigurator: boolean;\n}\n\nfunction normalizeBooleanFlag(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n}\n\nexport function getAuthenticatedAccessiUser(req: Request): AuthenticatedAccessiUser {\n const payload = (req as any)?.user;\n const utente = payload?.utente ?? payload?.userData?.utente ?? payload;\n const codiceUtente = Number(utente?.codiceUtente);\n\n if (!codiceUtente) {\n throw new UnauthorizedException('Utente non autenticato.');\n }\n\n return {\n codiceUtente,\n email: typeof utente?.email === 'string' ? utente.email : undefined,\n flagSuper: normalizeBooleanFlag(utente?.flagSuper),\n flagAdminConfigurator: normalizeBooleanFlag(utente?.flagAdminConfigurator),\n };\n}\n\nexport function ensureSuperUser(\n user: AuthenticatedAccessiUser,\n message = 'Operazione riservata agli amministratori.',\n): void {\n if (!user.flagSuper) {\n throw new ForbiddenException(message);\n }\n}\n\nexport function ensureSelfOrSuperUser(\n user: AuthenticatedAccessiUser,\n targetUserCode: number,\n message = 'Operazione non autorizzata su questo utente.',\n): void {\n if (user.flagSuper || user.codiceUtente === targetUserCode) {\n return;\n }\n\n throw new ForbiddenException(message);\n}\n\nexport function hasPrivilegedUserChanges(user: {\n statoRegistrazione?: unknown;\n flagSuper?: unknown;\n flagAdminConfigurator?: unknown;\n roles?: unknown;\n permissions?: unknown;\n}): boolean {\n return (\n user.statoRegistrazione !== undefined ||\n user.flagSuper !== undefined ||\n user.flagAdminConfigurator !== undefined ||\n user.roles !== undefined ||\n user.permissions !== undefined\n );\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { StatoRegistrazione } from '../Dtos/StatoRegistrazione';
2
+ export interface AccessiAuthenticatedUserSnapshot {
3
+ codiceUtente: number;
4
+ email?: string;
5
+ statoRegistrazione: StatoRegistrazione;
6
+ flagSuper: boolean;
7
+ flagAdminConfigurator: boolean;
8
+ }
9
+ export declare function resolveCodiceUtenteFromTokenPayload(decoded: unknown): number | undefined;
10
+ export declare function buildAuthenticatedTokenPayload(decoded: unknown, utente: AccessiAuthenticatedUserSnapshot): Record<string, unknown>;
11
+ export declare function isAuthenticatedUserEnabledForJwt(utente: AccessiAuthenticatedUserSnapshot | null | undefined): boolean;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveCodiceUtenteFromTokenPayload = resolveCodiceUtenteFromTokenPayload;
4
+ exports.buildAuthenticatedTokenPayload = buildAuthenticatedTokenPayload;
5
+ exports.isAuthenticatedUserEnabledForJwt = isAuthenticatedUserEnabledForJwt;
6
+ const StatoRegistrazione_1 = require("../Dtos/StatoRegistrazione");
7
+ function normalizeBooleanFlag(value) {
8
+ return value === true || value === 1 || value === '1';
9
+ }
10
+ function isRecord(value) {
11
+ return typeof value === 'object' && value !== null;
12
+ }
13
+ function resolveCodiceUtenteFromTokenPayload(decoded) {
14
+ var _a;
15
+ if (!isRecord(decoded)) {
16
+ return undefined;
17
+ }
18
+ const userData = isRecord(decoded.userData) ? decoded.userData : undefined;
19
+ const utente = isRecord(decoded.utente)
20
+ ? decoded.utente
21
+ : isRecord(userData === null || userData === void 0 ? void 0 : userData.utente)
22
+ ? userData.utente
23
+ : undefined;
24
+ const codiceUtente = Number((_a = utente === null || utente === void 0 ? void 0 : utente.codiceUtente) !== null && _a !== void 0 ? _a : decoded.codiceUtente);
25
+ if (!Number.isFinite(codiceUtente) || codiceUtente <= 0) {
26
+ return undefined;
27
+ }
28
+ return codiceUtente;
29
+ }
30
+ function buildAuthenticatedTokenPayload(decoded, utente) {
31
+ const basePayload = isRecord(decoded) ? Object.assign({}, decoded) : {};
32
+ const userData = isRecord(basePayload.userData) ? Object.assign({}, basePayload.userData) : {};
33
+ const normalizedUser = Object.assign(Object.assign({}, utente), { flagSuper: normalizeBooleanFlag(utente.flagSuper), flagAdminConfigurator: normalizeBooleanFlag(utente.flagAdminConfigurator) });
34
+ return Object.assign(Object.assign({}, basePayload), { utente: normalizedUser, userData: Object.assign(Object.assign({}, userData), { utente: normalizedUser }), tokenPayload: decoded });
35
+ }
36
+ function isAuthenticatedUserEnabledForJwt(utente) {
37
+ return (utente === null || utente === void 0 ? void 0 : utente.statoRegistrazione) === StatoRegistrazione_1.StatoRegistrazione.CONF;
38
+ }
39
+ //# sourceMappingURL=authenticatedToken.js.map