emilsoftware-utilities 2.0.0-dev.32 → 2.0.0-dev.34
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.
- package/dist/accessi-module/Console/console.css +10 -0
- package/dist/accessi-module/Console/console.js +102 -19
- package/dist/accessi-module/Console/console.js.map +1 -1
- package/dist/accessi-module/Console/generated/accessiApi.d.ts +2 -2
- package/dist/accessi-module/Console/generated/accessiApi.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.d.ts +0 -5
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.d.ts +0 -2
- package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/menuEntity.d.ts +0 -2
- package/dist/accessi-module/Console/generated/model/menuEntity.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/publicRegisterRequest.d.ts +0 -2
- package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/registerRequest.d.ts +0 -2
- package/dist/accessi-module/Console/generated/model/registerRequest.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.d.ts +0 -5
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/userDto.d.ts +0 -4
- package/dist/accessi-module/Console/generated/model/userDto.js.map +1 -1
- package/dist/accessi-module/Console/index.html +6 -0
- package/dist/accessi-module/Console/wiki.js +7 -4
- package/dist/accessi-module/Console/wiki.js.map +1 -1
- package/dist/accessi-module/Controllers/ConfiguratorController.d.ts +1 -3
- package/dist/accessi-module/Controllers/ConfiguratorController.js +4 -17
- package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
- package/dist/accessi-module/Controllers/FiltriController.js +4 -4
- package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
- package/dist/accessi-module/Controllers/PermissionController.js +14 -14
- package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
- package/dist/accessi-module/Controllers/ServiceTokenController.js +1 -1
- package/dist/accessi-module/Controllers/ServiceTokenController.js.map +1 -1
- package/dist/accessi-module/Controllers/UserController.js +8 -8
- package/dist/accessi-module/Controllers/UserController.js.map +1 -1
- package/dist/accessi-module/Dtos/CatalogDtos.d.ts +0 -2
- package/dist/accessi-module/Dtos/CatalogDtos.js +0 -14
- package/dist/accessi-module/Dtos/CatalogDtos.js.map +1 -1
- package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.d.ts +0 -1
- package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js +0 -8
- package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetMenusResponse.d.ts +0 -1
- package/dist/accessi-module/Dtos/GetMenusResponse.js +0 -8
- package/dist/accessi-module/Dtos/GetMenusResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterRequest.d.ts +0 -1
- package/dist/accessi-module/Dtos/RegisterRequest.js +0 -9
- package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/UserDto.d.ts +0 -2
- package/dist/accessi-module/Dtos/UserDto.js +0 -16
- package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
- package/dist/accessi-module/Services/AuthService/AuthService.js +0 -2
- package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
- package/dist/accessi-module/Services/PermissionService/PermissionService.js +5 -13
- package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
- package/dist/accessi-module/Services/UserService/UserService.d.ts +0 -3
- package/dist/accessi-module/Services/UserService/UserService.js +2 -41
- package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +7 -0
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
- package/dist/accessi-module/database-updates/accessiSchema.d.ts +13 -2
- package/dist/accessi-module/database-updates/accessiSchema.js +15 -7
- package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -1
- package/dist/accessi-module/federated-auth/FederatedAuthController.js +15 -15
- package/dist/accessi-module/federated-auth/FederatedAuthController.js.map +1 -1
- package/dist/accessi-module/security/accessControl.d.ts +11 -2
- package/dist/accessi-module/security/accessControl.js +28 -4
- package/dist/accessi-module/security/accessControl.js.map +1 -1
- package/dist/emilsoftware-utilities-2.0.0-dev.34.tgz +0 -0
- package/package.json +2 -2
- package/dist/emilsoftware-utilities-2.0.0-dev.32.tgz +0 -0
|
@@ -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)
|
|
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) {
|
|
@@ -74,22 +74,6 @@ let UserService = class UserService {
|
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
|
-
/** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMIN`). */
|
|
78
|
-
isAdminConfigurator(codiceUtente) {
|
|
79
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
-
var _a;
|
|
81
|
-
if (!codiceUtente) {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
const query = `SELECT FLGADMIN AS flag_admin FROM UTENTI_CONFIG WHERE CODUTE = ?`;
|
|
85
|
-
const result = yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, query, [codiceUtente]);
|
|
86
|
-
if (result.length === 0) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
const mapped = result.map(Utilities_1.RestUtilities.convertKeysToCamelCase);
|
|
90
|
-
return this.normalizeDatabaseBoolean((_a = mapped[0]) === null || _a === void 0 ? void 0 : _a.flagAdmin);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
77
|
/**
|
|
94
78
|
* Legge il minimo profilo autorevole usato da JWT e middleware. Restituisce `null` per utenti inesistenti.
|
|
95
79
|
* Non usare `UserDto` dal token per decisioni di sicurezza: i flag vengono sempre riletti qui.
|
|
@@ -138,7 +122,6 @@ let UserService = class UserService {
|
|
|
138
122
|
var _a, _b, _c, _d, _e;
|
|
139
123
|
try {
|
|
140
124
|
const filterColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'FILTRI');
|
|
141
|
-
const utentiColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI');
|
|
142
125
|
// Paginazione opzionale con limiti sani: il default resta "tutti gli utenti".
|
|
143
126
|
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
127
|
? Math.min(filters === null || filters === void 0 ? void 0 : filters.limit, 1000)
|
|
@@ -157,7 +140,6 @@ let UserService = class UserService {
|
|
|
157
140
|
U.DATSCAPWD as data_scadenza_password,
|
|
158
141
|
U.DATLASTLOGIN as data_last_login,
|
|
159
142
|
U.STAREG as stato_registrazione,
|
|
160
|
-
${(0, optionalColumns_1.optionalColumn)(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},
|
|
161
143
|
G.COGNOME as cognome,
|
|
162
144
|
G.NOME as nome,
|
|
163
145
|
G.AVATAR as avatar,
|
|
@@ -168,7 +150,6 @@ let UserService = class UserService {
|
|
|
168
150
|
G.FLGSUPER as flag_super,
|
|
169
151
|
G.FLGADMIN as flag_admin,
|
|
170
152
|
COALESCE(G.FLGPASSWORD, 1) as password_login_enabled,
|
|
171
|
-
G.PAGDEF as pagina_default,
|
|
172
153
|
G.JSON_METADATA as json_metadata,
|
|
173
154
|
${(0, optionalColumns_1.optionalColumn)(filterColumns, 'CODDIP', 'F', 'cod_dipendente')},
|
|
174
155
|
${(0, optionalColumns_1.optionalColumn)(filterColumns, 'NUMREP', 'F', 'num_rep', true)},
|
|
@@ -221,10 +202,6 @@ let UserService = class UserService {
|
|
|
221
202
|
query += ` AND TRIM(G.CELLULARE) = ? `;
|
|
222
203
|
queryParams.push(String(filters.cellulare).trim());
|
|
223
204
|
}
|
|
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
205
|
if ((filters === null || filters === void 0 ? void 0 : filters.flagSuper) !== undefined) {
|
|
229
206
|
query += filters.flagSuper ? ` AND COALESCE(G.FLGSUPER, 0) <> 0 ` : ` AND COALESCE(G.FLGSUPER, 0) = 0 `;
|
|
230
207
|
}
|
|
@@ -345,7 +322,6 @@ let UserService = class UserService {
|
|
|
345
322
|
/** Recupera il profilo locale usato dal login, compresi filtri Accessi eventualmente presenti. */
|
|
346
323
|
getUserByEmail(email) {
|
|
347
324
|
return __awaiter(this, void 0, void 0, function* () {
|
|
348
|
-
const utentiColumns = yield (0, optionalColumns_1.getTableColumns)(this.accessiOptions, 'UTENTI');
|
|
349
325
|
const query = `
|
|
350
326
|
SELECT
|
|
351
327
|
U.CODUTE AS codice_utente,
|
|
@@ -353,7 +329,6 @@ let UserService = class UserService {
|
|
|
353
329
|
U.FLGGDPR AS flag_gdpr,
|
|
354
330
|
U.DATSCAPWD as data_scadenza_password,
|
|
355
331
|
U.STAREG AS stato_registrazione,
|
|
356
|
-
${(0, optionalColumns_1.optionalColumn)(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},
|
|
357
332
|
C.COGNOME AS cognome,
|
|
358
333
|
C.NOME AS nome,
|
|
359
334
|
C.AVATAR AS avatar,
|
|
@@ -363,8 +338,7 @@ let UserService = class UserService {
|
|
|
363
338
|
C.CELLULARE AS cellulare,
|
|
364
339
|
C.FLGSUPER AS flag_super,
|
|
365
340
|
C.FLGADMIN AS flag_admin,
|
|
366
|
-
COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled
|
|
367
|
-
C.PAGDEF AS pagina_default
|
|
341
|
+
COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled
|
|
368
342
|
FROM UTENTI U
|
|
369
343
|
INNER JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE
|
|
370
344
|
WHERE LOWER(U.USRNAME) = ?
|
|
@@ -448,11 +422,6 @@ let UserService = class UserService {
|
|
|
448
422
|
dbField: 'FLG2FATT',
|
|
449
423
|
transform: (v) => (v ? 1 : 0),
|
|
450
424
|
},
|
|
451
|
-
{
|
|
452
|
-
key: 'paginaDefault',
|
|
453
|
-
dbField: 'PAGDEF',
|
|
454
|
-
transform: (v) => String(v),
|
|
455
|
-
},
|
|
456
425
|
];
|
|
457
426
|
if (allowPrivilegedFields) {
|
|
458
427
|
optionalFields.push({
|
|
@@ -543,10 +512,6 @@ let UserService = class UserService {
|
|
|
543
512
|
utentiUpdates.push('flggdpr = ?');
|
|
544
513
|
utentiParams.push(user.flagGdpr);
|
|
545
514
|
}
|
|
546
|
-
if (allowPrivilegedChanges && user.enableIa !== undefined) {
|
|
547
|
-
utentiUpdates.push('enableia = ?');
|
|
548
|
-
utentiParams.push(user.enableIa ? 1 : 0);
|
|
549
|
-
}
|
|
550
515
|
if (allowPrivilegedChanges && user.statoRegistrazione !== undefined) {
|
|
551
516
|
utentiUpdates.push('stareg = ?');
|
|
552
517
|
utentiParams.push(user.statoRegistrazione);
|
|
@@ -598,10 +563,6 @@ let UserService = class UserService {
|
|
|
598
563
|
utentiConfigUpdates.push('flgpassword = ?');
|
|
599
564
|
utentiConfigParams.push(user.passwordLoginEnabled ? 1 : 0);
|
|
600
565
|
}
|
|
601
|
-
if (user.paginaDefault !== undefined) {
|
|
602
|
-
utentiConfigUpdates.push('pagdef = ?');
|
|
603
|
-
utentiConfigParams.push(user.paginaDefault);
|
|
604
|
-
}
|
|
605
566
|
if (user.jsonMetadata !== undefined) {
|
|
606
567
|
utentiConfigUpdates.push('json_metadata = ?');
|
|
607
568
|
utentiConfigParams.push(user.jsonMetadata);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/UserService/UserService.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, ConflictException, Inject, Injectable, NotFoundException } from '@nestjs/common';\nimport { getTableColumns, optionalColumn } from '../../database-updates/optionalColumns';\nimport { autobind } from '../../../autobind';\nimport { Orm } from '../../../Orm';\nimport { RestUtilities } from '../../../Utilities';\nimport type { AccessiOptions } from '../../AccessiModule';\nimport { FILTRI_UTENTE_DB_MAPPING, FiltriUtente } from '../../Dtos/FiltriUtente';\nimport { GetUsersResult } from '../../Dtos/GetUsersResponse';\nimport { RegisterRequest } from '../../Dtos/RegisterRequest';\nimport { StatoRegistrazione } from '../../Dtos/StatoRegistrazione';\nimport { UserDto } from '../../Dtos/UserDto';\nimport { UserGrantsDto } from '../../Dtos/UserGrantsDto';\nimport { AccessiAuthenticatedUserSnapshot } from '../../security/authenticatedToken';\nimport { assertEmailConfigured } from '../../security/emailConfiguration';\nimport { EmailService } from '../EmailService/EmailService';\nimport { FiltriService } from '../FiltriService/FiltriService';\nimport { PermissionService } from '../PermissionService/PermissionService';\n\ninterface OptionalField<T> {\n key: string;\n dbField: string;\n transform?: (value: unknown) => T;\n}\n\n@autobind\n@Injectable()\nexport class UserService {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly emailService: EmailService,\n private readonly permissionService: PermissionService,\n private readonly filtriService: FiltriService,\n ) {}\n\n private normalizeDatabaseBoolean(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n }\n\n private normalizeUserFlags(user: UserDto): UserDto {\n const normalized: UserDto = { ...user,\n flagSuper: this.normalizeDatabaseBoolean(user.flagSuper),\n flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin),\n flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori),\n passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled),\n passwordLoginEnabled: user.passwordLoginEnabled == null || this.normalizeDatabaseBoolean(user.passwordLoginEnabled),\n enableIa: this.normalizeDatabaseBoolean(user.enableIa),\n };\n\n return normalized;\n }\n\n private normalizeEmail(email: string): string {\n if (typeof email !== 'string' || email.trim() === '') {\n throw new BadRequestException({ code: 'ACCESSI_EMAIL_REQUIRED', message: \"L'email è obbligatoria.\" });\n }\n\n return email.trim().toLowerCase();\n }\n\n private async ensureEmailIsAvailable(email: string, currentUserCode?: number): Promise<void> {\n const result = await Orm.query(\n this.accessiOptions.databaseOptions,\n 'SELECT FIRST 1 CODUTE as codice_utente FROM UTENTI WHERE LOWER(USRNAME) = ?',\n [email],\n );\n\n const existingUser = result.map(RestUtilities.convertKeysToCamelCase)[0] as\n | { codiceUtente?: number }\n | undefined;\n\n if (\n existingUser?.codiceUtente &&\n (!currentUserCode || existingUser.codiceUtente !== currentUserCode)\n ) {\n throw new ConflictException({ code: 'ACCESSI_EMAIL_ALREADY_EXISTS', message: \"L'email è già associata a un utente Accessi.\" });\n }\n }\n\n /** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMIN`). */\n async isAdminConfigurator(codiceUtente: number): Promise<boolean> {\n if (!codiceUtente) {\n return false;\n }\n\n const query = `SELECT FLGADMIN AS flag_admin FROM UTENTI_CONFIG WHERE CODUTE = ?`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n\n if (result.length === 0) {\n return false;\n }\n\n const mapped = result.map(RestUtilities.convertKeysToCamelCase);\n return this.normalizeDatabaseBoolean(mapped[0]?.flagAdmin);\n }\n\n /**\n * Legge il minimo profilo autorevole usato da JWT e middleware. Restituisce `null` per utenti inesistenti.\n * Non usare `UserDto` dal token per decisioni di sicurezza: i flag vengono sempre riletti qui.\n */\n async getAuthenticatedUserSnapshot(\n codiceUtente: number,\n ): Promise<AccessiAuthenticatedUserSnapshot | null> {\n if (!codiceUtente || codiceUtente <= 0) {\n return null;\n }\n\n const result = await Orm.query(\n this.accessiOptions.databaseOptions,\n `\n SELECT\n U.CODUTE AS codice_utente,\n U.USRNAME AS email,\n U.STAREG AS stato_registrazione,\n C.FLGSUPER AS flag_super,\n C.FLGADMIN AS flag_admin\n , C.FLG2FATT AS flag_due_fattori\n , C.FLGPWDLESS AS passwordless_login_enabled\n , COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled\n FROM UTENTI U\n LEFT JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE\n WHERE U.CODUTE = ?\n `,\n [codiceUtente],\n );\n\n const user = result.map(RestUtilities.convertKeysToCamelCase)[0] as\n | {\n codiceUtente?: number;\n email?: string;\n statoRegistrazione?: StatoRegistrazione | number;\n flagSuper?: unknown;\n flagAdmin?: unknown;\n flagDueFattori?: unknown;\n passwordlessLoginEnabled?: unknown;\n passwordLoginEnabled?: unknown;\n }\n | undefined;\n\n if (!user?.codiceUtente) {\n return null;\n }\n\n return {\n codiceUtente: Number(user.codiceUtente),\n email: typeof user.email === 'string' ? user.email : undefined,\n statoRegistrazione: Number(user.statoRegistrazione) as StatoRegistrazione,\n flagSuper: this.normalizeDatabaseBoolean(user.flagSuper),\n flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin),\n flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori),\n passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled),\n passwordLoginEnabled: this.normalizeDatabaseBoolean(user.passwordLoginEnabled),\n };\n }\n\n /**\n * Elenca gli utenti con filtri opzionali. Grant e campi estesi sono costosi e vengono caricati soltanto\n * quando richiesti esplicitamente nelle opzioni; usare filtri puntuali nei flussi di autenticazione.\n */\n async getUsers(\n filters?: {\n email?: string;\n codiceUtente?: number | number[];\n numRep?: number | number[];\n codDipendente?: number;\n cellulare?: string;\n cellute?: string;\n tipFil?: number;\n flagSuper?: boolean;\n limit?: number;\n offset?: number;\n },\n options?: { includeExtensionFields: boolean; includeGrants: boolean },\n ): Promise<GetUsersResult[]> {\n try {\n const filterColumns = await getTableColumns(this.accessiOptions, 'FILTRI');\n const utentiColumns = await getTableColumns(this.accessiOptions, 'UTENTI');\n\n // Paginazione opzionale con limiti sani: il default resta \"tutti gli utenti\".\n const limit = Number.isInteger(filters?.limit) && (filters?.limit ?? 0) > 0\n ? Math.min(filters?.limit as number, 1000)\n : undefined;\n const offset = Number.isInteger(filters?.offset) && (filters?.offset ?? 0) > 0\n ? Math.trunc(filters?.offset as number)\n : 0;\n const pagination = `${limit !== undefined ? ` FIRST ${limit}` : ''}${offset > 0 ? ` SKIP ${offset}` : ''}`;\n\n let query = ` \n SELECT${pagination} \n U.CODUTE as codice_utente, \n U.USRNAME as email, \n U.FLGGDPR as flag_gdpr, \n U.DATGDPR as data_gdpr, \n U.DATINS as data_inserimento, \n U.DATSCAPWD as data_scadenza_password, \n U.DATLASTLOGIN as data_last_login, \n U.STAREG as stato_registrazione, \n ${optionalColumn(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},\n G.COGNOME as cognome, \n G.NOME as nome, \n G.AVATAR as avatar, \n G.FLG2FATT as flag_due_fattori,\n G.FLGPWDLESS as passwordless_login_enabled,\n G.CODLINGUA as codice_lingua,\n G.CELLULARE as cellulare,\n G.FLGSUPER as flag_super, \n G.FLGADMIN as flag_admin,\n COALESCE(G.FLGPASSWORD, 1) as password_login_enabled,\n G.PAGDEF as pagina_default,\n G.JSON_METADATA as json_metadata,\n ${optionalColumn(filterColumns, 'CODDIP', 'F', 'cod_dipendente')},\n ${optionalColumn(filterColumns, 'NUMREP', 'F', 'num_rep', true)},\n ${optionalColumn(filterColumns, 'IDXPERS', 'F', 'idx_pers', true)},\n ${optionalColumn(filterColumns, 'CODCLISUPER', 'F', 'cod_cli_super', true)},\n ${optionalColumn(filterColumns, 'CODAGE', 'F', 'cod_age', true)},\n ${optionalColumn(filterColumns, 'CODCLICOL', 'F', 'cod_cli_col', true)},\n ${optionalColumn(filterColumns, 'CODCLIENTI', 'F', 'cod_clienti', false)},\n F.TIPFIL AS tip_fil,\n ${optionalColumn(filterColumns, 'IDXPOS', 'F', 'idx_postazione', true)}\n FROM UTENTI U \n INNER JOIN UTENTI_CONFIG G ON U.CODUTE = G.CODUTE\n LEFT JOIN FILTRI F ON F.CODUTE = U.CODUTE\n WHERE 1=1\n `;\n\n const queryParams: unknown[] = [];\n\n if (filters?.email) {\n query += ` AND LOWER(U.USRNAME) = ? `;\n queryParams.push(filters.email.trim().toLowerCase());\n }\n\n if (filters?.codiceUtente !== undefined) {\n const codes = (Array.isArray(filters.codiceUtente) ? filters.codiceUtente : [filters.codiceUtente])\n .map((value) => Number(value))\n .filter((value) => Number.isFinite(value) && value > 0);\n if (codes.length === 0) {\n return [];\n }\n query += ` AND U.CODUTE IN (${codes.map(() => '?').join(', ')}) `;\n queryParams.push(...codes);\n }\n\n if (filters?.numRep !== undefined) {\n const reparti = (Array.isArray(filters.numRep) ? filters.numRep : [filters.numRep])\n .map((value) => Number(value))\n .filter((value) => Number.isFinite(value));\n if (reparti.length === 0) {\n return [];\n }\n query += ` AND F.NUMREP IN (${reparti.map(() => '?').join(', ')}) `;\n queryParams.push(...reparti);\n }\n\n if (filters?.codDipendente !== undefined) {\n query += ` AND F.CODDIP = ? `;\n queryParams.push(Number(filters.codDipendente));\n }\n\n if (filters?.tipFil !== undefined) {\n query += ` AND F.TIPFIL = ? `;\n queryParams.push(Number(filters.tipFil));\n }\n\n if (filters?.cellulare) {\n query += ` AND TRIM(G.CELLULARE) = ? `;\n queryParams.push(String(filters.cellulare).trim());\n }\n\n if (filters?.cellute) {\n query += ` AND TRIM(U.CELLUTE) = ? `;\n queryParams.push(String(filters.cellute).trim());\n }\n\n if (filters?.flagSuper !== undefined) {\n query += filters.flagSuper ? ` AND COALESCE(G.FLGSUPER, 0) <> 0 ` : ` AND COALESCE(G.FLGSUPER, 0) = 0 `;\n }\n\n query += ` ORDER BY U.CODUTE DESC `;\n\n let users = (await Orm.query(\n this.accessiOptions.databaseOptions,\n query,\n queryParams,\n )) as UserDto[];\n users = users.map(RestUtilities.convertKeysToCamelCase).map(user => this.normalizeUserFlags(user as unknown as UserDto));\n\n const usersResponse: GetUsersResult[] = [];\n\n // I campi estensione sono caricati una volta per tabella (non una per utente) in query IN\n // suddivise in blocchi per non superare i limiti di parametri del driver.\n const extensionFieldsByUser = options?.includeExtensionFields\n ? await this.loadExtensionFieldsForUsers(users.map((user) => user.codiceUtente))\n : undefined;\n\n // I grant sono caricati in batch (query IN) invece che utente per utente.\n const grantsByUser = options?.includeGrants\n ? await this.permissionService.getUsersRolesAndGrants(users.map((user) => user.codiceUtente))\n : undefined;\n\n for (const user of users) {\n let userGrants: UserGrantsDto | undefined;\n\n if (options?.includeGrants) {\n userGrants = grantsByUser?.get(user.codiceUtente);\n }\n\n let extensionFields: Record<string, unknown[]> | undefined;\n\n if (options?.includeExtensionFields) {\n extensionFields = {};\n for (const ext of this.accessiOptions.extensionFieldsOptions ?? []) {\n extensionFields[ext.objectKey] = extensionFieldsByUser?.get(ext.objectKey)?.get(user.codiceUtente) ?? [];\n }\n }\n\n usersResponse.push({\n utente: user,\n userGrants,\n extensionFields,\n });\n }\n\n return usersResponse;\n } catch (error) {\n throw error;\n }\n }\n\n /** Conteggio utenti con gli stessi filtri di `getUsers`, per la paginazione (header X-Total-Count). */\n async countUsers(filters?: { email?: string; codiceUtente?: number }): Promise<number> {\n const conditions: string[] = [];\n const params: unknown[] = [];\n if (filters?.email) {\n conditions.push('LOWER(U.USRNAME) = ?');\n params.push(filters.email.trim().toLowerCase());\n }\n if (filters?.codiceUtente) {\n conditions.push('U.CODUTE = ?');\n params.push(filters.codiceUtente);\n }\n\n const query = `SELECT COUNT(*) AS TOTAL FROM UTENTI U INNER JOIN UTENTI_CONFIG G ON U.CODUTE = G.CODUTE WHERE 1=1 ${conditions.map((condition) => `AND ${condition}`).join(' ')}`;\n const rows = (await Orm.query(this.accessiOptions.databaseOptions, query, params, false)) as Array<Record<string, unknown>>;\n const row = rows[0];\n return Number(row?.TOTAL ?? row?.total ?? 0) || 0;\n }\n\n private async loadExtensionFieldsForUsers(\n codiceUtenti: number[],\n ): Promise<Map<string, Map<number, Record<string, unknown>[]>>> {\n const byObjectKey = new Map<string, Map<number, Record<string, unknown>[]>>();\n const extensions = this.accessiOptions.extensionFieldsOptions ?? [];\n const uniqueCodes = Array.from(new Set(codiceUtenti));\n\n for (const ext of extensions) {\n const grouped = new Map<number, Record<string, unknown>[]>();\n\n for (const chunk of this.chunkArray(uniqueCodes, 500)) {\n if (chunk.length === 0) {\n continue;\n }\n\n const placeholders = chunk.map(() => '?').join(', ');\n const rows = (await Orm.query(\n ext.databaseOptions,\n `SELECT ${ext.tableJoinFieldName} AS __joinkey, ${ext.tableFields.join(', ')} FROM ${ext.tableName} WHERE ${ext.tableJoinFieldName} IN (${placeholders})`,\n chunk,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n for (const row of rows) {\n const { __joinkey, ...rest } = row;\n const key = Number(__joinkey);\n if (!Number.isFinite(key)) {\n continue;\n }\n\n const bucket = grouped.get(key);\n if (bucket) {\n bucket.push(rest);\n } else {\n grouped.set(key, [rest]);\n }\n }\n }\n\n byObjectKey.set(ext.objectKey, grouped);\n }\n\n return byObjectKey;\n }\n\n private chunkArray<T>(items: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let index = 0; index < items.length; index += size) {\n chunks.push(items.slice(index, index + size));\n }\n return chunks;\n }\n\n /** Cerca il codice interno per email normalizzata. Il chiamante deve gestire il caso senza righe. */\n async getCodiceUtenteByEmail(email: string): Promise<{ codiceUtente: number }> {\n try {\n const query = `SELECT CODUTE as codice_utente FROM UTENTI WHERE LOWER(USRNAME) = ?`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, [\n email.trim().toLowerCase(),\n ]);\n return result.map(RestUtilities.convertKeysToCamelCase)[0] as { codiceUtente: number };\n } catch (error) {\n throw error;\n }\n }\n\n /** Recupera il profilo locale usato dal login, compresi filtri Accessi eventualmente presenti. */\n async getUserByEmail(email: string): Promise<UserDto | null> {\n const utentiColumns = await getTableColumns(this.accessiOptions, 'UTENTI');\n const query = `\n SELECT \n U.CODUTE AS codice_utente, \n U.USRNAME AS email, \n U.FLGGDPR AS flag_gdpr,\n U.DATSCAPWD as data_scadenza_password,\n U.STAREG AS stato_registrazione, \n ${optionalColumn(utentiColumns, 'ENABLEIA', 'U', 'enable_ia')},\n C.COGNOME AS cognome, \n C.NOME AS nome, \n C.AVATAR AS avatar, \n C.FLG2FATT AS flag_due_fattori,\n C.FLGPWDLESS AS passwordless_login_enabled,\n C.CODLINGUA AS codice_lingua, \n C.CELLULARE AS cellulare, \n C.FLGSUPER AS flag_super,\n C.FLGADMIN AS flag_admin,\n COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled,\n C.PAGDEF AS pagina_default\n FROM UTENTI U\n INNER JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE\n WHERE LOWER(U.USRNAME) = ?\n `;\n\n const utenti = (await Orm.query(this.accessiOptions.databaseOptions, query, [email]).then(\n (results) => results.map(RestUtilities.convertKeysToCamelCase),\n )) as UserDto[];\n\n const user = utenti[0];\n if (!user) return null;\n\n const filtro = (await this.filtriService.getFiltriUser(user.codiceUtente))[0];\n if (filtro) {\n const filterValues: Record<string, unknown> = {};\n\n Object.entries(FILTRI_UTENTE_DB_MAPPING).forEach(([key]) => {\n if (key in filtro) {\n filterValues[key] = filtro[key as keyof FiltriUtente];\n }\n });\n\n Object.assign(user, filterValues);\n }\n\n return this.normalizeUserFlags(user);\n }\n\n async insertUserFilters(codiceUtente: number, filterData: RegisterRequest): Promise<void> {\n await this.filtriService.upsertFiltriUtente(codiceUtente, filterData);\n }\n\n /**\n * Crea utente, configurazione e filtri. La registrazione pubblica resta in stato `INVIO` e non puo\n * impostare privilegi, ruoli o grant; soltanto flussi backend fidati possono usare `allowPrivilegedFields`.\n */\n async register(\n registrationData: RegisterRequest,\n options?: { allowPrivilegedFields?: boolean; initialState?: StatoRegistrazione },\n ): Promise<number> {\n try {\n const allowPrivilegedFields = options?.allowPrivilegedFields === true;\n const normalizedEmail = this.normalizeEmail(registrationData.email);\n\n if (registrationData.flagDueFattori !== undefined && typeof registrationData.flagDueFattori !== 'boolean') {\n throw new BadRequestException('Il flag due fattori deve essere booleano.');\n }\n if (registrationData.flagDueFattori && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(normalizedEmail)) {\n throw new BadRequestException('Per attivare i codici di accesso serve un indirizzo email valido.');\n }\n\n if (\n !allowPrivilegedFields &&\n (registrationData.flagSuper !== undefined ||\n registrationData.flagAdmin !== undefined ||\n registrationData.flagDueFattori !== undefined ||\n registrationData.roles !== undefined ||\n registrationData.permissions !== undefined)\n ) {\n throw new Error('I campi privilegiati non sono consentiti nella registrazione pubblica.');\n }\n\n await this.ensureEmailIsAvailable(normalizedEmail);\n\n const queryUtenti = `INSERT INTO UTENTI (USRNAME, STAREG) VALUES (?,?) RETURNING CODUTE`;\n // Public/local registrations keep the historic INVIO state; trusted master or SSO flows may opt into CONF.\n const paramsUtenti = [normalizedEmail, options?.initialState ?? StatoRegistrazione.INVIO];\n\n // Utente e configurazione sono creati in un'unica transazione; filtri e assegnazioni restano\n // fuori perché delegati a servizi dedicati.\n const codiceUtente = await Orm.withTransaction(\n this.accessiOptions.databaseOptions,\n async (transaction) => {\n const insertedUsers = await Orm.transactionQuery<unknown>(\n transaction,\n queryUtenti,\n paramsUtenti,\n );\n\n const insertedUser = (Array.isArray(insertedUsers) ? insertedUsers[0] : insertedUsers) as Record<string, unknown> | undefined;\n const newCodiceUtente = Number(\n insertedUser?.CODUTE ?? insertedUser?.codute,\n );\n if (!newCodiceUtente) {\n throw new Error('Creazione utente non riuscita: impossibile recuperare CODUTE.');\n }\n\n const utentiConfigFields = ['CODUTE', 'COGNOME', 'NOME'];\n const utentiConfigPlaceholders = ['?', '?', '?'];\n const utentiConfigParams: unknown[] = [newCodiceUtente, registrationData.cognome, registrationData.nome];\n\n const optionalFields: OptionalField<unknown>[] = [\n {\n key: 'cellulare',\n dbField: 'CELLULARE',\n transform: (v) => String(v),\n },\n {\n key: 'avatar',\n dbField: 'AVATAR',\n transform: (v) => String(v),\n },\n {\n key: 'flagDueFattori',\n dbField: 'FLG2FATT',\n transform: (v) => (v ? 1 : 0),\n },\n {\n key: 'paginaDefault',\n dbField: 'PAGDEF',\n transform: (v) => String(v),\n },\n ];\n\n if (allowPrivilegedFields) {\n optionalFields.push(\n {\n key: 'flagSuper',\n dbField: 'FLGSUPER',\n transform: (v) => (v ? 1 : 0),\n },\n {\n key: 'flagAdmin',\n dbField: 'FLGADMIN',\n transform: (v) => (v ? 1 : 0),\n },\n );\n }\n\n for (const field of optionalFields) {\n const value = (registrationData as unknown as Record<string, unknown>)[field.key];\n if (value !== undefined && value !== null) {\n utentiConfigFields.push(field.dbField);\n utentiConfigPlaceholders.push('?');\n utentiConfigParams.push(field.transform ? field.transform(value) : value);\n }\n }\n\n const queryUtentiConfig = `INSERT INTO UTENTI_CONFIG (${utentiConfigFields.join(\n ', ',\n )}) VALUES (${utentiConfigPlaceholders.join(', ')})`;\n await Orm.transactionQuery(transaction, queryUtentiConfig, utentiConfigParams);\n\n return newCodiceUtente;\n },\n );\n\n await this.filtriService.upsertFiltriUtente(codiceUtente, registrationData);\n\n if (allowPrivilegedFields && !!registrationData.roles && registrationData.roles.length > 0) {\n await this.permissionService.assignRolesToUser(codiceUtente, registrationData.roles);\n }\n\n if (\n allowPrivilegedFields &&\n !!registrationData.permissions &&\n registrationData.permissions.length > 0\n ) {\n await this.permissionService.assignPermissionsToUser(\n codiceUtente,\n registrationData.permissions,\n );\n }\n\n return codiceUtente;\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Aggiorna il profilo utente e i filtri. Le modifiche a stato, ruoli, grant e flag amministrativi richiedono\n * `allowPrivilegedChanges`; gli array ruolo/grant passati in un flusso fidato sostituiscono le assegnazioni.\n */\n async updateUser(\n codiceUtente: number,\n user: UserDto,\n options?: { allowPrivilegedChanges?: boolean },\n ): Promise<void> {\n try {\n if (!codiceUtente) throw new Error('Impossibile aggiornare senza codice utente.');\n const allowPrivilegedChanges = options?.allowPrivilegedChanges === true;\n\n for (const value of [user.flagDueFattori, user.passwordlessLoginEnabled]) {\n if (value !== undefined && typeof value !== 'boolean') throw new BadRequestException('Le policy di autenticazione devono essere booleane.');\n }\n\n if (\n !allowPrivilegedChanges &&\n (user.statoRegistrazione !== undefined ||\n user.flagSuper !== undefined ||\n user.flagAdmin !== undefined ||\n user.passwordLoginEnabled !== undefined ||\n user.passwordlessLoginEnabled !== undefined ||\n user.flagDueFattori !== undefined ||\n user.roles !== undefined ||\n user.permissions !== undefined)\n ) {\n throw new Error('Non e consentito modificare campi privilegiati.');\n }\n\n if (user.flagDueFattori !== undefined || user.passwordlessLoginEnabled !== undefined || user.email !== undefined) {\n const current = await this.getAuthenticatedUserSnapshot(codiceUtente);\n if (!current) throw new BadRequestException('Utente non trovato.');\n const twoFactor = user.flagDueFattori ?? current.flagDueFattori;\n const passwordless = user.passwordlessLoginEnabled ?? current.passwordlessLoginEnabled;\n if (passwordless && !twoFactor) throw new BadRequestException('Il login senza password richiede il codice di accesso attivo.');\n if (twoFactor && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test((user.email ?? current.email ?? '').trim())) {\n throw new BadRequestException('Per attivare i codici di accesso serve un indirizzo email valido.');\n }\n }\n\n const utentiUpdates = [];\n const utentiParams = [];\n\n if (user.email !== undefined) {\n const normalizedEmail = this.normalizeEmail(user.email);\n await this.ensureEmailIsAvailable(normalizedEmail, codiceUtente);\n utentiUpdates.push('usrname = ?');\n utentiParams.push(normalizedEmail);\n }\n if (user.flagGdpr !== undefined) {\n utentiUpdates.push('flggdpr = ?');\n utentiParams.push(user.flagGdpr);\n }\n if (allowPrivilegedChanges && user.enableIa !== undefined) {\n utentiUpdates.push('enableia = ?');\n utentiParams.push(user.enableIa ? 1 : 0);\n }\n if (allowPrivilegedChanges && user.statoRegistrazione !== undefined) {\n utentiUpdates.push('stareg = ?');\n utentiParams.push(user.statoRegistrazione);\n }\n\n if (utentiUpdates.length > 0) {\n const queryUtenti = `UPDATE UTENTI SET ${utentiUpdates.join(', ')} WHERE CODUTE = ?`;\n utentiParams.push(codiceUtente);\n await Orm.execute(this.accessiOptions.databaseOptions, queryUtenti, utentiParams);\n }\n\n const utentiConfigUpdates = [];\n const utentiConfigParams = [];\n\n if (user.cognome !== undefined) {\n utentiConfigUpdates.push('cognome = ?');\n utentiConfigParams.push(user.cognome);\n }\n if (user.nome !== undefined) {\n utentiConfigUpdates.push('nome = ?');\n utentiConfigParams.push(user.nome);\n }\n if (user.avatar !== undefined) {\n utentiConfigUpdates.push('avatar = ?');\n utentiConfigParams.push(user.avatar);\n }\n if (user.flagDueFattori !== undefined) {\n utentiConfigUpdates.push('flg2fatt = ?');\n utentiConfigParams.push(user.flagDueFattori ? 1 : 0);\n }\n if (user.passwordlessLoginEnabled !== undefined) {\n utentiConfigUpdates.push('flgpwdless = ?');\n utentiConfigParams.push(user.passwordlessLoginEnabled ? 1 : 0);\n }\n if (user.codiceLingua !== undefined) {\n utentiConfigUpdates.push('codlingua = ?');\n utentiConfigParams.push(user.codiceLingua);\n }\n if (user.cellulare !== undefined) {\n utentiConfigUpdates.push('cellulare = ?');\n utentiConfigParams.push(user.cellulare);\n }\n if (allowPrivilegedChanges && user.flagSuper !== undefined) {\n utentiConfigUpdates.push('flgsuper = ?');\n utentiConfigParams.push(user.flagSuper);\n }\n if (allowPrivilegedChanges && user.flagAdmin !== undefined) {\n utentiConfigUpdates.push('FLGADMIN = ?');\n utentiConfigParams.push(user.flagAdmin);\n }\n if (allowPrivilegedChanges && user.passwordLoginEnabled !== undefined) {\n utentiConfigUpdates.push('flgpassword = ?');\n utentiConfigParams.push(user.passwordLoginEnabled ? 1 : 0);\n }\n if (user.paginaDefault !== undefined) {\n utentiConfigUpdates.push('pagdef = ?');\n utentiConfigParams.push(user.paginaDefault);\n }\n if (user.jsonMetadata !== undefined) {\n utentiConfigUpdates.push('json_metadata = ?');\n utentiConfigParams.push(user.jsonMetadata);\n }\n\n if (utentiConfigUpdates.length > 0) {\n const queryUtentiConfig = `UPDATE UTENTI_CONFIG SET ${utentiConfigUpdates.join(\n ', ',\n )} WHERE CODUTE = ?`;\n utentiConfigParams.push(codiceUtente);\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n queryUtentiConfig,\n utentiConfigParams,\n );\n }\n\n if (allowPrivilegedChanges && Array.isArray(user.roles)) {\n await this.permissionService.assignRolesToUser(codiceUtente, user.roles);\n }\n\n if (allowPrivilegedChanges && Array.isArray(user.permissions)) {\n await this.permissionService.assignPermissionsToUser(codiceUtente, user.permissions);\n }\n\n await this.filtriService.upsertFiltriUtente(codiceUtente, user);\n } catch (error) {\n throw error;\n }\n }\n\n async updateUserFilters(codiceUtente: number, user: UserDto): Promise<void> {\n await this.filtriService.upsertFiltriUtente(codiceUtente, user);\n }\n\n /** Eliminazione logica: imposta lo stato `DELETE` senza cancellare lo storico o i collegamenti SSO. */\n async deleteUser(codiceCliente: number): Promise<void> {\n try {\n const query = `UPDATE UTENTI SET STAREG = ? WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [\n StatoRegistrazione.DELETE,\n codiceCliente,\n ]);\n } catch (error) {\n throw error;\n }\n }\n\n /** Cambia esplicitamente lo stato di registrazione; usare questa API per blocco, conferma o eliminazione logica. */\n async setStato(codiceCliente: number, statoRegistrazione: StatoRegistrazione) {\n try {\n const query = `UPDATE UTENTI SET STAREG = ? WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [\n statoRegistrazione,\n codiceCliente,\n ]);\n } catch (error) {\n throw error;\n }\n }\n\n public async setGdpr(codiceUtente: number) {\n try {\n return await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: 'INSERT INTO UTENTI_GDPR (CODUTE, GDPR) VALUES (?, ?)', params: [codiceUtente, 'true'] },\n { query: 'UPDATE UTENTI SET FLGGDPR = 1, DATGDPR = CURRENT_DATE WHERE CODUTE = ?', params: [codiceUtente] },\n ]);\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Forza l'invio dell'email di reset password per un utente. Operazione amministrativa.\n * Richiede un servizio email configurato: altrimenti solleva ACCESSI_EMAIL_NOT_CONFIGURED.\n */\n public async forcePasswordReset(codiceUtente: number): Promise<void> {\n assertEmailConfigured(this.accessiOptions);\n const rows = await this.getUsers({ codiceUtente });\n const email = rows[0]?.utente?.email;\n if (typeof email !== 'string' || email.trim() === '') {\n throw new NotFoundException(`Nessun utente con email per il codice ${codiceUtente}.`);\n }\n await this.emailService.sendPasswordResetEmail(email);\n }\n\n /**\n * Forza l'invio dell'email di reset a tutti gli utenti la cui password non e ancora nel formato\n * moderno (`scrypt$...`), cioe' legacy grezza o `scrypt-legacy` non piu verificabile. Utile quando\n * la `encryptionKey` storica e perduta. Richiede email configurata. Ritorna quanti utenti hanno\n * ricevuto l'email.\n */\n public async forcePasswordResetForLegacyPasswords(): Promise<number> {\n assertEmailConfigured(this.accessiOptions);\n const rows = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT U.CODUTE AS codice_utente, U.USRNAME AS email\n FROM UTENTI U\n JOIN UTENTI_PWD P ON P.CODUTE = U.CODUTE\n WHERE P.PWD IS NOT NULL AND P.PWD NOT STARTING WITH 'scrypt$'`,\n [],\n false,\n );\n\n let sent = 0;\n for (const row of rows as Array<Record<string, unknown>>) {\n const raw = RestUtilities.convertKeysToCamelCase(row) as Record<string, unknown>;\n const email = typeof raw.email === 'string' ? raw.email.trim() : '';\n if (email === '') continue;\n await this.emailService.sendPasswordResetEmail(email);\n sent += 1;\n }\n return sent;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"UserService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/UserService/UserService.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, ConflictException, Inject, Injectable, NotFoundException } from '@nestjs/common';\nimport { getTableColumns, optionalColumn } from '../../database-updates/optionalColumns';\nimport { autobind } from '../../../autobind';\nimport { Orm } from '../../../Orm';\nimport { RestUtilities } from '../../../Utilities';\nimport type { AccessiOptions } from '../../AccessiModule';\nimport { FILTRI_UTENTE_DB_MAPPING, FiltriUtente } from '../../Dtos/FiltriUtente';\nimport { GetUsersResult } from '../../Dtos/GetUsersResponse';\nimport { RegisterRequest } from '../../Dtos/RegisterRequest';\nimport { StatoRegistrazione } from '../../Dtos/StatoRegistrazione';\nimport { UserDto } from '../../Dtos/UserDto';\nimport { UserGrantsDto } from '../../Dtos/UserGrantsDto';\nimport { AccessiAuthenticatedUserSnapshot } from '../../security/authenticatedToken';\nimport { assertEmailConfigured } from '../../security/emailConfiguration';\nimport { EmailService } from '../EmailService/EmailService';\nimport { FiltriService } from '../FiltriService/FiltriService';\nimport { PermissionService } from '../PermissionService/PermissionService';\n\ninterface OptionalField<T> {\n key: string;\n dbField: string;\n transform?: (value: unknown) => T;\n}\n\n@autobind\n@Injectable()\nexport class UserService {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly emailService: EmailService,\n private readonly permissionService: PermissionService,\n private readonly filtriService: FiltriService,\n ) {}\n\n private normalizeDatabaseBoolean(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n }\n\n private normalizeUserFlags(user: UserDto): UserDto {\n const normalized: UserDto = { ...user,\n flagSuper: this.normalizeDatabaseBoolean(user.flagSuper),\n flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin),\n flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori),\n passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled),\n passwordLoginEnabled: user.passwordLoginEnabled == null || this.normalizeDatabaseBoolean(user.passwordLoginEnabled),\n };\n\n return normalized;\n }\n\n private normalizeEmail(email: string): string {\n if (typeof email !== 'string' || email.trim() === '') {\n throw new BadRequestException({ code: 'ACCESSI_EMAIL_REQUIRED', message: \"L'email è obbligatoria.\" });\n }\n\n return email.trim().toLowerCase();\n }\n\n private async ensureEmailIsAvailable(email: string, currentUserCode?: number): Promise<void> {\n const result = await Orm.query(\n this.accessiOptions.databaseOptions,\n 'SELECT FIRST 1 CODUTE as codice_utente FROM UTENTI WHERE LOWER(USRNAME) = ?',\n [email],\n );\n\n const existingUser = result.map(RestUtilities.convertKeysToCamelCase)[0] as\n | { codiceUtente?: number }\n | undefined;\n\n if (\n existingUser?.codiceUtente &&\n (!currentUserCode || existingUser.codiceUtente !== currentUserCode)\n ) {\n throw new ConflictException({ code: 'ACCESSI_EMAIL_ALREADY_EXISTS', message: \"L'email è già associata a un utente Accessi.\" });\n }\n }\n\n /**\n * Legge il minimo profilo autorevole usato da JWT e middleware. Restituisce `null` per utenti inesistenti.\n * Non usare `UserDto` dal token per decisioni di sicurezza: i flag vengono sempre riletti qui.\n */\n async getAuthenticatedUserSnapshot(\n codiceUtente: number,\n ): Promise<AccessiAuthenticatedUserSnapshot | null> {\n if (!codiceUtente || codiceUtente <= 0) {\n return null;\n }\n\n const result = await Orm.query(\n this.accessiOptions.databaseOptions,\n `\n SELECT\n U.CODUTE AS codice_utente,\n U.USRNAME AS email,\n U.STAREG AS stato_registrazione,\n C.FLGSUPER AS flag_super,\n C.FLGADMIN AS flag_admin\n , C.FLG2FATT AS flag_due_fattori\n , C.FLGPWDLESS AS passwordless_login_enabled\n , COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled\n FROM UTENTI U\n LEFT JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE\n WHERE U.CODUTE = ?\n `,\n [codiceUtente],\n );\n\n const user = result.map(RestUtilities.convertKeysToCamelCase)[0] as\n | {\n codiceUtente?: number;\n email?: string;\n statoRegistrazione?: StatoRegistrazione | number;\n flagSuper?: unknown;\n flagAdmin?: unknown;\n flagDueFattori?: unknown;\n passwordlessLoginEnabled?: unknown;\n passwordLoginEnabled?: unknown;\n }\n | undefined;\n\n if (!user?.codiceUtente) {\n return null;\n }\n\n return {\n codiceUtente: Number(user.codiceUtente),\n email: typeof user.email === 'string' ? user.email : undefined,\n statoRegistrazione: Number(user.statoRegistrazione) as StatoRegistrazione,\n flagSuper: this.normalizeDatabaseBoolean(user.flagSuper),\n flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin),\n flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori),\n passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled),\n passwordLoginEnabled: this.normalizeDatabaseBoolean(user.passwordLoginEnabled),\n };\n }\n\n /**\n * Elenca gli utenti con filtri opzionali. Grant e campi estesi sono costosi e vengono caricati soltanto\n * quando richiesti esplicitamente nelle opzioni; usare filtri puntuali nei flussi di autenticazione.\n */\n async getUsers(\n filters?: {\n email?: string;\n codiceUtente?: number | number[];\n numRep?: number | number[];\n codDipendente?: number;\n cellulare?: string;\n tipFil?: number;\n flagSuper?: boolean;\n limit?: number;\n offset?: number;\n },\n options?: { includeExtensionFields: boolean; includeGrants: boolean },\n ): Promise<GetUsersResult[]> {\n try {\n const filterColumns = await getTableColumns(this.accessiOptions, 'FILTRI');\n\n // Paginazione opzionale con limiti sani: il default resta \"tutti gli utenti\".\n const limit = Number.isInteger(filters?.limit) && (filters?.limit ?? 0) > 0\n ? Math.min(filters?.limit as number, 1000)\n : undefined;\n const offset = Number.isInteger(filters?.offset) && (filters?.offset ?? 0) > 0\n ? Math.trunc(filters?.offset as number)\n : 0;\n const pagination = `${limit !== undefined ? ` FIRST ${limit}` : ''}${offset > 0 ? ` SKIP ${offset}` : ''}`;\n\n let query = ` \n SELECT${pagination} \n U.CODUTE as codice_utente, \n U.USRNAME as email, \n U.FLGGDPR as flag_gdpr, \n U.DATGDPR as data_gdpr, \n U.DATINS as data_inserimento, \n U.DATSCAPWD as data_scadenza_password, \n U.DATLASTLOGIN as data_last_login, \n U.STAREG as stato_registrazione, \n G.COGNOME as cognome, \n G.NOME as nome, \n G.AVATAR as avatar, \n G.FLG2FATT as flag_due_fattori,\n G.FLGPWDLESS as passwordless_login_enabled,\n G.CODLINGUA as codice_lingua,\n G.CELLULARE as cellulare,\n G.FLGSUPER as flag_super, \n G.FLGADMIN as flag_admin,\n COALESCE(G.FLGPASSWORD, 1) as password_login_enabled,\n G.JSON_METADATA as json_metadata,\n ${optionalColumn(filterColumns, 'CODDIP', 'F', 'cod_dipendente')},\n ${optionalColumn(filterColumns, 'NUMREP', 'F', 'num_rep', true)},\n ${optionalColumn(filterColumns, 'IDXPERS', 'F', 'idx_pers', true)},\n ${optionalColumn(filterColumns, 'CODCLISUPER', 'F', 'cod_cli_super', true)},\n ${optionalColumn(filterColumns, 'CODAGE', 'F', 'cod_age', true)},\n ${optionalColumn(filterColumns, 'CODCLICOL', 'F', 'cod_cli_col', true)},\n ${optionalColumn(filterColumns, 'CODCLIENTI', 'F', 'cod_clienti', false)},\n F.TIPFIL AS tip_fil,\n ${optionalColumn(filterColumns, 'IDXPOS', 'F', 'idx_postazione', true)}\n FROM UTENTI U \n INNER JOIN UTENTI_CONFIG G ON U.CODUTE = G.CODUTE\n LEFT JOIN FILTRI F ON F.CODUTE = U.CODUTE\n WHERE 1=1\n `;\n\n const queryParams: unknown[] = [];\n\n if (filters?.email) {\n query += ` AND LOWER(U.USRNAME) = ? `;\n queryParams.push(filters.email.trim().toLowerCase());\n }\n\n if (filters?.codiceUtente !== undefined) {\n const codes = (Array.isArray(filters.codiceUtente) ? filters.codiceUtente : [filters.codiceUtente])\n .map((value) => Number(value))\n .filter((value) => Number.isFinite(value) && value > 0);\n if (codes.length === 0) {\n return [];\n }\n query += ` AND U.CODUTE IN (${codes.map(() => '?').join(', ')}) `;\n queryParams.push(...codes);\n }\n\n if (filters?.numRep !== undefined) {\n const reparti = (Array.isArray(filters.numRep) ? filters.numRep : [filters.numRep])\n .map((value) => Number(value))\n .filter((value) => Number.isFinite(value));\n if (reparti.length === 0) {\n return [];\n }\n query += ` AND F.NUMREP IN (${reparti.map(() => '?').join(', ')}) `;\n queryParams.push(...reparti);\n }\n\n if (filters?.codDipendente !== undefined) {\n query += ` AND F.CODDIP = ? `;\n queryParams.push(Number(filters.codDipendente));\n }\n\n if (filters?.tipFil !== undefined) {\n query += ` AND F.TIPFIL = ? `;\n queryParams.push(Number(filters.tipFil));\n }\n\n if (filters?.cellulare) {\n query += ` AND TRIM(G.CELLULARE) = ? `;\n queryParams.push(String(filters.cellulare).trim());\n }\n\n if (filters?.flagSuper !== undefined) {\n query += filters.flagSuper ? ` AND COALESCE(G.FLGSUPER, 0) <> 0 ` : ` AND COALESCE(G.FLGSUPER, 0) = 0 `;\n }\n\n query += ` ORDER BY U.CODUTE DESC `;\n\n let users = (await Orm.query(\n this.accessiOptions.databaseOptions,\n query,\n queryParams,\n )) as UserDto[];\n users = users.map(RestUtilities.convertKeysToCamelCase).map(user => this.normalizeUserFlags(user as unknown as UserDto));\n\n const usersResponse: GetUsersResult[] = [];\n\n // I campi estensione sono caricati una volta per tabella (non una per utente) in query IN\n // suddivise in blocchi per non superare i limiti di parametri del driver.\n const extensionFieldsByUser = options?.includeExtensionFields\n ? await this.loadExtensionFieldsForUsers(users.map((user) => user.codiceUtente))\n : undefined;\n\n // I grant sono caricati in batch (query IN) invece che utente per utente.\n const grantsByUser = options?.includeGrants\n ? await this.permissionService.getUsersRolesAndGrants(users.map((user) => user.codiceUtente))\n : undefined;\n\n for (const user of users) {\n let userGrants: UserGrantsDto | undefined;\n\n if (options?.includeGrants) {\n userGrants = grantsByUser?.get(user.codiceUtente);\n }\n\n let extensionFields: Record<string, unknown[]> | undefined;\n\n if (options?.includeExtensionFields) {\n extensionFields = {};\n for (const ext of this.accessiOptions.extensionFieldsOptions ?? []) {\n extensionFields[ext.objectKey] = extensionFieldsByUser?.get(ext.objectKey)?.get(user.codiceUtente) ?? [];\n }\n }\n\n usersResponse.push({\n utente: user,\n userGrants,\n extensionFields,\n });\n }\n\n return usersResponse;\n } catch (error) {\n throw error;\n }\n }\n\n /** Conteggio utenti con gli stessi filtri di `getUsers`, per la paginazione (header X-Total-Count). */\n async countUsers(filters?: { email?: string; codiceUtente?: number }): Promise<number> {\n const conditions: string[] = [];\n const params: unknown[] = [];\n if (filters?.email) {\n conditions.push('LOWER(U.USRNAME) = ?');\n params.push(filters.email.trim().toLowerCase());\n }\n if (filters?.codiceUtente) {\n conditions.push('U.CODUTE = ?');\n params.push(filters.codiceUtente);\n }\n\n const query = `SELECT COUNT(*) AS TOTAL FROM UTENTI U INNER JOIN UTENTI_CONFIG G ON U.CODUTE = G.CODUTE WHERE 1=1 ${conditions.map((condition) => `AND ${condition}`).join(' ')}`;\n const rows = (await Orm.query(this.accessiOptions.databaseOptions, query, params, false)) as Array<Record<string, unknown>>;\n const row = rows[0];\n return Number(row?.TOTAL ?? row?.total ?? 0) || 0;\n }\n\n private async loadExtensionFieldsForUsers(\n codiceUtenti: number[],\n ): Promise<Map<string, Map<number, Record<string, unknown>[]>>> {\n const byObjectKey = new Map<string, Map<number, Record<string, unknown>[]>>();\n const extensions = this.accessiOptions.extensionFieldsOptions ?? [];\n const uniqueCodes = Array.from(new Set(codiceUtenti));\n\n for (const ext of extensions) {\n const grouped = new Map<number, Record<string, unknown>[]>();\n\n for (const chunk of this.chunkArray(uniqueCodes, 500)) {\n if (chunk.length === 0) {\n continue;\n }\n\n const placeholders = chunk.map(() => '?').join(', ');\n const rows = (await Orm.query(\n ext.databaseOptions,\n `SELECT ${ext.tableJoinFieldName} AS __joinkey, ${ext.tableFields.join(', ')} FROM ${ext.tableName} WHERE ${ext.tableJoinFieldName} IN (${placeholders})`,\n chunk,\n )).map(RestUtilities.convertKeysToCamelCase) as Array<Record<string, unknown>>;\n\n for (const row of rows) {\n const { __joinkey, ...rest } = row;\n const key = Number(__joinkey);\n if (!Number.isFinite(key)) {\n continue;\n }\n\n const bucket = grouped.get(key);\n if (bucket) {\n bucket.push(rest);\n } else {\n grouped.set(key, [rest]);\n }\n }\n }\n\n byObjectKey.set(ext.objectKey, grouped);\n }\n\n return byObjectKey;\n }\n\n private chunkArray<T>(items: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let index = 0; index < items.length; index += size) {\n chunks.push(items.slice(index, index + size));\n }\n return chunks;\n }\n\n /** Cerca il codice interno per email normalizzata. Il chiamante deve gestire il caso senza righe. */\n async getCodiceUtenteByEmail(email: string): Promise<{ codiceUtente: number }> {\n try {\n const query = `SELECT CODUTE as codice_utente FROM UTENTI WHERE LOWER(USRNAME) = ?`;\n const result = await Orm.query(this.accessiOptions.databaseOptions, query, [\n email.trim().toLowerCase(),\n ]);\n return result.map(RestUtilities.convertKeysToCamelCase)[0] as { codiceUtente: number };\n } catch (error) {\n throw error;\n }\n }\n\n /** Recupera il profilo locale usato dal login, compresi filtri Accessi eventualmente presenti. */\n async getUserByEmail(email: string): Promise<UserDto | null> {\n const query = `\n SELECT \n U.CODUTE AS codice_utente, \n U.USRNAME AS email, \n U.FLGGDPR AS flag_gdpr,\n U.DATSCAPWD as data_scadenza_password,\n U.STAREG AS stato_registrazione, \n C.COGNOME AS cognome, \n C.NOME AS nome, \n C.AVATAR AS avatar, \n C.FLG2FATT AS flag_due_fattori,\n C.FLGPWDLESS AS passwordless_login_enabled,\n C.CODLINGUA AS codice_lingua, \n C.CELLULARE AS cellulare, \n C.FLGSUPER AS flag_super,\n C.FLGADMIN AS flag_admin,\n COALESCE(C.FLGPASSWORD, 1) AS password_login_enabled\n FROM UTENTI U\n INNER JOIN UTENTI_CONFIG C ON C.CODUTE = U.CODUTE\n WHERE LOWER(U.USRNAME) = ?\n `;\n\n const utenti = (await Orm.query(this.accessiOptions.databaseOptions, query, [email]).then(\n (results) => results.map(RestUtilities.convertKeysToCamelCase),\n )) as UserDto[];\n\n const user = utenti[0];\n if (!user) return null;\n\n const filtro = (await this.filtriService.getFiltriUser(user.codiceUtente))[0];\n if (filtro) {\n const filterValues: Record<string, unknown> = {};\n\n Object.entries(FILTRI_UTENTE_DB_MAPPING).forEach(([key]) => {\n if (key in filtro) {\n filterValues[key] = filtro[key as keyof FiltriUtente];\n }\n });\n\n Object.assign(user, filterValues);\n }\n\n return this.normalizeUserFlags(user);\n }\n\n async insertUserFilters(codiceUtente: number, filterData: RegisterRequest): Promise<void> {\n await this.filtriService.upsertFiltriUtente(codiceUtente, filterData);\n }\n\n /**\n * Crea utente, configurazione e filtri. La registrazione pubblica resta in stato `INVIO` e non puo\n * impostare privilegi, ruoli o grant; soltanto flussi backend fidati possono usare `allowPrivilegedFields`.\n */\n async register(\n registrationData: RegisterRequest,\n options?: { allowPrivilegedFields?: boolean; initialState?: StatoRegistrazione },\n ): Promise<number> {\n try {\n const allowPrivilegedFields = options?.allowPrivilegedFields === true;\n const normalizedEmail = this.normalizeEmail(registrationData.email);\n\n if (registrationData.flagDueFattori !== undefined && typeof registrationData.flagDueFattori !== 'boolean') {\n throw new BadRequestException('Il flag due fattori deve essere booleano.');\n }\n if (registrationData.flagDueFattori && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(normalizedEmail)) {\n throw new BadRequestException('Per attivare i codici di accesso serve un indirizzo email valido.');\n }\n\n if (\n !allowPrivilegedFields &&\n (registrationData.flagSuper !== undefined ||\n registrationData.flagAdmin !== undefined ||\n registrationData.flagDueFattori !== undefined ||\n registrationData.roles !== undefined ||\n registrationData.permissions !== undefined)\n ) {\n throw new Error('I campi privilegiati non sono consentiti nella registrazione pubblica.');\n }\n\n await this.ensureEmailIsAvailable(normalizedEmail);\n\n const queryUtenti = `INSERT INTO UTENTI (USRNAME, STAREG) VALUES (?,?) RETURNING CODUTE`;\n // Public/local registrations keep the historic INVIO state; trusted master or SSO flows may opt into CONF.\n const paramsUtenti = [normalizedEmail, options?.initialState ?? StatoRegistrazione.INVIO];\n\n // Utente e configurazione sono creati in un'unica transazione; filtri e assegnazioni restano\n // fuori perché delegati a servizi dedicati.\n const codiceUtente = await Orm.withTransaction(\n this.accessiOptions.databaseOptions,\n async (transaction) => {\n const insertedUsers = await Orm.transactionQuery<unknown>(\n transaction,\n queryUtenti,\n paramsUtenti,\n );\n\n const insertedUser = (Array.isArray(insertedUsers) ? insertedUsers[0] : insertedUsers) as Record<string, unknown> | undefined;\n const newCodiceUtente = Number(\n insertedUser?.CODUTE ?? insertedUser?.codute,\n );\n if (!newCodiceUtente) {\n throw new Error('Creazione utente non riuscita: impossibile recuperare CODUTE.');\n }\n\n const utentiConfigFields = ['CODUTE', 'COGNOME', 'NOME'];\n const utentiConfigPlaceholders = ['?', '?', '?'];\n const utentiConfigParams: unknown[] = [newCodiceUtente, registrationData.cognome, registrationData.nome];\n\n const optionalFields: OptionalField<unknown>[] = [\n {\n key: 'cellulare',\n dbField: 'CELLULARE',\n transform: (v) => String(v),\n },\n {\n key: 'avatar',\n dbField: 'AVATAR',\n transform: (v) => String(v),\n },\n {\n key: 'flagDueFattori',\n dbField: 'FLG2FATT',\n transform: (v) => (v ? 1 : 0),\n },\n ];\n\n if (allowPrivilegedFields) {\n optionalFields.push(\n {\n key: 'flagSuper',\n dbField: 'FLGSUPER',\n transform: (v) => (v ? 1 : 0),\n },\n {\n key: 'flagAdmin',\n dbField: 'FLGADMIN',\n transform: (v) => (v ? 1 : 0),\n },\n );\n }\n\n for (const field of optionalFields) {\n const value = (registrationData as unknown as Record<string, unknown>)[field.key];\n if (value !== undefined && value !== null) {\n utentiConfigFields.push(field.dbField);\n utentiConfigPlaceholders.push('?');\n utentiConfigParams.push(field.transform ? field.transform(value) : value);\n }\n }\n\n const queryUtentiConfig = `INSERT INTO UTENTI_CONFIG (${utentiConfigFields.join(\n ', ',\n )}) VALUES (${utentiConfigPlaceholders.join(', ')})`;\n await Orm.transactionQuery(transaction, queryUtentiConfig, utentiConfigParams);\n\n return newCodiceUtente;\n },\n );\n\n await this.filtriService.upsertFiltriUtente(codiceUtente, registrationData);\n\n if (allowPrivilegedFields && !!registrationData.roles && registrationData.roles.length > 0) {\n await this.permissionService.assignRolesToUser(codiceUtente, registrationData.roles);\n }\n\n if (\n allowPrivilegedFields &&\n !!registrationData.permissions &&\n registrationData.permissions.length > 0\n ) {\n await this.permissionService.assignPermissionsToUser(\n codiceUtente,\n registrationData.permissions,\n );\n }\n\n return codiceUtente;\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Aggiorna il profilo utente e i filtri. Le modifiche a stato, ruoli, grant e flag amministrativi richiedono\n * `allowPrivilegedChanges`; gli array ruolo/grant passati in un flusso fidato sostituiscono le assegnazioni.\n */\n async updateUser(\n codiceUtente: number,\n user: UserDto,\n options?: { allowPrivilegedChanges?: boolean },\n ): Promise<void> {\n try {\n if (!codiceUtente) throw new Error('Impossibile aggiornare senza codice utente.');\n const allowPrivilegedChanges = options?.allowPrivilegedChanges === true;\n\n for (const value of [user.flagDueFattori, user.passwordlessLoginEnabled]) {\n if (value !== undefined && typeof value !== 'boolean') throw new BadRequestException('Le policy di autenticazione devono essere booleane.');\n }\n\n if (\n !allowPrivilegedChanges &&\n (user.statoRegistrazione !== undefined ||\n user.flagSuper !== undefined ||\n user.flagAdmin !== undefined ||\n user.passwordLoginEnabled !== undefined ||\n user.passwordlessLoginEnabled !== undefined ||\n user.flagDueFattori !== undefined ||\n user.roles !== undefined ||\n user.permissions !== undefined)\n ) {\n throw new Error('Non e consentito modificare campi privilegiati.');\n }\n\n if (user.flagDueFattori !== undefined || user.passwordlessLoginEnabled !== undefined || user.email !== undefined) {\n const current = await this.getAuthenticatedUserSnapshot(codiceUtente);\n if (!current) throw new BadRequestException('Utente non trovato.');\n const twoFactor = user.flagDueFattori ?? current.flagDueFattori;\n const passwordless = user.passwordlessLoginEnabled ?? current.passwordlessLoginEnabled;\n if (passwordless && !twoFactor) throw new BadRequestException('Il login senza password richiede il codice di accesso attivo.');\n if (twoFactor && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test((user.email ?? current.email ?? '').trim())) {\n throw new BadRequestException('Per attivare i codici di accesso serve un indirizzo email valido.');\n }\n }\n\n const utentiUpdates = [];\n const utentiParams = [];\n\n if (user.email !== undefined) {\n const normalizedEmail = this.normalizeEmail(user.email);\n await this.ensureEmailIsAvailable(normalizedEmail, codiceUtente);\n utentiUpdates.push('usrname = ?');\n utentiParams.push(normalizedEmail);\n }\n if (user.flagGdpr !== undefined) {\n utentiUpdates.push('flggdpr = ?');\n utentiParams.push(user.flagGdpr);\n }\n if (allowPrivilegedChanges && user.statoRegistrazione !== undefined) {\n utentiUpdates.push('stareg = ?');\n utentiParams.push(user.statoRegistrazione);\n }\n\n if (utentiUpdates.length > 0) {\n const queryUtenti = `UPDATE UTENTI SET ${utentiUpdates.join(', ')} WHERE CODUTE = ?`;\n utentiParams.push(codiceUtente);\n await Orm.execute(this.accessiOptions.databaseOptions, queryUtenti, utentiParams);\n }\n\n const utentiConfigUpdates = [];\n const utentiConfigParams = [];\n\n if (user.cognome !== undefined) {\n utentiConfigUpdates.push('cognome = ?');\n utentiConfigParams.push(user.cognome);\n }\n if (user.nome !== undefined) {\n utentiConfigUpdates.push('nome = ?');\n utentiConfigParams.push(user.nome);\n }\n if (user.avatar !== undefined) {\n utentiConfigUpdates.push('avatar = ?');\n utentiConfigParams.push(user.avatar);\n }\n if (user.flagDueFattori !== undefined) {\n utentiConfigUpdates.push('flg2fatt = ?');\n utentiConfigParams.push(user.flagDueFattori ? 1 : 0);\n }\n if (user.passwordlessLoginEnabled !== undefined) {\n utentiConfigUpdates.push('flgpwdless = ?');\n utentiConfigParams.push(user.passwordlessLoginEnabled ? 1 : 0);\n }\n if (user.codiceLingua !== undefined) {\n utentiConfigUpdates.push('codlingua = ?');\n utentiConfigParams.push(user.codiceLingua);\n }\n if (user.cellulare !== undefined) {\n utentiConfigUpdates.push('cellulare = ?');\n utentiConfigParams.push(user.cellulare);\n }\n if (allowPrivilegedChanges && user.flagSuper !== undefined) {\n utentiConfigUpdates.push('flgsuper = ?');\n utentiConfigParams.push(user.flagSuper);\n }\n if (allowPrivilegedChanges && user.flagAdmin !== undefined) {\n utentiConfigUpdates.push('FLGADMIN = ?');\n utentiConfigParams.push(user.flagAdmin);\n }\n if (allowPrivilegedChanges && user.passwordLoginEnabled !== undefined) {\n utentiConfigUpdates.push('flgpassword = ?');\n utentiConfigParams.push(user.passwordLoginEnabled ? 1 : 0);\n }\n if (user.jsonMetadata !== undefined) {\n utentiConfigUpdates.push('json_metadata = ?');\n utentiConfigParams.push(user.jsonMetadata);\n }\n\n if (utentiConfigUpdates.length > 0) {\n const queryUtentiConfig = `UPDATE UTENTI_CONFIG SET ${utentiConfigUpdates.join(\n ', ',\n )} WHERE CODUTE = ?`;\n utentiConfigParams.push(codiceUtente);\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n queryUtentiConfig,\n utentiConfigParams,\n );\n }\n\n if (allowPrivilegedChanges && Array.isArray(user.roles)) {\n await this.permissionService.assignRolesToUser(codiceUtente, user.roles);\n }\n\n if (allowPrivilegedChanges && Array.isArray(user.permissions)) {\n await this.permissionService.assignPermissionsToUser(codiceUtente, user.permissions);\n }\n\n await this.filtriService.upsertFiltriUtente(codiceUtente, user);\n } catch (error) {\n throw error;\n }\n }\n\n async updateUserFilters(codiceUtente: number, user: UserDto): Promise<void> {\n await this.filtriService.upsertFiltriUtente(codiceUtente, user);\n }\n\n /** Eliminazione logica: imposta lo stato `DELETE` senza cancellare lo storico o i collegamenti SSO. */\n async deleteUser(codiceCliente: number): Promise<void> {\n try {\n const query = `UPDATE UTENTI SET STAREG = ? WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [\n StatoRegistrazione.DELETE,\n codiceCliente,\n ]);\n } catch (error) {\n throw error;\n }\n }\n\n /** Cambia esplicitamente lo stato di registrazione; usare questa API per blocco, conferma o eliminazione logica. */\n async setStato(codiceCliente: number, statoRegistrazione: StatoRegistrazione) {\n try {\n const query = `UPDATE UTENTI SET STAREG = ? WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [\n statoRegistrazione,\n codiceCliente,\n ]);\n } catch (error) {\n throw error;\n }\n }\n\n public async setGdpr(codiceUtente: number) {\n try {\n return await Orm.executeMultiple(this.accessiOptions.databaseOptions, [\n { query: 'INSERT INTO UTENTI_GDPR (CODUTE, GDPR) VALUES (?, ?)', params: [codiceUtente, 'true'] },\n { query: 'UPDATE UTENTI SET FLGGDPR = 1, DATGDPR = CURRENT_DATE WHERE CODUTE = ?', params: [codiceUtente] },\n ]);\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Forza l'invio dell'email di reset password per un utente. Operazione amministrativa.\n * Richiede un servizio email configurato: altrimenti solleva ACCESSI_EMAIL_NOT_CONFIGURED.\n */\n public async forcePasswordReset(codiceUtente: number): Promise<void> {\n assertEmailConfigured(this.accessiOptions);\n const rows = await this.getUsers({ codiceUtente });\n const email = rows[0]?.utente?.email;\n if (typeof email !== 'string' || email.trim() === '') {\n throw new NotFoundException(`Nessun utente con email per il codice ${codiceUtente}.`);\n }\n await this.emailService.sendPasswordResetEmail(email);\n }\n\n /**\n * Forza l'invio dell'email di reset a tutti gli utenti la cui password non e ancora nel formato\n * moderno (`scrypt$...`), cioe' legacy grezza o `scrypt-legacy` non piu verificabile. Utile quando\n * la `encryptionKey` storica e perduta. Richiede email configurata. Ritorna quanti utenti hanno\n * ricevuto l'email.\n */\n public async forcePasswordResetForLegacyPasswords(): Promise<number> {\n assertEmailConfigured(this.accessiOptions);\n const rows = await Orm.query(\n this.accessiOptions.databaseOptions,\n `SELECT U.CODUTE AS codice_utente, U.USRNAME AS email\n FROM UTENTI U\n JOIN UTENTI_PWD P ON P.CODUTE = U.CODUTE\n WHERE P.PWD IS NOT NULL AND P.PWD NOT STARTING WITH 'scrypt$'`,\n [],\n false,\n );\n\n let sent = 0;\n for (const row of rows as Array<Record<string, unknown>>) {\n const raw = RestUtilities.convertKeysToCamelCase(row) as Record<string, unknown>;\n const email = typeof raw.email === 'string' ? raw.email.trim() : '';\n if (email === '') continue;\n await this.emailService.sendPasswordResetEmail(email);\n sent += 1;\n }\n return sent;\n }\n}\n"]}
|
|
@@ -437,6 +437,13 @@ let AccessiDatabaseUpdater = AccessiDatabaseUpdater_1 = class AccessiDatabaseUpd
|
|
|
437
437
|
yield this.execute(options, `UPDATE ${rename.table} SET ${rename.to} = ${rename.from} WHERE ${rename.to} IS NULL AND ${rename.from} IS NOT NULL`);
|
|
438
438
|
yield this.execute(options, `ALTER TABLE ${rename.table} DROP ${rename.from}`);
|
|
439
439
|
}
|
|
440
|
+
// Copie tra tabelle diverse (es. telefono legacy UTENTI.CELLUTE -> UTENTI_CONFIG.CELLULARE).
|
|
441
|
+
for (const copy of accessiSchema_1.accessiColumnCopies) {
|
|
442
|
+
const hasSource = columns.some(row => row.TABLE_NAME === copy.sourceTable && row.COLUMN_NAME === copy.sourceColumn);
|
|
443
|
+
if (!hasSource)
|
|
444
|
+
continue;
|
|
445
|
+
yield this.execute(options, `UPDATE ${copy.targetTable} SET ${copy.targetColumn} = (SELECT S.${copy.sourceColumn} FROM ${copy.sourceTable} S WHERE S.${copy.joinColumn} = ${copy.targetTable}.${copy.joinColumn}) WHERE ${copy.targetColumn} IS NULL AND EXISTS (SELECT 1 FROM ${copy.sourceTable} S WHERE S.${copy.joinColumn} = ${copy.targetTable}.${copy.joinColumn} AND S.${copy.sourceColumn} IS NOT NULL)`);
|
|
446
|
+
}
|
|
440
447
|
for (const [table, obsoleteColumns] of Object.entries(accessiSchema_1.accessiObsoleteColumns)) {
|
|
441
448
|
for (const column of obsoleteColumns) {
|
|
442
449
|
if (columns.some(row => row.TABLE_NAME === table && row.COLUMN_NAME === column)) {
|