emilsoftware-utilities 2.0.0-dev.32 → 2.0.0-dev.33

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 (48) hide show
  1. package/dist/accessi-module/Console/console.js +3 -10
  2. package/dist/accessi-module/Console/console.js.map +1 -1
  3. package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.d.ts +0 -5
  4. package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.js.map +1 -1
  5. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.d.ts +0 -2
  6. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js.map +1 -1
  7. package/dist/accessi-module/Console/generated/model/menuEntity.d.ts +0 -2
  8. package/dist/accessi-module/Console/generated/model/menuEntity.js.map +1 -1
  9. package/dist/accessi-module/Console/generated/model/publicRegisterRequest.d.ts +0 -2
  10. package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js.map +1 -1
  11. package/dist/accessi-module/Console/generated/model/registerRequest.d.ts +0 -2
  12. package/dist/accessi-module/Console/generated/model/registerRequest.js.map +1 -1
  13. package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.d.ts +0 -5
  14. package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.js.map +1 -1
  15. package/dist/accessi-module/Console/generated/model/userDto.d.ts +0 -4
  16. package/dist/accessi-module/Console/generated/model/userDto.js.map +1 -1
  17. package/dist/accessi-module/Console/wiki.js +2 -2
  18. package/dist/accessi-module/Console/wiki.js.map +1 -1
  19. package/dist/accessi-module/Dtos/CatalogDtos.d.ts +0 -2
  20. package/dist/accessi-module/Dtos/CatalogDtos.js +0 -14
  21. package/dist/accessi-module/Dtos/CatalogDtos.js.map +1 -1
  22. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.d.ts +0 -1
  23. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js +0 -8
  24. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js.map +1 -1
  25. package/dist/accessi-module/Dtos/GetMenusResponse.d.ts +0 -1
  26. package/dist/accessi-module/Dtos/GetMenusResponse.js +0 -8
  27. package/dist/accessi-module/Dtos/GetMenusResponse.js.map +1 -1
  28. package/dist/accessi-module/Dtos/RegisterRequest.d.ts +0 -1
  29. package/dist/accessi-module/Dtos/RegisterRequest.js +0 -9
  30. package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
  31. package/dist/accessi-module/Dtos/UserDto.d.ts +0 -2
  32. package/dist/accessi-module/Dtos/UserDto.js +0 -16
  33. package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
  34. package/dist/accessi-module/Services/AuthService/AuthService.js +0 -2
  35. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  36. package/dist/accessi-module/Services/PermissionService/PermissionService.js +5 -13
  37. package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
  38. package/dist/accessi-module/Services/UserService/UserService.d.ts +0 -1
  39. package/dist/accessi-module/Services/UserService/UserService.js +2 -25
  40. package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
  41. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +7 -0
  42. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
  43. package/dist/accessi-module/database-updates/accessiSchema.d.ts +13 -2
  44. package/dist/accessi-module/database-updates/accessiSchema.js +15 -7
  45. package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -1
  46. package/dist/emilsoftware-utilities-2.0.0-dev.33.tgz +0 -0
  47. package/package.json +1 -1
  48. package/dist/emilsoftware-utilities-2.0.0-dev.32.tgz +0 -0
