188 lines
6.9 KiB
TypeScript
188 lines
6.9 KiB
TypeScript
import { MailerService } from '@nestjs-modules/mailer';
|
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
|
import { getAuth } from 'firebase-admin/auth';
|
|
import { join } from 'path';
|
|
import { ZodError } from 'zod';
|
|
import { SenderSchema, ShareByEMail, ShareByEMailSchema, User } from '../models/db.model';
|
|
import { ErrorResponse, MailInfo, isEmpty } from '../models/main.model';
|
|
import { UserService } from '../user/user.service';
|
|
// const __filename = fileURLToPath(import.meta.url);
|
|
// const __dirname = path.dirname(__filename);
|
|
|
|
@Injectable()
|
|
export class MailService {
|
|
constructor(
|
|
private mailerService: MailerService,
|
|
private userService: UserService,
|
|
) {}
|
|
|
|
async sendInquiry(mailInfo: MailInfo): Promise<void | ErrorResponse> {
|
|
try {
|
|
SenderSchema.parse(mailInfo.sender);
|
|
} catch (error) {
|
|
if (error instanceof ZodError) {
|
|
const formattedErrors = error.errors.map(err => ({
|
|
field: err.path.join('.'),
|
|
message: err.message,
|
|
}));
|
|
throw new BadRequestException(formattedErrors);
|
|
}
|
|
throw error;
|
|
}
|
|
const user = await this.userService.getUserByMail(mailInfo.email);
|
|
if (isEmpty(mailInfo.sender.name)) {
|
|
return { fields: [{ fieldname: 'name', message: 'Required' }] };
|
|
}
|
|
await this.mailerService.sendMail({
|
|
to: user.email,
|
|
from: '"Bizmatch Team" <info@bizmatch.net>', // override default from
|
|
subject: `Inquiry from ${mailInfo.sender.name}`,
|
|
//template: './inquiry', // `.hbs` extension is appended automatically
|
|
template: join(__dirname, '../..', 'mail/templates/inquiry.hbs'),
|
|
context: {
|
|
// ✏️ filling curly brackets with content
|
|
name: user.firstname,
|
|
inquiry: mailInfo.sender.comments,
|
|
internalListingNumber: mailInfo.listing.internalListingNumber,
|
|
title: mailInfo.listing.title,
|
|
iname: mailInfo.sender.name,
|
|
phone: mailInfo.sender.phoneNumber,
|
|
email: mailInfo.sender.email,
|
|
id: mailInfo.listing.id,
|
|
url: mailInfo.url,
|
|
},
|
|
});
|
|
}
|
|
async sendVerificationEmail(
|
|
email: string,
|
|
redirectConfig: { protocol: string, hostname: string, port?: number }
|
|
): Promise<void | ErrorResponse> {
|
|
try {
|
|
// Firebase Auth-Instanz holen
|
|
const auth = getAuth();
|
|
|
|
// Baue den Redirect-URL aus den übergebenen Parametern
|
|
let continueUrl = `${redirectConfig.protocol}://${redirectConfig.hostname}`;
|
|
if (redirectConfig.port) {
|
|
continueUrl += `:${redirectConfig.port}`;
|
|
}
|
|
continueUrl += '/auth/verify-email-success'; // Beispiel für einen Weiterleitungspfad
|
|
|
|
// Custom Verification Link generieren
|
|
const firebaseActionLink = await auth.generateEmailVerificationLink(email, {
|
|
url: continueUrl,
|
|
handleCodeInApp: false,
|
|
});
|
|
|
|
// Extrahiere den oobCode aus dem Firebase Link
|
|
const actionLinkUrl = new URL(firebaseActionLink);
|
|
const oobCode = actionLinkUrl.searchParams.get('oobCode');
|
|
|
|
if (!oobCode) {
|
|
throw new BadRequestException('Failed to generate verification code');
|
|
}
|
|
|
|
// Erstelle die benutzerdefinierte URL mit dem oobCode
|
|
let customActionLink = `${redirectConfig.protocol}://${redirectConfig.hostname}`;
|
|
if (redirectConfig.port) {
|
|
customActionLink += `:${redirectConfig.port}`;
|
|
}
|
|
|
|
// Ersetze die Platzhalter mit den tatsächlichen Werten
|
|
customActionLink += `/email-authorized?email=${encodeURIComponent(email)}&mode=verifyEmail&oobCode=${oobCode}`;
|
|
|
|
// Zufallszahl für die E-Mail generieren
|
|
const randomNumber = Math.floor(Math.random() * 10000);
|
|
|
|
// E-Mail senden
|
|
await this.mailerService.sendMail({
|
|
to: email,
|
|
from: '"Bizmatch Team" <info@bizmatch.net>',
|
|
subject: 'Verify your email address',
|
|
template: join(__dirname, '../..', 'mail/templates/email-verification.hbs'),
|
|
context: {
|
|
actionLink: customActionLink,
|
|
randomNumber: randomNumber
|
|
},
|
|
});
|
|
|
|
return;
|
|
} catch (error) {
|
|
console.error('Error sending verification email:', error);
|
|
throw new BadRequestException('Failed to send verification email');
|
|
}
|
|
}
|
|
async sendRequest(mailInfo: MailInfo): Promise<void | ErrorResponse> {
|
|
try {
|
|
SenderSchema.parse(mailInfo.sender);
|
|
} catch (error) {
|
|
if (error instanceof ZodError) {
|
|
const formattedErrors = error.errors.map(err => ({
|
|
field: err.path.join('.'),
|
|
message: err.message,
|
|
}));
|
|
throw new BadRequestException(formattedErrors);
|
|
}
|
|
throw error;
|
|
}
|
|
await this.mailerService.sendMail({
|
|
to: 'support@bizmatch.net',
|
|
from: `"Bizmatch Support Team" <info@bizmatch.net>`,
|
|
subject: `Support Request from ${mailInfo.sender.name}`,
|
|
//template: './inquiry', // `.hbs` extension is appended automatically
|
|
template: join(__dirname, '../..', 'mail/templates/request.hbs'),
|
|
context: {
|
|
// ✏️ filling curly brackets with content
|
|
request: mailInfo.sender.comments,
|
|
iname: mailInfo.sender.name,
|
|
phone: mailInfo.sender.phoneNumber,
|
|
email: mailInfo.sender.email,
|
|
},
|
|
});
|
|
}
|
|
async sendSubscriptionConfirmation(user: User): Promise<void> {
|
|
await this.mailerService.sendMail({
|
|
to: user.email,
|
|
from: `"Bizmatch Support Team" <info@bizmatch.net>`,
|
|
subject: `Subscription Confirmation`,
|
|
//template: './inquiry', // `.hbs` extension is appended automatically
|
|
template: join(__dirname, '../..', 'mail/templates/subscriptionConfirmation.hbs'),
|
|
context: {
|
|
// ✏️ filling curly brackets with content
|
|
firstname: user.firstname,
|
|
lastname: user.lastname,
|
|
subscriptionPlan: user.subscriptionPlan,
|
|
},
|
|
});
|
|
}
|
|
async send2Friend(shareByEMail: ShareByEMail): Promise<void | ErrorResponse> {
|
|
try {
|
|
ShareByEMailSchema.parse(shareByEMail);
|
|
} catch (error) {
|
|
if (error instanceof ZodError) {
|
|
const formattedErrors = error.errors.map(err => ({
|
|
field: err.path.join('.'),
|
|
message: err.message,
|
|
}));
|
|
throw new BadRequestException(formattedErrors);
|
|
}
|
|
throw error;
|
|
}
|
|
await this.mailerService.sendMail({
|
|
to: shareByEMail.recipientEmail,
|
|
from: `"Bizmatch.net" <info@bizmatch.net>`,
|
|
subject: `${shareByEMail.type === 'business' ? 'Business' : 'Commercial Property'} For Sale: ${shareByEMail.listingTitle}`,
|
|
//template: './inquiry', // `.hbs` extension is appended automatically
|
|
template: join(__dirname, '../..', 'mail/templates/send2Friend.hbs'),
|
|
context: {
|
|
name: shareByEMail.yourName,
|
|
email: shareByEMail.yourEmail,
|
|
listingTitle: shareByEMail.listingTitle,
|
|
url: shareByEMail.url,
|
|
id: shareByEMail.id,
|
|
type: shareByEMail.type,
|
|
},
|
|
});
|
|
}
|
|
}
|