diff --git a/api-v3/src/inspection-reports/document-delivery.controller.ts b/api-v3/src/inspection-reports/document-delivery.controller.ts index 54704b4..5fe49ca 100644 --- a/api-v3/src/inspection-reports/document-delivery.controller.ts +++ b/api-v3/src/inspection-reports/document-delivery.controller.ts @@ -1,17 +1,116 @@ -import { Body, Controller, Get, Param, ParseUUIDPipe, Patch, Post, Req } from '@nestjs/common'; +import { Body, Controller, Get, Param, ParseUUIDPipe, Patch, Post, Put, Req } from '@nestjs/common'; import { CurrentAuth } from '../auth/decorators/current-auth.decorator'; import { RequirePermissions } from '../authorization/decorators/require-permissions.decorator'; import type { AuthPrincipal, RequestWithContext } from '../common/http/request-context'; +import { administrationAuditContext } from '../administration/common/administration-audit'; +import { AuditService } from '../audit/audit.service'; +import { AuditAction } from '../database/entities'; import { InspectionDocumentDeliveryService } from './inspection-document-delivery.service'; import type { DeliveryRow } from './inspection-document-delivery.service'; +import { SmtpDeliveryService } from './smtp-delivery.service'; import { UpdateDocumentDeliverySettingsDto } from './dto/update-document-delivery-settings.dto'; +import { TestSmtpSettingsDto, UpdateSmtpSettingsDto } from './dto/update-smtp-settings.dto'; @Controller('document-delivery') export class DocumentDeliveryController { - constructor(private readonly delivery:InspectionDocumentDeliveryService){} - @Get('settings') @RequirePermissions('document_delivery.read') settings(){return this.delivery.settings();} - @Patch('settings') @RequirePermissions('document_delivery.manage') update(@Body() dto:UpdateDocumentDeliverySettingsDto,@CurrentAuth() principal:AuthPrincipal,@Req() request:RequestWithContext){return this.delivery.updateSettings(dto,principal,request);} - @Get('outbox') @RequirePermissions('document_delivery.read') outbox(){return this.delivery.list();} - @Post('outbox/:id/retry') @RequirePermissions('document_delivery.manage') retry(@Param('id',new ParseUUIDPipe({version:'4'})) id:string,@CurrentAuth() principal:AuthPrincipal,@Req() request:RequestWithContext):Promise{return this.delivery.retry(id,principal,request);} - @Post('outbox/retry-pending') @RequirePermissions('document_delivery.manage') retryPending(@CurrentAuth() principal:AuthPrincipal,@Req() request:RequestWithContext){return this.delivery.retryPending(principal,request);} + constructor( + private readonly delivery: InspectionDocumentDeliveryService, + private readonly smtp: SmtpDeliveryService, + private readonly audit: AuditService, + ) {} + + @Get('settings') + @RequirePermissions('document_delivery.read') + settings() { + return this.delivery.settings(); + } + + @Patch('settings') + @RequirePermissions('document_delivery.manage') + update( + @Body() dto: UpdateDocumentDeliverySettingsDto, + @CurrentAuth() principal: AuthPrincipal, + @Req() request: RequestWithContext, + ) { + return this.delivery.updateSettings(dto, principal, request); + } + + @Get('smtp') + @RequirePermissions('document_delivery.manage') + smtpSettings() { + return this.smtp.publicSettings(); + } + + @Put('smtp') + @RequirePermissions('document_delivery.manage') + async updateSmtp( + @Body() dto: UpdateSmtpSettingsDto, + @CurrentAuth() principal: AuthPrincipal, + @Req() request: RequestWithContext, + ) { + const before = await this.smtp.publicSettings(); + const after = await this.smtp.saveSettings(dto, principal.userId); + await this.audit.record({ + ...administrationAuditContext(principal, request), + action: AuditAction.SMTP_SETTINGS_UPDATED, + entityType: 'system_smtp_settings', + entityId: 'singleton', + beforeData: before as Record, + afterData: after as Record, + metadata: { passwordNeverReturned: true }, + }); + return after; + } + + @Post('smtp/test') + @RequirePermissions('document_delivery.manage') + async testSmtp( + @Body() dto: TestSmtpSettingsDto, + @CurrentAuth() principal: AuthPrincipal, + @Req() request: RequestWithContext, + ) { + const sent = await this.smtp.send({ + to: dto.email, + subject: 'DH Inspección · Prueba SMTP', + text: 'Este correo confirma que la configuración SMTP de DH Inspección funciona correctamente.', + attachment: { + filename: 'dh-inspeccion-smtp-test.txt', + mimeType: 'text/plain', + content: Buffer.from('DH Inspección · Prueba SMTP OK\n', 'utf8'), + }, + }); + await this.audit.record({ + ...administrationAuditContext(principal, request), + action: AuditAction.SMTP_TEST_SENT, + entityType: 'system_smtp_settings', + entityId: 'singleton', + afterData: { recipient: dto.email, messageId: sent.messageId }, + }); + return { ok: true, recipient: dto.email, messageId: sent.messageId }; + } + + @Get('outbox') + @RequirePermissions('document_delivery.read') + outbox() { + return this.delivery.list(); + } + + @Post('outbox/:id/retry') + @RequirePermissions('document_delivery.manage') + retry( + @Param('id', new ParseUUIDPipe({ version: '4' })) id: string, + @CurrentAuth() principal: AuthPrincipal, + @Req() request: RequestWithContext, + ): Promise { + return this.delivery.retry(id, principal, request); + } + + @Post('outbox/retry-pending') + @RequirePermissions('document_delivery.manage') + retryPending( + @CurrentAuth() principal: AuthPrincipal, + @Req() request: RequestWithContext, + ) { + return this.delivery.retryPending(principal, request); + } }