Skip to content

Commit

Permalink
code refactoring, welcome email added, profile section, otp verificat…
Browse files Browse the repository at this point in the history
…ion in profile section
  • Loading branch information
VaibhavArora314 committed May 31, 2024
1 parent b8507ed commit 0181d0c
Show file tree
Hide file tree
Showing 21 changed files with 647 additions and 653 deletions.
282 changes: 9 additions & 273 deletions backend/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jsonwebtoken": "^9.0.6",
"@types/nodemailer": "^6.4.15",
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
Expand All @@ -26,7 +27,6 @@
"express": "^4.19.2",
"jsonwebtoken": "^9.0.2",
"nodemailer": "^6.9.13",
"nodemon": "^3.1.1",
"prisma": "^5.14.0",
"ts-node": "^10.9.2",
"typescript": "^5.4.5",
Expand Down
1 change: 1 addition & 0 deletions backend/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ model User {
username String
email String
passwordHash String
verified Boolean @default(false)
otp Int?
posts Post[] @relation("authorPosts")
createdAt DateTime @default(now())
Expand Down
71 changes: 71 additions & 0 deletions backend/src/helpers/mail/otpMailBody.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const getOtpMailBody = (otp:number) => {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OTP Verification</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 100%;
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.header {
background-color: #4CAF50;
color: white;
padding: 10px 0;
text-align: center;
border-radius: 8px 8px 0 0;
}
.content {
margin: 20px 0;
text-align: center;
}
.otp {
font-size: 24px;
font-weight: bold;
margin: 20px 0;
color: #4CAF50;
}
.footer {
text-align: center;
color: #888888;
font-size: 12px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>OTP Verification</h1>
</div>
<div class="content">
<p>Hello,</p>
<p>Thank you for using style share. Please use the following OTP (One Time Password) to verify your email address:</p>
<div class="otp">${otp}</div>
<p>This OTP is valid for 10 minutes. Please do not share it with anyone.</p>
</div>
<div class="footer">
<p>If you did not request this OTP, please ignore this email.</p>
<p>Thank you!</p>
</div>
</div>
</body>
</html>
`
}

export default getOtpMailBody;
20 changes: 20 additions & 0 deletions backend/src/helpers/mail/sendOtpMail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import nodemailer from "nodemailer";
import getOtpMailBody from "./otpMailBody";

export const sendVerificationEmail = async (email: string, otp: number) => {
let transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});

let info = await transporter.sendMail({
from: '"Style Share" <[email protected]>',
to: email,
subject: "Email Verification",
text: `Your OTP for email verification is ${otp}`,
html: getOtpMailBody(otp),
});
};
88 changes: 88 additions & 0 deletions backend/src/helpers/mail/sendWelcomeMail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import nodemailer from "nodemailer";

export const sendWelcomeEmail = async (email: string, username: string) => {
let transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});

let info = await transporter.sendMail({
from: '"Style Share" <[email protected]>',
to: email,
subject: "Welcome to Style Share!",
text: `Welcome to Style Share, ${username}!`,
html: getWelcomeMailBody(username),
});
};

const getWelcomeMailBody = (username: string) => {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to Style Share</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 100%;
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.header {
background-color: #4CAF50;
color: white;
padding: 10px 0;
text-align: center;
border-radius: 8px 8px 0 0;
}
.content {
margin: 20px 0;
text-align: center;
}
.footer {
text-align: center;
color: #888888;
font-size: 12px;
margin-top: 20px;
}
.reset-link {
color: #4CAF50;
text-decoration: none;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Welcome to Style Share!</h1>
</div>
<div class="content">
<p>Hello ${username},</p>
<p>Thank you for signing up for Style Share. We are excited to have you on board!</p>
<p>If this account does not belong to you, please <a class="reset-link" href="https://yourapp.example.com/reset-password">reset your password</a> immediately from our website.</p>
</div>
<div class="footer">
<p>If you created this account, please verify this email in profile section.</p>
<p>Thank you!</p>
</div>
</div>
</body>
</html>
`;
};

export default getWelcomeMailBody;
93 changes: 0 additions & 93 deletions backend/src/helpers/sendMail.ts

This file was deleted.

27 changes: 24 additions & 3 deletions backend/src/routes/post/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,34 @@ export const createPostController = async (

if (!userId) {
return res.status(403).json({
error: "Invalid user",
error: { message: "Invalid user" },
});
}

const user = await prisma.user.findFirst({
where: {
id: userId,
},
select: {
verified: true,
},
});

if (!user?.verified) {
return res.status(403).json({
error: { message: "User is not verified!" },
});
}

const result = createPostSchema.safeParse(payload);

if (!result.success) {
const formattedError: any = {};
result.error.errors.forEach((e) => {
formattedError[e.path[0]] = e.message;
});
return res.status(411).json({
error: result.error.errors,
error: { ...formattedError, message: "" },
});
}

Expand Down Expand Up @@ -57,7 +76,9 @@ export const createPostController = async (
});
} catch (error) {
return res.status(500).json({
error: "An unexpected exception occurred!",
error: {
message: "An unexpected exception occurred!",
},
});
}
};
Expand Down
Loading

0 comments on commit 0181d0c

Please sign in to comment.