@@ -381,8 +381,7 @@ let PermissionService = class PermissionService {
381
381
  M.ICON AS icona,
382
382
  M.CODTIP AS tipo,
383
383
  M.PAGINA AS pagina,
384
- M.NOTE AS note,
385
- G.NOMECAMPO AS nome_campo
384
+ M.NOTE AS note
386
385
  FROM MENU M
387
386
  LEFT JOIN MENU_GRP G ON M.CODGRP = G.CODGRP
388
387
  WHERE M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1
@@ -414,8 +413,7 @@ let PermissionService = class PermissionService {
414
413
  G.ORDINE AS ordine_gruppo,
415
414
  M.ORDINE as ordine_menu,
416
415
  M.FLGENABLED AS menu_enabled,
417
- G.FLGENABLED AS group_enabled,
418
- G.NOMECAMPO AS nome_campo
416
+ G.FLGENABLED AS group_enabled
419
417
  FROM MENU M
420
418
  LEFT JOIN MENU_GRP G ON M.CODGRP = G.CODGRP
421
419
  ${filtersClause}
@@ -424,7 +422,7 @@ let PermissionService = class PermissionService {
424
422
  const result = yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, query, []);
425
423
  const groupMap = new Map();
426
424
  result.forEach((row) => {
427
- var _a, _b, _c, _d;
425
+ var _a, _b, _c;
428
426
  const converted = Utilities_1.RestUtilities.convertKeysToCamelCase(row);
429
427
  const { menuEnabled, groupEnabled } = converted, menuBase = __rest(converted, ["menuEnabled", "groupEnabled"]);
430
428
  const normalizedGroupKey = (_a = menuBase.codiceGruppo) !== null && _a !== void 0 ? _a : '__UNGROUPED__';
@@ -435,7 +433,6 @@ let PermissionService = class PermissionService {
435
433
  codiceGruppo: (_b = menuBase.codiceGruppo) !== null && _b !== void 0 ? _b : normalizedGroupKey,
436
434
  descrizioneGruppo: (_c = menuBase.descrizioneGruppo) !== null && _c !== void 0 ? _c : '',
437
435
  ordineGruppo: menuBase.ordineGruppo,
438
- nomeCampo: (_d = menuBase.nomeCampo) !== null && _d !== void 0 ? _d : null,
439
436
  enabled: groupEnabledFlag,
440
437
  menus: [],
441
438
  });
@@ -516,16 +513,15 @@ let PermissionService = class PermissionService {
516
513
  }
517
514
  createMenuGroup(input) {
518
515
  return __awaiter(this, void 0, void 0, function* () {
519
- var _a, _b, _c;
516
+ var _a, _b;
520
517
  if ((yield this.countWhere('MENU_GRP', 'CODGRP', input.codiceGruppo)) > 0) {
521
518
  throw new common_1.BadRequestException(`Il gruppo menu ${input.codiceGruppo} esiste gia.`);
522
519
  }
523
- yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, `INSERT INTO MENU_GRP (CODGRP, DESGRP, FLGENABLED, ORDINE, NOMECAMPO) VALUES (?, ?, ?, ?, ?)`, [
520
+ yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, `INSERT INTO MENU_GRP (CODGRP, DESGRP, FLGENABLED, ORDINE) VALUES (?, ?, ?, ?)`, [
524
521
  input.codiceGruppo,
525
522
  (_a = input.descrizioneGruppo) !== null && _a !== void 0 ? _a : null,
526
523
  input.enabled === false ? 0 : 1,
527
524
  (_b = input.ordineGruppo) !== null && _b !== void 0 ? _b : 0,
528
- (_c = input.nomeCampo) !== null && _c !== void 0 ? _c : null,
529
525
  ]);
530
526
  });
531
527
  }
@@ -546,10 +542,6 @@ let PermissionService = class PermissionService {
546
542
  sets.push('FLGENABLED = ?');
547
543
  params.push(input.enabled ? 1 : 0);
548
544
  }
549
- if (input.nomeCampo !== undefined) {
550
- sets.push('NOMECAMPO = ?');
551
- params.push(input.nomeCampo);
552
- }
553
545
  if (sets.length === 0)
554
546
  return;
555
547
  params.push(codiceGruppo);
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/PermissionService/PermissionService.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { Orm } from \"../../../Orm\";\nimport { RestUtilities } from \"../../../Utilities\";\nimport type { AccessiOptions } from \"../../AccessiModule\";\nimport { Permission, TipoAbilitazione } from \"../../Dtos\";\nimport { AbilitazioneMenu } from \"../../Dtos/AbilitazioneMenu\";\nimport { GroupWithMenusEntity } from \"../../Dtos/GetGroupsWithMenusResponse\";\nimport { MenuEntity } from \"../../Dtos/GetMenusResponse\";\nimport { Role } from \"../../Dtos/Role\";\nimport {\n CreateMenuGroupRequest,\n CreateMenuRequest,\n CreateMenuTypeRequest,\n MenuTypeEntity,\n UpdateMenuGroupRequest,\n UpdateMenuRequest,\n UpdateMenuTypeRequest,\n} from \"../../Dtos/CatalogDtos\";\nimport { BadRequestException, Inject, Injectable } from \"@nestjs/common\";\n\n/** Struttura storica menu/gruppi accettata dall'API legacy `addAbilitazioni`. */\ntype LegacyMenuGroup = {\n menu?: Array<{\n flgChk?: unknown;\n codiceMenu?: unknown;\n tipoAbilitazione?: unknown;\n }>;\n};\n\n@Injectable()\nexport class PermissionService {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions\n ) { }\n\n private getCountFromResult(result: ReadonlyArray<Record<string, unknown>>, fieldName = 'COUNT'): number {\n const rawValue = result?.[0]?.[fieldName]\n ?? result?.[0]?.[fieldName.toLowerCase()]\n ?? result?.[0]?.count;\n return typeof rawValue === 'number' ? rawValue : Number.parseInt(`${rawValue ?? '0'}`, 10);\n }\n\n private extractIntegerColumn(result: ReadonlyArray<Record<string, unknown>>, fieldName: string): Set<number> {\n return new Set(\n result.map((row) => Number(row[fieldName] ?? row[fieldName.toLowerCase()])),\n );\n }\n\n private async getAllActiveMenusAsGrants(): Promise<AbilitazioneMenu[]> {\n const query = `\n SELECT\n M.CODMNU AS codice_menu,\n 30 AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n G.DESGRP AS descrizione_gruppo,\n G.CODGRP AS codice_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM MENU M\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1\n `;\n\n return await Orm.query(this.accessiOptions.databaseOptions, query, [])\n .then(results => results.map(RestUtilities.convertKeysToCamelCase)) as AbilitazioneMenu[];\n }\n\n private async getUserDirectPermissions(codiceUtente: number): Promise<AbilitazioneMenu[]> {\n const queryAbilitazioni = `\n SELECT\n A.CODMNU AS codice_menu,\n A.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n G.DESGRP AS descrizione_gruppo,\n G.CODGRP AS codice_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM ABILITAZIONI A\n INNER JOIN MENU M ON A.CODMNU = M.CODMNU\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE A.CODUTE = ? AND M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1\n `;\n\n return await Orm.query(this.accessiOptions.databaseOptions, queryAbilitazioni, [codiceUtente])\n .then(results => results.map(RestUtilities.convertKeysToCamelCase)) as AbilitazioneMenu[];\n }\n\n private async getUserRoles(codiceUtente: number): Promise<Role[]> {\n const queryRuoli = `\n SELECT\n R.CODRUO AS codice_ruolo,\n R.DESRUO AS descrizione_ruolo,\n CASE WHEN COALESCE(G.FLGENABLED, 1) = 1 THEN M.CODMNU END AS codice_menu,\n RM.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n M.NOTE AS note\n FROM UTENTI_RUOLI RU\n INNER JOIN RUOLI R ON RU.CODRUO = R.CODRUO\n LEFT JOIN RUOLI_MNU RM ON R.CODRUO = RM.CODRUO\n LEFT JOIN MENU M\n ON RM.CODMNU = M.CODMNU\n AND M.FLGENABLED = 1\n LEFT JOIN MENU_GRP G\n ON G.CODGRP = M.CODGRP\n WHERE RU.CODUTE = ?\n `;\n const ruoliResult = (await Orm.query(this.accessiOptions.databaseOptions, queryRuoli, [codiceUtente]))\n .map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n return this.assembleRoles(ruoliResult);\n }\n\n /** Costruisce l'albero ruoli/menu a partire dalle righe (riusato da lettura singola e batch). */\n private assembleRoles(ruoliResult: Array<Record<string, unknown>>): Role[] {\n const ruoliMap = new Map<number, Role>();\n for (const row of ruoliResult) {\n const codiceRuolo = Number(row.codiceRuolo);\n const descrizioneRuolo = typeof row.descrizioneRuolo === 'string' ? row.descrizioneRuolo.trim() : '';\n const codiceMenu = typeof row.codiceMenu === 'string' ? row.codiceMenu : undefined;\n const descrizioneMenu = typeof row.descrizioneMenu === 'string' ? row.descrizioneMenu : undefined;\n const tipoAbilitazione = Number(row.tipoAbilitazione) as TipoAbilitazione;\n\n if (!ruoliMap.has(codiceRuolo)) {\n ruoliMap.set(codiceRuolo, {\n codiceRuolo,\n descrizioneRuolo,\n menu: []\n });\n }\n\n if (codiceMenu && descrizioneMenu) {\n ruoliMap.get(codiceRuolo)!.menu.push({\n codiceRuolo,\n codiceMenu,\n tipoAbilitazione,\n });\n }\n }\n\n return Array.from(ruoliMap.values());\n }\n\n /** Regola di composizione storica: grant diretti prevalgono, i ruoli si sommano per livello massimo. */\n private composeGrants(\n abilitazioni: AbilitazioneMenu[],\n ruoli: Role[],\n isSuperAdmin: boolean,\n allActiveMenus: AbilitazioneMenu[],\n ): AbilitazioneMenu[] {\n const grantsMap = new Map<string, AbilitazioneMenu>();\n\n for (const abilitazione of abilitazioni) {\n grantsMap.set(abilitazione.codiceMenu, abilitazione);\n }\n\n const directMenuCodes = new Set(abilitazioni.map(grant => grant.codiceMenu));\n for (const ruolo of ruoli) {\n for (const menu of ruolo.menu) {\n const existing = grantsMap.get(menu.codiceMenu);\n if (!directMenuCodes.has(menu.codiceMenu) &&\n (!existing || Number(menu.tipoAbilitazione) > Number(existing.tipoAbilitazione))) {\n grantsMap.set(menu.codiceMenu, menu);\n }\n }\n }\n\n return isSuperAdmin ? allActiveMenus : Array.from(grantsMap.values());\n }\n\n\n /**\n * API legacy per salvare grant dalla struttura storica menu/gruppi.\n * Sostituisce tutti i grant diretti dell'utente; per le nuove integrazioni preferire `assignPermissionsToUser`.\n */\n public async addAbilitazioni(codiceUtente: number, menuAbilitazioni: LegacyMenuGroup[]): Promise<void> {\n const abilitazioniToInsert = menuAbilitazioni\n .flatMap(menuGrp => menuGrp.menu ?? [])\n .filter(menu => menu.flgChk)\n .map(menu => [codiceUtente, menu.codiceMenu, menu.tipoAbilitazione]);\n\n const insertQuery = `UPDATE OR INSERT INTO ABILITAZIONI (CODUTE, CODMNU, TIPABI) VALUES (?, ?, ?)`;\n\n // Delete + insert atomici: un errore a metà non lascia l'utente senza abilitazioni.\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: `DELETE FROM ABILITAZIONI WHERE CODUTE = ?`, params: [codiceUtente] },\n ...abilitazioniToInsert.map(params => ({ query: insertQuery, params })),\n ]);\n }\n\n\n /** Rimuove tutti i grant diretti, senza toccare ruoli o menu ereditati dai ruoli. */\n public async resetAbilitazioni(codiceUtente: number): Promise<void> {\n const query = \"DELETE FROM ABILITAZIONI WHERE CODUTE = ?\";\n await Orm.execute(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n }\n\n /**\n * Crea o aggiorna un ruolo. In aggiornamento la lista `role.menu` sostituisce integralmente i menu del ruolo.\n * Validare i codici menu nel chiamante quando si usano dati non provenienti dalla console o dalle API Accessi.\n */\n public async updateOrInsertRole(role: Role, codiceRuolo: number | null = null): Promise<void> {\n // Ruolo, sostituzione menu e inserimenti in un'unica transazione: niente ruoli senza menu in caso di errore.\n await Orm.withTransaction(this.accessiOptions.databaseOptions, async (transaction) => {\n let resolvedCodiceRuolo = codiceRuolo;\n\n if (resolvedCodiceRuolo == null) {\n const createdRoleResult = await Orm.transactionQuery<unknown>(\n transaction,\n `INSERT INTO RUOLI (DESRUO) VALUES (?) RETURNING CODRUO`,\n [role.descrizioneRuolo],\n );\n const createdRole = (Array.isArray(createdRoleResult) ? createdRoleResult[0] : createdRoleResult) as Record<string, unknown> | undefined;\n const rawCodiceRuolo = createdRole?.CODRUO ?? createdRole?.codruo;\n const parsedCodiceRuolo = typeof rawCodiceRuolo === 'number'\n ? rawCodiceRuolo\n : Number.parseInt(`${rawCodiceRuolo ?? ''}`, 10);\n if (Number.isNaN(parsedCodiceRuolo)) {\n throw new Error('Creazione ruolo non riuscita: impossibile recuperare CODRUO.');\n }\n resolvedCodiceRuolo = parsedCodiceRuolo;\n } else {\n await Orm.transactionQuery(\n transaction,\n `UPDATE RUOLI SET DESRUO = ? WHERE CODRUO = ?`,\n [role.descrizioneRuolo, resolvedCodiceRuolo],\n );\n\n await Orm.transactionQuery(\n transaction,\n `DELETE FROM RUOLI_MNU WHERE CODRUO = ?`,\n [resolvedCodiceRuolo],\n );\n }\n\n if (resolvedCodiceRuolo === null) {\n throw new Error('Operazione ruolo non riuscita: codice ruolo non valorizzato.');\n }\n\n for (const menu of role.menu) {\n await Orm.transactionQuery(\n transaction,\n `INSERT INTO RUOLI_MNU (CODRUO, CODMNU, TIPABI) VALUES (?, ?, ?)`,\n [resolvedCodiceRuolo, menu.codiceMenu, menu.tipoAbilitazione],\n );\n }\n });\n }\n\n\n /** Restituisce il catalogo ruoli con ogni associazione menu e livello, inclusi ruoli senza menu. */\n public async getRolesWithMenus(): Promise<Role[]> {\n const query = `\n SELECT \n R.CODRUO AS codice_ruolo, \n R.DESRUO AS descrizione_ruolo, \n M.CODMNU AS codice_menu, \n M.DESMNU AS descrizione_menu,\n M.NOTE AS note,\n RM.TIPABI AS tipo_abilitazione\n FROM RUOLI R\n LEFT JOIN RUOLI_MNU RM ON R.CODRUO = RM.CODRUO\n LEFT JOIN MENU M ON RM.CODMNU = M.CODMNU\n ORDER BY R.CODRUO, M.CODMNU\n `;\n\n const result = (await Orm.query(this.accessiOptions.databaseOptions, query, []))\n .map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n const ruoliMap = new Map<number, Role>();\n\n for (const row of result) {\n const codiceRuolo = Number(row.codiceRuolo);\n const descrizioneRuolo = typeof row.descrizioneRuolo === 'string' ? row.descrizioneRuolo.trim() : '';\n const codiceMenu = typeof row.codiceMenu === 'string' ? row.codiceMenu : undefined;\n const rawTipoAbilitazione = row.tipoAbilitazione;\n\n if (!ruoliMap.has(codiceRuolo)) {\n ruoliMap.set(codiceRuolo, {\n codiceRuolo,\n descrizioneRuolo,\n menu: []\n });\n }\n\n const abilitationValue = typeof rawTipoAbilitazione === 'number'\n ? rawTipoAbilitazione\n : Number.parseInt(`${rawTipoAbilitazione ?? ''}`, 10);\n\n if (!codiceMenu || Number.isNaN(abilitationValue) || abilitationValue <= TipoAbilitazione.NESSUNA) {\n continue;\n }\n\n ruoliMap.get(codiceRuolo)!.menu.push({\n codiceRuolo,\n codiceMenu,\n tipoAbilitazione: abilitationValue as TipoAbilitazione,\n });\n }\n\n return Array.from(ruoliMap.values());\n }\n\n\n /**\n * Sostituisce l'intera lista di ruoli dell'utente con codici univoci e verificati.\n * Non modifica i grant diretti: il calcolo effettivo li unisce in `getUserRolesAndGrants`.\n */\n public async assignRolesToUser(codiceUtente: number, roles: number[]): Promise<void> {\n\n const userExistsQuery = `SELECT COUNT(*) FROM UTENTI WHERE CODUTE = ?`;\n let result = await Orm.query(this.accessiOptions.databaseOptions, userExistsQuery, [codiceUtente]);\n\n if (this.getCountFromResult(result) === 0) {\n throw new Error(`L'utente con codice ${codiceUtente} non esiste.`);\n }\n\n const normalizedRoles = Array.from(\n new Set(\n roles\n .map((role) => Number.parseInt(`${role ?? ''}`, 10))\n .filter((role) => Number.isInteger(role) && role > 0),\n ),\n );\n\n const queriesWithParams = [\n { query: `DELETE FROM UTENTI_RUOLI WHERE CODUTE = ?`, params: [codiceUtente] },\n ...normalizedRoles.map((codiceRuolo) => ({\n query: `INSERT INTO UTENTI_RUOLI (CODUTE, CODRUO) VALUES (?, ?)`,\n params: [codiceUtente, codiceRuolo],\n })),\n ];\n\n if (normalizedRoles.length > 0) {\n // Un'unica query IN invece di N count: stessa validazione, meno round-trip.\n const placeholders = normalizedRoles.map(() => '?').join(', ');\n const existingRolesResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT CODRUO FROM RUOLI WHERE CODRUO IN (${placeholders})`,\n normalizedRoles,\n );\n const existingRoles = this.extractIntegerColumn(existingRolesResult, 'CODRUO');\n const missingRole = normalizedRoles.find((codiceRuolo) => !existingRoles.has(codiceRuolo));\n if (missingRole !== undefined) {\n throw new Error(`Il ruolo con codice ${missingRole} non esiste.`);\n }\n }\n\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, queriesWithParams);\n\n const assignedRolesResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT COUNT(*) FROM UTENTI_RUOLI WHERE CODUTE = ?`,\n [codiceUtente],\n );\n const assignedRolesCount = this.getCountFromResult(assignedRolesResult);\n if (assignedRolesCount !== normalizedRoles.length) {\n throw new Error(\n `Persistenza ruoli non coerente per utente ${codiceUtente}: attesi ${normalizedRoles.length}, trovati ${assignedRolesCount}.`,\n );\n }\n }\n\n\n /**\n * Sostituisce tutti i grant diretti dell'utente. I ruoli rimangono invariati e i loro grant sono aggiunti\n * solo nel risultato effettivo; un grant diretto dello stesso menu ha precedenza nella composizione.\n */\n public async assignPermissionsToUser(codiceUtente: number, permissions: Permission[]): Promise<void> {\n\n const userExistsQuery = `SELECT COUNT(*) FROM UTENTI WHERE CODUTE = ?`;\n let result = await Orm.query(this.accessiOptions.databaseOptions, userExistsQuery, [codiceUtente]);\n\n if (this.getCountFromResult(result) === 0) {\n throw new Error(`L'utente con codice ${codiceUtente} non esiste.`);\n }\n\n const normalizedPermissions = Array.from(\n new Map(\n permissions\n .map((permission) => ({\n codiceMenu: `${permission?.codiceMenu ?? ''}`.trim(),\n tipoAbilitazione: Number.parseInt(`${permission?.tipoAbilitazione ?? ''}`, 10),\n }))\n .filter(\n (permission) =>\n permission.codiceMenu.length > 0 && Number.isInteger(permission.tipoAbilitazione),\n )\n .map((permission) => [permission.codiceMenu, permission] as const),\n ).values(),\n );\n\n const queriesWithParams = [\n { query: `DELETE FROM ABILITAZIONI WHERE CODUTE = ?`, params: [codiceUtente] },\n ...normalizedPermissions.map((permission) => ({\n query: `INSERT INTO ABILITAZIONI (CODUTE, CODMNU, TIPABI) VALUES (?, ?, ?)`,\n params: [codiceUtente, permission.codiceMenu, permission.tipoAbilitazione],\n })),\n ];\n\n if (normalizedPermissions.length > 0) {\n // Un'unica query IN invece di N count: stessa validazione, meno round-trip.\n const menuCodes = normalizedPermissions.map((permission) => permission.codiceMenu);\n const placeholders = menuCodes.map(() => '?').join(', ');\n const existingMenusResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT CODMNU FROM MENU WHERE CODMNU IN (${placeholders})`,\n menuCodes,\n );\n const existingMenus = new Set(\n existingMenusResult.map((row) => String((row as Record<string, unknown>).CODMNU ?? (row as Record<string, unknown>).codmnu ?? '')),\n );\n const missingMenu = menuCodes.find((codiceMenu) => !existingMenus.has(codiceMenu));\n if (missingMenu !== undefined) {\n throw new Error(`Il menu con codice ${missingMenu} non esiste.`);\n }\n }\n\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, queriesWithParams);\n\n const assignedPermissionsResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT COUNT(*) FROM ABILITAZIONI WHERE CODUTE = ?`,\n [codiceUtente],\n );\n const assignedPermissionsCount = this.getCountFromResult(assignedPermissionsResult);\n if (assignedPermissionsCount !== normalizedPermissions.length) {\n throw new Error(\n `Persistenza abilitazioni non coerente per utente ${codiceUtente}: attese ${normalizedPermissions.length}, trovate ${assignedPermissionsCount}.`,\n );\n }\n }\n\n\n /** Elimina fisicamente ruolo, associazioni menu e assegnazioni utente. Operazione amministrativa irreversibile. */\n public async deleteRole(codiceRuolo: number): Promise<void> {\n\n const existsQuery = `SELECT COUNT(*) FROM RUOLI WHERE CODRUO = ?`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, existsQuery, [codiceRuolo]);\n\n if (this.getCountFromResult(result) === 0) {\n throw new Error(`Il ruolo con codice ${codiceRuolo} non esiste.`);\n }\n\n // Le tre delete sono atomiche: nessun ruolo orfano se una fallisce.\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: `DELETE FROM RUOLI_MNU WHERE CODRUO = ?`, params: [codiceRuolo] },\n { query: `DELETE FROM UTENTI_RUOLI WHERE CODRUO = ?`, params: [codiceRuolo] },\n { query: `DELETE FROM RUOLI WHERE CODRUO = ?`, params: [codiceRuolo] },\n ]);\n\n }\n\n\n /** Restituisce solo menu abilitati; per il catalogo amministrativo usare `getGroupsWithMenus(true)`. */\n public async getMenus(): Promise<MenuEntity[]> {\n const query = `\n SELECT \n M.CODMNU AS codiceMenu, \n M.DESMNU AS descrizioneMenu,\n M.CODGRP AS codiceGruppo,\n G.DESGRP AS descrizioneGruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note,\n G.NOMECAMPO AS nome_campo\n FROM MENU M\n LEFT JOIN MENU_GRP G ON M.CODGRP = G.CODGRP\n WHERE M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1\n ORDER BY G.CODGRP, M.CODMNU\n `;\n\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, []);\n return result.map(RestUtilities.convertKeysToCamelCase) as unknown as MenuEntity[];\n }\n\n\n /**\n * Restituisce il catalogo ordinato per gruppo e menu. `includeDisabled` e riservato a console e amministrazione:\n * i flussi applicativi di autorizzazione devono usare il comportamento predefinito, che nasconde voci disabilitate.\n */\n public async getGroupsWithMenus(includeDisabled = false): Promise<GroupWithMenusEntity[]> {\n const filtersClause = includeDisabled\n ? ''\n : 'WHERE M.FLGENABLED = 1 AND (G.FLGENABLED IS NULL OR G.FLGENABLED = 1)';\n\n const query = `\n SELECT\n M.CODMNU AS codice_menu,\n M.DESMNU AS descrizione_menu,\n M.CODGRP AS codice_gruppo,\n G.DESGRP AS descrizione_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note,\n G.ORDINE AS ordine_gruppo,\n M.ORDINE as ordine_menu,\n M.FLGENABLED AS menu_enabled,\n G.FLGENABLED AS group_enabled,\n G.NOMECAMPO AS nome_campo\n FROM MENU M\n LEFT JOIN MENU_GRP G ON M.CODGRP = G.CODGRP\n ${filtersClause}\n ORDER BY G.CODGRP, M.CODMNU\n `;\n\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, []);\n\n const groupMap = new Map<\n string,\n GroupWithMenusEntity & { menus: (MenuEntity & { enabled?: boolean })[] }\n >();\n\n result.forEach((row: unknown) => {\n const converted = RestUtilities.convertKeysToCamelCase(row) as MenuEntity & {\n menuEnabled?: number | boolean;\n groupEnabled?: number | boolean;\n };\n\n const { menuEnabled, groupEnabled, ...menuBase } = converted;\n const normalizedGroupKey = menuBase.codiceGruppo ?? '__UNGROUPED__';\n const groupEnabledFlag =\n groupEnabled == null ? true : Number(groupEnabled) === 1 || groupEnabled === true;\n const menuEnabledFlag =\n menuEnabled === undefined ? true : Number(menuEnabled) === 1 || menuEnabled === true;\n\n if (!groupMap.has(normalizedGroupKey)) {\n groupMap.set(normalizedGroupKey, {\n codiceGruppo: menuBase.codiceGruppo ?? normalizedGroupKey,\n descrizioneGruppo: menuBase.descrizioneGruppo ?? '',\n ordineGruppo: menuBase.ordineGruppo,\n nomeCampo: menuBase.nomeCampo ?? null,\n enabled: groupEnabledFlag,\n menus: [],\n });\n }\n\n if (menuBase.codiceMenu) {\n groupMap.get(normalizedGroupKey)!.menus.push({\n ...menuBase,\n enabled: menuEnabledFlag,\n });\n }\n });\n\n const groupsArray = Array.from(groupMap.values())\n .map(group => ({\n ...group,\n menus: (group.menus ?? []).sort(\n (a, b) =>\n (a.ordineMenu ?? Number.MAX_SAFE_INTEGER) - (b.ordineMenu ?? Number.MAX_SAFE_INTEGER),\n ),\n }))\n .sort(\n (a, b) =>\n (a.ordineGruppo ?? Number.MAX_SAFE_INTEGER) - (b.ordineGruppo ?? Number.MAX_SAFE_INTEGER),\n );\n\n return groupsArray;\n }\n\n // -----------------------------------------------------------------------\n // Cataloghi di configurazione: CRUD di menu, gruppi, tipi menu.\n // `table` e `column` sono sempre costanti interne, mai input utente: i\n // valori sono parametrizzati, quindi non esiste superficie di SQL injection.\n // -----------------------------------------------------------------------\n\n private async countWhere(table: string, column: string, value: unknown): Promise<number> {\n const result = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT COUNT(*) FROM ${table} WHERE ${column} = ?`,\n [value],\n );\n return this.getCountFromResult(result);\n }\n\n private async assertMenuGroupExists(codiceGruppo: string): Promise<void> {\n if ((await this.countWhere('MENU_GRP', 'CODGRP', codiceGruppo)) === 0) {\n throw new BadRequestException(`Il gruppo menu ${codiceGruppo} non esiste.`);\n }\n }\n\n private async assertMenuTypeExists(codiceTipo: string): Promise<void> {\n if ((await this.countWhere('MENU_TIPI', 'CODTIP', codiceTipo)) === 0) {\n throw new BadRequestException(`Il tipo menu ${codiceTipo} non esiste.`);\n }\n }\n\n /** Catalogo completo dei tipi menu, usato dagli editor di configurazione. */\n public async getMenuTypes(): Promise<MenuTypeEntity[]> {\n const query = `SELECT CODTIP AS codice_tipo, DESTIP AS descrizione_tipo FROM MENU_TIPI ORDER BY CODTIP`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, []);\n return result.map(RestUtilities.convertKeysToCamelCase) as unknown as MenuTypeEntity[];\n }\n\n public async createMenuType(input: CreateMenuTypeRequest): Promise<void> {\n if ((await this.countWhere('MENU_TIPI', 'CODTIP', input.codiceTipo)) > 0) {\n throw new BadRequestException(`Il tipo menu ${input.codiceTipo} esiste gia.`);\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `INSERT INTO MENU_TIPI (CODTIP, DESTIP) VALUES (?, ?)`,\n [input.codiceTipo, input.descrizioneTipo ?? null],\n );\n }\n\n public async updateMenuType(codiceTipo: string, input: UpdateMenuTypeRequest): Promise<void> {\n await this.assertMenuTypeExists(codiceTipo);\n if (input.descrizioneTipo === undefined) return;\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `UPDATE MENU_TIPI SET DESTIP = ? WHERE CODTIP = ?`,\n [input.descrizioneTipo, codiceTipo],\n );\n }\n\n /** Elimina un tipo menu solo se nessun menu lo utilizza (la FK lo impedirebbe comunque). */\n public async deleteMenuType(codiceTipo: string): Promise<void> {\n await this.assertMenuTypeExists(codiceTipo);\n const used = await this.countWhere('MENU', 'CODTIP', codiceTipo);\n if (used > 0) {\n throw new BadRequestException(\n `Impossibile eliminare il tipo ${codiceTipo}: ${used} menu lo utilizzano.`,\n );\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `DELETE FROM MENU_TIPI WHERE CODTIP = ?`,\n [codiceTipo],\n );\n }\n\n public async createMenuGroup(input: CreateMenuGroupRequest): Promise<void> {\n if ((await this.countWhere('MENU_GRP', 'CODGRP', input.codiceGruppo)) > 0) {\n throw new BadRequestException(`Il gruppo menu ${input.codiceGruppo} esiste gia.`);\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `INSERT INTO MENU_GRP (CODGRP, DESGRP, FLGENABLED, ORDINE, NOMECAMPO) VALUES (?, ?, ?, ?, ?)`,\n [\n input.codiceGruppo,\n input.descrizioneGruppo ?? null,\n input.enabled === false ? 0 : 1,\n input.ordineGruppo ?? 0,\n input.nomeCampo ?? null,\n ],\n );\n }\n\n public async updateMenuGroup(codiceGruppo: string, input: UpdateMenuGroupRequest): Promise<void> {\n await this.assertMenuGroupExists(codiceGruppo);\n\n const sets: string[] = [];\n const params: unknown[] = [];\n if (input.descrizioneGruppo !== undefined) {\n sets.push('DESGRP = ?');\n params.push(input.descrizioneGruppo);\n }\n if (input.ordineGruppo !== undefined) {\n sets.push('ORDINE = ?');\n params.push(input.ordineGruppo);\n }\n if (input.enabled !== undefined) {\n sets.push('FLGENABLED = ?');\n params.push(input.enabled ? 1 : 0);\n }\n if (input.nomeCampo !== undefined) {\n sets.push('NOMECAMPO = ?');\n params.push(input.nomeCampo);\n }\n if (sets.length === 0) return;\n\n params.push(codiceGruppo);\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `UPDATE MENU_GRP SET ${sets.join(', ')} WHERE CODGRP = ?`,\n params,\n );\n }\n\n /** Elimina un gruppo solo se non contiene menu, per non lasciare menu orfani. */\n public async deleteMenuGroup(codiceGruppo: string): Promise<void> {\n await this.assertMenuGroupExists(codiceGruppo);\n const used = await this.countWhere('MENU', 'CODGRP', codiceGruppo);\n if (used > 0) {\n throw new BadRequestException(\n `Impossibile eliminare il gruppo ${codiceGruppo}: contiene ${used} menu.`,\n );\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `DELETE FROM MENU_GRP WHERE CODGRP = ?`,\n [codiceGruppo],\n );\n }\n\n public async createMenu(input: CreateMenuRequest): Promise<void> {\n if ((await this.countWhere('MENU', 'CODMNU', input.codiceMenu)) > 0) {\n throw new BadRequestException(`Il menu ${input.codiceMenu} esiste gia.`);\n }\n await this.assertMenuGroupExists(input.codiceGruppo);\n if (input.tipo) await this.assertMenuTypeExists(input.tipo);\n\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `INSERT INTO MENU (CODMNU, DESMNU, CODGRP, FLGENABLED, ICON, ORDINE, CODTIP, PAGINA, RIFMENU, NOTE)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n input.codiceMenu,\n input.descrizioneMenu ?? null,\n input.codiceGruppo,\n input.enabled === false ? 0 : 1,\n input.icona ?? null,\n input.ordineMenu ?? null,\n input.tipo ?? null,\n input.pagina ?? null,\n input.rifMenu ?? null,\n input.note ?? null,\n ],\n );\n }\n\n public async updateMenu(codiceMenu: string, input: UpdateMenuRequest): Promise<void> {\n if ((await this.countWhere('MENU', 'CODMNU', codiceMenu)) === 0) {\n throw new BadRequestException(`Il menu ${codiceMenu} non esiste.`);\n }\n if (input.codiceGruppo !== undefined) await this.assertMenuGroupExists(input.codiceGruppo);\n if (input.tipo) await this.assertMenuTypeExists(input.tipo);\n\n const sets: string[] = [];\n const params: unknown[] = [];\n if (input.descrizioneMenu !== undefined) {\n sets.push('DESMNU = ?');\n params.push(input.descrizioneMenu);\n }\n if (input.codiceGruppo !== undefined) {\n sets.push('CODGRP = ?');\n params.push(input.codiceGruppo);\n }\n if (input.tipo !== undefined) {\n sets.push('CODTIP = ?');\n params.push(input.tipo || null);\n }\n if (input.icona !== undefined) {\n sets.push('ICON = ?');\n params.push(input.icona);\n }\n if (input.pagina !== undefined) {\n sets.push('PAGINA = ?');\n params.push(input.pagina);\n }\n if (input.ordineMenu !== undefined) {\n sets.push('ORDINE = ?');\n params.push(input.ordineMenu);\n }\n if (input.enabled !== undefined) {\n sets.push('FLGENABLED = ?');\n params.push(input.enabled ? 1 : 0);\n }\n if (input.rifMenu !== undefined) {\n sets.push('RIFMENU = ?');\n params.push(input.rifMenu);\n }\n if (input.note !== undefined) {\n sets.push('NOTE = ?');\n params.push(input.note);\n }\n if (sets.length === 0) return;\n\n params.push(codiceMenu);\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `UPDATE MENU SET ${sets.join(', ')} WHERE CODMNU = ?`,\n params,\n );\n }\n\n /** Elimina menu, grant utente e associazioni ruolo in un'unica transazione. */\n public async deleteMenu(codiceMenu: string): Promise<void> {\n if ((await this.countWhere('MENU', 'CODMNU', codiceMenu)) === 0) {\n throw new BadRequestException(`Il menu ${codiceMenu} non esiste.`);\n }\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: `DELETE FROM ABILITAZIONI WHERE CODMNU = ?`, params: [codiceMenu] },\n { query: `DELETE FROM RUOLI_MNU WHERE CODMNU = ?`, params: [codiceMenu] },\n { query: `DELETE FROM MENU WHERE CODMNU = ?`, params: [codiceMenu] },\n ]);\n }\n\n\n /**\n * Calcola l'autorizzazione effettiva: grant diretti e grant dei ruoli sono uniti per codice menu.\n * Per compatibilita storica un grant diretto prevale su quello del ruolo; i superutenti ricevono tutti i menu attivi.\n */\n public async getUserRolesAndGrants(codiceUtente: number): Promise<{\n abilitazioni: AbilitazioneMenu[],\n ruoli: Role[],\n grants: AbilitazioneMenu[]\n }> {\n const codiceUtenteQuery = \"SELECT FLGSUPER as flag_super FROM UTENTI_CONFIG WHERE CODUTE = ?\";\n const result = await Orm.query(this.accessiOptions.databaseOptions, codiceUtenteQuery, [codiceUtente]);\n if (!result || result.length == 0) throw new Error(\"Nessun utente trovato con il codice utente \" + codiceUtente);\n\n const isSuperAdmin = this.isSuperFlag(\n (result.map(RestUtilities.convertKeysToCamelCase)[0] as { flagSuper?: unknown } | undefined)?.flagSuper,\n );\n\n const abilitazioni = await this.getUserDirectPermissions(codiceUtente);\n const ruoli = await this.getUserRoles(codiceUtente);\n const grants = this.composeGrants(\n abilitazioni,\n ruoli,\n isSuperAdmin,\n isSuperAdmin ? await this.getAllActiveMenusAsGrants() : [],\n );\n\n return { abilitazioni, ruoli, grants };\n }\n\n private isSuperFlag(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n }\n\n /**\n * Versione batch di `getUserRolesAndGrants`: esegue un numero costante di query per N utenti\n * (invece di N set di query) e restituisce mappa per codice utente. Stessa composizione della\n * lettura singola.\n */\n public async getUsersRolesAndGrants(codiciUtente: number[]): Promise<Map<number, {\n abilitazioni: AbilitazioneMenu[],\n ruoli: Role[],\n grants: AbilitazioneMenu[]\n }>> {\n const result = new Map<number, { abilitazioni: AbilitazioneMenu[], ruoli: Role[], grants: AbilitazioneMenu[] }>();\n const ids = Array.from(new Set(codiciUtente.filter((id) => Number.isInteger(id) && id > 0)));\n if (ids.length === 0) {\n return result;\n }\n\n const placeholders = ids.map(() => '?').join(', ');\n\n const superRows = (await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT CODUTE AS codice_utente, FLGSUPER AS flag_super FROM UTENTI_CONFIG WHERE CODUTE IN (${placeholders})`,\n ids,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n const superUsers = new Set<number>();\n for (const row of superRows) {\n if (this.isSuperFlag(row.flagSuper)) {\n superUsers.add(Number(row.codiceUtente));\n }\n }\n\n const permissionRows = (await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT\n A.CODUTE AS codice_utente,\n A.CODMNU AS codice_menu,\n A.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n G.DESGRP AS descrizione_gruppo,\n G.CODGRP AS codice_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM ABILITAZIONI A\n INNER JOIN MENU M ON A.CODMNU = M.CODMNU\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE A.CODUTE IN (${placeholders}) AND M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1`,\n ids,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n const roleRows = (await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT\n RU.CODUTE AS codice_utente,\n R.CODRUO AS codice_ruolo,\n R.DESRUO AS descrizione_ruolo,\n CASE WHEN COALESCE(G.FLGENABLED, 1) = 1 THEN M.CODMNU END AS codice_menu,\n RM.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n M.NOTE AS note\n FROM UTENTI_RUOLI RU\n INNER JOIN RUOLI R ON RU.CODRUO = R.CODRUO\n LEFT JOIN RUOLI_MNU RM ON R.CODRUO = RM.CODRUO\n LEFT JOIN MENU M ON RM.CODMNU = M.CODMNU AND M.FLGENABLED = 1\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE RU.CODUTE IN (${placeholders})`,\n ids,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n const allActiveMenus = superUsers.size > 0 ? await this.getAllActiveMenusAsGrants() : [];\n\n const permissionsByUser = new Map<number, AbilitazioneMenu[]>();\n for (const row of permissionRows) {\n const { codiceUtente, ...grant } = row;\n const key = Number(codiceUtente);\n const bucket = permissionsByUser.get(key);\n if (bucket) {\n bucket.push(grant as unknown as AbilitazioneMenu);\n } else {\n permissionsByUser.set(key, [grant as unknown as AbilitazioneMenu]);\n }\n }\n\n const rolesByUser = new Map<number, Array<Record<string, unknown>>>();\n for (const row of roleRows) {\n const { codiceUtente, ...roleRow } = row;\n const key = Number(codiceUtente);\n const bucket = rolesByUser.get(key);\n if (bucket) {\n bucket.push(roleRow);\n } else {\n rolesByUser.set(key, [roleRow]);\n }\n }\n\n for (const id of ids) {\n const abilitazioni = permissionsByUser.get(id) ?? [];\n const ruoli = this.assembleRoles(rolesByUser.get(id) ?? []);\n const isSuperAdmin = superUsers.has(id);\n result.set(id, {\n abilitazioni,\n ruoli,\n grants: this.composeGrants(abilitazioni, ruoli, isSuperAdmin, isSuperAdmin ? allActiveMenus : []),\n });\n }\n\n return result;\n }\n\n\n\n}\n\n\n"]}
1
+ {"version":3,"file":"PermissionService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/PermissionService/PermissionService.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { Orm } from \"../../../Orm\";\nimport { RestUtilities } from \"../../../Utilities\";\nimport type { AccessiOptions } from \"../../AccessiModule\";\nimport { Permission, TipoAbilitazione } from \"../../Dtos\";\nimport { AbilitazioneMenu } from \"../../Dtos/AbilitazioneMenu\";\nimport { GroupWithMenusEntity } from \"../../Dtos/GetGroupsWithMenusResponse\";\nimport { MenuEntity } from \"../../Dtos/GetMenusResponse\";\nimport { Role } from \"../../Dtos/Role\";\nimport {\n CreateMenuGroupRequest,\n CreateMenuRequest,\n CreateMenuTypeRequest,\n MenuTypeEntity,\n UpdateMenuGroupRequest,\n UpdateMenuRequest,\n UpdateMenuTypeRequest,\n} from \"../../Dtos/CatalogDtos\";\nimport { BadRequestException, Inject, Injectable } from \"@nestjs/common\";\n\n/** Struttura storica menu/gruppi accettata dall'API legacy `addAbilitazioni`. */\ntype LegacyMenuGroup = {\n menu?: Array<{\n flgChk?: unknown;\n codiceMenu?: unknown;\n tipoAbilitazione?: unknown;\n }>;\n};\n\n@Injectable()\nexport class PermissionService {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions\n ) { }\n\n private getCountFromResult(result: ReadonlyArray<Record<string, unknown>>, fieldName = 'COUNT'): number {\n const rawValue = result?.[0]?.[fieldName]\n ?? result?.[0]?.[fieldName.toLowerCase()]\n ?? result?.[0]?.count;\n return typeof rawValue === 'number' ? rawValue : Number.parseInt(`${rawValue ?? '0'}`, 10);\n }\n\n private extractIntegerColumn(result: ReadonlyArray<Record<string, unknown>>, fieldName: string): Set<number> {\n return new Set(\n result.map((row) => Number(row[fieldName] ?? row[fieldName.toLowerCase()])),\n );\n }\n\n private async getAllActiveMenusAsGrants(): Promise<AbilitazioneMenu[]> {\n const query = `\n SELECT\n M.CODMNU AS codice_menu,\n 30 AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n G.DESGRP AS descrizione_gruppo,\n G.CODGRP AS codice_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM MENU M\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1\n `;\n\n return await Orm.query(this.accessiOptions.databaseOptions, query, [])\n .then(results => results.map(RestUtilities.convertKeysToCamelCase)) as AbilitazioneMenu[];\n }\n\n private async getUserDirectPermissions(codiceUtente: number): Promise<AbilitazioneMenu[]> {\n const queryAbilitazioni = `\n SELECT\n A.CODMNU AS codice_menu,\n A.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n G.DESGRP AS descrizione_gruppo,\n G.CODGRP AS codice_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM ABILITAZIONI A\n INNER JOIN MENU M ON A.CODMNU = M.CODMNU\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE A.CODUTE = ? AND M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1\n `;\n\n return await Orm.query(this.accessiOptions.databaseOptions, queryAbilitazioni, [codiceUtente])\n .then(results => results.map(RestUtilities.convertKeysToCamelCase)) as AbilitazioneMenu[];\n }\n\n private async getUserRoles(codiceUtente: number): Promise<Role[]> {\n const queryRuoli = `\n SELECT\n R.CODRUO AS codice_ruolo,\n R.DESRUO AS descrizione_ruolo,\n CASE WHEN COALESCE(G.FLGENABLED, 1) = 1 THEN M.CODMNU END AS codice_menu,\n RM.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n M.NOTE AS note\n FROM UTENTI_RUOLI RU\n INNER JOIN RUOLI R ON RU.CODRUO = R.CODRUO\n LEFT JOIN RUOLI_MNU RM ON R.CODRUO = RM.CODRUO\n LEFT JOIN MENU M\n ON RM.CODMNU = M.CODMNU\n AND M.FLGENABLED = 1\n LEFT JOIN MENU_GRP G\n ON G.CODGRP = M.CODGRP\n WHERE RU.CODUTE = ?\n `;\n const ruoliResult = (await Orm.query(this.accessiOptions.databaseOptions, queryRuoli, [codiceUtente]))\n .map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n return this.assembleRoles(ruoliResult);\n }\n\n /** Costruisce l'albero ruoli/menu a partire dalle righe (riusato da lettura singola e batch). */\n private assembleRoles(ruoliResult: Array<Record<string, unknown>>): Role[] {\n const ruoliMap = new Map<number, Role>();\n for (const row of ruoliResult) {\n const codiceRuolo = Number(row.codiceRuolo);\n const descrizioneRuolo = typeof row.descrizioneRuolo === 'string' ? row.descrizioneRuolo.trim() : '';\n const codiceMenu = typeof row.codiceMenu === 'string' ? row.codiceMenu : undefined;\n const descrizioneMenu = typeof row.descrizioneMenu === 'string' ? row.descrizioneMenu : undefined;\n const tipoAbilitazione = Number(row.tipoAbilitazione) as TipoAbilitazione;\n\n if (!ruoliMap.has(codiceRuolo)) {\n ruoliMap.set(codiceRuolo, {\n codiceRuolo,\n descrizioneRuolo,\n menu: []\n });\n }\n\n if (codiceMenu && descrizioneMenu) {\n ruoliMap.get(codiceRuolo)!.menu.push({\n codiceRuolo,\n codiceMenu,\n tipoAbilitazione,\n });\n }\n }\n\n return Array.from(ruoliMap.values());\n }\n\n /** Regola di composizione storica: grant diretti prevalgono, i ruoli si sommano per livello massimo. */\n private composeGrants(\n abilitazioni: AbilitazioneMenu[],\n ruoli: Role[],\n isSuperAdmin: boolean,\n allActiveMenus: AbilitazioneMenu[],\n ): AbilitazioneMenu[] {\n const grantsMap = new Map<string, AbilitazioneMenu>();\n\n for (const abilitazione of abilitazioni) {\n grantsMap.set(abilitazione.codiceMenu, abilitazione);\n }\n\n const directMenuCodes = new Set(abilitazioni.map(grant => grant.codiceMenu));\n for (const ruolo of ruoli) {\n for (const menu of ruolo.menu) {\n const existing = grantsMap.get(menu.codiceMenu);\n if (!directMenuCodes.has(menu.codiceMenu) &&\n (!existing || Number(menu.tipoAbilitazione) > Number(existing.tipoAbilitazione))) {\n grantsMap.set(menu.codiceMenu, menu);\n }\n }\n }\n\n return isSuperAdmin ? allActiveMenus : Array.from(grantsMap.values());\n }\n\n\n /**\n * API legacy per salvare grant dalla struttura storica menu/gruppi.\n * Sostituisce tutti i grant diretti dell'utente; per le nuove integrazioni preferire `assignPermissionsToUser`.\n */\n public async addAbilitazioni(codiceUtente: number, menuAbilitazioni: LegacyMenuGroup[]): Promise<void> {\n const abilitazioniToInsert = menuAbilitazioni\n .flatMap(menuGrp => menuGrp.menu ?? [])\n .filter(menu => menu.flgChk)\n .map(menu => [codiceUtente, menu.codiceMenu, menu.tipoAbilitazione]);\n\n const insertQuery = `UPDATE OR INSERT INTO ABILITAZIONI (CODUTE, CODMNU, TIPABI) VALUES (?, ?, ?)`;\n\n // Delete + insert atomici: un errore a metà non lascia l'utente senza abilitazioni.\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: `DELETE FROM ABILITAZIONI WHERE CODUTE = ?`, params: [codiceUtente] },\n ...abilitazioniToInsert.map(params => ({ query: insertQuery, params })),\n ]);\n }\n\n\n /** Rimuove tutti i grant diretti, senza toccare ruoli o menu ereditati dai ruoli. */\n public async resetAbilitazioni(codiceUtente: number): Promise<void> {\n const query = \"DELETE FROM ABILITAZIONI WHERE CODUTE = ?\";\n await Orm.execute(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n }\n\n /**\n * Crea o aggiorna un ruolo. In aggiornamento la lista `role.menu` sostituisce integralmente i menu del ruolo.\n * Validare i codici menu nel chiamante quando si usano dati non provenienti dalla console o dalle API Accessi.\n */\n public async updateOrInsertRole(role: Role, codiceRuolo: number | null = null): Promise<void> {\n // Ruolo, sostituzione menu e inserimenti in un'unica transazione: niente ruoli senza menu in caso di errore.\n await Orm.withTransaction(this.accessiOptions.databaseOptions, async (transaction) => {\n let resolvedCodiceRuolo = codiceRuolo;\n\n if (resolvedCodiceRuolo == null) {\n const createdRoleResult = await Orm.transactionQuery<unknown>(\n transaction,\n `INSERT INTO RUOLI (DESRUO) VALUES (?) RETURNING CODRUO`,\n [role.descrizioneRuolo],\n );\n const createdRole = (Array.isArray(createdRoleResult) ? createdRoleResult[0] : createdRoleResult) as Record<string, unknown> | undefined;\n const rawCodiceRuolo = createdRole?.CODRUO ?? createdRole?.codruo;\n const parsedCodiceRuolo = typeof rawCodiceRuolo === 'number'\n ? rawCodiceRuolo\n : Number.parseInt(`${rawCodiceRuolo ?? ''}`, 10);\n if (Number.isNaN(parsedCodiceRuolo)) {\n throw new Error('Creazione ruolo non riuscita: impossibile recuperare CODRUO.');\n }\n resolvedCodiceRuolo = parsedCodiceRuolo;\n } else {\n await Orm.transactionQuery(\n transaction,\n `UPDATE RUOLI SET DESRUO = ? WHERE CODRUO = ?`,\n [role.descrizioneRuolo, resolvedCodiceRuolo],\n );\n\n await Orm.transactionQuery(\n transaction,\n `DELETE FROM RUOLI_MNU WHERE CODRUO = ?`,\n [resolvedCodiceRuolo],\n );\n }\n\n if (resolvedCodiceRuolo === null) {\n throw new Error('Operazione ruolo non riuscita: codice ruolo non valorizzato.');\n }\n\n for (const menu of role.menu) {\n await Orm.transactionQuery(\n transaction,\n `INSERT INTO RUOLI_MNU (CODRUO, CODMNU, TIPABI) VALUES (?, ?, ?)`,\n [resolvedCodiceRuolo, menu.codiceMenu, menu.tipoAbilitazione],\n );\n }\n });\n }\n\n\n /** Restituisce il catalogo ruoli con ogni associazione menu e livello, inclusi ruoli senza menu. */\n public async getRolesWithMenus(): Promise<Role[]> {\n const query = `\n SELECT \n R.CODRUO AS codice_ruolo, \n R.DESRUO AS descrizione_ruolo, \n M.CODMNU AS codice_menu, \n M.DESMNU AS descrizione_menu,\n M.NOTE AS note,\n RM.TIPABI AS tipo_abilitazione\n FROM RUOLI R\n LEFT JOIN RUOLI_MNU RM ON R.CODRUO = RM.CODRUO\n LEFT JOIN MENU M ON RM.CODMNU = M.CODMNU\n ORDER BY R.CODRUO, M.CODMNU\n `;\n\n const result = (await Orm.query(this.accessiOptions.databaseOptions, query, []))\n .map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n const ruoliMap = new Map<number, Role>();\n\n for (const row of result) {\n const codiceRuolo = Number(row.codiceRuolo);\n const descrizioneRuolo = typeof row.descrizioneRuolo === 'string' ? row.descrizioneRuolo.trim() : '';\n const codiceMenu = typeof row.codiceMenu === 'string' ? row.codiceMenu : undefined;\n const rawTipoAbilitazione = row.tipoAbilitazione;\n\n if (!ruoliMap.has(codiceRuolo)) {\n ruoliMap.set(codiceRuolo, {\n codiceRuolo,\n descrizioneRuolo,\n menu: []\n });\n }\n\n const abilitationValue = typeof rawTipoAbilitazione === 'number'\n ? rawTipoAbilitazione\n : Number.parseInt(`${rawTipoAbilitazione ?? ''}`, 10);\n\n if (!codiceMenu || Number.isNaN(abilitationValue) || abilitationValue <= TipoAbilitazione.NESSUNA) {\n continue;\n }\n\n ruoliMap.get(codiceRuolo)!.menu.push({\n codiceRuolo,\n codiceMenu,\n tipoAbilitazione: abilitationValue as TipoAbilitazione,\n });\n }\n\n return Array.from(ruoliMap.values());\n }\n\n\n /**\n * Sostituisce l'intera lista di ruoli dell'utente con codici univoci e verificati.\n * Non modifica i grant diretti: il calcolo effettivo li unisce in `getUserRolesAndGrants`.\n */\n public async assignRolesToUser(codiceUtente: number, roles: number[]): Promise<void> {\n\n const userExistsQuery = `SELECT COUNT(*) FROM UTENTI WHERE CODUTE = ?`;\n let result = await Orm.query(this.accessiOptions.databaseOptions, userExistsQuery, [codiceUtente]);\n\n if (this.getCountFromResult(result) === 0) {\n throw new Error(`L'utente con codice ${codiceUtente} non esiste.`);\n }\n\n const normalizedRoles = Array.from(\n new Set(\n roles\n .map((role) => Number.parseInt(`${role ?? ''}`, 10))\n .filter((role) => Number.isInteger(role) && role > 0),\n ),\n );\n\n const queriesWithParams = [\n { query: `DELETE FROM UTENTI_RUOLI WHERE CODUTE = ?`, params: [codiceUtente] },\n ...normalizedRoles.map((codiceRuolo) => ({\n query: `INSERT INTO UTENTI_RUOLI (CODUTE, CODRUO) VALUES (?, ?)`,\n params: [codiceUtente, codiceRuolo],\n })),\n ];\n\n if (normalizedRoles.length > 0) {\n // Un'unica query IN invece di N count: stessa validazione, meno round-trip.\n const placeholders = normalizedRoles.map(() => '?').join(', ');\n const existingRolesResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT CODRUO FROM RUOLI WHERE CODRUO IN (${placeholders})`,\n normalizedRoles,\n );\n const existingRoles = this.extractIntegerColumn(existingRolesResult, 'CODRUO');\n const missingRole = normalizedRoles.find((codiceRuolo) => !existingRoles.has(codiceRuolo));\n if (missingRole !== undefined) {\n throw new Error(`Il ruolo con codice ${missingRole} non esiste.`);\n }\n }\n\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, queriesWithParams);\n\n const assignedRolesResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT COUNT(*) FROM UTENTI_RUOLI WHERE CODUTE = ?`,\n [codiceUtente],\n );\n const assignedRolesCount = this.getCountFromResult(assignedRolesResult);\n if (assignedRolesCount !== normalizedRoles.length) {\n throw new Error(\n `Persistenza ruoli non coerente per utente ${codiceUtente}: attesi ${normalizedRoles.length}, trovati ${assignedRolesCount}.`,\n );\n }\n }\n\n\n /**\n * Sostituisce tutti i grant diretti dell'utente. I ruoli rimangono invariati e i loro grant sono aggiunti\n * solo nel risultato effettivo; un grant diretto dello stesso menu ha precedenza nella composizione.\n */\n public async assignPermissionsToUser(codiceUtente: number, permissions: Permission[]): Promise<void> {\n\n const userExistsQuery = `SELECT COUNT(*) FROM UTENTI WHERE CODUTE = ?`;\n let result = await Orm.query(this.accessiOptions.databaseOptions, userExistsQuery, [codiceUtente]);\n\n if (this.getCountFromResult(result) === 0) {\n throw new Error(`L'utente con codice ${codiceUtente} non esiste.`);\n }\n\n const normalizedPermissions = Array.from(\n new Map(\n permissions\n .map((permission) => ({\n codiceMenu: `${permission?.codiceMenu ?? ''}`.trim(),\n tipoAbilitazione: Number.parseInt(`${permission?.tipoAbilitazione ?? ''}`, 10),\n }))\n .filter(\n (permission) =>\n permission.codiceMenu.length > 0 && Number.isInteger(permission.tipoAbilitazione),\n )\n .map((permission) => [permission.codiceMenu, permission] as const),\n ).values(),\n );\n\n const queriesWithParams = [\n { query: `DELETE FROM ABILITAZIONI WHERE CODUTE = ?`, params: [codiceUtente] },\n ...normalizedPermissions.map((permission) => ({\n query: `INSERT INTO ABILITAZIONI (CODUTE, CODMNU, TIPABI) VALUES (?, ?, ?)`,\n params: [codiceUtente, permission.codiceMenu, permission.tipoAbilitazione],\n })),\n ];\n\n if (normalizedPermissions.length > 0) {\n // Un'unica query IN invece di N count: stessa validazione, meno round-trip.\n const menuCodes = normalizedPermissions.map((permission) => permission.codiceMenu);\n const placeholders = menuCodes.map(() => '?').join(', ');\n const existingMenusResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT CODMNU FROM MENU WHERE CODMNU IN (${placeholders})`,\n menuCodes,\n );\n const existingMenus = new Set(\n existingMenusResult.map((row) => String((row as Record<string, unknown>).CODMNU ?? (row as Record<string, unknown>).codmnu ?? '')),\n );\n const missingMenu = menuCodes.find((codiceMenu) => !existingMenus.has(codiceMenu));\n if (missingMenu !== undefined) {\n throw new Error(`Il menu con codice ${missingMenu} non esiste.`);\n }\n }\n\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, queriesWithParams);\n\n const assignedPermissionsResult = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT COUNT(*) FROM ABILITAZIONI WHERE CODUTE = ?`,\n [codiceUtente],\n );\n const assignedPermissionsCount = this.getCountFromResult(assignedPermissionsResult);\n if (assignedPermissionsCount !== normalizedPermissions.length) {\n throw new Error(\n `Persistenza abilitazioni non coerente per utente ${codiceUtente}: attese ${normalizedPermissions.length}, trovate ${assignedPermissionsCount}.`,\n );\n }\n }\n\n\n /** Elimina fisicamente ruolo, associazioni menu e assegnazioni utente. Operazione amministrativa irreversibile. */\n public async deleteRole(codiceRuolo: number): Promise<void> {\n\n const existsQuery = `SELECT COUNT(*) FROM RUOLI WHERE CODRUO = ?`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, existsQuery, [codiceRuolo]);\n\n if (this.getCountFromResult(result) === 0) {\n throw new Error(`Il ruolo con codice ${codiceRuolo} non esiste.`);\n }\n\n // Le tre delete sono atomiche: nessun ruolo orfano se una fallisce.\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: `DELETE FROM RUOLI_MNU WHERE CODRUO = ?`, params: [codiceRuolo] },\n { query: `DELETE FROM UTENTI_RUOLI WHERE CODRUO = ?`, params: [codiceRuolo] },\n { query: `DELETE FROM RUOLI WHERE CODRUO = ?`, params: [codiceRuolo] },\n ]);\n\n }\n\n\n /** Restituisce solo menu abilitati; per il catalogo amministrativo usare `getGroupsWithMenus(true)`. */\n public async getMenus(): Promise<MenuEntity[]> {\n const query = `\n SELECT \n M.CODMNU AS codiceMenu, \n M.DESMNU AS descrizioneMenu,\n M.CODGRP AS codiceGruppo,\n G.DESGRP AS descrizioneGruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM MENU M\n LEFT JOIN MENU_GRP G ON M.CODGRP = G.CODGRP\n WHERE M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1\n ORDER BY G.CODGRP, M.CODMNU\n `;\n\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, []);\n return result.map(RestUtilities.convertKeysToCamelCase) as unknown as MenuEntity[];\n }\n\n\n /**\n * Restituisce il catalogo ordinato per gruppo e menu. `includeDisabled` e riservato a console e amministrazione:\n * i flussi applicativi di autorizzazione devono usare il comportamento predefinito, che nasconde voci disabilitate.\n */\n public async getGroupsWithMenus(includeDisabled = false): Promise<GroupWithMenusEntity[]> {\n const filtersClause = includeDisabled\n ? ''\n : 'WHERE M.FLGENABLED = 1 AND (G.FLGENABLED IS NULL OR G.FLGENABLED = 1)';\n\n const query = `\n SELECT\n M.CODMNU AS codice_menu,\n M.DESMNU AS descrizione_menu,\n M.CODGRP AS codice_gruppo,\n G.DESGRP AS descrizione_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note,\n G.ORDINE AS ordine_gruppo,\n M.ORDINE as ordine_menu,\n M.FLGENABLED AS menu_enabled,\n G.FLGENABLED AS group_enabled\n FROM MENU M\n LEFT JOIN MENU_GRP G ON M.CODGRP = G.CODGRP\n ${filtersClause}\n ORDER BY G.CODGRP, M.CODMNU\n `;\n\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, []);\n\n const groupMap = new Map<\n string,\n GroupWithMenusEntity & { menus: (MenuEntity & { enabled?: boolean })[] }\n >();\n\n result.forEach((row: unknown) => {\n const converted = RestUtilities.convertKeysToCamelCase(row) as MenuEntity & {\n menuEnabled?: number | boolean;\n groupEnabled?: number | boolean;\n };\n\n const { menuEnabled, groupEnabled, ...menuBase } = converted;\n const normalizedGroupKey = menuBase.codiceGruppo ?? '__UNGROUPED__';\n const groupEnabledFlag =\n groupEnabled == null ? true : Number(groupEnabled) === 1 || groupEnabled === true;\n const menuEnabledFlag =\n menuEnabled === undefined ? true : Number(menuEnabled) === 1 || menuEnabled === true;\n\n if (!groupMap.has(normalizedGroupKey)) {\n groupMap.set(normalizedGroupKey, {\n codiceGruppo: menuBase.codiceGruppo ?? normalizedGroupKey,\n descrizioneGruppo: menuBase.descrizioneGruppo ?? '',\n ordineGruppo: menuBase.ordineGruppo,\n enabled: groupEnabledFlag,\n menus: [],\n });\n }\n\n if (menuBase.codiceMenu) {\n groupMap.get(normalizedGroupKey)!.menus.push({\n ...menuBase,\n enabled: menuEnabledFlag,\n });\n }\n });\n\n const groupsArray = Array.from(groupMap.values())\n .map(group => ({\n ...group,\n menus: (group.menus ?? []).sort(\n (a, b) =>\n (a.ordineMenu ?? Number.MAX_SAFE_INTEGER) - (b.ordineMenu ?? Number.MAX_SAFE_INTEGER),\n ),\n }))\n .sort(\n (a, b) =>\n (a.ordineGruppo ?? Number.MAX_SAFE_INTEGER) - (b.ordineGruppo ?? Number.MAX_SAFE_INTEGER),\n );\n\n return groupsArray;\n }\n\n // -----------------------------------------------------------------------\n // Cataloghi di configurazione: CRUD di menu, gruppi, tipi menu.\n // `table` e `column` sono sempre costanti interne, mai input utente: i\n // valori sono parametrizzati, quindi non esiste superficie di SQL injection.\n // -----------------------------------------------------------------------\n\n private async countWhere(table: string, column: string, value: unknown): Promise<number> {\n const result = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT COUNT(*) FROM ${table} WHERE ${column} = ?`,\n [value],\n );\n return this.getCountFromResult(result);\n }\n\n private async assertMenuGroupExists(codiceGruppo: string): Promise<void> {\n if ((await this.countWhere('MENU_GRP', 'CODGRP', codiceGruppo)) === 0) {\n throw new BadRequestException(`Il gruppo menu ${codiceGruppo} non esiste.`);\n }\n }\n\n private async assertMenuTypeExists(codiceTipo: string): Promise<void> {\n if ((await this.countWhere('MENU_TIPI', 'CODTIP', codiceTipo)) === 0) {\n throw new BadRequestException(`Il tipo menu ${codiceTipo} non esiste.`);\n }\n }\n\n /** Catalogo completo dei tipi menu, usato dagli editor di configurazione. */\n public async getMenuTypes(): Promise<MenuTypeEntity[]> {\n const query = `SELECT CODTIP AS codice_tipo, DESTIP AS descrizione_tipo FROM MENU_TIPI ORDER BY CODTIP`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, []);\n return result.map(RestUtilities.convertKeysToCamelCase) as unknown as MenuTypeEntity[];\n }\n\n public async createMenuType(input: CreateMenuTypeRequest): Promise<void> {\n if ((await this.countWhere('MENU_TIPI', 'CODTIP', input.codiceTipo)) > 0) {\n throw new BadRequestException(`Il tipo menu ${input.codiceTipo} esiste gia.`);\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `INSERT INTO MENU_TIPI (CODTIP, DESTIP) VALUES (?, ?)`,\n [input.codiceTipo, input.descrizioneTipo ?? null],\n );\n }\n\n public async updateMenuType(codiceTipo: string, input: UpdateMenuTypeRequest): Promise<void> {\n await this.assertMenuTypeExists(codiceTipo);\n if (input.descrizioneTipo === undefined) return;\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `UPDATE MENU_TIPI SET DESTIP = ? WHERE CODTIP = ?`,\n [input.descrizioneTipo, codiceTipo],\n );\n }\n\n /** Elimina un tipo menu solo se nessun menu lo utilizza (la FK lo impedirebbe comunque). */\n public async deleteMenuType(codiceTipo: string): Promise<void> {\n await this.assertMenuTypeExists(codiceTipo);\n const used = await this.countWhere('MENU', 'CODTIP', codiceTipo);\n if (used > 0) {\n throw new BadRequestException(\n `Impossibile eliminare il tipo ${codiceTipo}: ${used} menu lo utilizzano.`,\n );\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `DELETE FROM MENU_TIPI WHERE CODTIP = ?`,\n [codiceTipo],\n );\n }\n\n public async createMenuGroup(input: CreateMenuGroupRequest): Promise<void> {\n if ((await this.countWhere('MENU_GRP', 'CODGRP', input.codiceGruppo)) > 0) {\n throw new BadRequestException(`Il gruppo menu ${input.codiceGruppo} esiste gia.`);\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `INSERT INTO MENU_GRP (CODGRP, DESGRP, FLGENABLED, ORDINE) VALUES (?, ?, ?, ?)`,\n [\n input.codiceGruppo,\n input.descrizioneGruppo ?? null,\n input.enabled === false ? 0 : 1,\n input.ordineGruppo ?? 0,\n ],\n );\n }\n\n public async updateMenuGroup(codiceGruppo: string, input: UpdateMenuGroupRequest): Promise<void> {\n await this.assertMenuGroupExists(codiceGruppo);\n\n const sets: string[] = [];\n const params: unknown[] = [];\n if (input.descrizioneGruppo !== undefined) {\n sets.push('DESGRP = ?');\n params.push(input.descrizioneGruppo);\n }\n if (input.ordineGruppo !== undefined) {\n sets.push('ORDINE = ?');\n params.push(input.ordineGruppo);\n }\n if (input.enabled !== undefined) {\n sets.push('FLGENABLED = ?');\n params.push(input.enabled ? 1 : 0);\n }\n if (sets.length === 0) return;\n\n params.push(codiceGruppo);\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `UPDATE MENU_GRP SET ${sets.join(', ')} WHERE CODGRP = ?`,\n params,\n );\n }\n\n /** Elimina un gruppo solo se non contiene menu, per non lasciare menu orfani. */\n public async deleteMenuGroup(codiceGruppo: string): Promise<void> {\n await this.assertMenuGroupExists(codiceGruppo);\n const used = await this.countWhere('MENU', 'CODGRP', codiceGruppo);\n if (used > 0) {\n throw new BadRequestException(\n `Impossibile eliminare il gruppo ${codiceGruppo}: contiene ${used} menu.`,\n );\n }\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `DELETE FROM MENU_GRP WHERE CODGRP = ?`,\n [codiceGruppo],\n );\n }\n\n public async createMenu(input: CreateMenuRequest): Promise<void> {\n if ((await this.countWhere('MENU', 'CODMNU', input.codiceMenu)) > 0) {\n throw new BadRequestException(`Il menu ${input.codiceMenu} esiste gia.`);\n }\n await this.assertMenuGroupExists(input.codiceGruppo);\n if (input.tipo) await this.assertMenuTypeExists(input.tipo);\n\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `INSERT INTO MENU (CODMNU, DESMNU, CODGRP, FLGENABLED, ICON, ORDINE, CODTIP, PAGINA, RIFMENU, NOTE)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n input.codiceMenu,\n input.descrizioneMenu ?? null,\n input.codiceGruppo,\n input.enabled === false ? 0 : 1,\n input.icona ?? null,\n input.ordineMenu ?? null,\n input.tipo ?? null,\n input.pagina ?? null,\n input.rifMenu ?? null,\n input.note ?? null,\n ],\n );\n }\n\n public async updateMenu(codiceMenu: string, input: UpdateMenuRequest): Promise<void> {\n if ((await this.countWhere('MENU', 'CODMNU', codiceMenu)) === 0) {\n throw new BadRequestException(`Il menu ${codiceMenu} non esiste.`);\n }\n if (input.codiceGruppo !== undefined) await this.assertMenuGroupExists(input.codiceGruppo);\n if (input.tipo) await this.assertMenuTypeExists(input.tipo);\n\n const sets: string[] = [];\n const params: unknown[] = [];\n if (input.descrizioneMenu !== undefined) {\n sets.push('DESMNU = ?');\n params.push(input.descrizioneMenu);\n }\n if (input.codiceGruppo !== undefined) {\n sets.push('CODGRP = ?');\n params.push(input.codiceGruppo);\n }\n if (input.tipo !== undefined) {\n sets.push('CODTIP = ?');\n params.push(input.tipo || null);\n }\n if (input.icona !== undefined) {\n sets.push('ICON = ?');\n params.push(input.icona);\n }\n if (input.pagina !== undefined) {\n sets.push('PAGINA = ?');\n params.push(input.pagina);\n }\n if (input.ordineMenu !== undefined) {\n sets.push('ORDINE = ?');\n params.push(input.ordineMenu);\n }\n if (input.enabled !== undefined) {\n sets.push('FLGENABLED = ?');\n params.push(input.enabled ? 1 : 0);\n }\n if (input.rifMenu !== undefined) {\n sets.push('RIFMENU = ?');\n params.push(input.rifMenu);\n }\n if (input.note !== undefined) {\n sets.push('NOTE = ?');\n params.push(input.note);\n }\n if (sets.length === 0) return;\n\n params.push(codiceMenu);\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n `UPDATE MENU SET ${sets.join(', ')} WHERE CODMNU = ?`,\n params,\n );\n }\n\n /** Elimina menu, grant utente e associazioni ruolo in un'unica transazione. */\n public async deleteMenu(codiceMenu: string): Promise<void> {\n if ((await this.countWhere('MENU', 'CODMNU', codiceMenu)) === 0) {\n throw new BadRequestException(`Il menu ${codiceMenu} non esiste.`);\n }\n await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: `DELETE FROM ABILITAZIONI WHERE CODMNU = ?`, params: [codiceMenu] },\n { query: `DELETE FROM RUOLI_MNU WHERE CODMNU = ?`, params: [codiceMenu] },\n { query: `DELETE FROM MENU WHERE CODMNU = ?`, params: [codiceMenu] },\n ]);\n }\n\n\n /**\n * Calcola l'autorizzazione effettiva: grant diretti e grant dei ruoli sono uniti per codice menu.\n * Per compatibilita storica un grant diretto prevale su quello del ruolo; i superutenti ricevono tutti i menu attivi.\n */\n public async getUserRolesAndGrants(codiceUtente: number): Promise<{\n abilitazioni: AbilitazioneMenu[],\n ruoli: Role[],\n grants: AbilitazioneMenu[]\n }> {\n const codiceUtenteQuery = \"SELECT FLGSUPER as flag_super FROM UTENTI_CONFIG WHERE CODUTE = ?\";\n const result = await Orm.query(this.accessiOptions.databaseOptions, codiceUtenteQuery, [codiceUtente]);\n if (!result || result.length == 0) throw new Error(\"Nessun utente trovato con il codice utente \" + codiceUtente);\n\n const isSuperAdmin = this.isSuperFlag(\n (result.map(RestUtilities.convertKeysToCamelCase)[0] as { flagSuper?: unknown } | undefined)?.flagSuper,\n );\n\n const abilitazioni = await this.getUserDirectPermissions(codiceUtente);\n const ruoli = await this.getUserRoles(codiceUtente);\n const grants = this.composeGrants(\n abilitazioni,\n ruoli,\n isSuperAdmin,\n isSuperAdmin ? await this.getAllActiveMenusAsGrants() : [],\n );\n\n return { abilitazioni, ruoli, grants };\n }\n\n private isSuperFlag(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n }\n\n /**\n * Versione batch di `getUserRolesAndGrants`: esegue un numero costante di query per N utenti\n * (invece di N set di query) e restituisce mappa per codice utente. Stessa composizione della\n * lettura singola.\n */\n public async getUsersRolesAndGrants(codiciUtente: number[]): Promise<Map<number, {\n abilitazioni: AbilitazioneMenu[],\n ruoli: Role[],\n grants: AbilitazioneMenu[]\n }>> {\n const result = new Map<number, { abilitazioni: AbilitazioneMenu[], ruoli: Role[], grants: AbilitazioneMenu[] }>();\n const ids = Array.from(new Set(codiciUtente.filter((id) => Number.isInteger(id) && id > 0)));\n if (ids.length === 0) {\n return result;\n }\n\n const placeholders = ids.map(() => '?').join(', ');\n\n const superRows = (await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT CODUTE AS codice_utente, FLGSUPER AS flag_super FROM UTENTI_CONFIG WHERE CODUTE IN (${placeholders})`,\n ids,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n const superUsers = new Set<number>();\n for (const row of superRows) {\n if (this.isSuperFlag(row.flagSuper)) {\n superUsers.add(Number(row.codiceUtente));\n }\n }\n\n const permissionRows = (await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT\n A.CODUTE AS codice_utente,\n A.CODMNU AS codice_menu,\n A.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n G.DESGRP AS descrizione_gruppo,\n G.CODGRP AS codice_gruppo,\n M.ICON AS icona,\n M.CODTIP AS tipo,\n M.PAGINA AS pagina,\n M.NOTE AS note\n FROM ABILITAZIONI A\n INNER JOIN MENU M ON A.CODMNU = M.CODMNU\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE A.CODUTE IN (${placeholders}) AND M.FLGENABLED = 1 AND COALESCE(G.FLGENABLED, 1) = 1`,\n ids,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n const roleRows = (await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT\n RU.CODUTE AS codice_utente,\n R.CODRUO AS codice_ruolo,\n R.DESRUO AS descrizione_ruolo,\n CASE WHEN COALESCE(G.FLGENABLED, 1) = 1 THEN M.CODMNU END AS codice_menu,\n RM.TIPABI AS tipo_abilitazione,\n M.DESMNU AS descrizione_menu,\n M.NOTE AS note\n FROM UTENTI_RUOLI RU\n INNER JOIN RUOLI R ON RU.CODRUO = R.CODRUO\n LEFT JOIN RUOLI_MNU RM ON R.CODRUO = RM.CODRUO\n LEFT JOIN MENU M ON RM.CODMNU = M.CODMNU AND M.FLGENABLED = 1\n LEFT JOIN MENU_GRP G ON G.CODGRP = M.CODGRP\n WHERE RU.CODUTE IN (${placeholders})`,\n ids,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n const allActiveMenus = superUsers.size > 0 ? await this.getAllActiveMenusAsGrants() : [];\n\n const permissionsByUser = new Map<number, AbilitazioneMenu[]>();\n for (const row of permissionRows) {\n const { codiceUtente, ...grant } = row;\n const key = Number(codiceUtente);\n const bucket = permissionsByUser.get(key);\n if (bucket) {\n bucket.push(grant as unknown as AbilitazioneMenu);\n } else {\n permissionsByUser.set(key, [grant as unknown as AbilitazioneMenu]);\n }\n }\n\n const rolesByUser = new Map<number, Array<Record<string, unknown>>>();\n for (const row of roleRows) {\n const { codiceUtente, ...roleRow } = row;\n const key = Number(codiceUtente);\n const bucket = rolesByUser.get(key);\n if (bucket) {\n bucket.push(roleRow);\n } else {\n rolesByUser.set(key, [roleRow]);\n }\n }\n\n for (const id of ids) {\n const abilitazioni = permissionsByUser.get(id) ?? [];\n const ruoli = this.assembleRoles(rolesByUser.get(id) ?? []);\n const isSuperAdmin = superUsers.has(id);\n result.set(id, {\n abilitazioni,\n ruoli,\n grants: this.composeGrants(abilitazioni, ruoli, isSuperAdmin, isSuperAdmin ? allActiveMenus : []),\n });\n }\n\n return result;\n }\n\n\n\n}\n\n\n"]}
@@ -34,7 +34,6 @@ export declare class UserService {
34
34
  numRep?: number | number[];
35
35
  codDipendente?: number;
36
36
  cellulare?: string;
37
- cellute?: string;
38
37
  tipFil?: number;
39
38
  flagSuper?: boolean;
40
39
  limit?: number;
@@ -55,7 +55,7 @@ let UserService = class UserService {
55
55
  return value === true || value === 1 || value === '1';
56
56
  }
57
57
  normalizeUserFlags(user) {
58
- const normalized = Object.assign(Object.assign({}, user), { flagSuper: this.normalizeDatabaseBoolean(user.flagSuper), flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin), flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori), passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled), passwordLoginEnabled: user.passwordLoginEnabled == null || this.normalizeDatabaseBoolean(user.passwordLoginEnabled), enableIa: this.normalizeDatabaseBoolean(user.enableIa) });
58
+ const normalized = Object.assign(Object.assign({}, user), { flagSuper: this.normalizeDatabaseBoolean(user.flagSuper), flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin), flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori), passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled), passwordLoginEnabled: user.passwordLoginEnabled == null || this.normalizeDatabaseBoolean(user.passwordLoginEnabled) });
59
59
  return normalized;
