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

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 (55) hide show
  1. package/dist/accessi-module/Console/console.js +26 -17
  2. package/dist/accessi-module/Console/console.js.map +1 -1
  3. package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.d.ts +1 -1
  4. package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.js.map +1 -1
  5. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.d.ts +3 -1
  6. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js.map +1 -1
  7. package/dist/accessi-module/Console/generated/model/menuEntity.d.ts +2 -0
  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 -4
  10. package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js.map +1 -1
  11. package/dist/accessi-module/Console/generated/model/registerRequest.d.ts +2 -6
  12. package/dist/accessi-module/Console/generated/model/registerRequest.js.map +1 -1
  13. package/dist/accessi-module/Console/generated/model/userDto.d.ts +5 -7
  14. package/dist/accessi-module/Console/generated/model/userDto.js.map +1 -1
  15. package/dist/accessi-module/Console/wiki.js +2 -0
  16. package/dist/accessi-module/Console/wiki.js.map +1 -1
  17. package/dist/accessi-module/Controllers/ConfiguratorController.js +2 -2
  18. package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
  19. package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.d.ts +1 -1
  20. package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js +1 -1
  21. package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js.map +1 -1
  22. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.d.ts +1 -0
  23. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js +9 -1
  24. package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js.map +1 -1
  25. package/dist/accessi-module/Dtos/GetMenusResponse.d.ts +1 -0
  26. package/dist/accessi-module/Dtos/GetMenusResponse.js +8 -0
  27. package/dist/accessi-module/Dtos/GetMenusResponse.js.map +1 -1
  28. package/dist/accessi-module/Dtos/PublicRegisterRequest.d.ts +1 -1
  29. package/dist/accessi-module/Dtos/PublicRegisterRequest.js +1 -1
  30. package/dist/accessi-module/Dtos/PublicRegisterRequest.js.map +1 -1
  31. package/dist/accessi-module/Dtos/RegisterRequest.d.ts +1 -3
  32. package/dist/accessi-module/Dtos/RegisterRequest.js +2 -22
  33. package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
  34. package/dist/accessi-module/Dtos/UserDto.d.ts +3 -4
  35. package/dist/accessi-module/Dtos/UserDto.js +9 -19
  36. package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
  37. package/dist/accessi-module/Services/PermissionService/PermissionService.js +12 -9
  38. package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
  39. package/dist/accessi-module/Services/UserService/UserService.d.ts +1 -2
  40. package/dist/accessi-module/Services/UserService/UserService.js +26 -61
  41. package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
  42. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +16 -0
  43. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
  44. package/dist/accessi-module/database-updates/accessiSchema.d.ts +12 -1
  45. package/dist/accessi-module/database-updates/accessiSchema.js +24 -4
  46. package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -1
  47. package/dist/accessi-module/security/accessControl.d.ts +2 -2
  48. package/dist/accessi-module/security/accessControl.js +2 -2
  49. package/dist/accessi-module/security/accessControl.js.map +1 -1
  50. package/dist/accessi-module/security/authenticatedToken.d.ts +1 -1
  51. package/dist/accessi-module/security/authenticatedToken.js +2 -2
  52. package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
  53. package/dist/emilsoftware-utilities-2.0.0-dev.32.tgz +0 -0
  54. package/package.json +1 -1
  55. package/dist/emilsoftware-utilities-2.0.0-dev.30.tgz +0 -0
