+ signup and + verify
All checks were successful
gitea/MERN_STACK_TEMPLATE/pipeline/head This commit looks good

This commit is contained in:
2025-05-02 22:19:30 +02:00
parent 7333cf79bd
commit 3f76d4f3d4
12 changed files with 589 additions and 22 deletions

View File

@ -0,0 +1,95 @@
export const VERIFICATION_EMAIL_TEMPLATE = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verify Your Email</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px;">
<div style="background: linear-gradient(to right, #4CAF50, #45a049); padding: 20px; text-align: center;">
<h1 style="color: white; margin: 0;">Verify Your Email</h1>
</div>
<div style="background-color: #f9f9f9; padding: 20px; border-radius: 0 0 5px 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<p>Hello,</p>
<p>Thank you for signing up! Your verification code is:</p>
<div style="text-align: center; margin: 30px 0;">
<span style="font-size: 32px; font-weight: bold; letter-spacing: 5px; color: #4CAF50;">{verificationCode}</span>
</div>
<p>Enter this code on the verification page to complete your registration.</p>
<p>This code will expire in 15 minutes for security reasons.</p>
<p>If you didn't create an account with us, please ignore this email.</p>
<p>Best regards,<br>Your App Team</p>
</div>
<div style="text-align: center; margin-top: 20px; color: #888; font-size: 0.8em;">
<p>This is an automated message, please do not reply to this email.</p>
</div>
</body>
</html>
`;
export const PASSWORD_RESET_SUCCESS_TEMPLATE = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Reset Successful</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px;">
<div style="background: linear-gradient(to right, #4CAF50, #45a049); padding: 20px; text-align: center;">
<h1 style="color: white; margin: 0;">Password Reset Successful</h1>
</div>
<div style="background-color: #f9f9f9; padding: 20px; border-radius: 0 0 5px 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<p>Hello,</p>
<p>We're writing to confirm that your password has been successfully reset.</p>
<div style="text-align: center; margin: 30px 0;">
<div style="background-color: #4CAF50; color: white; width: 50px; height: 50px; line-height: 50px; border-radius: 50%; display: inline-block; font-size: 30px;">
</div>
</div>
<p>If you did not initiate this password reset, please contact our support team immediately.</p>
<p>For security reasons, we recommend that you:</p>
<ul>
<li>Use a strong, unique password</li>
<li>Enable two-factor authentication if available</li>
<li>Avoid using the same password across multiple sites</li>
</ul>
<p>Thank you for helping us keep your account secure.</p>
<p>Best regards,<br>Your App Team</p>
</div>
<div style="text-align: center; margin-top: 20px; color: #888; font-size: 0.8em;">
<p>This is an automated message, please do not reply to this email.</p>
</div>
</body>
</html>
`;
export const PASSWORD_RESET_REQUEST_TEMPLATE = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reset Your Password</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px;">
<div style="background: linear-gradient(to right, #4CAF50, #45a049); padding: 20px; text-align: center;">
<h1 style="color: white; margin: 0;">Password Reset</h1>
</div>
<div style="background-color: #f9f9f9; padding: 20px; border-radius: 0 0 5px 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<p>Hello,</p>
<p>We received a request to reset your password. If you didn't make this request, please ignore this email.</p>
<p>To reset your password, click the button below:</p>
<div style="text-align: center; margin: 30px 0;">
<a href="{resetURL}" style="background-color: #4CAF50; color: white; padding: 12px 20px; text-decoration: none; border-radius: 5px; font-weight: bold;">Reset Password</a>
</div>
<p>This link will expire in 1 hour for security reasons.</p>
<p>Best regards,<br>Your App Team</p>
</div>
<div style="text-align: center; margin-top: 20px; color: #888; font-size: 0.8em;">
<p>This is an automated message, please do not reply to this email.</p>
</div>
</body>
</html>
`;

View File

@ -0,0 +1,44 @@
import { VERIFICATION_EMAIL_TEMPLATE } from "./emailTemplates.js"
import { mailtrapClient, sender} from "./mailtrap.config.js"
export const sendVerificationEmail = async (email, verificationToken) => {
const recepient = [{ email }]
try {
const response = await mailtrapClient.send({
from: sender,
to: recepient,
subject: "Verify your email",
html: VERIFICATION_EMAIL_TEMPLATE.replace("{verificationCode}", verificationToken),
category: "Email Verification"
})
} catch (error) {
console.error(`Error sending verification`, error);
throw new Error(`Error sending verification email: ${error}`);
}
}
export const sendWelcomeEmail = async (email, name) => {
const recipients = [{email}];
try {
const response = await mailtrapClient.send({
from: sender,
to: recipients,
template_uuid: "eee83ead-5e6d-4784-bd67-c7296f4649b5",
template_variables: {
"company_info_name": "Ai Laplace Lab",
"name": name,
"company_info_address": "Rinstraße 19C",
"company_info_city": "Schwabhausen",
"company_info_zip_code": "85247",
"company_info_country": "Germany"
},
});
console.log("Welcome email sent successfully", response);
} catch (error) {
console.error(`Error sending welcome email`, error);
throw new Error(`Error sending welcome email: ${error}`);
}
};

View File

@ -0,0 +1,13 @@
import { MailtrapClient } from "mailtrap"
import dotenv from "dotenv";
dotenv.config();
export const mailtrapClient = new MailtrapClient({
token: process.env.MAILTRAP_TOKEN,
});
export const sender = {
email: "hello@demomailtrap.co",
name: "Mailtrap Test",
};