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

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 (119) hide show
  1. package/README.MD +38 -34
  2. package/dist/ContractGenerator.js.map +1 -1
  3. package/dist/DatabaseUpdater.js +24 -24
  4. package/dist/DatabaseUpdater.js.map +1 -1
  5. package/dist/EmilsoftwareModule.js.map +1 -1
  6. package/dist/ExecutionTimeLogger.js.map +1 -1
  7. package/dist/Logger.js.map +1 -1
  8. package/dist/Orm.js.map +1 -1
  9. package/dist/RoutesLoggerMiddleware.js.map +1 -1
  10. package/dist/Utilities.d.ts +18 -0
  11. package/dist/Utilities.js +90 -1
  12. package/dist/Utilities.js.map +1 -1
  13. package/dist/accessi-module/AccessiModule.d.ts +15 -0
  14. package/dist/accessi-module/AccessiModule.js.map +1 -1
  15. package/dist/accessi-module/Controllers/AuthController.d.ts +4 -4
  16. package/dist/accessi-module/Controllers/AuthController.js +36 -21
  17. package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
  18. package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
  19. package/dist/accessi-module/Controllers/EmailController.d.ts +3 -3
  20. package/dist/accessi-module/Controllers/EmailController.js +15 -15
  21. package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
  22. package/dist/accessi-module/Controllers/FiltriController.d.ts +3 -3
  23. package/dist/accessi-module/Controllers/FiltriController.js +32 -15
  24. package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
  25. package/dist/accessi-module/Controllers/PermissionController.d.ts +12 -17
  26. package/dist/accessi-module/Controllers/PermissionController.js +140 -124
  27. package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
  28. package/dist/accessi-module/Controllers/UserController.d.ts +12 -11
  29. package/dist/accessi-module/Controllers/UserController.js +112 -79
  30. package/dist/accessi-module/Controllers/UserController.js.map +1 -1
  31. package/dist/accessi-module/Dtos/Abilitazione.js.map +1 -1
  32. package/dist/accessi-module/Dtos/AbilitazioneMenu.js.map +1 -1
  33. package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js +6 -0
  34. package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js.map +1 -1
  35. package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js +6 -0
  36. package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
  37. package/dist/accessi-module/Dtos/BaseResponse.js.map +1 -1
  38. package/dist/accessi-module/Dtos/FiltriUtente.js.map +1 -1
  39. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js.map +1 -1
  40. package/dist/accessi-module/Dtos/GetMenusResponse.js.map +1 -1
  41. package/dist/accessi-module/Dtos/GetRolesResponse.js.map +1 -1
  42. package/dist/accessi-module/Dtos/GetUsersResponse.js.map +1 -1
  43. package/dist/accessi-module/Dtos/LoginRequest.js.map +1 -1
  44. package/dist/accessi-module/Dtos/LoginResponse.js.map +1 -1
  45. package/dist/accessi-module/Dtos/Permission.js +5 -0
  46. package/dist/accessi-module/Dtos/Permission.js.map +1 -1
  47. package/dist/accessi-module/Dtos/RegisterRequest.js +37 -1
  48. package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
  49. package/dist/accessi-module/Dtos/RegisterResponse.js.map +1 -1
  50. package/dist/accessi-module/Dtos/Role.js +13 -2
  51. package/dist/accessi-module/Dtos/Role.js.map +1 -1
  52. package/dist/accessi-module/Dtos/RuoliMenu.js.map +1 -1
  53. package/dist/accessi-module/Dtos/SetStatoRegistrazione.js +6 -0
  54. package/dist/accessi-module/Dtos/SetStatoRegistrazione.js.map +1 -1
  55. package/dist/accessi-module/Dtos/StatoRegistrazione.js.map +1 -1
  56. package/dist/accessi-module/Dtos/TipoAbilitazione.js.map +1 -1
  57. package/dist/accessi-module/Dtos/TipoFiltro.js.map +1 -1
  58. package/dist/accessi-module/Dtos/TokenResult.js.map +1 -1
  59. package/dist/accessi-module/Dtos/UpdateEnabledStatusRequest.js.map +1 -1
  60. package/dist/accessi-module/Dtos/UserDto.js +59 -1
  61. package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
  62. package/dist/accessi-module/Dtos/UserGrantsDto.js.map +1 -1
  63. package/dist/accessi-module/Dtos/index.js.map +1 -1
  64. package/dist/accessi-module/Services/AuthService/AuthService.d.ts +8 -3
  65. package/dist/accessi-module/Services/AuthService/AuthService.js +159 -27
  66. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  67. package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.js.map +1 -1
  68. package/dist/accessi-module/Services/EmailService/EmailService.js +44 -21
  69. package/dist/accessi-module/Services/EmailService/EmailService.js.map +1 -1
  70. package/dist/accessi-module/Services/FiltriService/FiltriService.js +1 -1
  71. package/dist/accessi-module/Services/FiltriService/FiltriService.js.map +1 -1
  72. package/dist/accessi-module/Services/PermissionService/PermissionService.js +87 -87
  73. package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
  74. package/dist/accessi-module/Services/UserService/UserService.d.ts +15 -6
  75. package/dist/accessi-module/Services/UserService/UserService.js +165 -139
  76. package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
  77. package/dist/accessi-module/Views/reset-password.html +213 -195
  78. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +25 -16
  79. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
  80. package/dist/accessi-module/database-updates/runAccessiDbUpdate.js.map +1 -1
  81. package/dist/accessi-module/index.js +33 -4
  82. package/dist/accessi-module/index.js.map +1 -1
  83. package/dist/accessi-module/jwt/jwt.strategy.d.ts +4 -2
  84. package/dist/accessi-module/jwt/jwt.strategy.js +47 -19
  85. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  86. package/dist/accessi-module/middleware/accessiRequirements.js.map +1 -1
  87. package/dist/accessi-module/middleware/authenticateGen.d.ts +3 -1
  88. package/dist/accessi-module/middleware/authenticateGen.js +17 -11
  89. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  90. package/dist/accessi-module/security/accessControl.d.ts +17 -0
  91. package/dist/accessi-module/security/accessControl.js +44 -0
  92. package/dist/accessi-module/security/accessControl.js.map +1 -0
  93. package/dist/accessi-module/security/authenticatedToken.d.ts +11 -0
  94. package/dist/accessi-module/security/authenticatedToken.js +39 -0
  95. package/dist/accessi-module/security/authenticatedToken.js.map +1 -0
  96. package/dist/accessi-module/security/passwordResetToken.d.ts +8 -0
  97. package/dist/accessi-module/security/passwordResetToken.js +73 -0
  98. package/dist/accessi-module/security/passwordResetToken.js.map +1 -0
  99. package/dist/accessi-module/security/publicAuthRateLimit.d.ts +10 -0
  100. package/dist/accessi-module/security/publicAuthRateLimit.js +105 -0
  101. package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -0
  102. package/dist/allegati-module/AllegatiModule.js.map +1 -1
  103. package/dist/allegati-module/Controllers/AllegatiController.js.map +1 -1
  104. package/dist/allegati-module/Dtos/AllegatoDto.js.map +1 -1
  105. package/dist/allegati-module/Dtos/BaseResponse.js.map +1 -1
  106. package/dist/allegati-module/Dtos/UploadSingleFileRequest.js.map +1 -1
  107. package/dist/allegati-module/Dtos/index.js.map +1 -1
  108. package/dist/allegati-module/Dtos/responses/DownloadAllegatoResponseDto.js.map +1 -1
  109. package/dist/allegati-module/Dtos/responses/GetListResponse.js.map +1 -1
  110. package/dist/allegati-module/Dtos/responses/UploadAllegatoResponseDto.js.map +1 -1
  111. package/dist/allegati-module/Services/AllegatiService/AllegatiService.js +49 -49
  112. package/dist/allegati-module/Services/AllegatiService/AllegatiService.js.map +1 -1
  113. package/dist/allegati-module/index.js.map +1 -1
  114. package/dist/autobind.js.map +1 -1
  115. package/dist/index.js.map +1 -1
  116. package/dist/initEmilsoftwareModule.js.map +1 -1
  117. package/dist/swagger/SwaggerConfig.js.map +1 -1
  118. package/package.json +83 -83
  119. package/dist/emilsoftware-utilities-1.8.0-dev.2.tgz +0 -0
