This commit is contained in:
1 parent
de1b3754df
commit
f085517732
3 files changed
+45
-18
No files matched your search
+11
-15
@@ -12,10 +12,7 @@ export const auth = betterAuth({
|
|||||||
emailOTP({
|
emailOTP({
|
||||||
async sendVerificationOTP({ email, otp, type }) {
|
async sendVerificationOTP({ email, otp, type }) {
|
||||||
if (type === 'sign-in') {
|
if (type === 'sign-in') {
|
||||||
// Send the OTP for sign in
|
EmailSender.sendInBackground({
|
||||||
console.log({ email, otp, type });
|
|
||||||
|
|
||||||
void EmailSender.getTransporter().sendMail({
|
|
||||||
to: email,
|
to: email,
|
||||||
subject: `Your OTP code is: ${otp}`,
|
subject: `Your OTP code is: ${otp}`,
|
||||||
text: `Your OTP code is: ${otp}`,
|
text: `Your OTP code is: ${otp}`,
|
||||||
@@ -23,8 +20,13 @@ export const auth = betterAuth({
|
|||||||
} else if (type === 'email-verification') {
|
} else if (type === 'email-verification') {
|
||||||
// Send the OTP for email verification
|
// Send the OTP for email verification
|
||||||
console.log({ email, otp, type });
|
console.log({ email, otp, type });
|
||||||
|
} else if (type === 'forget-password') {
|
||||||
|
EmailSender.sendInBackground({
|
||||||
|
to: email,
|
||||||
|
subject: `Your password reset code is: ${otp}`,
|
||||||
|
text: `Your password reset code is: ${otp}`,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Send the OTP for password reset
|
|
||||||
console.log({ email, otp, type });
|
console.log({ email, otp, type });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -47,26 +49,21 @@ export const auth = betterAuth({
|
|||||||
autoSignIn: false,
|
autoSignIn: false,
|
||||||
requireEmailVerification: true,
|
requireEmailVerification: true,
|
||||||
onExistingUserSignUp: async ({ user }, request) => {
|
onExistingUserSignUp: async ({ user }, request) => {
|
||||||
console.log('onExistingUserSignUp', { user });
|
EmailSender.sendInBackground({
|
||||||
|
|
||||||
void EmailSender.getTransporter().sendMail({
|
|
||||||
to: user.email,
|
to: user.email,
|
||||||
subject: 'Sign-up attempt with your email',
|
subject: 'Sign-up attempt with your email',
|
||||||
text: 'Someone tried to create an account using your email address. If this was you, try signing in instead. If not, you can safely ignore this email.',
|
text: 'Someone tried to create an account using your email address. If this was you, try signing in instead. If not, you can safely ignore this email.',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
sendResetPassword: async ({ user, url, token }, request) => {
|
sendResetPassword: async ({ user, url, token }, request) => {
|
||||||
console.log('sendResetPassword', { user, url, token });
|
EmailSender.sendInBackground({
|
||||||
void EmailSender.getTransporter().sendMail({
|
|
||||||
to: user.email,
|
to: user.email,
|
||||||
subject: 'Reset your password',
|
subject: 'Reset your password',
|
||||||
text: `Click the link to reset your password: ${url}`,
|
text: `Click the link to reset your password: ${url}`,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onPasswordReset: async ({ user }, request) => {
|
onPasswordReset: async ({ user }, request) => {
|
||||||
// your logic here
|
EmailSender.sendInBackground({
|
||||||
console.log('onPasswordReset', { user });
|
|
||||||
void EmailSender.getTransporter().sendMail({
|
|
||||||
to: user.email,
|
to: user.email,
|
||||||
subject: 'Reset your password result',
|
subject: 'Reset your password result',
|
||||||
text: `Password for user ${user.email} has been reset.`,
|
text: `Password for user ${user.email} has been reset.`,
|
||||||
@@ -77,8 +74,7 @@ export const auth = betterAuth({
|
|||||||
sendOnSignIn: true,
|
sendOnSignIn: true,
|
||||||
autoSignInAfterVerification: true,
|
autoSignInAfterVerification: true,
|
||||||
sendVerificationEmail: async ({ user, url }) => {
|
sendVerificationEmail: async ({ user, url }) => {
|
||||||
console.log('emailVerification', { user, url });
|
EmailSender.sendInBackground({
|
||||||
void EmailSender.getTransporter().sendMail({
|
|
||||||
to: user.email,
|
to: user.email,
|
||||||
subject: 'Verify your email address',
|
subject: 'Verify your email address',
|
||||||
text: `Click the link to verify your email: ${url}`,
|
text: `Click the link to verify your email: ${url}`,
|
||||||
|
|||||||
+33
-2
@@ -1,13 +1,44 @@
|
|||||||
|
import { Logger } from '@nestjs/common';
|
||||||
import nodemailer, { SendMailOptions, Transporter } from 'nodemailer';
|
import nodemailer, { SendMailOptions, Transporter } from 'nodemailer';
|
||||||
|
|
||||||
export default class EmailSender {
|
export default class EmailSender {
|
||||||
static getTransporter() {
|
private static readonly logger = new Logger(EmailSender.name);
|
||||||
return nodemailer.createTransport({
|
private static transporter?: Transporter;
|
||||||
|
|
||||||
|
private static isLocal() {
|
||||||
|
return process.env.NODE_ENV === 'local';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getTransporter() {
|
||||||
|
this.transporter ??= nodemailer.createTransport({
|
||||||
service: 'gmail',
|
service: 'gmail',
|
||||||
auth: {
|
auth: {
|
||||||
user: process.env.GOOGLE_APP_USER,
|
user: process.env.GOOGLE_APP_USER,
|
||||||
pass: process.env.GOOGLE_APP_PASSWORD,
|
pass: process.env.GOOGLE_APP_PASSWORD,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
return this.transporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sends an email; throws on failure. In local env only logs the message. */
|
||||||
|
static async send(options: SendMailOptions): Promise<void> {
|
||||||
|
if (this.isLocal()) {
|
||||||
|
this.logger.log(
|
||||||
|
`[local] email not sent\n to: ${String(options.to)}\n subject: ${options.subject}\n text: ${String(options.text)}`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.getTransporter().sendMail(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fire-and-forget variant: never throws, errors are logged. */
|
||||||
|
static sendInBackground(options: SendMailOptions): void {
|
||||||
|
this.send(options).catch((error: unknown) => {
|
||||||
|
this.logger.error(
|
||||||
|
`Failed to send email "${options.subject}" to ${String(options.to)}`,
|
||||||
|
error instanceof Error ? error.stack : String(error),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ export class EmailChannelSender implements NotificationChannelSender {
|
|||||||
select: { email: true },
|
select: { email: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
await EmailSender.getTransporter().sendMail({
|
await EmailSender.send({
|
||||||
to: user.email,
|
to: user.email,
|
||||||
subject: params.subject ?? 'Уведомление',
|
subject: params.subject ?? 'Уведомление',
|
||||||
text: params.content,
|
text: params.content,
|
||||||
|
|||||||
Reference in new issue
Block a user