1
0
mirror of https://github.com/stonith404/pingvin-share.git synced 2024-09-30 16:40:11 +02:00

refactor: improve error handling for failed emails

This commit is contained in:
Elias Schneider 2023-03-12 19:29:39 +01:00
parent 8ff417a013
commit 0ce8b528e1
No known key found for this signature in database
GPG Key ID: 07E623B294202B6C
2 changed files with 54 additions and 44 deletions

View File

@ -1,4 +1,8 @@
import { Injectable, InternalServerErrorException } from "@nestjs/common"; import {
Injectable,
InternalServerErrorException,
Logger,
} from "@nestjs/common";
import { User } from "@prisma/client"; import { User } from "@prisma/client";
import * as nodemailer from "nodemailer"; import * as nodemailer from "nodemailer";
import { ConfigService } from "src/config/config.service"; import { ConfigService } from "src/config/config.service";
@ -6,6 +10,7 @@ import { ConfigService } from "src/config/config.service";
@Injectable() @Injectable()
export class EmailService { export class EmailService {
constructor(private config: ConfigService) {} constructor(private config: ConfigService) {}
private readonly logger = new Logger(EmailService.name);
getTransporter() { getTransporter() {
if (!this.config.get("smtp.enabled")) if (!this.config.get("smtp.enabled"))
@ -22,6 +27,22 @@ export class EmailService {
}); });
} }
private async sendMail(email: string, subject: string, text: string) {
await this.getTransporter()
.sendMail({
from: `"${this.config.get("general.appName")}" <${this.config.get(
"smtp.email"
)}>`,
to: email,
subject,
text,
})
.catch((e) => {
this.logger.error(e);
throw new InternalServerErrorException("Failed to send email");
});
}
async sendMailToShareRecepients( async sendMailToShareRecepients(
recipientEmail: string, recipientEmail: string,
shareId: string, shareId: string,
@ -32,34 +53,28 @@ export class EmailService {
const shareUrl = `${this.config.get("general.appUrl")}/share/${shareId}`; const shareUrl = `${this.config.get("general.appUrl")}/share/${shareId}`;
await this.getTransporter().sendMail({ await this.sendMail(
from: `"${this.config.get("general.appName")}" <${this.config.get( recipientEmail,
"smtp.email" this.config.get("email.shareRecipientsSubject"),
)}>`, this.config
to: recipientEmail,
subject: this.config.get("email.shareRecipientsSubject"),
text: this.config
.get("email.shareRecipientsMessage") .get("email.shareRecipientsMessage")
.replaceAll("\\n", "\n") .replaceAll("\\n", "\n")
.replaceAll("{creator}", creator?.username ?? "Someone") .replaceAll("{creator}", creator?.username ?? "Someone")
.replaceAll("{shareUrl}", shareUrl), .replaceAll("{shareUrl}", shareUrl)
}); );
} }
async sendMailToReverseShareCreator(recipientEmail: string, shareId: string) { async sendMailToReverseShareCreator(recipientEmail: string, shareId: string) {
const shareUrl = `${this.config.get("general.appUrl")}/share/${shareId}`; const shareUrl = `${this.config.get("general.appUrl")}/share/${shareId}`;
await this.getTransporter().sendMail({ await this.sendMail(
from: `"${this.config.get("general.appName")}" <${this.config.get( recipientEmail,
"smtp.email" this.config.get("email.reverseShareSubject"),
)}>`, this.config
to: recipientEmail,
subject: this.config.get("email.reverseShareSubject"),
text: this.config
.get("email.reverseShareMessage") .get("email.reverseShareMessage")
.replaceAll("\\n", "\n") .replaceAll("\\n", "\n")
.replaceAll("{shareUrl}", shareUrl), .replaceAll("{shareUrl}", shareUrl)
}); );
} }
async sendResetPasswordEmail(recipientEmail: string, token: string) { async sendResetPasswordEmail(recipientEmail: string, token: string) {
@ -67,47 +82,42 @@ export class EmailService {
"general.appUrl" "general.appUrl"
)}/auth/resetPassword/${token}`; )}/auth/resetPassword/${token}`;
await this.getTransporter().sendMail({ await this.sendMail(
from: `"${this.config.get("general.appName")}" <${this.config.get( recipientEmail,
"smtp.email" this.config.get("email.resetPasswordSubject"),
)}>`, this.config
to: recipientEmail,
subject: this.config.get("email.resetPasswordSubject"),
text: this.config
.get("email.resetPasswordMessage") .get("email.resetPasswordMessage")
.replaceAll("{url}", resetPasswordUrl), .replaceAll("\\n", "\n")
}); .replaceAll("{url}", resetPasswordUrl)
);
} }
async sendInviteEmail(recipientEmail: string, password: string) { async sendInviteEmail(recipientEmail: string, password: string) {
const loginUrl = `${this.config.get("general.appUrl")}/auth/signIn`; const loginUrl = `${this.config.get("general.appUrl")}/auth/signIn`;
await this.getTransporter().sendMail({ await this.sendMail(
from: `"${this.config.get("general.appName")}" <${this.config.get( recipientEmail,
"smtp.email" this.config.get("email.inviteSubject"),
)}>`, this.config
to: recipientEmail,
subject: this.config.get("email.inviteSubject"),
text: this.config
.get("email.inviteMessage") .get("email.inviteMessage")
.replaceAll("{url}", loginUrl) .replaceAll("{url}", loginUrl)
.replaceAll("{password}", password), .replaceAll("{password}", password)
}); );
} }
async sendTestMail(recipientEmail: string) { async sendTestMail(recipientEmail: string) {
try { await this.getTransporter()
await this.getTransporter().sendMail({ .sendMail({
from: `"${this.config.get("general.appName")}" <${this.config.get( from: `"${this.config.get("general.appName")}" <${this.config.get(
"smtp.email" "smtp.email"
)}>`, )}>`,
to: recipientEmail, to: recipientEmail,
subject: "Test email", subject: "Test email",
text: "This is a test email", text: "This is a test email",
})
.catch((e) => {
this.logger.error(e);
throw new InternalServerErrorException(e.message);
}); });
} catch (e) {
console.error(e);
throw new InternalServerErrorException(e.message);
}
} }
} }

View File

@ -29,7 +29,7 @@ export class UserSevice {
if (!dto.password) { if (!dto.password) {
const randomPassword = crypto.randomUUID(); const randomPassword = crypto.randomUUID();
hash = await argon.hash(randomPassword); hash = await argon.hash(randomPassword);
this.emailService.sendInviteEmail(dto.email, randomPassword); await this.emailService.sendInviteEmail(dto.email, randomPassword);
} else { } else {
hash = await argon.hash(dto.password); hash = await argon.hash(dto.password);
} }