@@ -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 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, 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 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"]}
@@ -13,12 +13,11 @@ export declare class UserService {
13
13
  private readonly permissionService;
14
14
  private readonly filtriService;
15
15
  constructor(accessiOptions: AccessiOptions, emailService: EmailService, permissionService: PermissionService, filtriService: FiltriService);
16
- private validateApplicationFields;
17
16
  private normalizeDatabaseBoolean;
18
17
  private normalizeUserFlags;
19
18
  private normalizeEmail;
20
19
  private ensureEmailIsAvailable;
21
- /** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMINCONFIG`). */
20
+ /** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMIN`). */
22
21
  isAdminConfigurator(codiceUtente: number): Promise<boolean>;
23
22
  /**
24
23
  * Legge il minimo profilo autorevole usato da JWT e middleware. Restituisce `null` per utenti inesistenti.
@@ -51,34 +51,16 @@ let UserService = class UserService {
51
51
  this.permissionService = permissionService;
52
52
  this.filtriService = filtriService;
53
53
  }
54
- validateApplicationFields(value) {
55
- return __awaiter(this, void 0, void 0, function* () {
56
- const applicationFields = [['nummac', 'NUMMAC'], ['ragSocCli', 'RAGSOCCLI']];
57
- let configColumns;
58
- if (applicationFields.some(([key]) => value[key] !== undefined)) {
59
- configColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI_CONFIG');
60
- for (const [key, column] of applicationFields) {
61
- if (value[key] !== undefined && value[key] !== null && !configColumns.has(column)) {
62
- throw new common_1.BadRequestException(`Campo applicativo non configurato: UTENTI_CONFIG.${column}`);
63
- }
64
- }
65
- }
66
- const filterKeys = Object.keys(FiltriUtente_1.FILTRI_UTENTE_DB_MAPPING);
67
- if (filterKeys.some(key => value[key] !== undefined && value[key] !== null && value[key] !== '')) {
68
- yield this.filtriService.validateSupportedFields(value);
69
- }
70
- return { configColumns };
71
- });
72
- }
73
54
  normalizeDatabaseBoolean(value) {
74
55
  return value === true || value === 1 || value === '1';
75
56
  }
76
57
  normalizeUserFlags(user) {
77
- return Object.assign(Object.assign({}, user), { flagSuper: this.normalizeDatabaseBoolean(user.flagSuper), flagAdminConfigurator: this.normalizeDatabaseBoolean(user.flagAdminConfigurator), flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori), passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled), passwordLoginEnabled: user.passwordLoginEnabled == null || this.normalizeDatabaseBoolean(user.passwordLoginEnabled) });
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) });
59
+ return normalized;
78
60
  }
79
61
  normalizeEmail(email) {
80
62
  if (typeof email !== 'string' || email.trim() === '') {
81
- throw new common_1.BadRequestException({ code: 'ACCESSI_EMAIL_REQUIRED', message: "L'email è obbligatoria." });
63
+ throw new common_1.BadRequestException({ code: 'ACCESSI_EMAIL_REQUIRED', message: "L'email è obbligatoria." });
82
64
  }
83
65
  return email.trim().toLowerCase();
84
66
  }
@@ -88,24 +70,24 @@ let UserService = class UserService {
88
70
  const existingUser = result.map(Utilities_1.RestUtilities.convertKeysToCamelCase)[0];
89
71
  if ((existingUser === null || existingUser === void 0 ? void 0 : existingUser.codiceUtente) &&
90
72
  (!currentUserCode || existingUser.codiceUtente !== currentUserCode)) {
91
- throw new common_1.ConflictException({ code: 'ACCESSI_EMAIL_ALREADY_EXISTS', message: "L'email è già associata a un utente Accessi." });
73
+ throw new common_1.ConflictException({ code: 'ACCESSI_EMAIL_ALREADY_EXISTS', message: "L'email è già associata a un utente Accessi." });
92
74
  }
93
75
  });
94
76
  }
95
- /** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMINCONFIG`). */
77
+ /** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMIN`). */
96
78
  isAdminConfigurator(codiceUtente) {
97
79
  return __awaiter(this, void 0, void 0, function* () {
98
80
  var _a;
99
81
  if (!codiceUtente) {
100
82
  return false;
101
83
  }
102
- const query = `SELECT FLGADMINCONFIG AS flag_admin_configurator FROM UTENTI_CONFIG WHERE CODUTE = ?`;
84
+ const query = `SELECT FLGADMIN AS flag_admin FROM UTENTI_CONFIG WHERE CODUTE = ?`;
103
85
  const result = yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, query, [codiceUtente]);
104
86
  if (result.length === 0) {
105
87
  return false;
106
88
  }
107
89
  const mapped = result.map(Utilities_1.RestUtilities.convertKeysToCamelCase);
108
- return this.normalizeDatabaseBoolean((_a = mapped[0]) === null || _a === void 0 ? void 0 : _a.flagAdminConfigurator);
90
+ return this.normalizeDatabaseBoolean((_a = mapped[0]) === null || _a === void 0 ? void 0 : _a.flagAdmin);
109
91
  });
110
92
  }
