exp-node-server 1.1.2 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +5 -9
  2. package/package.json +1 -1
  3. package/src/createProject.js +3 -0
  4. package/src/generateModule.js +54 -22
  5. package/src/utils/getProjectType.js +13 -0
  6. package/src/utils/{schemaGenerator.js → mongoose/schemaGenerator.js} +2 -2
  7. package/src/utils/prisma/prismaSchemaGenerator.js +10 -0
  8. package/src/utils/prisma/prismaServiceGenerator.js +47 -0
  9. package/templates/mongoose/.projectrc.json +3 -0
  10. package/templates/mongoose/package.json +0 -2
  11. package/templates/mongoose/readme.md +3 -7
  12. package/templates/mongoose/src/app/middlewares/request_validator.ts +2 -2
  13. package/templates/prisma/.env.example +20 -0
  14. package/templates/prisma/.projectrc.json +3 -0
  15. package/templates/prisma/Dockerfile +27 -0
  16. package/templates/prisma/docker-compose.yml +27 -0
  17. package/templates/prisma/dockerignore +0 -0
  18. package/templates/prisma/package.json +47 -0
  19. package/templates/prisma/prisma/schema/account.schema.prisma +19 -0
  20. package/templates/prisma/prisma/schema/profile.schema.prisma +8 -0
  21. package/templates/prisma/prisma/schema/schema.prisma +8 -0
  22. package/templates/prisma/prisma.config.ts +14 -0
  23. package/templates/prisma/readme.md +126 -0
  24. package/templates/prisma/src/app/configs/index.ts +26 -0
  25. package/templates/prisma/src/app/errors/zodError.ts +20 -0
  26. package/templates/prisma/src/app/lib/prisma.ts +10 -0
  27. package/templates/prisma/src/app/middlewares/auth.ts +30 -0
  28. package/templates/prisma/src/app/middlewares/global_error_handler.ts +51 -0
  29. package/templates/prisma/src/app/middlewares/not_found_api.ts +10 -0
  30. package/templates/prisma/src/app/middlewares/request_validator.ts +14 -0
  31. package/templates/prisma/src/app/middlewares/uploader.ts +16 -0
  32. package/templates/prisma/src/app/modules/account/account.controller.ts +116 -0
  33. package/templates/prisma/src/app/modules/account/account.route.ts +55 -0
  34. package/templates/prisma/src/app/modules/account/account.service.ts +402 -0
  35. package/templates/prisma/src/app/modules/account/account.swagger.ts +187 -0
  36. package/templates/prisma/src/app/modules/account/account.validation.ts +41 -0
  37. package/templates/prisma/src/app/modules/profile/profile.controller.ts +17 -0
  38. package/templates/prisma/src/app/modules/profile/profile.route.ts +22 -0
  39. package/templates/prisma/src/app/modules/profile/profile.service.ts +26 -0
  40. package/templates/prisma/src/app/modules/profile/profile.swagger.ts +34 -0
  41. package/templates/prisma/src/app/modules/profile/profile.validation.ts +8 -0
  42. package/templates/prisma/src/app/types/error.d.ts +10 -0
  43. package/templates/prisma/src/app/types/index.d.ts +12 -0
  44. package/templates/prisma/src/app/utils/JWT.ts +27 -0
  45. package/templates/prisma/src/app/utils/app_error.ts +12 -0
  46. package/templates/prisma/src/app/utils/catch_async.ts +13 -0
  47. package/templates/prisma/src/app/utils/cloudinary.ts +66 -0
  48. package/templates/prisma/src/app/utils/mail_sender.ts +102 -0
  49. package/templates/prisma/src/app/utils/manage_response.ts +24 -0
  50. package/templates/prisma/src/app/utils/otpGenerator.ts +29 -0
  51. package/templates/prisma/src/app.ts +42 -0
  52. package/templates/prisma/src/routes.ts +11 -0
  53. package/templates/prisma/src/server.ts +19 -0
  54. package/templates/prisma/src/swaggerOptions.ts +48 -0
  55. package/templates/prisma/tsconfig.json +23 -0
  56. /package/src/utils/{controllerGenerator.js → mongoose/controllerGenerator.js} +0 -0
  57. /package/src/utils/{routeGenerator.js → mongoose/routeGenerator.js} +0 -0
  58. /package/src/utils/{serviceGenerator.js → mongoose/serviceGenerator.js} +0 -0
  59. /package/src/utils/{swaggerGenerator.js → mongoose/swaggerGenerator.js} +0 -0
  60. /package/src/utils/{validationGenerator.js → mongoose/validationGenerator.js} +0 -0
