init: init project
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import { configs } from "../../configs";
|
||||
import catchAsync from "../../utils/catch_async";
|
||||
import manageResponse from "../../utils/manage_response";
|
||||
import { account_services } from "./account.service";
|
||||
|
||||
const create_account = catchAsync(async (req, res) => {
|
||||
const result = await account_services.create_account_into_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Account created successfully",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const verify_account_using_otp = catchAsync(async (req, res) => {
|
||||
const result = await account_services.verify_account_using_otp_into_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Otp verification successfull",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const verify_account_using_link = catchAsync(async (req, res) => {
|
||||
const result = await account_services.verify_account_using_link_into_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Account verification successfull",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const login_user = catchAsync(async (req, res) => {
|
||||
const result = await account_services.login_user_into_db(req);
|
||||
|
||||
// set access token into cookie
|
||||
res.cookie("access_token", result, {
|
||||
secure: configs.env === "production",
|
||||
httpOnly: true,
|
||||
});
|
||||
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "User logged in successfully",
|
||||
data: {
|
||||
accessToken: result,
|
||||
},
|
||||
});
|
||||
});
|
||||
const get_user_account = catchAsync(async (req, res) => {
|
||||
const result = await account_services.get_user_account_from_db(req);
|
||||
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Account fetched successfully",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const change_password = catchAsync(async (req, res) => {
|
||||
const result = await account_services.change_password_into_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Password Change successfully",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const resend_otp_and_verification_link = catchAsync(async (req, res) => {
|
||||
const result =
|
||||
await account_services.resend_otp_and_verification_link_from_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "OTP reset successfully",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const forget_password_genereate_reset_token = catchAsync(async (req, res) => {
|
||||
const result =
|
||||
await account_services.forget_password_genereate_reset_token_from_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Password reset successfully",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
const reset_password_using_token = catchAsync(async (req, res) => {
|
||||
const result = await account_services.reset_password_using_token_into_db(req);
|
||||
manageResponse(res, {
|
||||
statusCode: 200,
|
||||
success: true,
|
||||
message: "Password reset successfully",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
export const account_controller = {
|
||||
create_account,
|
||||
login_user,
|
||||
get_user_account,
|
||||
change_password,
|
||||
verify_account_using_otp,
|
||||
resend_otp_and_verification_link,
|
||||
verify_account_using_link,
|
||||
forget_password_genereate_reset_token,
|
||||
reset_password_using_token
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
import { Router } from "express";
|
||||
import auth from "../../middlewares/auth";
|
||||
import RequestValidator from "../../middlewares/request_validator";
|
||||
import { account_controller } from "./account.controller";
|
||||
import { account_validation } from "./account.validation";
|
||||
|
||||
const accountRouter = Router();
|
||||
|
||||
accountRouter.post(
|
||||
"/sign-up",
|
||||
RequestValidator(account_validation.sign_up),
|
||||
account_controller.create_account,
|
||||
);
|
||||
accountRouter.post(
|
||||
"/sign-in",
|
||||
RequestValidator(account_validation.sing_in),
|
||||
account_controller.login_user,
|
||||
);
|
||||
accountRouter.put(
|
||||
"/verify-otp",
|
||||
RequestValidator(account_validation.verify_otp),
|
||||
account_controller.verify_account_using_otp,
|
||||
);
|
||||
accountRouter.put(
|
||||
"/verify-link",
|
||||
RequestValidator(account_validation.verify_link),
|
||||
account_controller.verify_account_using_link,
|
||||
);
|
||||
accountRouter.get(
|
||||
"/me",
|
||||
auth("USER", "ADMIN"),
|
||||
account_controller.get_user_account,
|
||||
);
|
||||
accountRouter.put(
|
||||
"/change-password",
|
||||
auth("USER", "ADMIN"),
|
||||
RequestValidator(account_validation.change_password),
|
||||
account_controller.change_password,
|
||||
);
|
||||
accountRouter.put(
|
||||
"/resend-otp",
|
||||
RequestValidator(account_validation.resend_otp),
|
||||
account_controller.resend_otp_and_verification_link,
|
||||
);
|
||||
accountRouter.put(
|
||||
"/forget-password",
|
||||
RequestValidator(account_validation.resend_otp),
|
||||
account_controller.forget_password_genereate_reset_token,
|
||||
);
|
||||
accountRouter.put(
|
||||
"/reset-password",
|
||||
RequestValidator(account_validation.reset_pass),
|
||||
account_controller.reset_password_using_token,
|
||||
);
|
||||
export default accountRouter;
|
||||
@@ -0,0 +1,402 @@
|
||||
import bcrypt from "bcrypt";
|
||||
import { Request } from "express";
|
||||
import { configs } from "../../configs";
|
||||
import { prisma } from "../../lib/prisma";
|
||||
import { AppError } from "../../utils/app_error";
|
||||
import { jwtHelpers } from "../../utils/JWT";
|
||||
import { otpGenerator } from "../../utils/otpGenerator";
|
||||
import sendMail from "../../utils/mail_sender";
|
||||
|
||||
const create_account_into_db = async (req: Request) => {
|
||||
const payload = req?.body;
|
||||
|
||||
// hash password
|
||||
const hashPassword = bcrypt.hashSync(payload.password, 10);
|
||||
|
||||
// create account and profile
|
||||
const result = await prisma.$transaction(async (tx) => {
|
||||
const account = await tx.account.create({
|
||||
data: {
|
||||
email: payload.email,
|
||||
password: hashPassword,
|
||||
},
|
||||
});
|
||||
|
||||
const profile = await tx.profile.create({
|
||||
data: {
|
||||
fullName: payload.fullName,
|
||||
accountId: account.id,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
account,
|
||||
profile,
|
||||
};
|
||||
});
|
||||
|
||||
// sending otp and verification link
|
||||
const newOtp = otpGenerator();
|
||||
const verificationToken = jwtHelpers.generateToken(
|
||||
{
|
||||
email: payload.email,
|
||||
accountId: result.account.id,
|
||||
},
|
||||
configs.jwt.verified_token as string,
|
||||
"5m",
|
||||
);
|
||||
const verificationLink = `${configs.jwt.front_end_url}/verify/token?=${verificationToken}`;
|
||||
// save otp into db
|
||||
await prisma.account.update({
|
||||
where: {
|
||||
email: payload.email,
|
||||
},
|
||||
data: {
|
||||
lastOtp: newOtp,
|
||||
lastOtpSendingTime: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
await sendMail({
|
||||
to: payload.email as string,
|
||||
subject: "welcome to - Please verify your account",
|
||||
htmlBody: `
|
||||
<p><strong>OTP</strong> ${newOtp}</p>
|
||||
<small>Otp will be expire in 5 minutes</small>
|
||||
|
||||
<br/> <br/>
|
||||
|
||||
<p>Or you can use Verification link </p>
|
||||
<p>${verificationLink}</p>
|
||||
`,
|
||||
textBody: "You can use otp or direct link",
|
||||
name: payload.fullName,
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const verify_account_using_otp_into_db = async (req: Request) => {
|
||||
const payload: { email: string; otp: string } = req?.body;
|
||||
// check account
|
||||
const account = await prisma.account.findUnique({
|
||||
where: {
|
||||
email: payload.email,
|
||||
},
|
||||
});
|
||||
// check if account exists
|
||||
if (!account) {
|
||||
throw new AppError("Account not found", 404);
|
||||
}
|
||||
// match with last otp
|
||||
const isOtpMatch = payload.otp === account.lastOtp;
|
||||
if (!isOtpMatch) {
|
||||
throw new AppError("Invalid OTP, Please try again!!", 401);
|
||||
}
|
||||
// check otp timing
|
||||
const OTP_EXPIRY_TIME = 5 * 60 * 1000; // 5 minutes in ms
|
||||
const isOtpExpired = account.lastOtpSendingTime
|
||||
? new Date().getTime() - new Date(account.lastOtpSendingTime).getTime() >
|
||||
OTP_EXPIRY_TIME
|
||||
: true;
|
||||
|
||||
if (isOtpExpired) {
|
||||
throw new AppError("OTP Expired, Please try again!!", 401);
|
||||
}
|
||||
// change account status
|
||||
await prisma.account.update({
|
||||
where: {
|
||||
id: account.id,
|
||||
},
|
||||
data: {
|
||||
isAccountVerified: true,
|
||||
},
|
||||
});
|
||||
// infuter user welcome email
|
||||
return "";
|
||||
};
|
||||
|
||||
const verify_account_using_link_into_db = async (req: Request) => {
|
||||
const token = req?.body?.token as string;
|
||||
let decoadeToken: any;
|
||||
try {
|
||||
decoadeToken = jwtHelpers.verifyToken(
|
||||
token,
|
||||
configs.jwt.verified_token as string,
|
||||
);
|
||||
} catch (error: any) {
|
||||
if (error?.message == "invalid signature") {
|
||||
throw new AppError("Invalid Token", 403);
|
||||
} else if (error?.message == "jwt expired") {
|
||||
throw new AppError("Token expired, please reset again", 403);
|
||||
}
|
||||
}
|
||||
// check account
|
||||
const account = await prisma.account.findUnique({
|
||||
where: {
|
||||
email: decoadeToken.email,
|
||||
},
|
||||
});
|
||||
// check if account exists
|
||||
if (!account) {
|
||||
throw new AppError("Account not found", 404);
|
||||
}
|
||||
|
||||
// change account status
|
||||
await prisma.account.update({
|
||||
where: {
|
||||
id: account.id,
|
||||
},
|
||||
data: {
|
||||
isAccountVerified: true,
|
||||
},
|
||||
});
|
||||
// infuter user welcome email
|
||||
return "";
|
||||
};
|
||||
|
||||
const login_user_into_db = async (req: Request) => {
|
||||
const payload = req?.body;
|
||||
const account = await prisma.account.findUnique({
|
||||
where: {
|
||||
email: payload.email,
|
||||
},
|
||||
});
|
||||
|
||||
// check if account exists
|
||||
if (!account) {
|
||||
throw new AppError("Account not found", 404);
|
||||
}
|
||||
|
||||
// checking password
|
||||
const isPasswordMatch = bcrypt.compareSync(
|
||||
payload.password,
|
||||
account.password,
|
||||
);
|
||||
|
||||
if (!isPasswordMatch) {
|
||||
throw new AppError("Invalid password", 401);
|
||||
}
|
||||
|
||||
// check if account is deleted
|
||||
if (account.isDeleted) {
|
||||
throw new AppError("Account is deleted", 401);
|
||||
}
|
||||
// check if account is verified
|
||||
if (!account.isAccountVerified) {
|
||||
throw new AppError("Account is not verified", 401);
|
||||
}
|
||||
|
||||
// generate access
|
||||
const accessToken = jwtHelpers.generateToken(
|
||||
{
|
||||
email: account.email,
|
||||
role: account.role,
|
||||
accountId: account.id,
|
||||
},
|
||||
configs.jwt.access_token as string,
|
||||
configs.jwt.access_expires as string,
|
||||
);
|
||||
return accessToken;
|
||||
};
|
||||
|
||||
const get_user_account_from_db = async (req: Request) => {
|
||||
const user = req?.user;
|
||||
|
||||
const result = await prisma.account.findUnique({
|
||||
where: {
|
||||
id: user?.accountId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
role: true,
|
||||
isAccountVerified: true,
|
||||
isDeleted: true,
|
||||
profile: true,
|
||||
},
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const change_password_into_db = async (req: Request) => {
|
||||
const user = req?.user;
|
||||
// payload
|
||||
const payload: { oldPassword: string; newPassword: string } = req?.body;
|
||||
// check old and new password is not same
|
||||
const isSamePassword = payload.oldPassword === payload.newPassword;
|
||||
if (isSamePassword) {
|
||||
throw new AppError(
|
||||
"Old and new password are same, Please provide deffirent password",
|
||||
404,
|
||||
);
|
||||
}
|
||||
// check user validity
|
||||
const isUserExist = await prisma.account.findFirst({
|
||||
where: {
|
||||
email: user?.email,
|
||||
},
|
||||
});
|
||||
// if account not exists
|
||||
if (!isUserExist) {
|
||||
throw new AppError("Account not found!!", 404);
|
||||
}
|
||||
// check old password
|
||||
const isPasswordMatch = bcrypt.compareSync(
|
||||
payload.oldPassword,
|
||||
isUserExist.password,
|
||||
);
|
||||
if (!isPasswordMatch) {
|
||||
throw new AppError("Incorrect password", 401);
|
||||
}
|
||||
// change password logic
|
||||
const newHashPassword = bcrypt.hashSync(payload.newPassword, 10);
|
||||
await prisma.account.update({
|
||||
where: {
|
||||
id: isUserExist.id,
|
||||
},
|
||||
data: {
|
||||
password: newHashPassword,
|
||||
},
|
||||
});
|
||||
|
||||
// in future email notification for more sucurity
|
||||
return "";
|
||||
};
|
||||
|
||||
const resend_otp_and_verification_link_from_db = async (req: Request) => {
|
||||
const email = req?.body?.email as string;
|
||||
const account = await prisma.account.findUnique({
|
||||
where: {
|
||||
email,
|
||||
},
|
||||
});
|
||||
// check if account exists
|
||||
if (!account) {
|
||||
throw new AppError("Account not found", 404);
|
||||
}
|
||||
// if already verified
|
||||
if (account.isAccountVerified) {
|
||||
throw new AppError("Account already verified", 403);
|
||||
}
|
||||
// make new otp and verification link
|
||||
const newOtp = otpGenerator();
|
||||
const verificationToken = jwtHelpers.generateToken(
|
||||
{
|
||||
email,
|
||||
accountId: account.id,
|
||||
},
|
||||
configs.jwt.verified_token as string,
|
||||
"5m",
|
||||
);
|
||||
const verificationLink = `${configs.jwt.front_end_url}/verify/token?=${verificationToken}`;
|
||||
// save otp into db
|
||||
await prisma.account.update({
|
||||
where: {
|
||||
email,
|
||||
},
|
||||
data: {
|
||||
lastOtp: newOtp,
|
||||
lastOtpSendingTime: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
await sendMail({
|
||||
to: email as string,
|
||||
subject: "New Verification otp and link",
|
||||
htmlBody: `
|
||||
<p><strong>OTP</strong> ${newOtp}</p>
|
||||
<small>Otp will be expire in 5 minutes</small>
|
||||
|
||||
<br/> <br/>
|
||||
|
||||
<p>Or you can use Verification link </p>
|
||||
<p>${verificationLink}</p>
|
||||
`,
|
||||
textBody: "You can use otp or direct link",
|
||||
});
|
||||
};
|
||||
|
||||
const forget_password_genereate_reset_token_from_db = async (req: Request) => {
|
||||
const email = req?.body?.email as string;
|
||||
const account = await prisma.account.findUnique({
|
||||
where: {
|
||||
email,
|
||||
},
|
||||
});
|
||||
// check if account exists
|
||||
if (!account) {
|
||||
throw new AppError("Account not found", 404);
|
||||
}
|
||||
// generate forget token
|
||||
const verificationToken = jwtHelpers.generateToken(
|
||||
{
|
||||
email: email,
|
||||
accountId: account.id,
|
||||
},
|
||||
configs.jwt.verified_token as string,
|
||||
"5m",
|
||||
);
|
||||
const verificationLink = `${configs.jwt.front_end_url}/verify/token?=${verificationToken}`;
|
||||
|
||||
await sendMail({
|
||||
to: email as string,
|
||||
subject: "Forget Password- Use this link for new password ",
|
||||
htmlBody: `
|
||||
<p>Your Reset Link: </p>
|
||||
<p>${verificationLink}</p>
|
||||
`,
|
||||
textBody: "",
|
||||
});
|
||||
};
|
||||
|
||||
const reset_password_using_token_into_db = async (req: Request) => {
|
||||
const token = req?.body?.token as string;
|
||||
const newPass = req?.body?.newPass as string;
|
||||
let decoadeToken: any;
|
||||
try {
|
||||
decoadeToken = jwtHelpers.verifyToken(
|
||||
token,
|
||||
configs.jwt.verified_token as string,
|
||||
);
|
||||
} catch (error: any) {
|
||||
if (error?.message == "invalid signature") {
|
||||
throw new AppError("Invalid Token", 403);
|
||||
} else if (error?.message == "jwt expired") {
|
||||
throw new AppError("Link expired, please reset again", 403);
|
||||
}
|
||||
}
|
||||
// check account
|
||||
const account = await prisma.account.findUnique({
|
||||
where: {
|
||||
email: decoadeToken.email,
|
||||
},
|
||||
});
|
||||
// check if account exists
|
||||
if (!account) {
|
||||
throw new AppError("Account not found", 404);
|
||||
}
|
||||
|
||||
// change account password
|
||||
const newHash = bcrypt.hashSync(newPass, 10);
|
||||
await prisma.account.update({
|
||||
where: {
|
||||
id: account.id,
|
||||
},
|
||||
data: {
|
||||
password: newHash,
|
||||
},
|
||||
});
|
||||
// infuter user alart for changing password
|
||||
return "";
|
||||
};
|
||||
export const account_services = {
|
||||
create_account_into_db,
|
||||
login_user_into_db,
|
||||
get_user_account_from_db,
|
||||
change_password_into_db,
|
||||
verify_account_using_otp_into_db,
|
||||
resend_otp_and_verification_link_from_db,
|
||||
verify_account_using_link_into_db,
|
||||
forget_password_genereate_reset_token_from_db,
|
||||
reset_password_using_token_into_db
|
||||
};
|
||||
@@ -0,0 +1,187 @@
|
||||
export const accountSwaggerDocs = {
|
||||
"/api/auth/sign-up": {
|
||||
post: {
|
||||
tags: ["account"],
|
||||
summary: "Create new account",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
email: "user@gmail.com",
|
||||
password: "password",
|
||||
fullName: "User",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "account created successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/sign-in": {
|
||||
post: {
|
||||
tags: ["account"],
|
||||
summary: "Sign In your account",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
email: "user@gmail.com",
|
||||
password: "password",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "User signed in successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/verify-otp": {
|
||||
put: {
|
||||
tags: ["account"],
|
||||
summary: "Verify OTP",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
email: "user@gmail.com",
|
||||
otp: "654321",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "OTP verification successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/verify-link": {
|
||||
put: {
|
||||
tags: ["account"],
|
||||
summary: "Verify Link",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
token: "dsakfjasdkj",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "Token verification successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/me": {
|
||||
get: {
|
||||
tags: ["account"],
|
||||
summary: "Get me account",
|
||||
description: "",
|
||||
responses: {
|
||||
200: { description: "account fetched successfully" },
|
||||
401: { description: "unauthorized" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/change-password": {
|
||||
put: {
|
||||
tags: ["account"],
|
||||
summary: "Change Password",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
oldPassword: "123456",
|
||||
newPassword: "654321",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "Passwrod change successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/resend-otp": {
|
||||
put: {
|
||||
tags: ["account"],
|
||||
summary: "Resend OTP",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
email: "user@gmail.com",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "OTP resend successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/forget-password": {
|
||||
put: {
|
||||
tags: ["account"],
|
||||
summary: "Forget Password",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
email: "user@gmail.com",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "Forget password successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/auth/reset-password": {
|
||||
put: {
|
||||
tags: ["account"],
|
||||
summary: "Reset Password",
|
||||
description: "",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
example: JSON.stringify({
|
||||
token: "dkfjadskfds",
|
||||
newPass: "newpass",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: { description: "Password reset successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
import z from "zod";
|
||||
|
||||
const sign_up = z.object({
|
||||
email: z.string("Email is required."),
|
||||
password: z.string("Password is required."),
|
||||
fullName: z.string("Full name is required."),
|
||||
});
|
||||
|
||||
const sing_in = z.object({
|
||||
email: z.string("Email is required."),
|
||||
password: z.string("Password is required."),
|
||||
});
|
||||
|
||||
const change_password = z.object({
|
||||
oldPassword: z.string("Old Password is requied"),
|
||||
newPassword: z.string("New Password is required"),
|
||||
});
|
||||
|
||||
const verify_otp = z.object({
|
||||
email: z.string("Email is requied"),
|
||||
otp: z.string("OTP is required"),
|
||||
});
|
||||
const verify_link = z.object({
|
||||
token: z.string("Token is required "),
|
||||
});
|
||||
const resend_otp = z.object({
|
||||
email: z.string("Email is requied"),
|
||||
});
|
||||
const reset_pass = z.object({
|
||||
token: z.string("Token is required"),
|
||||
newPass: z.string("Password is required"),
|
||||
});
|
||||
export const account_validation = {
|
||||
sign_up,
|
||||
sing_in,
|
||||
change_password,
|
||||
verify_otp,
|
||||
resend_otp,
|
||||
verify_link,
|
||||
reset_pass
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import catchAsync from "../../utils/catch_async";
|
||||
import manageResponse from "../../utils/manage_response";
|
||||
import { profile_service } from "./profile.service";
|
||||
|
||||
const update_profile = catchAsync(async (req, res) => {
|
||||
const result = await profile_service.update_profile_into_db(req);
|
||||
manageResponse(res, {
|
||||
success: true,
|
||||
statusCode: 200,
|
||||
message: "profile updated successfully.",
|
||||
data: result,
|
||||
});
|
||||
});
|
||||
|
||||
export const profile_controller = {
|
||||
update_profile,
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Router } from "express";
|
||||
import RequestValidator from "../../middlewares/request_validator";
|
||||
import { profile_controller } from "./profile.controller";
|
||||
import { profile_validations } from "./profile.validation";
|
||||
import auth from "../../middlewares/auth";
|
||||
import uploader from "../../middlewares/uploader";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.patch(
|
||||
"/",
|
||||
auth("USER"),
|
||||
uploader.single("file"),
|
||||
(req, res, next) => {
|
||||
req.body = JSON.parse(req?.body?.data);
|
||||
next();
|
||||
},
|
||||
RequestValidator(profile_validations.update_profile),
|
||||
profile_controller.update_profile,
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Request } from "express";
|
||||
import uploadCloud from "../../utils/cloudinary";
|
||||
import { prisma } from "../../lib/prisma";
|
||||
import { JwtPayloadType } from "../../utils/JWT";
|
||||
|
||||
const update_profile_into_db = async (req: Request) => {
|
||||
const user = req?.user as JwtPayloadType;
|
||||
const payload = req?.body;
|
||||
const file = req?.file;
|
||||
// check file and upload to cloud
|
||||
if (file) {
|
||||
const cloudRes = await uploadCloud(file);
|
||||
payload.profilePhoto = cloudRes?.secure_url;
|
||||
}
|
||||
const result = await prisma.profile.update({
|
||||
where: {
|
||||
accountId: user.accountId as string,
|
||||
},
|
||||
data: payload,
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
export const profile_service = {
|
||||
update_profile_into_db,
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
export const profileSwaggerDocs = {
|
||||
"/api/profile": {
|
||||
patch: {
|
||||
tags: ["profile"],
|
||||
summary: "Update profile",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"multipart/form-data": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
data: {
|
||||
type: "object",
|
||||
properties: {
|
||||
fullName: { type: "string" },
|
||||
},
|
||||
},
|
||||
file: {
|
||||
type: "string",
|
||||
format: "binary",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: { description: "profile updated successfully" },
|
||||
500: { description: "Validation error or internal server error" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { z } from "zod";
|
||||
const update_profile = z.object({
|
||||
fullName: z.string().optional(),
|
||||
});
|
||||
|
||||
export const profile_validations = {
|
||||
update_profile,
|
||||
};
|
||||
Reference in New Issue
Block a user