@@ -38,12 +38,18 @@ let AccessiDatabaseUpdater = AccessiDatabaseUpdater_1 = class AccessiDatabaseUpd
38
38
  AccessiDatabaseUpdater_1.logger.info("Aggiornamento automatico database accessi disabilitato da configurazione.");
39
39
  return;
40
40
  }
41
+ AccessiDatabaseUpdater_1.logger.info("Avvio updater database accessi.");
41
42
  yield AccessiDatabaseUpdater_1.run(this.accessiOptions);
43
+ AccessiDatabaseUpdater_1.logger.info("Updater database accessi completato.");
42
44
  });
43
45
  }
44
46
  static run(options) {
45
47
  return __awaiter(this, void 0, void 0, function* () {
48
+ var _a, _b, _c;
49
+ const startedAt = performance.now();
50
+ this.logger.info(`Verifica schema accessi su ${(_a = options.databaseOptions.host) !== null && _a !== void 0 ? _a : "?"}:${(_b = options.databaseOptions.port) !== null && _b !== void 0 ? _b : "?"} -> ${(_c = options.databaseOptions.database) !== null && _c !== void 0 ? _c : "?"}`);
46
51
  yield this.createParametersTable(options.databaseOptions);
52
+ this.logger.info("Tabella PARAMETRI verificata.");
47
53
  const currentVersion = yield this.getDatabaseVersion(options.databaseOptions);
48
54
  const currentIndex = this.updates.findIndex((update) => update.toVersion === currentVersion);
49
55
  const startIndex = currentIndex >= 0 ? currentIndex + 1 : 0;
@@ -61,10 +67,13 @@ let AccessiDatabaseUpdater = AccessiDatabaseUpdater_1 = class AccessiDatabaseUpd
61
67
  }
62
68
  for (let index = startIndex; index < this.updates.length; index++) {
63
69
  const update = this.updates[index];
70
+ const stepStartedAt = performance.now();
64
71
  this.logger.info(`Applico aggiornamento accessi ${update.fromVersion} -> ${update.toVersion}: ${update.description}`);
65
72
  yield update.apply(options);
66
73
  yield this.setDatabaseVersion(options.databaseOptions, update.toVersion);
74
+ this.logger.info(`Aggiornamento accessi ${update.toVersion} completato in ${(performance.now() - stepStartedAt).toFixed(2)} ms`);
67
75
  }
76
+ this.logger.info(`Verifica/aggiornamento database accessi completato in ${(performance.now() - startedAt).toFixed(2)} ms`);
68
77
  });
69
78
  }