60
60
  }
61
61
  normalizeEmail(email) {
@@ -138,7 +138,6 @@ let UserService = class UserService {
138
138
  var _a, _b, _c, _d, _e;
139
139
  try {
140
140
  const filterColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'FILTRI');
141
- const utentiColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI');
142
141
  // Paginazione opzionale con limiti sani: il default resta "tutti gli utenti".
143
142
  const limit = Number.isInteger(filters === null || filters === void 0 ? void 0 : filters.limit) && ((_a = filters === null || filters === void 0 ? void 0 : filters.limit) !== null && _a !== void 0 ? _a : 0) > 0
144
143
  ? Math.min(filters === null || filters === void 0 ? void 0 : filters.limit, 1000)
@@ -157,7 +156,6 @@ let UserService = class UserService {
157
156
  U.DATSCAPWD as data_scadenza_password,
158
157
  U.DATLASTLOGIN as data_last_login,
159
158
  U.STAREG as stato_registrazione,
160
- ${(0, optionalColumns_1.optionalColumn)(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},
161
159
  G.COGNOME as cognome,
162
160
  G.NOME as nome,
163
161
  G.AVATAR as avatar,
@@ -168,7 +166,6 @@ let UserService = class UserService {
168
166
  G.FLGSUPER as flag_super,
169
167
  G.FLGADMIN as flag_admin,
170
168
  COALESCE(G.FLGPASSWORD, 1) as password_login_enabled,
171
- G.PAGDEF as pagina_default,
172
169
  G.JSON_METADATA as json_metadata,
173
170
  ${(0, optionalColumns_1.optionalColumn)(filterColumns, 'CODDIP', 'F', 'cod_dipendente')},
174
171
  ${(0, optionalColumns_1.optionalColumn)(filterColumns, 'NUMREP', 'F', 'num_rep', true)},
@@ -221,10 +218,6 @@ let UserService = class UserService {
221
218
  query += ` AND TRIM(G.CELLULARE) = ? `;
222
219
  queryParams.push(String(filters.cellulare).trim());
223
220
  }
224
- if (filters === null || filters === void 0 ? void 0 : filters.cellute) {
225
- query += ` AND TRIM(U.CELLUTE) = ? `;
226
- queryParams.push(String(filters.cellute).trim());
227
- }
228
221
  if ((filters === null || filters === void 0 ? void 0 : filters.flagSuper) !== undefined) {
229
222
  query += filters.flagSuper ? ` AND COALESCE(G.FLGSUPER, 0) <> 0 ` : ` AND COALESCE(G.FLGSUPER, 0) = 0 `;
230
223
  }
@@ -345,7 +338,6 @@ let UserService = class UserService {
345
338
  /** Recupera il profilo locale usato dal login, compresi filtri Accessi eventualmente presenti. */
346
339
  getUserByEmail(email) {
347
340
  return __awaiter(this, void 0, void 0, function* () {
348
- const utentiColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI');
349
341
  const query = `
350
342
  SELECT
351
343
  U.CODUTE AS codice_utente,
@@ -353,7 +345,6 @@ let UserService = class UserService {
353
345
  U.FLGGDPR AS flag_gdpr,
354
346
  U.DATSCAPWD as data_scadenza_password,
355
347
  U.STAREG AS stato_registrazione,
356
- ${(0, optionalColumns_1.optionalColumn)(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},
357
348
  C.COGNOME AS cognome,
358
349
  C.NOME AS nome,
359
350
  C.AVATAR AS avatar,
@@ -363,8 +354,7 @@ let UserService = class UserService {
363
354
  C.CELLULARE AS cellulare,
364
355
  C.FLGSUPER AS flag_super,
365
356
  C.FLGADMIN AS flag_admin,
366
- COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled,
367
- C.PAGDEF AS pagina_default
357
+ COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled
368
358
  FROM UTENTI U
369
359
  INNER JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE
370
360
  WHERE LOWER(U.USRNAME) = ?
@@ -448,11 +438,6 @@ let UserService = class UserService {
448
438
  dbField: 'FLG2FATT',
449
439
  transform: (v) => (v ? 1 : 0),
450
440
  },
451
- {
452
- key: 'paginaDefault',
453
- dbField: 'PAGDEF',
454
- transform: (v) => String(v),
455
- },
456
441
  ];
457
442
  if (allowPrivilegedFields) {
458
443
  optionalFields.push({
@@ -543,10 +528,6 @@ let UserService = class UserService {
543
528
  utentiUpdates.push('flggdpr = ?');
544
529
  utentiParams.push(user.flagGdpr);
545
530
  }
546
- if (allowPrivilegedChanges && user.enableIa !== undefined) {
547
- utentiUpdates.push('enableia = ?');
548
- utentiParams.push(user.enableIa ? 1 : 0);
549
- }
550
531
  if (allowPrivilegedChanges && user.statoRegistrazione !== undefined) {
551
532
  utentiUpdates.push('stareg = ?');
552
533
  utentiParams.push(user.statoRegistrazione);
@@ -598,10 +579,6 @@ let UserService = class UserService {
598
579
  utentiConfigUpdates.push('flgpassword = ?');
599
580
  utentiConfigParams.push(user.passwordLoginEnabled ? 1 : 0);
600
581
  }
601
- if (user.paginaDefault !== undefined) {
602
- utentiConfigUpdates.push('pagdef = ?');
603
- utentiConfigParams.push(user.paginaDefault);
604
- }
605
582
  if (user.jsonMetadata !== undefined) {
606
583
  utentiConfigUpdates.push('json_metadata = ?');
607
584
  utentiConfigParams.push(user.jsonMetadata);