111
93
  /**
@@ -123,7 +105,7 @@ let UserService = class UserService {
123
105
  U.USRNAME AS email,
124
106
  U.STAREG AS stato_registrazione,
125
107
  C.FLGSUPER AS flag_super,
126
- C.FLGADMINCONFIG AS flag_admin_configurator
108
+ C.FLGADMIN AS flag_admin
127
109
  , C.FLG2FATT AS flag_due_fattori
128
110
  , C.FLGPWDLESS AS passwordless_login_enabled
129
111
  , COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled
@@ -140,7 +122,7 @@ let UserService = class UserService {
140
122
  email: typeof user.email === 'string' ? user.email : undefined,
141
123
  statoRegistrazione: Number(user.statoRegistrazione),
142
124
  flagSuper: this.normalizeDatabaseBoolean(user.flagSuper),
143
- flagAdminConfigurator: this.normalizeDatabaseBoolean(user.flagAdminConfigurator),
125
+ flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin),
144
126
  flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori),
145
127
  passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled),
146
128
  passwordLoginEnabled: this.normalizeDatabaseBoolean(user.passwordLoginEnabled),
@@ -155,7 +137,6 @@ let UserService = class UserService {
155
137
  return __awaiter(this, void 0, void 0, function* () {
156
138
  var _a, _b, _c, _d, _e;
157
139
  try {
158
- const configColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI_CONFIG');
159
140
  const filterColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'FILTRI');
160
141
  const utentiColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI');
161
142
  // Paginazione opzionale con limiti sani: il default resta "tutti gli utenti".
@@ -185,13 +166,10 @@ let UserService = class UserService {
185
166
  G.CODLINGUA as codice_lingua,
186
167
  G.CELLULARE as cellulare,
187
168
  G.FLGSUPER as flag_super,
188
- G.FLGADMINCONFIG as flag_admin_configurator,
169
+ G.FLGADMIN as flag_admin,
189
170
  COALESCE(G.FLGPASSWORD, 1) as password_login_enabled,
190
171
  G.PAGDEF as pagina_default,
191
172
  G.JSON_METADATA as json_metadata,
192
- ${(0, optionalColumns_1.optionalColumn)(configColumns, 'RAGSOCCLI', 'G', 'rag_soc_cli', false)},
193
- ${(0, optionalColumns_1.optionalColumn)(configColumns, 'NUMMAC', 'G', 'nummac')},
194
- ${(0, optionalColumns_1.optionalColumn)(configColumns, 'CAUMOV', 'G', 'caumov')},
195
173
  ${(0, optionalColumns_1.optionalColumn)(filterColumns, 'CODDIP', 'F', 'cod_dipendente')},
196
174
  ${(0, optionalColumns_1.optionalColumn)(filterColumns, 'NUMREP', 'F', 'num_rep', true)},
197
175
  ${(0, optionalColumns_1.optionalColumn)(filterColumns, 'IDXPERS', 'F', 'idx_pers', true)},
@@ -367,7 +345,7 @@ let UserService = class UserService {
367
345
  /** Recupera il profilo locale usato dal login, compresi filtri Accessi eventualmente presenti. */
