This commit is contained in:
Bastian Wagner
2026-07-16 15:05:20 +02:00
parent ba7029ac7b
commit 8c6ad294b2
2 changed files with 44 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common'; import { BadRequestException, Injectable, ServiceUnavailableException, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { IsNull, Repository } from 'typeorm'; import { IsNull, Repository } from 'typeorm';
@@ -60,7 +60,7 @@ export class PasswordService {
} }
const token = randomToken(); const token = randomToken();
await this.resetTokens.save( const resetToken = await this.resetTokens.save(
this.resetTokens.create({ this.resetTokens.create({
username: user.id, username: user.id,
email: user.email, email: user.email,
@@ -69,7 +69,24 @@ export class PasswordService {
}), }),
); );
try {
await this.mail.sendPasswordResetMail(user.email, token); await this.mail.sendPasswordResetMail(user.email, token);
} catch (error) {
await this.resetTokens.delete({ id: resetToken.id }).catch(() => undefined);
await this.audit
.record({
type: 'password.reset_mail_failed',
username: user.id,
ipAddress,
userAgent,
metadata: { error: this.errorMessage(error) },
})
.catch(() => undefined);
throw new ServiceUnavailableException(
'Der Reset-Link konnte nicht versendet werden. Bitte versuche es spaeter erneut.',
);
}
await this.audit.record({ await this.audit.record({
type: 'password.reset_requested', type: 'password.reset_requested',
username: user.id, username: user.id,
@@ -105,4 +122,8 @@ export class PasswordService {
private get tokenSecret(): string { private get tokenSecret(): string {
return this.config.getOrThrow<string>('TOKEN_SECRET'); return this.config.getOrThrow<string>('TOKEN_SECRET');
} }
private errorMessage(error: unknown): string {
return error instanceof Error ? error.message : 'unknown error';
}
} }

View File

@@ -1,4 +1,4 @@
import { BadRequestException, ConflictException, Injectable } from '@nestjs/common'; import { BadRequestException, ConflictException, Injectable, ServiceUnavailableException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { In, IsNull, Repository } from 'typeorm'; import { In, IsNull, Repository } from 'typeorm';
@@ -60,7 +60,25 @@ export class RegistrationService {
}), }),
); );
try {
await this.mail.sendVerificationMail(registration.email, token); await this.mail.sendVerificationMail(registration.email, token);
} catch (error) {
await this.emailTokens.delete({ registrationId: registration.id }).catch(() => undefined);
await this.registrations.delete({ id: registration.id }).catch(() => undefined);
await this.audit
.record({
type: 'registration.verification_mail_failed',
username: registration.username,
ipAddress,
userAgent,
metadata: { error: this.errorMessage(error) },
})
.catch(() => undefined);
throw new ServiceUnavailableException(
'Die Bestaetigungs-E-Mail konnte nicht versendet werden. Bitte versuche es spaeter erneut.',
);
}
await this.audit.record({ await this.audit.record({
type: 'registration.started', type: 'registration.started',
username: registration.username, username: registration.username,