emilsoftware-utilities 2.0.0-dev.33 → 2.0.0-dev.35
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/README.MD +14 -0
- package/dist/accessi-module/AccessiModule.d.ts +24 -0
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/console.css +10 -0
- package/dist/accessi-module/Console/console.js +133 -11
- 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/index.html +6 -0
- package/dist/accessi-module/Console/wiki.js +34 -3
- 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/Services/UserService/UserService.d.ts +0 -2
- package/dist/accessi-module/Services/UserService/UserService.js +0 -16
- package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
- package/dist/accessi-module/database-updates/AccessiCatalogMigrator.d.ts +64 -0
- package/dist/accessi-module/database-updates/AccessiCatalogMigrator.js +288 -0
- package/dist/accessi-module/database-updates/AccessiCatalogMigrator.js.map +1 -0
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.d.ts +6 -0
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +20 -1
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
- package/dist/accessi-module/database-updates/accessiOptionsFromEnv.d.ts +5 -0
- package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js +79 -0
- package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js.map +1 -0
- package/dist/accessi-module/database-updates/accessiSchema.d.ts +1 -1
- package/dist/accessi-module/database-updates/accessiSchema.js +10 -1
- package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -1
- package/dist/accessi-module/database-updates/runAccessiCatalogMigrations.d.ts +1 -0
- package/dist/accessi-module/database-updates/runAccessiCatalogMigrations.js +57 -0
- package/dist/accessi-module/database-updates/runAccessiCatalogMigrations.js.map +1 -0
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js +2 -58
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.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/index.d.ts +3 -0
- package/dist/accessi-module/index.js +8 -1
- package/dist/accessi-module/index.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.35.tgz +0 -0
- package/package.json +6 -4
- package/dist/emilsoftware-utilities-2.0.0-dev.33.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserController.js","sourceRoot":"","sources":["../../../src/accessi-module/Controllers/UserController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Body,\n Controller,\n Delete,\n Get,\n HttpException,\n HttpStatus,\n Param,\n ParseBoolPipe,\n ParseIntPipe,\n Patch,\n Post,\n Put,\n Query,\n Inject,\n Req,\n Res,\n UseGuards,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport {\n ApiBearerAuth,\n ApiBody,\n ApiCreatedResponse,\n ApiOperation,\n ApiParam,\n ApiQuery,\n ApiResponse,\n ApiTags,\n} from '@nestjs/swagger';\nimport { join } from 'path';\nimport { Logger } from '../../Logger';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { ActionResponse, ErrorResponse } from '../Dtos/BaseResponse';\nimport { GetUsersResponse } from '../Dtos/GetUsersResponse';\nimport { PublicRegisterRequest } from '../Dtos/PublicRegisterRequest';\nimport { RegisterResponse } from '../Dtos/RegisterResponse';\nimport { RegisterRequest } from '../Dtos/RegisterRequest';\nimport { SetStatoRegistrazioneDto } from '../Dtos/SetStatoRegistrazione';\nimport { UserDto } from '../Dtos/UserDto';\nimport { EmailService } from '../Services/EmailService/EmailService';\nimport { UserService } from '../Services/UserService/UserService';\nimport { JwtSimpleGuard } from '../jwt/jwt.strategy';\nimport {\n checkPublicAuthRateLimit,\n sendPublicAuthRateLimitExceeded,\n} from '../security/publicAuthRateLimit';\nimport {\n ensureSelfOrSuperUser,\n ensureSuperUser,\n getAuthenticatedAccessiUser,\n hasPrivilegedUserChanges,\n} from '../security/accessControl';\n\n@ApiTags('User')\n@Controller('accessi/user')\n/**\n * Gestione utenti: la registrazione pubblica e opt-in, mentre creazione, stato e profili privilegiati\n * richiedono un superutente Accessi. Le API restituiscono sempre il wrapper `BaseResponse` storico.\n */\nexport class UserController {\n private readonly logger = new Logger(UserController.name);\n\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly userService: UserService,\n private readonly emailService: EmailService,\n ) {}\n\n private sendControllerError(res: Response, error: unknown) {\n // Lo status viene derivato centralmente da RestUtilities (HttpException o 500).\n return RestUtilities.sendErrorMessage(res, error, UserController.name);\n }\n\n @ApiOperation({\n summary: 'Serve la pagina di reset password',\n operationId: 'serveResetPasswordPageUser',\n })\n @ApiParam({\n name: 'token',\n description: 'Token per il reset della password',\n required: true,\n })\n @Get('reset-password/:token')\n async serveResetPasswordPage(@Res() res: Response, @Param('token') _token: string) {\n return res.sendFile(join(__dirname, '..', 'Views', 'reset-password.html'));\n }\n\n @ApiOperation({\n summary: 'Recupera la lista degli utenti',\n operationId: 'getUsers',\n })\n @ApiResponse({\n status: 200,\n description: 'Lista utenti recuperata con successo',\n type: GetUsersResponse,\n })\n @ApiResponse({ status: 401, description: 'Credenziali non valide', type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Operazione non autorizzata', type: ErrorResponse })\n @ApiResponse({ status: 500, description: 'Errore interno del server', type: ErrorResponse })\n @ApiQuery({\n name: 'email',\n required: false,\n description: \"Email dell'utente da cercare\",\n type: String,\n })\n @ApiQuery({\n name: 'codiceUtente',\n required: false,\n description: \"Codice dell'utente da cercare\",\n type: Number,\n })\n @ApiQuery({\n name: 'includeExtensionFields',\n required: false,\n description: 'Includi extension fields',\n type: Boolean,\n })\n @ApiQuery({\n name: 'includeGrants',\n required: false,\n description: 'Includi permessi',\n type: Boolean,\n })\n @ApiQuery({\n name: 'limit',\n required: false,\n description: 'Numero massimo di utenti restituiti (1-1000). Omesso = tutti.',\n type: Number,\n })\n @ApiQuery({\n name: 'offset',\n required: false,\n description: 'Numero di utenti da saltare (paginazione).',\n type: Number,\n })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Get('get-users')\n async getUsers(\n @Req() request: Request,\n @Res() res: Response,\n @Query('email') email?: string,\n @Query('codiceUtente', new ParseIntPipe({ optional: true })) codiceUtente?: number,\n @Query('includeExtensionFields', new ParseBoolPipe({ optional: true }))\n includeExtensionFields?: boolean,\n @Query('includeGrants', new ParseBoolPipe({ optional: true }))\n includeGrants?: boolean,\n @Query('limit', new ParseIntPipe({ optional: true })) limit?: number,\n @Query('offset', new ParseIntPipe({ optional: true })) offset?: number,\n ) {\n try {\n ensureSuperUser(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono consultare gli utenti.',\n );\n\n const filters = { email, codiceUtente, limit, offset };\n const options = {\n includeExtensionFields: includeExtensionFields ?? true,\n includeGrants: includeGrants ?? true,\n };\n\n const users = await this.userService.getUsers(filters, options);\n const total = await this.userService.countUsers({ email, codiceUtente });\n res.setHeader('X-Total-Count', String(total));\n return RestUtilities.sendBaseResponse(res, users);\n } catch (error) {\n this.logger.error('Errore durante il recupero degli utenti: ', error);\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Elimina un utente',\n operationId: 'deleteUser',\n description: 'Imposta lo stato di un utente a eliminato senza rimuovere i record.',\n })\n @ApiParam({\n name: 'codiceUtente',\n description: \"Codice identificativo dell'utente da eliminare\",\n required: true,\n example: 123,\n })\n @ApiResponse({ status: 200, description: 'Utente eliminato con successo', type: ActionResponse })\n @ApiResponse({\n status: 400,\n description: 'Errore nei parametri della richiesta',\n type: ErrorResponse,\n })\n @ApiResponse({ status: 500, description: 'Errore interno del server', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Delete('delete-user/:codiceUtente')\n async deleteUser(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Res() res: Response,\n ) {\n try {\n ensureSuperUser(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono eliminare utenti.',\n );\n\n await this.userService.deleteUser(codiceUtente);\n return RestUtilities.sendOKMessage(res, \"L'utente e' stato eliminato con successo.\");\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Forza l invio dell email di reset password a un utente',\n operationId: 'forcePasswordReset',\n description: 'Riservato al superutente. Richiede un servizio email configurato; altrimenti risponde con ACCESSI_EMAIL_NOT_CONFIGURED.',\n })\n @ApiParam({ name: 'codiceUtente', description: 'Codice identificativo dell utente', required: true, example: 123, type: Number })\n @ApiResponse({ status: 200, description: 'Email di reset inviata', type: ActionResponse })\n @ApiResponse({ status: 400, description: 'Servizio email non configurato', type: ErrorResponse })\n @ApiResponse({ status: 404, description: 'Utente non trovato', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('force-password-reset/:codiceUtente')\n async forcePasswordReset(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Res() res: Response,\n ) {\n try {\n ensureSuperUser(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono forzare il reset password.',\n );\n await this.userService.forcePasswordReset(codiceUtente);\n return RestUtilities.sendOKMessage(res, `Email di reset inviata all utente ${codiceUtente}.`);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Forza il reset password per tutti gli utenti con password legacy',\n operationId: 'forcePasswordResetLegacy',\n description: 'Riservato al superutente. Invia l email di reset a tutti gli utenti la cui password non e ancora nel formato moderno. Richiede un servizio email configurato.',\n })\n @ApiResponse({ status: 200, description: 'Email di reset inviate', type: ActionResponse })\n @ApiResponse({ status: 400, description: 'Servizio email non configurato', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('force-password-reset-legacy')\n async forcePasswordResetLegacy(@Req() request: Request, @Res() res: Response) {\n try {\n ensureSuperUser(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono forzare il reset password.',\n );\n const sent = await this.userService.forcePasswordResetForLegacyPasswords();\n return RestUtilities.sendOKMessage(res, `Email di reset inviata a ${sent} utenti con password legacy.`);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Imposta lo stato di registrazione di un utente',\n operationId: 'setStatoRegistrazione',\n })\n @ApiResponse({\n status: 200,\n description: 'Stato registrazione aggiornato con successo',\n type: ActionResponse,\n })\n @ApiResponse({\n status: 400,\n description: 'Errore nei parametri della richiesta',\n type: ErrorResponse,\n })\n @ApiResponse({\n status: 500,\n description: 'Errore interno del server',\n type: ErrorResponse,\n })\n @ApiBody({ type: SetStatoRegistrazioneDto })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('set-stato')\n async setStatoRegistrazione(\n @Req() request: Request,\n @Body() body: SetStatoRegistrazioneDto,\n @Res() res: Response,\n ) {\n try {\n ensureSuperUser(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono modificare lo stato di registrazione.',\n );\n\n const { codiceUtente, statoRegistrazione } = body;\n if (!codiceUtente) throw new BadRequestException('Il codice utente e\\' obbligatorio.');\n if (statoRegistrazione === undefined) {\n throw new BadRequestException('Lo stato registrazione e\\' obbligatorio.');\n }\n\n await this.userService.setStato(codiceUtente, statoRegistrazione);\n return RestUtilities.sendOKMessage(\n res,\n `Lo stato dell'utente ${codiceUtente} e' stato aggiornato a ${statoRegistrazione}.`,\n );\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Registra un nuovo utente',\n description: 'Disponibile soltanto quando publicRegistration.enabled e true. Per utenti SSO usare il provisioning master nel tag Federated authentication.',\n operationId: 'register',\n })\n @ApiBody({\n type: PublicRegisterRequest,\n description: \"Dati necessari per la registrazione dell'utente\",\n })\n @ApiCreatedResponse({\n description:\n 'Utente registrato con successo. Restituisce il codice utente e invia una mail di reset password.',\n type: RegisterResponse,\n })\n @ApiResponse({\n status: HttpStatus.BAD_REQUEST,\n description: 'Errore nella registrazione.',\n type: ErrorResponse,\n })\n @ApiResponse({\n status: HttpStatus.INTERNAL_SERVER_ERROR,\n description: 'Errore interno del server durante la registrazione o l\\'invio email.',\n type: ErrorResponse,\n })\n @Post('register')\n async register(\n @Req() request: Request,\n @Body() registrationData: PublicRegisterRequest,\n @Res() res: Response,\n ) {\n try {\n if (this.accessiOptions.publicRegistration?.enabled !== true) {\n throw new HttpException(\n 'La registrazione pubblica e disabilitata. Un amministratore deve creare l utente.',\n HttpStatus.FORBIDDEN,\n );\n }\n\n const rateLimitDecision = checkPublicAuthRateLimit(\n this.accessiOptions,\n 'register',\n request,\n [registrationData?.email],\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n const codiceUtente = await this.userService.register(registrationData, {\n allowPrivilegedFields: false,\n });\n\n await this.emailService.sendPasswordResetEmail(registrationData.email);\n return RestUtilities.sendBaseResponse(res, codiceUtente, HttpStatus.CREATED);\n } catch (error) {\n const status =\n error instanceof HttpException ? error.getStatus() : HttpStatus.BAD_REQUEST;\n return RestUtilities.sendErrorMessage(res, error, UserController.name, status);\n }\n }\n\n @ApiOperation({ summary: 'Crea un utente locale da amministrazione', operationId: 'createManagedUser', description: 'Riservato a superutente. Crea un utente in attesa di impostazione password e invia la mail di reset.' })\n @ApiBody({ type: RegisterRequest })\n @ApiCreatedResponse({ type: RegisterResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('create-managed-user')\n async createManagedUser(@Req() request: Request, @Body() registrationData: RegisterRequest, @Res() res: Response) {\n try {\n ensureSuperUser(getAuthenticatedAccessiUser(request), 'Solo gli amministratori possono creare utenti.');\n const codiceUtente = await this.userService.register(registrationData, { allowPrivilegedFields: true });\n await this.emailService.sendPasswordResetEmail(registrationData.email, registrationData.htmlMail);\n return RestUtilities.sendBaseResponse(res, codiceUtente, HttpStatus.CREATED);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Aggiorna un utente esistente',\n operationId: 'updateUtente',\n })\n @ApiParam({\n name: 'codiceUtente',\n description: \"Codice identificativo dell'utente da aggiornare\",\n required: true,\n example: 123,\n })\n @ApiBody({\n type: UserDto,\n description: \"Dati aggiornati dell'utente\",\n })\n @ApiResponse({\n status: HttpStatus.OK,\n description: 'Utente aggiornato con successo',\n type: ActionResponse,\n })\n @ApiResponse({ status: 400, description: \"Errore nell'aggiornamento\", type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Operazione non autorizzata', type: ErrorResponse })\n @ApiResponse({ status: 500, description: 'Errore interno del server', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Put('update-user/:codiceUtente')\n async updateUtente(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Body() user: UserDto,\n @Res() res: Response,\n ) {\n try {\n const authenticatedUser = getAuthenticatedAccessiUser(request);\n const isPrivilegedUpdate = hasPrivilegedUserChanges(user);\n\n if (isPrivilegedUpdate) {\n ensureSuperUser(\n authenticatedUser,\n 'Solo gli amministratori possono modificare ruoli, permessi o flag privilegiati.',\n );\n } else {\n ensureSelfOrSuperUser(\n authenticatedUser,\n codiceUtente,\n 'Puoi modificare solo il tuo profilo.',\n );\n }\n\n if (user.codiceUtente !== undefined && user.codiceUtente !== codiceUtente) {\n throw new BadRequestException('Il codice utente nel body non coincide con quello del path.');\n }\n\n await this.userService.updateUser(codiceUtente, user, {\n allowPrivilegedChanges: authenticatedUser.flagSuper,\n });\n\n return RestUtilities.sendOKMessage(\n res,\n `L'utente ${codiceUtente} e' stato aggiornato con successo.`,\n );\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Imposta il consenso GDPR per un utente',\n operationId: 'setGdpr',\n })\n @ApiParam({\n name: 'codiceUtente',\n description: \"Codice identificativo dell'utente che accetta il GDPR\",\n required: true,\n example: 123,\n })\n @ApiResponse({\n status: 200,\n description: 'Consenso GDPR impostato con successo',\n type: ActionResponse,\n })\n @ApiResponse({ status: 400, description: 'Errore nella richiesta', type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Operazione non autorizzata', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Patch('set-gdpr/:codiceUtente')\n async setGdpr(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Res() res: Response,\n ) {\n try {\n ensureSelfOrSuperUser(\n getAuthenticatedAccessiUser(request),\n codiceUtente,\n 'Puoi impostare il GDPR solo sul tuo utente.',\n );\n\n await this.userService.setGdpr(codiceUtente);\n return RestUtilities.sendOKMessage(res, `L'utente ${codiceUtente} ha accettato il GDPR.`);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"UserController.js","sourceRoot":"","sources":["../../../src/accessi-module/Controllers/UserController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Body,\n Controller,\n Delete,\n Get,\n HttpException,\n HttpStatus,\n Param,\n ParseBoolPipe,\n ParseIntPipe,\n Patch,\n Post,\n Put,\n Query,\n Inject,\n Req,\n Res,\n UseGuards,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport {\n ApiBearerAuth,\n ApiBody,\n ApiCreatedResponse,\n ApiOperation,\n ApiParam,\n ApiQuery,\n ApiResponse,\n ApiTags,\n} from '@nestjs/swagger';\nimport { join } from 'path';\nimport { Logger } from '../../Logger';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { ActionResponse, ErrorResponse } from '../Dtos/BaseResponse';\nimport { GetUsersResponse } from '../Dtos/GetUsersResponse';\nimport { PublicRegisterRequest } from '../Dtos/PublicRegisterRequest';\nimport { RegisterResponse } from '../Dtos/RegisterResponse';\nimport { RegisterRequest } from '../Dtos/RegisterRequest';\nimport { SetStatoRegistrazioneDto } from '../Dtos/SetStatoRegistrazione';\nimport { UserDto } from '../Dtos/UserDto';\nimport { EmailService } from '../Services/EmailService/EmailService';\nimport { UserService } from '../Services/UserService/UserService';\nimport { JwtSimpleGuard } from '../jwt/jwt.strategy';\nimport {\n checkPublicAuthRateLimit,\n sendPublicAuthRateLimitExceeded,\n} from '../security/publicAuthRateLimit';\nimport {\n ensureSelfOrSuperUser,\n ensureUserManagement,\n getAuthenticatedAccessiUser,\n hasPrivilegedUserChanges,\n} from '../security/accessControl';\n\n@ApiTags('User')\n@Controller('accessi/user')\n/**\n * Gestione utenti: la registrazione pubblica e opt-in, mentre creazione, stato e profili privilegiati\n * richiedono un superutente Accessi. Le API restituiscono sempre il wrapper `BaseResponse` storico.\n */\nexport class UserController {\n private readonly logger = new Logger(UserController.name);\n\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly userService: UserService,\n private readonly emailService: EmailService,\n ) {}\n\n private sendControllerError(res: Response, error: unknown) {\n // Lo status viene derivato centralmente da RestUtilities (HttpException o 500).\n return RestUtilities.sendErrorMessage(res, error, UserController.name);\n }\n\n @ApiOperation({\n summary: 'Serve la pagina di reset password',\n operationId: 'serveResetPasswordPageUser',\n })\n @ApiParam({\n name: 'token',\n description: 'Token per il reset della password',\n required: true,\n })\n @Get('reset-password/:token')\n async serveResetPasswordPage(@Res() res: Response, @Param('token') _token: string) {\n return res.sendFile(join(__dirname, '..', 'Views', 'reset-password.html'));\n }\n\n @ApiOperation({\n summary: 'Recupera la lista degli utenti',\n operationId: 'getUsers',\n })\n @ApiResponse({\n status: 200,\n description: 'Lista utenti recuperata con successo',\n type: GetUsersResponse,\n })\n @ApiResponse({ status: 401, description: 'Credenziali non valide', type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Operazione non autorizzata', type: ErrorResponse })\n @ApiResponse({ status: 500, description: 'Errore interno del server', type: ErrorResponse })\n @ApiQuery({\n name: 'email',\n required: false,\n description: \"Email dell'utente da cercare\",\n type: String,\n })\n @ApiQuery({\n name: 'codiceUtente',\n required: false,\n description: \"Codice dell'utente da cercare\",\n type: Number,\n })\n @ApiQuery({\n name: 'includeExtensionFields',\n required: false,\n description: 'Includi extension fields',\n type: Boolean,\n })\n @ApiQuery({\n name: 'includeGrants',\n required: false,\n description: 'Includi permessi',\n type: Boolean,\n })\n @ApiQuery({\n name: 'limit',\n required: false,\n description: 'Numero massimo di utenti restituiti (1-1000). Omesso = tutti.',\n type: Number,\n })\n @ApiQuery({\n name: 'offset',\n required: false,\n description: 'Numero di utenti da saltare (paginazione).',\n type: Number,\n })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Get('get-users')\n async getUsers(\n @Req() request: Request,\n @Res() res: Response,\n @Query('email') email?: string,\n @Query('codiceUtente', new ParseIntPipe({ optional: true })) codiceUtente?: number,\n @Query('includeExtensionFields', new ParseBoolPipe({ optional: true }))\n includeExtensionFields?: boolean,\n @Query('includeGrants', new ParseBoolPipe({ optional: true }))\n includeGrants?: boolean,\n @Query('limit', new ParseIntPipe({ optional: true })) limit?: number,\n @Query('offset', new ParseIntPipe({ optional: true })) offset?: number,\n ) {\n try {\n ensureUserManagement(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono consultare gli utenti.',\n );\n\n const filters = { email, codiceUtente, limit, offset };\n const options = {\n includeExtensionFields: includeExtensionFields ?? true,\n includeGrants: includeGrants ?? true,\n };\n\n const users = await this.userService.getUsers(filters, options);\n const total = await this.userService.countUsers({ email, codiceUtente });\n res.setHeader('X-Total-Count', String(total));\n return RestUtilities.sendBaseResponse(res, users);\n } catch (error) {\n this.logger.error('Errore durante il recupero degli utenti: ', error);\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Elimina un utente',\n operationId: 'deleteUser',\n description: 'Imposta lo stato di un utente a eliminato senza rimuovere i record.',\n })\n @ApiParam({\n name: 'codiceUtente',\n description: \"Codice identificativo dell'utente da eliminare\",\n required: true,\n example: 123,\n })\n @ApiResponse({ status: 200, description: 'Utente eliminato con successo', type: ActionResponse })\n @ApiResponse({\n status: 400,\n description: 'Errore nei parametri della richiesta',\n type: ErrorResponse,\n })\n @ApiResponse({ status: 500, description: 'Errore interno del server', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Delete('delete-user/:codiceUtente')\n async deleteUser(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Res() res: Response,\n ) {\n try {\n ensureUserManagement(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono eliminare utenti.',\n );\n\n await this.userService.deleteUser(codiceUtente);\n return RestUtilities.sendOKMessage(res, \"L'utente e' stato eliminato con successo.\");\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Forza l invio dell email di reset password a un utente',\n operationId: 'forcePasswordReset',\n description: 'Riservato al superutente. Richiede un servizio email configurato; altrimenti risponde con ACCESSI_EMAIL_NOT_CONFIGURED.',\n })\n @ApiParam({ name: 'codiceUtente', description: 'Codice identificativo dell utente', required: true, example: 123, type: Number })\n @ApiResponse({ status: 200, description: 'Email di reset inviata', type: ActionResponse })\n @ApiResponse({ status: 400, description: 'Servizio email non configurato', type: ErrorResponse })\n @ApiResponse({ status: 404, description: 'Utente non trovato', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('force-password-reset/:codiceUtente')\n async forcePasswordReset(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Res() res: Response,\n ) {\n try {\n ensureUserManagement(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono forzare il reset password.',\n );\n await this.userService.forcePasswordReset(codiceUtente);\n return RestUtilities.sendOKMessage(res, `Email di reset inviata all utente ${codiceUtente}.`);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Forza il reset password per tutti gli utenti con password legacy',\n operationId: 'forcePasswordResetLegacy',\n description: 'Riservato al superutente. Invia l email di reset a tutti gli utenti la cui password non e ancora nel formato moderno. Richiede un servizio email configurato.',\n })\n @ApiResponse({ status: 200, description: 'Email di reset inviate', type: ActionResponse })\n @ApiResponse({ status: 400, description: 'Servizio email non configurato', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('force-password-reset-legacy')\n async forcePasswordResetLegacy(@Req() request: Request, @Res() res: Response) {\n try {\n ensureUserManagement(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono forzare il reset password.',\n );\n const sent = await this.userService.forcePasswordResetForLegacyPasswords();\n return RestUtilities.sendOKMessage(res, `Email di reset inviata a ${sent} utenti con password legacy.`);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Imposta lo stato di registrazione di un utente',\n operationId: 'setStatoRegistrazione',\n })\n @ApiResponse({\n status: 200,\n description: 'Stato registrazione aggiornato con successo',\n type: ActionResponse,\n })\n @ApiResponse({\n status: 400,\n description: 'Errore nei parametri della richiesta',\n type: ErrorResponse,\n })\n @ApiResponse({\n status: 500,\n description: 'Errore interno del server',\n type: ErrorResponse,\n })\n @ApiBody({ type: SetStatoRegistrazioneDto })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('set-stato')\n async setStatoRegistrazione(\n @Req() request: Request,\n @Body() body: SetStatoRegistrazioneDto,\n @Res() res: Response,\n ) {\n try {\n ensureUserManagement(\n getAuthenticatedAccessiUser(request),\n 'Solo gli amministratori possono modificare lo stato di registrazione.',\n );\n\n const { codiceUtente, statoRegistrazione } = body;\n if (!codiceUtente) throw new BadRequestException('Il codice utente e\\' obbligatorio.');\n if (statoRegistrazione === undefined) {\n throw new BadRequestException('Lo stato registrazione e\\' obbligatorio.');\n }\n\n await this.userService.setStato(codiceUtente, statoRegistrazione);\n return RestUtilities.sendOKMessage(\n res,\n `Lo stato dell'utente ${codiceUtente} e' stato aggiornato a ${statoRegistrazione}.`,\n );\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Registra un nuovo utente',\n description: 'Disponibile soltanto quando publicRegistration.enabled e true. Per utenti SSO usare il provisioning master nel tag Federated authentication.',\n operationId: 'register',\n })\n @ApiBody({\n type: PublicRegisterRequest,\n description: \"Dati necessari per la registrazione dell'utente\",\n })\n @ApiCreatedResponse({\n description:\n 'Utente registrato con successo. Restituisce il codice utente e invia una mail di reset password.',\n type: RegisterResponse,\n })\n @ApiResponse({\n status: HttpStatus.BAD_REQUEST,\n description: 'Errore nella registrazione.',\n type: ErrorResponse,\n })\n @ApiResponse({\n status: HttpStatus.INTERNAL_SERVER_ERROR,\n description: 'Errore interno del server durante la registrazione o l\\'invio email.',\n type: ErrorResponse,\n })\n @Post('register')\n async register(\n @Req() request: Request,\n @Body() registrationData: PublicRegisterRequest,\n @Res() res: Response,\n ) {\n try {\n if (this.accessiOptions.publicRegistration?.enabled !== true) {\n throw new HttpException(\n 'La registrazione pubblica e disabilitata. Un amministratore deve creare l utente.',\n HttpStatus.FORBIDDEN,\n );\n }\n\n const rateLimitDecision = checkPublicAuthRateLimit(\n this.accessiOptions,\n 'register',\n request,\n [registrationData?.email],\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n const codiceUtente = await this.userService.register(registrationData, {\n allowPrivilegedFields: false,\n });\n\n await this.emailService.sendPasswordResetEmail(registrationData.email);\n return RestUtilities.sendBaseResponse(res, codiceUtente, HttpStatus.CREATED);\n } catch (error) {\n const status =\n error instanceof HttpException ? error.getStatus() : HttpStatus.BAD_REQUEST;\n return RestUtilities.sendErrorMessage(res, error, UserController.name, status);\n }\n }\n\n @ApiOperation({ summary: 'Crea un utente locale da amministrazione', operationId: 'createManagedUser', description: 'Riservato a superutente. Crea un utente in attesa di impostazione password e invia la mail di reset.' })\n @ApiBody({ type: RegisterRequest })\n @ApiCreatedResponse({ type: RegisterResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Post('create-managed-user')\n async createManagedUser(@Req() request: Request, @Body() registrationData: RegisterRequest, @Res() res: Response) {\n try {\n ensureUserManagement(getAuthenticatedAccessiUser(request), 'Solo gli amministratori possono creare utenti.');\n const codiceUtente = await this.userService.register(registrationData, { allowPrivilegedFields: true });\n await this.emailService.sendPasswordResetEmail(registrationData.email, registrationData.htmlMail);\n return RestUtilities.sendBaseResponse(res, codiceUtente, HttpStatus.CREATED);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Aggiorna un utente esistente',\n operationId: 'updateUtente',\n })\n @ApiParam({\n name: 'codiceUtente',\n description: \"Codice identificativo dell'utente da aggiornare\",\n required: true,\n example: 123,\n })\n @ApiBody({\n type: UserDto,\n description: \"Dati aggiornati dell'utente\",\n })\n @ApiResponse({\n status: HttpStatus.OK,\n description: 'Utente aggiornato con successo',\n type: ActionResponse,\n })\n @ApiResponse({ status: 400, description: \"Errore nell'aggiornamento\", type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Operazione non autorizzata', type: ErrorResponse })\n @ApiResponse({ status: 500, description: 'Errore interno del server', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Put('update-user/:codiceUtente')\n async updateUtente(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Body() user: UserDto,\n @Res() res: Response,\n ) {\n try {\n const authenticatedUser = getAuthenticatedAccessiUser(request);\n const isPrivilegedUpdate = hasPrivilegedUserChanges(user);\n\n if (isPrivilegedUpdate) {\n ensureUserManagement(\n authenticatedUser,\n 'Solo gli amministratori possono modificare ruoli, permessi o flag privilegiati.',\n );\n } else {\n ensureSelfOrSuperUser(\n authenticatedUser,\n codiceUtente,\n 'Puoi modificare solo il tuo profilo.',\n );\n }\n\n if (user.codiceUtente !== undefined && user.codiceUtente !== codiceUtente) {\n throw new BadRequestException('Il codice utente nel body non coincide con quello del path.');\n }\n\n await this.userService.updateUser(codiceUtente, user, {\n allowPrivilegedChanges: authenticatedUser.flagSuper || authenticatedUser.flagAdmin,\n });\n\n return RestUtilities.sendOKMessage(\n res,\n `L'utente ${codiceUtente} e' stato aggiornato con successo.`,\n );\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n\n @ApiOperation({\n summary: 'Imposta il consenso GDPR per un utente',\n operationId: 'setGdpr',\n })\n @ApiParam({\n name: 'codiceUtente',\n description: \"Codice identificativo dell'utente che accetta il GDPR\",\n required: true,\n example: 123,\n })\n @ApiResponse({\n status: 200,\n description: 'Consenso GDPR impostato con successo',\n type: ActionResponse,\n })\n @ApiResponse({ status: 400, description: 'Errore nella richiesta', type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Operazione non autorizzata', type: ErrorResponse })\n @ApiBearerAuth()\n @UseGuards(JwtSimpleGuard)\n @Patch('set-gdpr/:codiceUtente')\n async setGdpr(\n @Req() request: Request,\n @Param('codiceUtente', ParseIntPipe) codiceUtente: number,\n @Res() res: Response,\n ) {\n try {\n ensureSelfOrSuperUser(\n getAuthenticatedAccessiUser(request),\n codiceUtente,\n 'Puoi impostare il GDPR solo sul tuo utente.',\n );\n\n await this.userService.setGdpr(codiceUtente);\n return RestUtilities.sendOKMessage(res, `L'utente ${codiceUtente} ha accettato il GDPR.`);\n } catch (error) {\n return this.sendControllerError(res, error);\n }\n }\n}\n"]}
|
|
@@ -17,8 +17,6 @@ export declare class UserService {
|
|
|
17
17
|
private normalizeUserFlags;
|
|
18
18
|
private normalizeEmail;
|
|
19
19
|
private ensureEmailIsAvailable;
|
|
20
|
-
/** Determina se l'utente puo amministrare il configuratore Accessi (`FLGADMIN`). */
|
|
21
|
-
isAdminConfigurator(codiceUtente: number): Promise<boolean>;
|
|
22
20
|
/**
|
|
23
21
|
* Legge il minimo profilo autorevole usato da JWT e middleware. Restituisce `null` per utenti inesistenti.
|
|
24
22
|
* Non usare `UserDto` dal token per decisioni di sicurezza: i flag vengono sempre riletti qui.
|
|
@@ -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.
|
|
@@ -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 };\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 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"]}
|
|
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"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { AccessiOptions, CatalogScriptsOptions } from '../AccessiModule';
|
|
2
|
+
export interface CatalogScriptMigration {
|
|
3
|
+
name: string;
|
|
4
|
+
applied: boolean;
|
|
5
|
+
skipped: boolean;
|
|
6
|
+
reapplied: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CatalogMigrationReport {
|
|
10
|
+
folder: string;
|
|
11
|
+
discovered: number;
|
|
12
|
+
applied: string[];
|
|
13
|
+
skipped: string[];
|
|
14
|
+
failed: {
|
|
15
|
+
script: string;
|
|
16
|
+
error: string;
|
|
17
|
+
}[];
|
|
18
|
+
}
|
|
19
|
+
/** Hash SHA-256 del contenuto dello script, usato per rilevare modifiche non versionate. */
|
|
20
|
+
export declare function computeCatalogScriptChecksum(content: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Divide un file SQL in statement eseguibili separatamente.
|
|
23
|
+
*
|
|
24
|
+
* Supporta:
|
|
25
|
+
* - terminator personalizzati con `SET TERM <char>` / `SET TERM <char> ;`
|
|
26
|
+
* - stringhe `'...'` con escape `''`
|
|
27
|
+
* - commenti di riga `--` e di blocco `/* ... * /`
|
|
28
|
+
*
|
|
29
|
+
* Non interpreta la semantica SQL: e volutamente un tokenizer prudente che non spezza
|
|
30
|
+
* mai all'interno di stringhe o commenti.
|
|
31
|
+
*/
|
|
32
|
+
export declare function splitSqlStatements(sql: string, defaultTerminator?: string): string[];
|
|
33
|
+
/** Elenca gli script `.sql` della cartella, ordinati per percorso (prefissi numerici consigliati). */
|
|
34
|
+
export declare function discoverCatalogScripts(options: CatalogScriptsOptions): {
|
|
35
|
+
name: string;
|
|
36
|
+
path: string;
|
|
37
|
+
}[];
|
|
38
|
+
/** Elenca gli script non ancora applicati (o con checksum diverso) senza eseguirli. */
|
|
39
|
+
export declare function listPendingCatalogScripts(options: AccessiOptions): Promise<{
|
|
40
|
+
applied: string[];
|
|
41
|
+
pending: string[];
|
|
42
|
+
changed: string[];
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Applica le catalog migrations presenti nella cartella configurata.
|
|
46
|
+
*
|
|
47
|
+
* Idempotenza:
|
|
48
|
+
* - uno script gia presente nel ledger con lo stesso checksum viene saltato;
|
|
49
|
+
* - uno script gia applicato ma modificato segue `onChecksumMismatch` (`error` default, `warn`, `reapply`);
|
|
50
|
+
* - un errore interrompe il run (default) senza avanzare, lasciando il ledger all'ultimo script completato.
|
|
51
|
+
*
|
|
52
|
+
* Il chiamante deve avere gia riconciliato lo schema (`AccessiDatabaseUpdater.run`): la tabella
|
|
53
|
+
* ledger `ACCESSI_CATALOG_SCRIPT` e creata dall'updater.
|
|
54
|
+
*/
|
|
55
|
+
export declare function applyCatalogScripts(options: AccessiOptions): Promise<CatalogMigrationReport>;
|
|
56
|
+
/** Esegue la riconciliazione dello schema non e responsabilita di questa classe: usare l'updater prima. */
|
|
57
|
+
export declare class AccessiCatalogMigrator {
|
|
58
|
+
static apply(options: AccessiOptions): Promise<CatalogMigrationReport>;
|
|
59
|
+
static listPending(options: AccessiOptions): Promise<{
|
|
60
|
+
applied: string[];
|
|
61
|
+
pending: string[];
|
|
62
|
+
changed: string[];
|
|
63
|
+
}>;
|
|
64
|
+
}
|