@@ -0,0 +1,30 @@
1
+ import { NextFunction, Request, Response } from "express";
2
+ import { configs } from "../configs";
3
+ import { AppError } from "../utils/app_error";
4
+ import { jwtHelpers, JwtPayloadType } from "../utils/JWT";
5
+
6
+ type Role = "ADMIN" | "USER";
7
+
8
+ const auth = (...roles: Role[]) => {
9
+ return async (req: Request, res: Response, next: NextFunction) => {
10
+ try {
11
+ const token = req.headers.authorization || req.cookies.access_token;
12
+ if (!token) {
13
+ throw new AppError("You are not authorize!!", 401);
14
+ }
15
+ const verifiedUser = jwtHelpers.verifyToken(
16
+ token,
17
+ configs.jwt.access_token as string,
18
+ );
19
+ if (!roles.length || !roles.includes(verifiedUser.role)) {
20
+ throw new AppError("You are not authorize!!", 401);
21
+ }
22
+ req.user = verifiedUser as JwtPayloadType;
23
+ next();
24
+ } catch (err) {
25
+ next(err);
26
+ }
27
+ };
28
+ };
29
+
30
+ export default auth;
@@ -0,0 +1,51 @@
1
+ import { ErrorRequestHandler } from "express";
2
+ import { ZodError } from "zod";
3
+ import { configs } from "../configs";
4
+ import handleZodError from "../errors/zodError";
5
+ import { TErrorSources } from "../types/error";
6
+ import { AppError } from "../utils/app_error";
7
+
8
+ const globalErrorHandler: ErrorRequestHandler = (err, req, res, next) => {
9
+ let statusCode = 500;
10
+ let message = "Something went wrong!";
11
+ let errorSources: TErrorSources = [
12
+ {
13
+ path: "",
14
+ message: "Something went wrong",
15
+ },
16
+ ];
17
+
18
+ if (err instanceof ZodError) {
19
+ const simplifiedError = handleZodError(err);
20
+ statusCode = simplifiedError?.statusCode;
21
+ message = simplifiedError?.message;
22
+ errorSources = simplifiedError?.errorSources;
23
+ } else if (err instanceof AppError) {
24
+ statusCode = err?.statusCode;
25
+ message = err.message;
26
+ errorSources = [
27
+ {
28
+ path: "",
29
+ message: err?.message,
30
+ },
31
+ ];
32
+ } else if (err instanceof Error) {
33
+ message = err.message;
34
+ errorSources = [
35
+ {
36
+ path: "",
37
+ message: err?.message,
38
+ },
39
+ ];
40
+ }
41
+
42
+ res.status(statusCode).json({
43
+ success: false,
44
+ message,
45
+ errorSources,
46
+ err,
47
+ stack: configs.env === "development" ? err?.stack : null,
48
+ });
49
+ };
50
+
51
+ export default globalErrorHandler;
@@ -0,0 +1,10 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+
3
+ const notFound = (req: Request, res: Response, next: NextFunction) => {
4
+ res.status(404).json({
5
+ message: 'Sorry Route is not found!! 😴😴😴',
6
+ success: false,
7
+ error: '',
8
+ });
9
+ };
10
+ export default notFound;
@@ -0,0 +1,14 @@
1
+ import { NextFunction, Request, Response } from "express";
2
+
3
+ const RequestValidator = (schema: any) => {
4
+ return async (req: Request, res: Response, next: NextFunction) => {
5
+ try {
6
+ req.body = await schema.parseAsync(req.body);
7
+ next();
8
+ } catch (err) {
9
+ next(err);
10
+ }
11
+ };
12
+ };
13
+
14
+ export default RequestValidator;
@@ -0,0 +1,16 @@
1
+ import multer from "multer";
2
+ import path from "path";
3
+
4
+ const storage = multer.diskStorage({
5
+ destination: function (req, file, cb) {
6
+ cb(null, path.join(process.cwd(), "uploads"))
7
+ },
8
+ filename: function (req, file, cb) {
9
+
10
+ cb(null, file.originalname)
11
+ }
12
+ })
13
+
14
+ const uploader = multer({ storage: storage })
15
+
16
+ export default uploader;
@@ -0,0 +1,116 @@
1
+ import { configs } from "../../configs";
2
+ import catchAsync from "../../utils/catch_async";
3
+ import manageResponse from "../../utils/manage_response";
4
+ import { account_services } from "./account.service";
5
+
6
+ const create_account = catchAsync(async (req, res) => {
7
+ const result = await account_services.create_account_into_db(req);
8
+ manageResponse(res, {
9
+ statusCode: 200,
10
+ success: true,
11
+ message: "Account created successfully",
12
+ data: result,
13
+ });
14
+ });
15
+
16
+ const verify_account_using_otp = catchAsync(async (req, res) => {
17
+ const result = await account_services.verify_account_using_otp_into_db(req);
18
+ manageResponse(res, {
19
+ statusCode: 200,
20
+ success: true,
21
+ message: "Otp verification successfull",
22
+ data: result,
23
+ });
24
+ });
25
+
26
+ const verify_account_using_link = catchAsync(async (req, res) => {
27
+ const result = await account_services.verify_account_using_link_into_db(req);
28
+ manageResponse(res, {
29
+ statusCode: 200,
30
+ success: true,
31
+ message: "Account verification successfull",
32
+ data: result,
33
+ });
34
+ });
35
+
36
+ const login_user = catchAsync(async (req, res) => {
37
+ const result = await account_services.login_user_into_db(req);
38
+
39
+ // set access token into cookie
40
+ res.cookie("access_token", result, {
41
+ secure: configs.env === "production",
42
+ httpOnly: true,
43
+ });
44
+
45
+ manageResponse(res, {
46
+ statusCode: 200,
47
+ success: true,
48
+ message: "User logged in successfully",
49
+ data: {
50
+ accessToken: result,
51
+ },
52
+ });
53
+ });
54
+ const get_user_account = catchAsync(async (req, res) => {
55
+ const result = await account_services.get_user_account_from_db(req);
56
+
57
+ manageResponse(res, {
58
+ statusCode: 200,
59
+ success: true,
60
+ message: "Account fetched successfully",
61
+ data: result,
62
+ });
63
+ });
64
+
65
+ const change_password = catchAsync(async (req, res) => {
66
+ const result = await account_services.change_password_into_db(req);
67
+ manageResponse(res, {
68
+ statusCode: 200,
69
+ success: true,
70
+ message: "Password Change successfully",
71
+ data: result,
72
+ });
73
+ });
74
+
75
+ const resend_otp_and_verification_link = catchAsync(async (req, res) => {
76
+ const result =
77
+ await account_services.resend_otp_and_verification_link_from_db(req);
78
+ manageResponse(res, {
79
+ statusCode: 200,
80
+ success: true,
81
+ message: "OTP reset successfully",
82
+ data: result,
83
+ });
84
+ });
85
+
86
+ const forget_password_genereate_reset_token = catchAsync(async (req, res) => {
87
+ const result =
88
+ await account_services.forget_password_genereate_reset_token_from_db(req);
89
+ manageResponse(res, {
90
+ statusCode: 200,
91
+ success: true,
92
+ message: "Password reset successfully",
93
+ data: result,
94
+ });
95
+ });
96
+
97
+ const reset_password_using_token = catchAsync(async (req, res) => {
98
+ const result = await account_services.reset_password_using_token_into_db(req);
99
+ manageResponse(res, {
100
+ statusCode: 200,
101
+ success: true,
102
+ message: "Password reset successfully",
103
+ data: result,
104
+ });
105
+ });
106
+ export const account_controller = {
107
+ create_account,
108
+ login_user,
109
+ get_user_account,
110
+ change_password,
111
+ verify_account_using_otp,
112
+ resend_otp_and_verification_link,
113
+ verify_account_using_link,
114
+ forget_password_genereate_reset_token,
115
+ reset_password_using_token
116
+ };
@@ -0,0 +1,55 @@
1
+ import { Router } from "express";
2
+ import auth from "../../middlewares/auth";
3
+ import RequestValidator from "../../middlewares/request_validator";
4
+ import { account_controller } from "./account.controller";
5
+ import { account_validation } from "./account.validation";
6
+
7
+ const accountRouter = Router();
8
+
9
+ accountRouter.post(
10
+ "/sign-up",
11
+ RequestValidator(account_validation.sign_up),
12
+ account_controller.create_account,
13
+ );
14
+ accountRouter.post(
15
+ "/sign-in",
16
+ RequestValidator(account_validation.sing_in),
17
+ account_controller.login_user,
18
+ );
19
+ accountRouter.put(
20
+ "/verify-otp",
21
+ RequestValidator(account_validation.verify_otp),
22
+ account_controller.verify_account_using_otp,
23
+ );
24
+ accountRouter.put(
25
+ "/verify-link",
26
+ RequestValidator(account_validation.verify_link),
27
+ account_controller.verify_account_using_link,
28
+ );
29
+ accountRouter.get(
30
+ "/me",
31
+ auth("USER", "ADMIN"),
32
+ account_controller.get_user_account,
33
+ );
34
+ accountRouter.put(
35
+ "/change-password",
36
+ auth("USER", "ADMIN"),
37
+ RequestValidator(account_validation.change_password),
38
+ account_controller.change_password,
39
+ );
40
+ accountRouter.put(
41
+ "/resend-otp",
42
+ RequestValidator(account_validation.resend_otp),
43
+ account_controller.resend_otp_and_verification_link,
44
+ );
45
+ accountRouter.put(
46
+ "/forget-password",
47
+ RequestValidator(account_validation.resend_otp),
48
+ account_controller.forget_password_genereate_reset_token,
49
+ );
50
+ accountRouter.put(
51
+ "/reset-password",
52
+ RequestValidator(account_validation.reset_pass),
53
+ account_controller.reset_password_using_token,
54
+ );
55
+ export default accountRouter;
@@ -0,0 +1,402 @@
1
+ import bcrypt from "bcrypt";
2
+ import { Request } from "express";
3
+ import { configs } from "../../configs";
4
+ import { prisma } from "../../lib/prisma";
5
+ import { AppError } from "../../utils/app_error";
6
+ import { jwtHelpers } from "../../utils/JWT";
7
+ import { otpGenerator } from "../../utils/otpGenerator";
8
+ import sendMail from "../../utils/mail_sender";
9
+
10
+ const create_account_into_db = async (req: Request) => {
11
+ const payload = req?.body;
12
+
13
+ // hash password
14
+ const hashPassword = bcrypt.hashSync(payload.password, 10);
15
+
16
+ // create account and profile
17
+ const result = await prisma.$transaction(async (tx) => {
18
+ const account = await tx.account.create({
19
+ data: {
20
+ email: payload.email,
21
+ password: hashPassword,
22
+ },
23
+ });
24
+
25
+ const profile = await tx.profile.create({
26
+ data: {
27
+ fullName: payload.fullName,
28
+ accountId: account.id,
29
+ },
30
+ });
31
+
32
+ return {
33
+ account,
34
+ profile,
35
+ };
36
+ });
37
+
38
+ // sending otp and verification link
39
+ const newOtp = otpGenerator();
40
+ const verificationToken = jwtHelpers.generateToken(
41
+ {
42
+ email: payload.email,
43
+ accountId: result.account.id,
44
+ },
45
+ configs.jwt.verified_token as string,
46
+ "5m",
47
+ );
48
+ const verificationLink = `${configs.jwt.front_end_url}/verify/token?=${verificationToken}`;
49
+ // save otp into db
50
+ await prisma.account.update({
51
+ where: {
52
+ email: payload.email,
53
+ },
54
+ data: {
55
+ lastOtp: newOtp,
56
+ lastOtpSendingTime: new Date(),
57
+ },
58
+ });
59
+
60
+ await sendMail({
61
+ to: payload.email as string,
62
+ subject: "welcome to - Please verify your account",
63
+ htmlBody: `
64
+ <p><strong>OTP</strong> ${newOtp}</p>
65
+ <small>Otp will be expire in 5 minutes</small>
66
+
67
+ <br/> <br/>
68
+
69
+ <p>Or you can use Verification link </p>
70
+ <p>${verificationLink}</p>
71
+ `,
72
+ textBody: "You can use otp or direct link",
73
+ name: payload.fullName,
74
+ });
75
+ return result;
76
+ };
77
+
78
+ const verify_account_using_otp_into_db = async (req: Request) => {
79
+ const payload: { email: string; otp: string } = req?.body;
80
+ // check account
81
+ const account = await prisma.account.findUnique({
82
+ where: {
83
+ email: payload.email,
84
+ },
85
+ });
86
+ // check if account exists
87
+ if (!account) {
88
+ throw new AppError("Account not found", 404);
89
+ }
90
+ // match with last otp
91
+ const isOtpMatch = payload.otp === account.lastOtp;
92
+ if (!isOtpMatch) {
93
+ throw new AppError("Invalid OTP, Please try again!!", 401);
94
+ }
95
+ // check otp timing
96
+ const OTP_EXPIRY_TIME = 5 * 60 * 1000; // 5 minutes in ms
97
+ const isOtpExpired = account.lastOtpSendingTime
98
+ ? new Date().getTime() - new Date(account.lastOtpSendingTime).getTime() >
99
+ OTP_EXPIRY_TIME
100
+ : true;
101
+
102
+ if (isOtpExpired) {
103
+ throw new AppError("OTP Expired, Please try again!!", 401);
104
+ }
105
+ // change account status
106
+ await prisma.account.update({
107
+ where: {
108
+ id: account.id,
109
+ },
110
+ data: {
111
+ isAccountVerified: true,
112
+ },
113
+ });
114
+ // infuter user welcome email
115
+ return "";
116
+ };
117
+
118
+ const verify_account_using_link_into_db = async (req: Request) => {
119
+ const token = req?.body?.token as string;
120
+ let decoadeToken: any;
121
+ try {
122
+ decoadeToken = jwtHelpers.verifyToken(
123
+ token,
124
+ configs.jwt.verified_token as string,
125
+ );
126
+ } catch (error: any) {
127
+ if (error?.message == "invalid signature") {
128
+ throw new AppError("Invalid Token", 403);
129
+ } else if (error?.message == "jwt expired") {
130
+ throw new AppError("Token expired, please reset again", 403);
131
+ }
132
+ }
133
+ // check account
134
+ const account = await prisma.account.findUnique({
135
+ where: {
136
+ email: decoadeToken.email,
137
+ },
138
+ });
139
+ // check if account exists
140
+ if (!account) {
141
+ throw new AppError("Account not found", 404);
142
+ }
143
+
144
+ // change account status
145
+ await prisma.account.update({
146
+ where: {
147
+ id: account.id,
148
+ },
149
+ data: {
150
+ isAccountVerified: true,
151
+ },
152
+ });
153
+ // infuter user welcome email
154
+ return "";
155
+ };
156
+
157
+ const login_user_into_db = async (req: Request) => {
158
+ const payload = req?.body;
159
+ const account = await prisma.account.findUnique({
160
+ where: {
161
+ email: payload.email,
162
+ },
163
+ });
164
+
165
+ // check if account exists
166
+ if (!account) {
167
+ throw new AppError("Account not found", 404);
168
+ }
169
+
170
+ // checking password
171
+ const isPasswordMatch = bcrypt.compareSync(
172
+ payload.password,
173
+ account.password,
174
+ );
175
+
176
+ if (!isPasswordMatch) {
177
+ throw new AppError("Invalid password", 401);
178
+ }
179
+
180
+ // check if account is deleted
181
+ if (account.isDeleted) {
182
+ throw new AppError("Account is deleted", 401);
183
+ }
184
+ // check if account is verified
185
+ if (!account.isAccountVerified) {
186
+ throw new AppError("Account is not verified", 401);
187
+ }
188
+
189
+ // generate access
190
+ const accessToken = jwtHelpers.generateToken(
191
+ {
192
+ email: account.email,
193
+ role: account.role,
194
+ accountId: account.id,
195
+ },
196
+ configs.jwt.access_token as string,
197
+ configs.jwt.access_expires as string,
198
+ );
199
+ return accessToken;
200
+ };
201
+
202
+ const get_user_account_from_db = async (req: Request) => {
203
+ const user = req?.user;
204
+
205
+ const result = await prisma.account.findUnique({
206
+ where: {
207
+ id: user?.accountId,
208
+ },
209
+ select: {
210
+ id: true,
211
+ email: true,
212
+ role: true,
213
+ isAccountVerified: true,
214
+ isDeleted: true,
215
+ profile: true,
216
+ },
217
+ });
218
+ return result;
219
+ };
220
+
221
+ const change_password_into_db = async (req: Request) => {
222
+ const user = req?.user;
223
+ // payload
224
+ const payload: { oldPassword: string; newPassword: string } = req?.body;
225
+ // check old and new password is not same
226
+ const isSamePassword = payload.oldPassword === payload.newPassword;
227
+ if (isSamePassword) {
228
+ throw new AppError(
229
+ "Old and new password are same, Please provide deffirent password",
230
+ 404,
231
+ );
232
+ }
233
+ // check user validity
234
+ const isUserExist = await prisma.account.findFirst({
235
+ where: {
236
+ email: user?.email,
237
+ },
238
+ });
239
+ // if account not exists
240
+ if (!isUserExist) {
241
+ throw new AppError("Account not found!!", 404);
242
+ }
243
+ // check old password
244
+ const isPasswordMatch = bcrypt.compareSync(
245
+ payload.oldPassword,
246
+ isUserExist.password,
247
+ );
248
+ if (!isPasswordMatch) {
249
+ throw new AppError("Incorrect password", 401);
250
+ }
251
+ // change password logic
252
+ const newHashPassword = bcrypt.hashSync(payload.newPassword, 10);
253
+ await prisma.account.update({
254
+ where: {
255
+ id: isUserExist.id,
256
+ },
257
+ data: {
258
+ password: newHashPassword,
259
+ },
260
+ });
261
+
262
+ // in future email notification for more sucurity
263
+ return "";
264
+ };
265
+
266
+ const resend_otp_and_verification_link_from_db = async (req: Request) => {
267
+ const email = req?.body?.email as string;
268
+ const account = await prisma.account.findUnique({
269
+ where: {
270
+ email,
271
+ },
272
+ });
273
+ // check if account exists
274
+ if (!account) {
275
+ throw new AppError("Account not found", 404);
276
+ }
277
+ // if already verified
278
+ if (account.isAccountVerified) {
279
+ throw new AppError("Account already verified", 403);
280
+ }
281
+ // make new otp and verification link
282
+ const newOtp = otpGenerator();
283
+ const verificationToken = jwtHelpers.generateToken(
284
+ {
285
+ email,
286
+ accountId: account.id,
287
+ },
288
+ configs.jwt.verified_token as string,
289
+ "5m",
290
+ );
291
+ const verificationLink = `${configs.jwt.front_end_url}/verify/token?=${verificationToken}`;
292
+ // save otp into db
293
+ await prisma.account.update({
294
+ where: {
295
+ email,
296
+ },
297
+ data: {
298
+ lastOtp: newOtp,
299
+ lastOtpSendingTime: new Date(),
300
+ },
301
+ });
302
+
303
+ await sendMail({
304
+ to: email as string,
305
+ subject: "New Verification otp and link",
306
+ htmlBody: `
307
+ <p><strong>OTP</strong> ${newOtp}</p>
308
+ <small>Otp will be expire in 5 minutes</small>
309
+
310
+ <br/> <br/>
311
+
312
+ <p>Or you can use Verification link </p>
313
+ <p>${verificationLink}</p>
314
+ `,
315
+ textBody: "You can use otp or direct link",
316
+ });
317
+ };
318
+
319
+ const forget_password_genereate_reset_token_from_db = async (req: Request) => {
320
+ const email = req?.body?.email as string;
321
+ const account = await prisma.account.findUnique({
322
+ where: {
323
+ email,
324
+ },
325
+ });
326
+ // check if account exists
327
+ if (!account) {
328
+ throw new AppError("Account not found", 404);
329
+ }
330
+ // generate forget token
331
+ const verificationToken = jwtHelpers.generateToken(
332
+ {
333
+ email: email,
334
+ accountId: account.id,
335
+ },
336
+ configs.jwt.verified_token as string,
337
+ "5m",
338
+ );
339
+ const verificationLink = `${configs.jwt.front_end_url}/verify/token?=${verificationToken}`;
340
+
341
+ await sendMail({
342
+ to: email as string,
343
+ subject: "Forget Password- Use this link for new password ",
344
+ htmlBody: `
345
+ <p>Your Reset Link: </p>
346
+ <p>${verificationLink}</p>
347
+ `,
348
+ textBody: "",
349
+ });
350
+ };
351
+
352
+ const reset_password_using_token_into_db = async (req: Request) => {
353
+ const token = req?.body?.token as string;
354
+ const newPass = req?.body?.newPass as string;
355
+ let decoadeToken: any;
356
+ try {
357
+ decoadeToken = jwtHelpers.verifyToken(
358
+ token,
359
+ configs.jwt.verified_token as string,
360
+ );
361
+ } catch (error: any) {
362
+ if (error?.message == "invalid signature") {
363
+ throw new AppError("Invalid Token", 403);
364
+ } else if (error?.message == "jwt expired") {
365
+ throw new AppError("Link expired, please reset again", 403);
366
+ }
367
+ }
368
+ // check account
369
+ const account = await prisma.account.findUnique({
370
+ where: {
371
+ email: decoadeToken.email,
372
+ },
373
+ });
374
+ // check if account exists
375
+ if (!account) {
376
+ throw new AppError("Account not found", 404);
377
+ }
378
+
379
+ // change account password
380
+ const newHash = bcrypt.hashSync(newPass, 10);
381
+ await prisma.account.update({
382
+ where: {
383
+ id: account.id,
384
+ },
385
+ data: {
386
+ password: newHash,
387
+ },
388
+ });
389
+ // infuter user alart for changing password
390
+ return "";
391
+ };
392
+ export const account_services = {
393
+ create_account_into_db,
394
+ login_user_into_db,
395
+ get_user_account_from_db,
396
+ change_password_into_db,
397
+ verify_account_using_otp_into_db,
398
+ resend_otp_and_verification_link_from_db,
399
+ verify_account_using_link_into_db,
400
+ forget_password_genereate_reset_token_from_db,
401
+ reset_password_using_token_into_db
402
+ };