70
79
  static getCurrentVersion(options) {
@@ -111,7 +120,7 @@ let AccessiDatabaseUpdater = AccessiDatabaseUpdater_1 = class AccessiDatabaseUpd
111
120
  return __awaiter(this, void 0, void 0, function* () {
112
121
  const existing = yield Orm_1.Orm.query(options.databaseOptions, "SELECT CODMNU FROM MENU WHERE CODMNU = ?", [menu.CODMNU]);
113
122
  if (existing.length === 0) {
114
- yield Orm_1.Orm.execute(options.databaseOptions, `INSERT INTO MENU (CODMNU, DESMNU, CODGRP, FLGENABLED, ICON, ORDINE, CODTIP, PAGINA, RIFMENU)
123
+ yield Orm_1.Orm.execute(options.databaseOptions, `INSERT INTO MENU (CODMNU, DESMNU, CODGRP, FLGENABLED, ICON, ORDINE, CODTIP, PAGINA, RIFMENU)
115
124
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
116
125
  menu.CODMNU,
117
126
  menu.DESMNU,
@@ -125,15 +134,15 @@ let AccessiDatabaseUpdater = AccessiDatabaseUpdater_1 = class AccessiDatabaseUpd
125
134
  ]);
126
135
  return;
127
136
  }
128
- yield Orm_1.Orm.execute(options.databaseOptions, `UPDATE MENU
129
- SET DESMNU = ?,
130
- CODGRP = ?,
131
- FLGENABLED = COALESCE(FLGENABLED, ?),
132
- ICON = ?,
133
- ORDINE = ?,
134
- CODTIP = ?,
135
- PAGINA = ?,
136
- RIFMENU = ?
137
+ yield Orm_1.Orm.execute(options.databaseOptions, `UPDATE MENU
138
+ SET DESMNU = ?,
139
+ CODGRP = ?,
140
+ FLGENABLED = COALESCE(FLGENABLED, ?),
141
+ ICON = ?,
142
+ ORDINE = ?,
143
+ CODTIP = ?,
144
+ PAGINA = ?,
145
+ RIFMENU = ?
137
146
  WHERE CODMNU = ?`, [
138
147
  menu.DESMNU,
139
148
  menu.CODGRP,
@@ -209,12 +218,12 @@ AccessiDatabaseUpdater.updates = [
209
218
  yield Orm_1.Orm.execute(options.databaseOptions, "CREATE SEQUENCE GEN_RUOLI_ID");
210
219
  }
211
220
  if (!(yield AccessiDatabaseUpdater_1.triggerExists(options.databaseOptions, "RUOLI_BI"))) {
212
- yield Orm_1.Orm.execute(options.databaseOptions, `CREATE TRIGGER RUOLI_BI FOR RUOLI
213
- ACTIVE BEFORE INSERT POSITION 0
214
- AS
215
- BEGIN
216
- IF (NEW.CODRUO IS NULL) THEN
217
- NEW.CODRUO = GEN_ID(GEN_RUOLI_ID,1);
221
+ yield Orm_1.Orm.execute(options.databaseOptions, `CREATE TRIGGER RUOLI_BI FOR RUOLI
222
+ ACTIVE BEFORE INSERT POSITION 0
223
+ AS
224
+ BEGIN
225
+ IF (NEW.CODRUO IS NULL) THEN
226
+ NEW.CODRUO = GEN_ID(GEN_RUOLI_ID,1);
218
227
  END`);
219
228
  }
220
229
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"AccessiDatabaseUpdater.js","sourceRoot":"","sources":["../../../src/accessi-module/database-updates/AccessiDatabaseUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Inject, OnModuleInit } from \"@nestjs/common\";\nimport { DatabaseUpdater } from \"../../DatabaseUpdater\";\nimport { AccessiOptions } from \"../AccessiModule\";\nimport { Orm } from \"../../Orm\";\nimport { Logger } from \"../../Logger\";\n\ntype AccessiUpdateStep = {\n fromVersion: string;\n toVersion: string;\n description: string;\n apply: (options: AccessiOptions) => Promise<void>;\n};\n\n@Injectable()\nexport class AccessiDatabaseUpdater extends DatabaseUpdater implements OnModuleInit {\n protected static override logger: Logger = new Logger(AccessiDatabaseUpdater.name);\n\n private static readonly updates: AccessiUpdateStep[] = [\n {\n fromVersion: \"1.0.0\",\n toVersion: \"1.1.0\",\n description: \"Aggiunge filtro postazione, colonna IDXPOS e menu verifica RFID\",\n apply: async (options) => {\n await AccessiDatabaseUpdater.upsertFiltroTipo(options, 20, \"POSTAZIONE\", \"IDXPOS\", undefined);\n await AccessiDatabaseUpdater.ensureColumn(\n options,\n \"FILTRI\",\n \"IDXPOS SMALLINT\",\n \"IDXPOS\",\n \"idx della postazione nella tabella ANTENNE_POS di PROLAV\"\n );\n await AccessiDatabaseUpdater.upsertMenu(options, {\n CODMNU: \"MNUVERRFID\",\n DESMNU: \"Verifica RFID\",\n CODGRP: \"F\",\n FLGENABLED: 1,\n ICON: \"hardware-chip-outline\",\n ORDINE: 10,\n CODTIP: \"M\",\n PAGINA: \"/verifica-rfid\",\n RIFMENU: null,\n });\n },\n },\n {\n fromVersion: \"1.1.0\",\n toVersion: \"1.1.1\",\n description: \"Aggiunge FLGENABLED su FILTRI_TIPO\",\n apply: async (options) => {\n const columnCreated = await AccessiDatabaseUpdater.ensureColumn(\n options,\n \"FILTRI_TIPO\",\n \"FLGENABLED SMALLINT DEFAULT 1 NOT NULL\",\n \"FLGENABLED\"\n );\n\n if (!columnCreated) {\n await Orm.execute(\n options.databaseOptions,\n \"UPDATE FILTRI_TIPO SET FLGENABLED = 1 WHERE FLGENABLED IS NULL\"\n );\n }\n },\n },\n {\n fromVersion: \"1.1.1\",\n toVersion: \"1.1.2\",\n description: \"Aggiunge filtro vettore e colonna CODVET\",\n apply: async (options) => {\n await AccessiDatabaseUpdater.upsertFiltroTipo(options, 30, \"VETTORE\", \"CODVET\", 1);\n await AccessiDatabaseUpdater.ensureColumn(\n options,\n \"FILTRI\",\n \"CODVET INTEGER\",\n \"CODVET\",\n \"CODICE DEL VETTORE DA INSERIRE SE COME FILTRO HA 30\"\n );\n },\n },\n {\n fromVersion: \"1.1.2\",\n toVersion: \"1.1.3\",\n description: \"Aggiunge FLGADMINCONFIG e inizializza PARAMETRI\",\n apply: async (options) => {\n await AccessiDatabaseUpdater.ensureColumn(\n options,\n \"UTENTI_CONFIG\",\n \"FLGADMINCONFIG SMALLINT DEFAULT 0\",\n \"FLGADMINCONFIG\",\n \"flag utente configuratore dei menu amministratore\"\n );\n await AccessiDatabaseUpdater.createParametersTable(options.databaseOptions);\n },\n },\n {\n fromVersion: \"1.1.3\",\n toVersion: \"1.1.4\",\n description: \"Aggiunge sequence e trigger per RUOLI\",\n apply: async (options) => {\n if (!(await AccessiDatabaseUpdater.generatorExists(options.databaseOptions, \"GEN_RUOLI_ID\"))) {\n await Orm.execute(options.databaseOptions, \"CREATE SEQUENCE GEN_RUOLI_ID\");\n }\n\n if (!(await AccessiDatabaseUpdater.triggerExists(options.databaseOptions, \"RUOLI_BI\"))) {\n await Orm.execute(\n options.databaseOptions,\n `CREATE TRIGGER RUOLI_BI FOR RUOLI\nACTIVE BEFORE INSERT POSITION 0\nAS\nBEGIN\n IF (NEW.CODRUO IS NULL) THEN\n NEW.CODRUO = GEN_ID(GEN_RUOLI_ID,1);\nEND`\n );\n }\n },\n },\n {\n fromVersion: \"1.1.4\",\n toVersion: \"1.1.5\",\n description: \"Aggiunge NOTE su MENU\",\n apply: async (options) => {\n await AccessiDatabaseUpdater.ensureColumn(\n options,\n \"MENU\",\n \"NOTE VARCHAR(1000)\",\n \"NOTE\"\n );\n },\n },\n {\n fromVersion: \"1.1.5\",\n toVersion: \"1.1.6\",\n description: \"Aggiunge NUMMAC su UTENTI_CONFIG\",\n apply: async (options) => {\n await AccessiDatabaseUpdater.ensureColumn(\n options,\n \"UTENTI_CONFIG\",\n \"NUMMAC INTEGER\",\n \"NUMMAC\",\n 'Numero macchina DESPOST PROLAV'\n );\n },\n },\n ];\n\n constructor(\n @Inject(\"ACCESSI_OPTIONS\") private readonly accessiOptions: AccessiOptions\n ) {\n super();\n }\n\n async onModuleInit(): Promise<void> {\n if (this.accessiOptions.autoUpdateDatabase === false) {\n AccessiDatabaseUpdater.logger.info(\"Aggiornamento automatico database accessi disabilitato da configurazione.\");\n return;\n }\n\n await AccessiDatabaseUpdater.run(this.accessiOptions);\n }\n\n static async run(options: AccessiOptions): Promise<void> {\n await this.createParametersTable(options.databaseOptions);\n\n const currentVersion = await this.getDatabaseVersion(options.databaseOptions);\n const currentIndex = this.updates.findIndex(\n (update) => update.toVersion === currentVersion\n );\n const startIndex = currentIndex >= 0 ? currentIndex + 1 : 0;\n\n if (currentVersion && currentIndex === this.updates.length - 1) {\n this.logger.info(`Database accessi gia' all'ultima versione disponibile (${currentVersion}).`);\n } else if (currentVersion && currentIndex >= 0) {\n this.logger.info(`Database accessi rilevato alla versione ${currentVersion}.`);\n } else if (currentVersion) {\n this.logger.warning(\n `Versione database accessi non riconosciuta (${currentVersion}). Verifico tutti gli update idempotenti.`\n );\n } else {\n this.logger.warning(\n \"Versione database accessi assente. Verifico tutti gli update idempotenti.\"\n );\n }\n\n for (let index = startIndex; index < this.updates.length; index++) {\n const update = this.updates[index];\n this.logger.info(\n `Applico aggiornamento accessi ${update.fromVersion} -> ${update.toVersion}: ${update.description}`\n );\n await update.apply(options);\n await this.setDatabaseVersion(options.databaseOptions, update.toVersion);\n }\n }\n\n static async getCurrentVersion(options: AccessiOptions): Promise<string | null> {\n return await this.getDatabaseVersion(options.databaseOptions);\n }\n\n static getLatestVersion(): string {\n return this.updates[this.updates.length - 1]?.toVersion ?? \"0.0.0\";\n }\n\n private static async ensureColumn(\n options: AccessiOptions,\n tableName: string,\n columnDefinition: string,\n columnName: string,\n comment?: string\n ): Promise<boolean> {\n const exists = await this.columnExists(\n options.databaseOptions,\n tableName,\n columnName\n );\n\n if (!exists) {\n await Orm.execute(\n options.databaseOptions,\n `ALTER TABLE ${tableName} ADD ${columnDefinition}`\n );\n }\n\n if (comment) {\n await Orm.execute(\n options.databaseOptions,\n `COMMENT ON COLUMN ${tableName}.${columnName} IS '${comment.replace(/'/g, \"''\")}'`\n );\n }\n\n return !exists;\n }\n\n private static async upsertFiltroTipo(\n options: AccessiOptions,\n tipfil: number,\n desfil: string,\n fldfil: string,\n flgEnabled?: number\n ): Promise<void> {\n const hasEnabledColumn = await this.columnExists(\n options.databaseOptions,\n \"FILTRI_TIPO\",\n \"FLGENABLED\"\n );\n\n const existing = await Orm.query(\n options.databaseOptions,\n \"SELECT TIPFIL FROM FILTRI_TIPO WHERE TIPFIL = ?\",\n [tipfil]\n );\n\n if (existing.length === 0) {\n if (hasEnabledColumn && flgEnabled !== undefined) {\n await Orm.execute(\n options.databaseOptions,\n \"INSERT INTO FILTRI_TIPO (TIPFIL, DESFIL, FLDFIL, FLGENABLED) VALUES (?, ?, ?, ?)\",\n [tipfil, desfil, fldfil, flgEnabled]\n );\n return;\n }\n\n await Orm.execute(\n options.databaseOptions,\n \"INSERT INTO FILTRI_TIPO (TIPFIL, DESFIL, FLDFIL) VALUES (?, ?, ?)\",\n [tipfil, desfil, fldfil]\n );\n return;\n }\n\n if (hasEnabledColumn && flgEnabled !== undefined) {\n await Orm.execute(\n options.databaseOptions,\n \"UPDATE FILTRI_TIPO SET DESFIL = ?, FLDFIL = ?, FLGENABLED = COALESCE(FLGENABLED, ?) WHERE TIPFIL = ?\",\n [desfil, fldfil, flgEnabled, tipfil]\n );\n return;\n }\n\n await Orm.execute(\n options.databaseOptions,\n \"UPDATE FILTRI_TIPO SET DESFIL = ?, FLDFIL = ? WHERE TIPFIL = ?\",\n [desfil, fldfil, tipfil]\n );\n }\n\n private static async upsertMenu(\n options: AccessiOptions,\n menu: {\n CODMNU: string;\n DESMNU: string;\n CODGRP: string;\n FLGENABLED: number;\n ICON: string;\n ORDINE: number;\n CODTIP: string;\n PAGINA: string;\n RIFMENU: string | null;\n }\n ): Promise<void> {\n const existing = await Orm.query(\n options.databaseOptions,\n \"SELECT CODMNU FROM MENU WHERE CODMNU = ?\",\n [menu.CODMNU]\n );\n\n if (existing.length === 0) {\n await Orm.execute(\n options.databaseOptions,\n `INSERT INTO MENU (CODMNU, DESMNU, CODGRP, FLGENABLED, ICON, ORDINE, CODTIP, PAGINA, RIFMENU)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n menu.CODMNU,\n menu.DESMNU,\n menu.CODGRP,\n menu.FLGENABLED,\n menu.ICON,\n menu.ORDINE,\n menu.CODTIP,\n menu.PAGINA,\n menu.RIFMENU,\n ]\n );\n return;\n }\n\n await Orm.execute(\n options.databaseOptions,\n `UPDATE MENU\n SET DESMNU = ?,\n CODGRP = ?,\n FLGENABLED = COALESCE(FLGENABLED, ?),\n ICON = ?,\n ORDINE = ?,\n CODTIP = ?,\n PAGINA = ?,\n RIFMENU = ?\n WHERE CODMNU = ?`,\n [\n menu.DESMNU,\n menu.CODGRP,\n menu.FLGENABLED,\n menu.ICON,\n menu.ORDINE,\n menu.CODTIP,\n menu.PAGINA,\n menu.RIFMENU,\n menu.CODMNU,\n ]\n );\n }\n}\n"]}
1
+ {"version":3,"file":"AccessiDatabaseUpdater.js","sourceRoot":"","sources":["../../../src/accessi-module/database-updates/AccessiDatabaseUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Inject, OnModuleInit } from \"@nestjs/common\";\r\nimport { DatabaseUpdater } from \"../../DatabaseUpdater\";\r\nimport { AccessiOptions } from \"../AccessiModule\";\r\nimport { Orm } from \"../../Orm\";\r\nimport { Logger } from \"../../Logger\";\r\n\r\ntype AccessiUpdateStep = {\r\n fromVersion: string;\r\n toVersion: string;\r\n description: string;\r\n apply: (options: AccessiOptions) => Promise<void>;\r\n};\r\n\r\n@Injectable()\r\nexport class AccessiDatabaseUpdater extends DatabaseUpdater implements OnModuleInit {\n protected static override logger: Logger = new Logger(AccessiDatabaseUpdater.name);\n\r\n private static readonly updates: AccessiUpdateStep[] = [\r\n {\r\n fromVersion: \"1.0.0\",\r\n toVersion: \"1.1.0\",\r\n description: \"Aggiunge filtro postazione, colonna IDXPOS e menu verifica RFID\",\r\n apply: async (options) => {\r\n await AccessiDatabaseUpdater.upsertFiltroTipo(options, 20, \"POSTAZIONE\", \"IDXPOS\", undefined);\r\n await AccessiDatabaseUpdater.ensureColumn(\r\n options,\r\n \"FILTRI\",\r\n \"IDXPOS SMALLINT\",\r\n \"IDXPOS\",\r\n \"idx della postazione nella tabella ANTENNE_POS di PROLAV\"\r\n );\r\n await AccessiDatabaseUpdater.upsertMenu(options, {\r\n CODMNU: \"MNUVERRFID\",\r\n DESMNU: \"Verifica RFID\",\r\n CODGRP: \"F\",\r\n FLGENABLED: 1,\r\n ICON: \"hardware-chip-outline\",\r\n ORDINE: 10,\r\n CODTIP: \"M\",\r\n PAGINA: \"/verifica-rfid\",\r\n RIFMENU: null,\r\n });\r\n },\r\n },\r\n {\r\n fromVersion: \"1.1.0\",\r\n toVersion: \"1.1.1\",\r\n description: \"Aggiunge FLGENABLED su FILTRI_TIPO\",\r\n apply: async (options) => {\r\n const columnCreated = await AccessiDatabaseUpdater.ensureColumn(\r\n options,\r\n \"FILTRI_TIPO\",\r\n \"FLGENABLED SMALLINT DEFAULT 1 NOT NULL\",\r\n \"FLGENABLED\"\r\n );\r\n\r\n if (!columnCreated) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n \"UPDATE FILTRI_TIPO SET FLGENABLED = 1 WHERE FLGENABLED IS NULL\"\r\n );\r\n }\r\n },\r\n },\r\n {\r\n fromVersion: \"1.1.1\",\r\n toVersion: \"1.1.2\",\r\n description: \"Aggiunge filtro vettore e colonna CODVET\",\r\n apply: async (options) => {\r\n await AccessiDatabaseUpdater.upsertFiltroTipo(options, 30, \"VETTORE\", \"CODVET\", 1);\r\n await AccessiDatabaseUpdater.ensureColumn(\r\n options,\r\n \"FILTRI\",\r\n \"CODVET INTEGER\",\r\n \"CODVET\",\r\n \"CODICE DEL VETTORE DA INSERIRE SE COME FILTRO HA 30\"\r\n );\r\n },\r\n },\r\n {\r\n fromVersion: \"1.1.2\",\r\n toVersion: \"1.1.3\",\r\n description: \"Aggiunge FLGADMINCONFIG e inizializza PARAMETRI\",\r\n apply: async (options) => {\r\n await AccessiDatabaseUpdater.ensureColumn(\r\n options,\r\n \"UTENTI_CONFIG\",\r\n \"FLGADMINCONFIG SMALLINT DEFAULT 0\",\r\n \"FLGADMINCONFIG\",\r\n \"flag utente configuratore dei menu amministratore\"\r\n );\r\n await AccessiDatabaseUpdater.createParametersTable(options.databaseOptions);\r\n },\r\n },\r\n {\r\n fromVersion: \"1.1.3\",\r\n toVersion: \"1.1.4\",\r\n description: \"Aggiunge sequence e trigger per RUOLI\",\r\n apply: async (options) => {\r\n if (!(await AccessiDatabaseUpdater.generatorExists(options.databaseOptions, \"GEN_RUOLI_ID\"))) {\r\n await Orm.execute(options.databaseOptions, \"CREATE SEQUENCE GEN_RUOLI_ID\");\r\n }\r\n\r\n if (!(await AccessiDatabaseUpdater.triggerExists(options.databaseOptions, \"RUOLI_BI\"))) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n `CREATE TRIGGER RUOLI_BI FOR RUOLI\r\nACTIVE BEFORE INSERT POSITION 0\r\nAS\r\nBEGIN\r\n IF (NEW.CODRUO IS NULL) THEN\r\n NEW.CODRUO = GEN_ID(GEN_RUOLI_ID,1);\r\nEND`\r\n );\r\n }\r\n },\r\n },\r\n {\r\n fromVersion: \"1.1.4\",\r\n toVersion: \"1.1.5\",\r\n description: \"Aggiunge NOTE su MENU\",\r\n apply: async (options) => {\r\n await AccessiDatabaseUpdater.ensureColumn(\r\n options,\r\n \"MENU\",\r\n \"NOTE VARCHAR(1000)\",\r\n \"NOTE\"\r\n );\r\n },\r\n },\r\n {\r\n fromVersion: \"1.1.5\",\r\n toVersion: \"1.1.6\",\r\n description: \"Aggiunge NUMMAC su UTENTI_CONFIG\",\r\n apply: async (options) => {\r\n await AccessiDatabaseUpdater.ensureColumn(\r\n options,\r\n \"UTENTI_CONFIG\",\r\n \"NUMMAC INTEGER\",\r\n \"NUMMAC\",\r\n 'Numero macchina DESPOST PROLAV'\r\n );\r\n },\r\n },\r\n ];\r\n\r\n constructor(\r\n @Inject(\"ACCESSI_OPTIONS\") private readonly accessiOptions: AccessiOptions\r\n ) {\r\n super();\r\n }\r\n\r\n async onModuleInit(): Promise<void> {\n if (this.accessiOptions.autoUpdateDatabase === false) {\n AccessiDatabaseUpdater.logger.info(\"Aggiornamento automatico database accessi disabilitato da configurazione.\");\n return;\n }\n\n AccessiDatabaseUpdater.logger.info(\"Avvio updater database accessi.\");\n await AccessiDatabaseUpdater.run(this.accessiOptions);\n AccessiDatabaseUpdater.logger.info(\"Updater database accessi completato.\");\n }\n\n static async run(options: AccessiOptions): Promise<void> {\n const startedAt = performance.now();\n this.logger.info(\n `Verifica schema accessi su ${options.databaseOptions.host ?? \"?\"}:${options.databaseOptions.port ?? \"?\"} -> ${options.databaseOptions.database ?? \"?\"}`\n );\n await this.createParametersTable(options.databaseOptions);\n this.logger.info(\"Tabella PARAMETRI verificata.\");\n\n const currentVersion = await this.getDatabaseVersion(options.databaseOptions);\n const currentIndex = this.updates.findIndex(\r\n (update) => update.toVersion === currentVersion\r\n );\r\n const startIndex = currentIndex >= 0 ? currentIndex + 1 : 0;\r\n\r\n if (currentVersion && currentIndex === this.updates.length - 1) {\r\n this.logger.info(`Database accessi gia' all'ultima versione disponibile (${currentVersion}).`);\r\n } else if (currentVersion && currentIndex >= 0) {\r\n this.logger.info(`Database accessi rilevato alla versione ${currentVersion}.`);\r\n } else if (currentVersion) {\r\n this.logger.warning(\r\n `Versione database accessi non riconosciuta (${currentVersion}). Verifico tutti gli update idempotenti.`\r\n );\r\n } else {\r\n this.logger.warning(\r\n \"Versione database accessi assente. Verifico tutti gli update idempotenti.\"\r\n );\r\n }\r\n\r\n for (let index = startIndex; index < this.updates.length; index++) {\n const update = this.updates[index];\n const stepStartedAt = performance.now();\n this.logger.info(\n `Applico aggiornamento accessi ${update.fromVersion} -> ${update.toVersion}: ${update.description}`\n );\n await update.apply(options);\n await this.setDatabaseVersion(options.databaseOptions, update.toVersion);\n this.logger.info(\n `Aggiornamento accessi ${update.toVersion} completato in ${(performance.now() - stepStartedAt).toFixed(2)} ms`\n );\n }\n\n this.logger.info(\n `Verifica/aggiornamento database accessi completato in ${(performance.now() - startedAt).toFixed(2)} ms`\n );\n }\n\r\n static async getCurrentVersion(options: AccessiOptions): Promise<string | null> {\r\n return await this.getDatabaseVersion(options.databaseOptions);\r\n }\r\n\r\n static getLatestVersion(): string {\r\n return this.updates[this.updates.length - 1]?.toVersion ?? \"0.0.0\";\r\n }\r\n\r\n private static async ensureColumn(\r\n options: AccessiOptions,\r\n tableName: string,\r\n columnDefinition: string,\r\n columnName: string,\r\n comment?: string\r\n ): Promise<boolean> {\r\n const exists = await this.columnExists(\r\n options.databaseOptions,\r\n tableName,\r\n columnName\r\n );\r\n\r\n if (!exists) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n `ALTER TABLE ${tableName} ADD ${columnDefinition}`\r\n );\r\n }\r\n\r\n if (comment) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n `COMMENT ON COLUMN ${tableName}.${columnName} IS '${comment.replace(/'/g, \"''\")}'`\r\n );\r\n }\r\n\r\n return !exists;\r\n }\r\n\r\n private static async upsertFiltroTipo(\r\n options: AccessiOptions,\r\n tipfil: number,\r\n desfil: string,\r\n fldfil: string,\r\n flgEnabled?: number\r\n ): Promise<void> {\r\n const hasEnabledColumn = await this.columnExists(\r\n options.databaseOptions,\r\n \"FILTRI_TIPO\",\r\n \"FLGENABLED\"\r\n );\r\n\r\n const existing = await Orm.query(\r\n options.databaseOptions,\r\n \"SELECT TIPFIL FROM FILTRI_TIPO WHERE TIPFIL = ?\",\r\n [tipfil]\r\n );\r\n\r\n if (existing.length === 0) {\r\n if (hasEnabledColumn && flgEnabled !== undefined) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n \"INSERT INTO FILTRI_TIPO (TIPFIL, DESFIL, FLDFIL, FLGENABLED) VALUES (?, ?, ?, ?)\",\r\n [tipfil, desfil, fldfil, flgEnabled]\r\n );\r\n return;\r\n }\r\n\r\n await Orm.execute(\r\n options.databaseOptions,\r\n \"INSERT INTO FILTRI_TIPO (TIPFIL, DESFIL, FLDFIL) VALUES (?, ?, ?)\",\r\n [tipfil, desfil, fldfil]\r\n );\r\n return;\r\n }\r\n\r\n if (hasEnabledColumn && flgEnabled !== undefined) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n \"UPDATE FILTRI_TIPO SET DESFIL = ?, FLDFIL = ?, FLGENABLED = COALESCE(FLGENABLED, ?) WHERE TIPFIL = ?\",\r\n [desfil, fldfil, flgEnabled, tipfil]\r\n );\r\n return;\r\n }\r\n\r\n await Orm.execute(\r\n options.databaseOptions,\r\n \"UPDATE FILTRI_TIPO SET DESFIL = ?, FLDFIL = ? WHERE TIPFIL = ?\",\r\n [desfil, fldfil, tipfil]\r\n );\r\n }\r\n\r\n private static async upsertMenu(\r\n options: AccessiOptions,\r\n menu: {\r\n CODMNU: string;\r\n DESMNU: string;\r\n CODGRP: string;\r\n FLGENABLED: number;\r\n ICON: string;\r\n ORDINE: number;\r\n CODTIP: string;\r\n PAGINA: string;\r\n RIFMENU: string | null;\r\n }\r\n ): Promise<void> {\r\n const existing = await Orm.query(\r\n options.databaseOptions,\r\n \"SELECT CODMNU FROM MENU WHERE CODMNU = ?\",\r\n [menu.CODMNU]\r\n );\r\n\r\n if (existing.length === 0) {\r\n await Orm.execute(\r\n options.databaseOptions,\r\n `INSERT INTO MENU (CODMNU, DESMNU, CODGRP, FLGENABLED, ICON, ORDINE, CODTIP, PAGINA, RIFMENU)\r\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\r\n [\r\n menu.CODMNU,\r\n menu.DESMNU,\r\n menu.CODGRP,\r\n menu.FLGENABLED,\r\n menu.ICON,\r\n menu.ORDINE,\r\n menu.CODTIP,\r\n menu.PAGINA,\r\n menu.RIFMENU,\r\n ]\r\n );\r\n return;\r\n }\r\n\r\n await Orm.execute(\r\n options.databaseOptions,\r\n `UPDATE MENU\r\n SET DESMNU = ?,\r\n CODGRP = ?,\r\n FLGENABLED = COALESCE(FLGENABLED, ?),\r\n ICON = ?,\r\n ORDINE = ?,\r\n CODTIP = ?,\r\n PAGINA = ?,\r\n RIFMENU = ?\r\n WHERE CODMNU = ?`,\r\n [\r\n menu.DESMNU,\r\n menu.CODGRP,\r\n menu.FLGENABLED,\r\n menu.ICON,\r\n menu.ORDINE,\r\n menu.CODTIP,\r\n menu.PAGINA,\r\n menu.RIFMENU,\r\n menu.CODMNU,\r\n ]\r\n );\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runAccessiDbUpdate.js","sourceRoot":"","sources":["../../../src/accessi-module/database-updates/runAccessiDbUpdate.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccessiOptions } from \"../AccessiModule\";\nimport { AccessiDatabaseUpdater } from \"./AccessiDatabaseUpdater\";\nimport { DatabaseUtilities } from \"../../Utilities\";\n\nfunction getEnv(name: string, fallback?: string): string {\n const value = process.env[name] ?? fallback;\n if (!value) {\n throw new Error(`Variabile ambiente mancante: ${name}`);\n }\n return value;\n}\n\nfunction getOptionalBoolean(name: string, fallback: boolean): boolean {\n const value = process.env[name];\n if (value === undefined) {\n return fallback;\n }\n\n return value.toLowerCase() === \"true\";\n}\n\nfunction createAccessiOptionsFromEnv(): AccessiOptions {\n return {\n databaseOptions: DatabaseUtilities.createOption(\n getEnv(\"ACCESSI_DB_HOST\"),\n Number(getEnv(\"ACCESSI_DB_PORT\", \"3050\")),\n getEnv(\"ACCESSI_DB_DATABASE\"),\n getEnv(\"ACCESSI_DB_USER\", \"SYSDBA\"),\n getEnv(\"ACCESSI_DB_PASSWORD\", \"masterkey\")\n ),\n confirmationEmailUrl: getEnv(\"ACCESSI_CONFIRMATION_EMAIL_URL\", \"http://localhost\"),\n confirmationEmailReturnUrl: getEnv(\"ACCESSI_CONFIRMATION_RETURN_EMAIL_URL\", \"http://localhost\"),\n confirmationEmailPrefix: process.env.ACCESSI_CONFIRMATION_EMAIL_PREFIX,\n customResetPage: process.env.ACCESSI_CUSTOM_RESET_PAGE,\n encryptionKey: getEnv(\"ACCESSI_ENCRYPTION_KEY\", \"1234567890ABCDEF\"),\n mockDemoUser: getOptionalBoolean(\"ACCESSI_MOCK_DEMO_USER\", false),\n passwordExpiration: getOptionalBoolean(\"ACCESSI_PASSWORD_EXPIRATION\", false),\n autoUpdateDatabase: true,\n jwtOptions: {\n secret: getEnv(\"ACCESSI_JWT_SECRET\", \"local-accessi-update\"),\n expiresIn: getEnv(\"ACCESSI_JWT_EXPIRES\", \"24h\"),\n },\n emailOptions: {\n host: getEnv(\"ACCESSI_EMAIL_HOST\", \"localhost\"),\n port: Number(getEnv(\"ACCESSI_EMAIL_PORT\", \"25\")),\n secure: getOptionalBoolean(\"ACCESSI_EMAIL_SECURE\", false),\n requireTLS: getOptionalBoolean(\"ACCESSI_EMAIL_REQUIRE_TLS\", false),\n tls: {\n rejectUnauthorized: getOptionalBoolean(\"ACCESSI_EMAIL_TLS_REJECT_UNAUTHORIZED\", false),\n },\n from: getEnv(\"ACCESSI_EMAIL_FROM\", \"noreply@example.local\"),\n auth: {\n user: getEnv(\"ACCESSI_EMAIL_USER\", \"local-user\"),\n pass: getEnv(\"ACCESSI_EMAIL_PASSWORD\", \"local-password\"),\n },\n },\n extensionFieldsOptions: [],\n };\n}\n\nasync function main(): Promise<void> {\n const options = createAccessiOptionsFromEnv();\n\n console.log(\"[Accessi DB Update] Avvio aggiornamento database...\");\n console.log(\n `[Accessi DB Update] Target: ${options.databaseOptions.host}:${options.databaseOptions.port} -> ${options.databaseOptions.database}`\n );\n\n await AccessiDatabaseUpdater.run(options);\n\n const currentVersion = await AccessiDatabaseUpdater.getCurrentVersion(options);\n console.log(\n `[Accessi DB Update] Completato. Versione corrente: ${currentVersion ?? \"N/D\"} | Ultima disponibile: ${AccessiDatabaseUpdater.getLatestVersion()}`\n );\n}\n\nmain().catch((error) => {\n console.error(\"[Accessi DB Update] Errore durante l'aggiornamento:\", error);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"file":"runAccessiDbUpdate.js","sourceRoot":"","sources":["../../../src/accessi-module/database-updates/runAccessiDbUpdate.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccessiOptions } from \"../AccessiModule\";\r\nimport { AccessiDatabaseUpdater } from \"./AccessiDatabaseUpdater\";\r\nimport { DatabaseUtilities } from \"../../Utilities\";\r\n\r\nfunction getEnv(name: string, fallback?: string): string {\r\n const value = process.env[name] ?? fallback;\r\n if (!value) {\r\n throw new Error(`Variabile ambiente mancante: ${name}`);\r\n }\r\n return value;\r\n}\r\n\r\nfunction getOptionalBoolean(name: string, fallback: boolean): boolean {\r\n const value = process.env[name];\r\n if (value === undefined) {\r\n return fallback;\r\n }\r\n\r\n return value.toLowerCase() === \"true\";\r\n}\r\n\r\nfunction createAccessiOptionsFromEnv(): AccessiOptions {\r\n return {\r\n databaseOptions: DatabaseUtilities.createOption(\r\n getEnv(\"ACCESSI_DB_HOST\"),\r\n Number(getEnv(\"ACCESSI_DB_PORT\", \"3050\")),\r\n getEnv(\"ACCESSI_DB_DATABASE\"),\r\n getEnv(\"ACCESSI_DB_USER\", \"SYSDBA\"),\r\n getEnv(\"ACCESSI_DB_PASSWORD\", \"masterkey\")\r\n ),\r\n confirmationEmailUrl: getEnv(\"ACCESSI_CONFIRMATION_EMAIL_URL\", \"http://localhost\"),\r\n confirmationEmailReturnUrl: getEnv(\"ACCESSI_CONFIRMATION_RETURN_EMAIL_URL\", \"http://localhost\"),\r\n confirmationEmailPrefix: process.env.ACCESSI_CONFIRMATION_EMAIL_PREFIX,\r\n customResetPage: process.env.ACCESSI_CUSTOM_RESET_PAGE,\r\n encryptionKey: getEnv(\"ACCESSI_ENCRYPTION_KEY\", \"1234567890ABCDEF\"),\r\n mockDemoUser: getOptionalBoolean(\"ACCESSI_MOCK_DEMO_USER\", false),\r\n passwordExpiration: getOptionalBoolean(\"ACCESSI_PASSWORD_EXPIRATION\", false),\r\n autoUpdateDatabase: true,\r\n jwtOptions: {\r\n secret: getEnv(\"ACCESSI_JWT_SECRET\", \"local-accessi-update\"),\r\n expiresIn: getEnv(\"ACCESSI_JWT_EXPIRES\", \"24h\"),\r\n },\r\n emailOptions: {\r\n host: getEnv(\"ACCESSI_EMAIL_HOST\", \"localhost\"),\r\n port: Number(getEnv(\"ACCESSI_EMAIL_PORT\", \"25\")),\r\n secure: getOptionalBoolean(\"ACCESSI_EMAIL_SECURE\", false),\r\n requireTLS: getOptionalBoolean(\"ACCESSI_EMAIL_REQUIRE_TLS\", false),\r\n tls: {\r\n rejectUnauthorized: getOptionalBoolean(\"ACCESSI_EMAIL_TLS_REJECT_UNAUTHORIZED\", false),\r\n },\r\n from: getEnv(\"ACCESSI_EMAIL_FROM\", \"noreply@example.local\"),\r\n auth: {\r\n user: getEnv(\"ACCESSI_EMAIL_USER\", \"local-user\"),\r\n pass: getEnv(\"ACCESSI_EMAIL_PASSWORD\", \"local-password\"),\r\n },\r\n },\r\n extensionFieldsOptions: [],\r\n };\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n const options = createAccessiOptionsFromEnv();\r\n\r\n console.log(\"[Accessi DB Update] Avvio aggiornamento database...\");\r\n console.log(\r\n `[Accessi DB Update] Target: ${options.databaseOptions.host}:${options.databaseOptions.port} -> ${options.databaseOptions.database}`\r\n );\r\n\r\n await AccessiDatabaseUpdater.run(options);\r\n\r\n const currentVersion = await AccessiDatabaseUpdater.getCurrentVersion(options);\r\n console.log(\r\n `[Accessi DB Update] Completato. Versione corrente: ${currentVersion ?? \"N/D\"} | Ultima disponibile: ${AccessiDatabaseUpdater.getLatestVersion()}`\r\n );\r\n}\r\n\r\nmain().catch((error) => {\r\n console.error(\"[Accessi DB Update] Errore durante l'aggiornamento:\", error);\r\n process.exit(1);\r\n});\r\n"]}
@@ -25,32 +25,61 @@ 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");
35
+ function describeDatabaseTarget(options) {
36
+ var _a, _b, _c, _d;
37
+ const dbOptions = options.databaseOptions;
38
+ return `${(_a = dbOptions.host) !== null && _a !== void 0 ? _a : "?"}:${(_b = dbOptions.port) !== null && _b !== void 0 ? _b : "?"} -> ${(_c = dbOptions.database) !== null && _c !== void 0 ? _c : "?"} as ${(_d = dbOptions.user) !== null && _d !== void 0 ? _d : "?"}`;
39
+ }
33
40
  function initializeAccessiModule(app, options) {
34
41
  return __awaiter(this, void 0, void 0, function* () {
35
42
  const logger = new Logger_1.Logger("initializeAccessiModule");
36
43
  (0, authenticateGen_1.beginAccessiAuthInitialization)();
37
- console.log("Accessi initialized");
44
+ const startedAt = performance.now();
38
45
  try {
46
+ logger.info("Inizializzazione modulo accessi avviata.");
47
+ logger.info(`Target database accessi: ${describeDatabaseTarget(options)}`);
48
+ logger.info(`Configurazione accessi: autoUpdateDatabase=${options.autoUpdateDatabase !== false}, legacyPasswordMigrationOnStartup=${options.legacyPasswordMigrationOnStartup !== false}`);
39
49
  // Creiamo un'istanza Express separata per NestJS
40
50
  const nestExpressInstance = new platform_express_1.ExpressAdapter(app);
41
51
  // Creiamo l'app NestJS attaccata a Express
42
52
  const nestApp = yield core_1.NestFactory.create(AccessiModule_1.AccessiModule.forRoot(options), nestExpressInstance, {
43
53
  bufferLogs: true
44
54
  });
55
+ logger.info("Applicazione Nest accessi creata.");
45
56
  nestApp.enableCors();
57
+ nestApp.useGlobalPipes(new common_1.ValidationPipe({
58
+ whitelist: true,
59
+ forbidNonWhitelisted: true,
60
+ transform: true,
61
+ transformOptions: {
62
+ enableImplicitConversion: true,
63
+ },
64
+ }));
46
65
  nestApp.setGlobalPrefix('api', {
47
66
  exclude: ['/swagger', '/swagger/(.*)']
48
67
  });
49
68
  // Note: Swagger setup is now handled by the unified module
69
+ logger.info("Avvio init del modulo accessi.");
50
70
  yield nestApp.init();
51
- const authService = nestApp.get(authenticateGen_1.AuthenticateGenService);
52
- app.locals.accessiAuthService = authService;
53
- (0, authenticateGen_1.setAccessiAuthService)(authService);
71
+ logger.info("Init del modulo accessi completata.");
72
+ if (options.legacyPasswordMigrationOnStartup !== false) {
73
+ logger.info("Avvio migrazione password legacy accessi.");
74
+ const passwordMigrationService = nestApp.get(AuthService_1.AuthService);
75
+ yield passwordMigrationService.migrateLegacyEncryptedPasswords();
76
+ logger.info("Migrazione password legacy accessi completata.");
77
+ }
78
+ const accessiAuthService = nestApp.get(authenticateGen_1.AuthenticateGenService);
79
+ app.locals.accessiAuthService = accessiAuthService;
80
+ (0, authenticateGen_1.setAccessiAuthService)(accessiAuthService);
81
+ const elapsedMs = performance.now() - startedAt;
82
+ logger.info(`Accessi initialized. Tempo totale bootstrap: ${elapsedMs.toFixed(2)} ms`);
54
83
  }
55
84
  catch (error) {
56
85
  (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":"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","sourcesContent":["import { Application } from \"express\";\r\nimport { ValidationPipe } from \"@nestjs/common\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\r\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\r\nimport { Logger } from \"../Logger\";\r\nimport { AuthService } from \"./Services/AuthService/AuthService\";\r\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n AuthenticateGenService,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\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\nexport async function initializeAccessiModule(app: Application, options: AccessiOptions) {\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n const startedAt = performance.now();\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 // 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 logger.info(\"Applicazione Nest accessi creata.\");\n\n nestApp.enableCors();\n nestApp.useGlobalPipes(\n new ValidationPipe({\n whitelist: true,\r\n forbidNonWhitelisted: true,\r\n transform: true,\r\n transformOptions: {\r\n enableImplicitConversion: true,\r\n },\r\n }),\r\n );\r\n\r\n nestApp.setGlobalPrefix('api', {\n exclude: ['/swagger', '/swagger/(.*)']\n });\n\n // Note: Swagger setup is now handled by the unified module\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 accessiAuthService = nestApp.get(AuthenticateGenService);\n app.locals.accessiAuthService = accessiAuthService;\n setAccessiAuthService(accessiAuthService);\n const elapsedMs = performance.now() - startedAt;\n logger.info(`Accessi initialized. Tempo totale bootstrap: ${elapsedMs.toFixed(2)} ms`);\n\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\"Errore in initialize AccessiModule:\", error);\n throw error;\r\n }\r\n}\r\n\r\nexport { AccessiModule } from \"./AccessiModule\";\r\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\r\nexport * from \"./Dtos\";\r\nexport {\r\n authorizeAccessi,\r\n authenticateGen\r\n} from \"./middleware/authenticateGen\";\r\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\r\nexport type {\r\n AccessiAuthorizationOptions,\r\n AccessiRequirementNode,\r\n AccessiCustomRequirementContext,\r\n AccessiCustomRequirementHandler\r\n} from \"./middleware/accessiRequirements\";\r\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 {\r\n CanActivate,\r\n ExecutionContext,\r\n Inject,\r\n Injectable,\r\n InternalServerErrorException,\r\n UnauthorizedException,\r\n} from '@nestjs/common';\r\nimport * as jwt from 'jsonwebtoken';\r\nimport { AccessiOptions } from '../AccessiModule';\r\nimport { UserService } from '../Services/UserService/UserService';\r\nimport {\r\n buildAuthenticatedTokenPayload,\r\n isAuthenticatedUserEnabledForJwt,\r\n resolveCodiceUtenteFromTokenPayload,\r\n} from '../security/authenticatedToken';\r\n\r\n@Injectable()\r\nexport class JwtSimpleGuard implements CanActivate {\r\n constructor(\r\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\r\n private readonly userService: UserService,\r\n ) {}\r\n\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n const request = context.switchToHttp().getRequest();\r\n\r\n const authHeader = request.headers['authorization'];\r\n if (!authHeader) throw new UnauthorizedException('Token mancante.');\r\n\r\n const token = authHeader.split(' ')[1];\r\n if (!token) throw new UnauthorizedException('Formato token non valido.');\r\n\r\n try {\r\n const secret = this.accessiOptions?.jwtOptions?.secret || process.env.ACC_JWT_SECRET;\r\n if (!secret) {\r\n throw new InternalServerErrorException('JWT secret non configurato.');\r\n }\r\n const payload = jwt.verify(token, secret);\r\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(payload);\r\n if (!codiceUtente) {\r\n throw new UnauthorizedException('Token privo di un utente valido.');\r\n }\r\n\r\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\r\n if (!isAuthenticatedUserEnabledForJwt(currentUser)) {\r\n throw new UnauthorizedException('Utente non piu autorizzato.');\r\n }\r\n\r\n request.user = buildAuthenticatedTokenPayload(payload, currentUser);\r\n return true;\r\n } catch (error) {\r\n if (error instanceof InternalServerErrorException || error instanceof UnauthorizedException) {\r\n throw error;\r\n }\r\n throw new UnauthorizedException('Token non valido o scaduto.');\r\n }\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"accessiRequirements.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/accessiRequirements.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\n\nexport type AccessiGrant = {\n codiceMenu: string;\n tipoAbilitazione?: number;\n};\n\nexport type GrantsResult = {\n grants?: AccessiGrant[];\n [key: string]: unknown;\n};\n\nexport type AccessiPermissionRequirement = {\n type: \"permission\";\n menuCode: string;\n minPermissionLevel: number;\n};\n\nexport type AccessiAllRequirement = {\n type: \"and\";\n requirements: AccessiRequirementNode[];\n};\n\nexport type AccessiAnyRequirement = {\n type: \"or\";\n requirements: AccessiRequirementNode[];\n};\n\nexport type AccessiNotRequirement = {\n type: \"not\";\n requirement: AccessiRequirementNode;\n};\n\nexport type AccessiCustomRequirement = {\n type: \"custom\";\n key: string;\n payload?: unknown;\n};\n\nexport type AccessiRequirementNode =\n | AccessiPermissionRequirement\n | AccessiAllRequirement\n | AccessiAnyRequirement\n | AccessiNotRequirement\n | AccessiCustomRequirement;\n\nexport type AccessiCustomRequirementContext = {\n req: Request;\n decodedToken: any;\n userCode: number;\n getGrantsResult: () => Promise<GrantsResult>;\n};\n\nexport type AccessiCustomRequirementHandler = (\n context: AccessiCustomRequirementContext,\n payload?: unknown\n) => boolean | Promise<boolean>;\n\nexport type AccessiAuthorizationOptions = {\n requirements?: { menuCode: string; minPermissionLevel: number }[];\n requirementTree?: AccessiRequirementNode;\n customRequirementHandlers?: Record<string, AccessiCustomRequirementHandler>;\n};\n\nexport class RequirementEvaluationError extends Error {\n constructor(public readonly code: string, message: string) {\n super(message);\n this.name = \"RequirementEvaluationError\";\n }\n}\n\nfunction requirementError(code: string, message: string): RequirementEvaluationError {\n return new RequirementEvaluationError(code, message);\n}\n\nexport const accessiRequirement = {\n permission: (\n menuCode: string,\n minPermissionLevel: number\n ): AccessiPermissionRequirement => ({\n type: \"permission\",\n menuCode,\n minPermissionLevel,\n }),\n and: (...requirements: AccessiRequirementNode[]): AccessiAllRequirement => ({\n type: \"and\",\n requirements,\n }),\n or: (...requirements: AccessiRequirementNode[]): AccessiAnyRequirement => ({\n type: \"or\",\n requirements,\n }),\n not: (requirement: AccessiRequirementNode): AccessiNotRequirement => ({\n type: \"not\",\n requirement,\n }),\n custom: (key: string, payload?: unknown): AccessiCustomRequirement => ({\n type: \"custom\",\n key,\n payload,\n }),\n};\n\nexport function buildRequirementTree(\n options?: AccessiAuthorizationOptions\n): AccessiRequirementNode | undefined {\n if (options?.requirementTree) return options.requirementTree;\n\n const requirements = options?.requirements ?? [];\n if (requirements.length === 0) return undefined;\n\n const nodes: AccessiRequirementNode[] = requirements.map((requirement) =>\n accessiRequirement.permission(\n requirement.menuCode,\n requirement.minPermissionLevel\n )\n );\n\n return accessiRequirement.and(...nodes);\n}\n\nexport async function evaluateRequirement(\n requirement: AccessiRequirementNode,\n context: AccessiCustomRequirementContext,\n options?: AccessiAuthorizationOptions\n): Promise<boolean> {\n switch (requirement.type) {\n case \"permission\": {\n const grantsResult = await context.getGrantsResult();\n const grants = grantsResult.grants ?? [];\n return grants.some(\n (grant) =>\n grant.codiceMenu == requirement.menuCode &&\n Number(grant.tipoAbilitazione ?? 0) >= requirement.minPermissionLevel\n );\n }\n case \"and\":\n if (!requirement.requirements || requirement.requirements.length === 0) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"AND requirement must contain at least one child requirement\"\n );\n }\n for (const child of requirement.requirements) {\n if (!(await evaluateRequirement(child, context, options))) return false;\n }\n return true;\n case \"or\":\n if (!requirement.requirements || requirement.requirements.length === 0) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"OR requirement must contain at least one child requirement\"\n );\n }\n for (const child of requirement.requirements) {\n if (await evaluateRequirement(child, context, options)) return true;\n }\n return false;\n case \"not\":\n return !(await evaluateRequirement(requirement.requirement, context, options));\n case \"custom\": {\n const handlers = options?.customRequirementHandlers ?? {};\n const handler = handlers[requirement.key];\n if (!handler) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n `Custom requirement handler \"${requirement.key}\" not found`\n );\n }\n return Boolean(await handler(context, requirement.payload));\n }\n default:\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"Unknown requirement node type\"\n );\n }\n}\n"]}
1
+ {"version":3,"file":"accessiRequirements.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/accessiRequirements.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\r\n\r\nexport type AccessiGrant = {\r\n codiceMenu: string;\r\n tipoAbilitazione?: number;\r\n};\r\n\r\nexport type GrantsResult = {\r\n grants?: AccessiGrant[];\r\n [key: string]: unknown;\r\n};\r\n\r\nexport type AccessiPermissionRequirement = {\r\n type: \"permission\";\r\n menuCode: string;\r\n minPermissionLevel: number;\r\n};\r\n\r\nexport type AccessiAllRequirement = {\r\n type: \"and\";\r\n requirements: AccessiRequirementNode[];\r\n};\r\n\r\nexport type AccessiAnyRequirement = {\r\n type: \"or\";\r\n requirements: AccessiRequirementNode[];\r\n};\r\n\r\nexport type AccessiNotRequirement = {\r\n type: \"not\";\r\n requirement: AccessiRequirementNode;\r\n};\r\n\r\nexport type AccessiCustomRequirement = {\r\n type: \"custom\";\r\n key: string;\r\n payload?: unknown;\r\n};\r\n\r\nexport type AccessiRequirementNode =\r\n | AccessiPermissionRequirement\r\n | AccessiAllRequirement\r\n | AccessiAnyRequirement\r\n | AccessiNotRequirement\r\n | AccessiCustomRequirement;\r\n\r\nexport type AccessiCustomRequirementContext = {\r\n req: Request;\r\n decodedToken: any;\r\n userCode: number;\r\n getGrantsResult: () => Promise<GrantsResult>;\r\n};\r\n\r\nexport type AccessiCustomRequirementHandler = (\r\n context: AccessiCustomRequirementContext,\r\n payload?: unknown\r\n) => boolean | Promise<boolean>;\r\n\r\nexport type AccessiAuthorizationOptions = {\r\n requirements?: { menuCode: string; minPermissionLevel: number }[];\r\n requirementTree?: AccessiRequirementNode;\r\n customRequirementHandlers?: Record<string, AccessiCustomRequirementHandler>;\r\n};\r\n\r\nexport class RequirementEvaluationError extends Error {\r\n constructor(public readonly code: string, message: string) {\r\n super(message);\r\n this.name = \"RequirementEvaluationError\";\r\n }\r\n}\r\n\r\nfunction requirementError(code: string, message: string): RequirementEvaluationError {\r\n return new RequirementEvaluationError(code, message);\r\n}\r\n\r\nexport const accessiRequirement = {\r\n permission: (\r\n menuCode: string,\r\n minPermissionLevel: number\r\n ): AccessiPermissionRequirement => ({\r\n type: \"permission\",\r\n menuCode,\r\n minPermissionLevel,\r\n }),\r\n and: (...requirements: AccessiRequirementNode[]): AccessiAllRequirement => ({\r\n type: \"and\",\r\n requirements,\r\n }),\r\n or: (...requirements: AccessiRequirementNode[]): AccessiAnyRequirement => ({\r\n type: \"or\",\r\n requirements,\r\n }),\r\n not: (requirement: AccessiRequirementNode): AccessiNotRequirement => ({\r\n type: \"not\",\r\n requirement,\r\n }),\r\n custom: (key: string, payload?: unknown): AccessiCustomRequirement => ({\r\n type: \"custom\",\r\n key,\r\n payload,\r\n }),\r\n};\r\n\r\nexport function buildRequirementTree(\r\n options?: AccessiAuthorizationOptions\r\n): AccessiRequirementNode | undefined {\r\n if (options?.requirementTree) return options.requirementTree;\r\n\r\n const requirements = options?.requirements ?? [];\r\n if (requirements.length === 0) return undefined;\r\n\r\n const nodes: AccessiRequirementNode[] = requirements.map((requirement) =>\r\n accessiRequirement.permission(\r\n requirement.menuCode,\r\n requirement.minPermissionLevel\r\n )\r\n );\r\n\r\n return accessiRequirement.and(...nodes);\r\n}\r\n\r\nexport async function evaluateRequirement(\r\n requirement: AccessiRequirementNode,\r\n context: AccessiCustomRequirementContext,\r\n options?: AccessiAuthorizationOptions\r\n): Promise<boolean> {\r\n switch (requirement.type) {\r\n case \"permission\": {\r\n const grantsResult = await context.getGrantsResult();\r\n const grants = grantsResult.grants ?? [];\r\n return grants.some(\r\n (grant) =>\r\n grant.codiceMenu == requirement.menuCode &&\r\n Number(grant.tipoAbilitazione ?? 0) >= requirement.minPermissionLevel\r\n );\r\n }\r\n case \"and\":\r\n if (!requirement.requirements || requirement.requirements.length === 0) {\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n \"AND requirement must contain at least one child requirement\"\r\n );\r\n }\r\n for (const child of requirement.requirements) {\r\n if (!(await evaluateRequirement(child, context, options))) return false;\r\n }\r\n return true;\r\n case \"or\":\r\n if (!requirement.requirements || requirement.requirements.length === 0) {\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n \"OR requirement must contain at least one child requirement\"\r\n );\r\n }\r\n for (const child of requirement.requirements) {\r\n if (await evaluateRequirement(child, context, options)) return true;\r\n }\r\n return false;\r\n case \"not\":\r\n return !(await evaluateRequirement(requirement.requirement, context, options));\r\n case \"custom\": {\r\n const handlers = options?.customRequirementHandlers ?? {};\r\n const handler = handlers[requirement.key];\r\n if (!handler) {\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n `Custom requirement handler \"${requirement.key}\" not found`\r\n );\r\n }\r\n return Boolean(await handler(context, requirement.payload));\r\n }\r\n default:\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n \"Unknown requirement node type\"\r\n );\r\n }\r\n}\r\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;