368
346
  getUserByEmail(email) {
369
347
  return __awaiter(this, void 0, void 0, function* () {
370
- const configColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI_CONFIG');
348
+ const utentiColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI');
371
349
  const query = `
372
350
  SELECT
373
351
  U.CODUTE AS codice_utente,
@@ -375,6 +353,7 @@ let UserService = class UserService {
375
353
  U.FLGGDPR AS flag_gdpr,
376
354
  U.DATSCAPWD as data_scadenza_password,
377
355
  U.STAREG AS stato_registrazione,
356
+ ${(0, optionalColumns_1.optionalColumn)(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},
378
357
  C.COGNOME AS cognome,
379
358
  C.NOME AS nome,
380
359
  C.AVATAR AS avatar,
@@ -383,11 +362,9 @@ let UserService = class UserService {
383
362
  C.CODLINGUA AS codice_lingua,
384
363
  C.CELLULARE AS cellulare,
385
364
  C.FLGSUPER AS flag_super,
386
- C.FLGADMINCONFIG AS flag_admin_configurator,
365
+ C.FLGADMIN AS flag_admin,
387
366
  COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled,
388
- C.PAGDEF AS pagina_default,
389
- ${(0, optionalColumns_1.optionalColumn)(configColumns, 'NUMMAC', 'C', 'nummac')},
390
- ${(0, optionalColumns_1.optionalColumn)(configColumns, 'RAGSOCCLI', 'C', 'rag_soc_cli', false)}
367
+ C.PAGDEF AS pagina_default
391
368
  FROM UTENTI U
392
369
  INNER JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE
393
370
  WHERE LOWER(U.USRNAME) = ?
@@ -432,19 +409,18 @@ let UserService = class UserService {
432
409
  }
433
410
  if (!allowPrivilegedFields &&
434
411
  (registrationData.flagSuper !== undefined ||
435
- registrationData.flagAdminConfigurator !== undefined ||
412
+ registrationData.flagAdmin !== undefined ||
436
413
  registrationData.flagDueFattori !== undefined ||
437
414
  registrationData.roles !== undefined ||
438
415
  registrationData.permissions !== undefined)) {
439
416
  throw new Error('I campi privilegiati non sono consentiti nella registrazione pubblica.');
440
417
  }
441
- yield this.validateApplicationFields(registrationData);
442
418
  yield this.ensureEmailIsAvailable(normalizedEmail);
443
419
  const queryUtenti = `INSERT INTO UTENTI (USRNAME, STAREG) VALUES (?,?) RETURNING CODUTE`;
444
420
  // Public/local registrations keep the historic INVIO state; trusted master or SSO flows may opt into CONF.
445
421
  const paramsUtenti = [normalizedEmail, (_a = options === null || options === void 0 ? void 0 : options.initialState) !== null && _a !== void 0 ? _a : StatoRegistrazione_1.StatoRegistrazione.INVIO];
446
422
  // Utente e configurazione sono creati in un'unica transazione; filtri e assegnazioni restano
447
- // fuori perché delegati a servizi dedicati.
423
+ // fuori perché delegati a servizi dedicati.
448
424
  const codiceUtente = yield Orm_1.Orm.withTransaction(this.accessiOptions.databaseOptions, (transaction) => __awaiter(this, void 0, void 0, function* () {
449
425
  var _a;
450
426
  const insertedUsers = yield Orm_1.Orm.transactionQuery(transaction, queryUtenti, paramsUtenti);
@@ -477,16 +453,6 @@ let UserService = class UserService {
477
453
  dbField: 'PAGDEF',
478
454
  transform: (v) => String(v),
479
455
  },
480
- {
481
- key: 'nummac',
482
- dbField: 'NUMMAC',
483
- transform: (v) => Number(v),
484
- },
485
- {
486
- key: 'ragSocCli',
487
- dbField: 'RAGSOCCLI',
488
- transform: (v) => String(v),
489
- },
490
456
  ];
491
457
  if (allowPrivilegedFields) {
492
458
  optionalFields.push({
@@ -494,8 +460,8 @@ let UserService = class UserService {
494
460
  dbField: 'FLGSUPER',
495
461
  transform: (v) => (v ? 1 : 0),
496
462
  }, {
497
- key: 'flagAdminConfigurator',
498
- dbField: 'FLGADMINCONFIG',
463
+ key: 'flagAdmin',
464
+ dbField: 'FLGADMIN',
499
465
  transform: (v) => (v ? 1 : 0),
500
466
  });
501
467
  }
@@ -545,7 +511,7 @@ let UserService = class UserService {
545
511
  if (!allowPrivilegedChanges &&
546
512
  (user.statoRegistrazione !== undefined ||
547
513
  user.flagSuper !== undefined ||
548
- user.flagAdminConfigurator !== undefined ||
514
+ user.flagAdmin !== undefined ||
549
515
  user.passwordLoginEnabled !== undefined ||
550
516
  user.passwordlessLoginEnabled !== undefined ||
551
517
  user.flagDueFattori !== undefined ||
@@ -565,7 +531,6 @@ let UserService = class UserService {
565
531
  throw new common_1.BadRequestException('Per attivare i codici di accesso serve un indirizzo email valido.');
566
532
  }
567
533
  }
568
- const { configColumns } = yield this.validateApplicationFields(user);
569
534
  const utentiUpdates = [];
570
535
  const utentiParams = [];
571
536
  if (user.email !== undefined) {
@@ -578,6 +543,10 @@ let UserService = class UserService {
578
543
  utentiUpdates.push('flggdpr = ?');
579
544
  utentiParams.push(user.flagGdpr);
580
545
  }
546
+ if (allowPrivilegedChanges && user.enableIa !== undefined) {
547
+ utentiUpdates.push('enableia = ?');
548
+ utentiParams.push(user.enableIa ? 1 : 0);
549
+ }
581
550
  if (allowPrivilegedChanges && user.statoRegistrazione !== undefined) {
582
551
  utentiUpdates.push('stareg = ?');
583
552
  utentiParams.push(user.statoRegistrazione);
@@ -621,9 +590,9 @@ let UserService = class UserService {
621
590
  utentiConfigUpdates.push('flgsuper = ?');
622
591
  utentiConfigParams.push(user.flagSuper);
623
592
  }
624
- if (allowPrivilegedChanges && user.flagAdminConfigurator !== undefined) {
625
- utentiConfigUpdates.push('flgadminconfig = ?');
626
- utentiConfigParams.push(user.flagAdminConfigurator);
593
+ if (allowPrivilegedChanges && user.flagAdmin !== undefined) {
594
+ utentiConfigUpdates.push('FLGADMIN = ?');
595
+ utentiConfigParams.push(user.flagAdmin);
627
596
  }
628
597
  if (allowPrivilegedChanges && user.passwordLoginEnabled !== undefined) {
629
598
  utentiConfigUpdates.push('flgpassword = ?');
@@ -637,10 +606,6 @@ let UserService = class UserService {
637
606
  utentiConfigUpdates.push('json_metadata = ?');
638
607
  utentiConfigParams.push(user.jsonMetadata);
639
608
  }
640
- if (user.ragSocCli !== undefined && (user.ragSocCli !== null || (configColumns === null || configColumns === void 0 ? void 0 : configColumns.has('RAGSOCCLI')))) {
641
- utentiConfigUpdates.push('ragsoccli = ?');
642
- utentiConfigParams.push(user.ragSocCli);
643
- }
644
609
  if (utentiConfigUpdates.length > 0) {
645
610
  const queryUtentiConfig = `UPDATE UTENTI_CONFIG SET ${utentiConfigUpdates.join(', ')} WHERE CODUTE = ?`;
646
611
  utentiConfigParams.push(codiceUtente);