Spaces:
Running
Running
Commit
·
677259a
1
Parent(s):
093279d
update: users service
Browse files- src/helpers/jwt.helper.ts +1 -1
- src/lib/error-handling/http-error.ts +13 -0
- src/modules/common/users/models/user.model.ts +2 -0
- src/modules/common/users/services/users.base.service.ts +40 -100
- src/modules/console/users/controllers/users.controller.ts +7 -13
- src/modules/console/users/services/users.service.ts +2 -2
- src/modules/users/auth/controllers/auth.controller.ts +14 -45
- src/modules/users/auth/services/users.service.ts +14 -33
- src/modules/users/auth/validation/{user.Validation.ts → login.validation.ts} +0 -0
src/helpers/jwt.helper.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import jwt from "jsonwebtoken";
|
2 |
import { config } from "../configs/config";
|
3 |
|
4 |
-
export class
|
5 |
static generateToken(payload: any) {
|
6 |
return jwt.sign(payload, config.jwt.secret, {
|
7 |
expiresIn: config.jwt.expiresIn,
|
|
|
1 |
import jwt from "jsonwebtoken";
|
2 |
import { config } from "../configs/config";
|
3 |
|
4 |
+
export class JwtHelper {
|
5 |
static generateToken(payload: any) {
|
6 |
return jwt.sign(payload, config.jwt.secret, {
|
7 |
expiresIn: config.jwt.expiresIn,
|
src/lib/error-handling/http-error.ts
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import http from "http";
|
2 |
+
|
3 |
+
export class HttpError extends Error {
|
4 |
+
status: number;
|
5 |
+
constructor(status: number, message?: string | object) {
|
6 |
+
if (typeof message === "object") {
|
7 |
+
message = JSON.stringify(message);
|
8 |
+
}
|
9 |
+
|
10 |
+
super(message || http.STATUS_CODES[status] || "Error");
|
11 |
+
this.status = status;
|
12 |
+
}
|
13 |
+
}
|
src/modules/common/users/models/user.model.ts
CHANGED
@@ -85,4 +85,6 @@ userSchema.pre("save", async function (next) {
|
|
85 |
next();
|
86 |
});
|
87 |
|
|
|
|
|
88 |
export const userModel = mongoose.model<IUser>("users", userSchema);
|
|
|
85 |
next();
|
86 |
});
|
87 |
|
88 |
+
export type UserDocument = IUser & mongoose.Document;
|
89 |
+
|
90 |
export const userModel = mongoose.model<IUser>("users", userSchema);
|
src/modules/common/users/services/users.base.service.ts
CHANGED
@@ -1,114 +1,54 @@
|
|
1 |
-
import {
|
|
|
|
|
2 |
|
3 |
-
export abstract class
|
4 |
-
async
|
5 |
-
|
6 |
-
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
|
15 |
-
return
|
16 |
-
success: true,
|
17 |
-
code: 200,
|
18 |
-
record: resultObject,
|
19 |
-
};
|
20 |
} catch (err) {
|
21 |
-
console.
|
22 |
-
|
23 |
-
success: false,
|
24 |
-
code: 500,
|
25 |
-
error: err.message,
|
26 |
-
};
|
27 |
}
|
28 |
}
|
29 |
|
30 |
-
async
|
31 |
-
|
32 |
-
if (form.email) {
|
33 |
-
form.email = form.email.toLowerCase();
|
34 |
-
let user = await this.find({ email: form.email });
|
35 |
-
if (user.success)
|
36 |
-
return {
|
37 |
-
success: false,
|
38 |
-
error: "This email already exists",
|
39 |
-
code: 409,
|
40 |
-
};
|
41 |
-
}
|
42 |
-
let newUser = new userModel(form);
|
43 |
-
await newUser.save();
|
44 |
-
return {
|
45 |
-
success: true,
|
46 |
-
code: 201,
|
47 |
-
};
|
48 |
-
} catch (err) {
|
49 |
-
console.log(`err.message`, err.message);
|
50 |
-
return {
|
51 |
-
success: false,
|
52 |
-
code: 500,
|
53 |
-
error: err.message,
|
54 |
-
};
|
55 |
-
}
|
56 |
}
|
57 |
|
58 |
-
async
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
if (!resultObject)
|
65 |
-
return {
|
66 |
-
success: false,
|
67 |
-
code: 404,
|
68 |
-
error: "No Matching Result Found.",
|
69 |
-
};
|
70 |
-
return {
|
71 |
-
success: true,
|
72 |
-
code: 200,
|
73 |
-
record: resultObject,
|
74 |
-
};
|
75 |
-
} catch (err) {
|
76 |
-
console.log(`err.message`, err.message);
|
77 |
-
return {
|
78 |
-
success: false,
|
79 |
-
code: 500,
|
80 |
-
error: err.message,
|
81 |
-
};
|
82 |
-
}
|
83 |
}
|
84 |
|
85 |
-
async
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
code: 200,
|
102 |
-
record: resultArray,
|
103 |
-
count,
|
104 |
-
};
|
105 |
-
} catch (err) {
|
106 |
-
console.log(`err.message`, err.message);
|
107 |
-
return {
|
108 |
-
success: false,
|
109 |
-
code: 500,
|
110 |
-
error: "Unexpected Error Happened.",
|
111 |
-
};
|
112 |
-
}
|
113 |
}
|
114 |
}
|
|
|
1 |
+
import { FilterQuery, QueryWithHelpers } from "mongoose";
|
2 |
+
import { IUser, UserDocument, userModel } from "../models/user.model";
|
3 |
+
import { HttpError } from "src/lib/error-handling/http-error";
|
4 |
|
5 |
+
export abstract class BaseUsersService {
|
6 |
+
async findOne(filterObject: FilterQuery<UserDocument>) {
|
7 |
+
return userModel.findOne(filterObject);
|
8 |
+
}
|
9 |
|
10 |
+
async findOneOrFail(
|
11 |
+
filterObject: FilterQuery<UserDocument>
|
12 |
+
): Promise<UserDocument> {
|
13 |
+
try {
|
14 |
+
const document = await this.findOne(filterObject);
|
15 |
+
if (!document) throw new HttpError(404, "No Matching Result Found.");
|
16 |
|
17 |
+
return document;
|
|
|
|
|
|
|
|
|
18 |
} catch (err) {
|
19 |
+
console.error(err);
|
20 |
+
throw new HttpError(500, "Unexpected Error Happened.");
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
}
|
23 |
|
24 |
+
async userExists(filterObject: FilterQuery<UserDocument>): Promise<boolean> {
|
25 |
+
return (await this.findOne(filterObject)) !== null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
}
|
27 |
|
28 |
+
async create(createParams: IUser): Promise<UserDocument> {
|
29 |
+
if (await this.userExists({ email: createParams.email }))
|
30 |
+
throw new HttpError(409, "Email Already Exists.");
|
31 |
+
|
32 |
+
const newUser = new userModel(createParams) as UserDocument;
|
33 |
+
return newUser.save();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
+
async get(filterObject: FilterQuery<UserDocument>): Promise<UserDocument> {
|
37 |
+
const user: UserDocument = await userModel
|
38 |
+
.findOne(filterObject)
|
39 |
+
.select("-password");
|
40 |
+
if (!user) throw new HttpError(404, "No Matching Result Found.");
|
41 |
+
return user;
|
42 |
+
}
|
43 |
|
44 |
+
async list(filterObject: FilterQuery<UserDocument>): Promise<{
|
45 |
+
docs: UserDocument[];
|
46 |
+
count: number;
|
47 |
+
}> {
|
48 |
+
const users = (await userModel
|
49 |
+
.find(filterObject)
|
50 |
+
.select("-password")) as UserDocument[];
|
51 |
+
const count = await userModel.countDocuments(filterObject);
|
52 |
+
return { docs: users, count };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
}
|
54 |
}
|
src/modules/console/users/controllers/users.controller.ts
CHANGED
@@ -1,10 +1,11 @@
|
|
1 |
import { userRegisterSchema } from "src/modules/common/users/validation/user-register.validation";
|
2 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
3 |
-
import {
|
4 |
import { bodyValidator } from "../../../../helpers/validation.helper";
|
5 |
import { BaseController } from "../../../../lib/controllers/controller.base";
|
6 |
import { Prefix } from "../../../../lib/decorators/prefix.decorator";
|
7 |
import { UsersService } from "../services/users.service";
|
|
|
8 |
|
9 |
const allowedRoles = ["superAdmin", "admin"];
|
10 |
|
@@ -15,23 +16,16 @@ export class AdminUsersController extends BaseController {
|
|
15 |
setRoutes() {
|
16 |
this.router.post(
|
17 |
"/create",
|
18 |
-
|
19 |
bodyValidator(userRegisterSchema),
|
20 |
asyncHandler(this.create)
|
21 |
);
|
22 |
}
|
23 |
|
24 |
create = async (req, res) => {
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
}
|
29 |
-
console.log(`err.message`, err.message);
|
30 |
-
return res.status(500).json({
|
31 |
-
success: false,
|
32 |
-
code: 500,
|
33 |
-
error: err.message,
|
34 |
-
});
|
35 |
-
}
|
36 |
};
|
37 |
}
|
|
|
1 |
import { userRegisterSchema } from "src/modules/common/users/validation/user-register.validation";
|
2 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
3 |
+
import { JwtHelper } from "../../../../helpers/jwt.helper";
|
4 |
import { bodyValidator } from "../../../../helpers/validation.helper";
|
5 |
import { BaseController } from "../../../../lib/controllers/controller.base";
|
6 |
import { Prefix } from "../../../../lib/decorators/prefix.decorator";
|
7 |
import { UsersService } from "../services/users.service";
|
8 |
+
import { JsonResponse } from "src/lib/responses/json-response";
|
9 |
|
10 |
const allowedRoles = ["superAdmin", "admin"];
|
11 |
|
|
|
16 |
setRoutes() {
|
17 |
this.router.post(
|
18 |
"/create",
|
19 |
+
JwtHelper.verifyToken(allowedRoles),
|
20 |
bodyValidator(userRegisterSchema),
|
21 |
asyncHandler(this.create)
|
22 |
);
|
23 |
}
|
24 |
|
25 |
create = async (req, res) => {
|
26 |
+
let user = await this.usersService.create(req.body);
|
27 |
+
return new JsonResponse({
|
28 |
+
data: user,
|
29 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
};
|
31 |
}
|
src/modules/console/users/services/users.service.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
import {
|
2 |
|
3 |
-
export class UsersService extends
|
|
|
1 |
+
import { BaseUsersService } from "../../../common/users/services/users.base.service";
|
2 |
|
3 |
+
export class UsersService extends BaseUsersService {}
|
src/modules/users/auth/controllers/auth.controller.ts
CHANGED
@@ -1,15 +1,17 @@
|
|
1 |
import { UsersAuthService } from "../services/users.service";
|
2 |
-
import { jwtHelper } from "../../../../helpers/jwt.helper";
|
3 |
import { BaseController } from "../../../../lib/controllers/controller.base";
|
4 |
import { bodyValidator } from "../../../../helpers/validation.helper";
|
5 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
6 |
import { Prefix } from "../../../../lib/decorators/prefix.decorator";
|
7 |
-
import { loginValidationSchema } from "../validation/
|
8 |
import { userRegisterSchema } from "src/modules/common/users/validation/user-register.validation";
|
|
|
|
|
|
|
9 |
|
10 |
@Prefix("/users/auth")
|
11 |
export class UsersAuthController extends BaseController {
|
12 |
-
private
|
13 |
|
14 |
setRoutes(): void {
|
15 |
this.router.post(
|
@@ -24,50 +26,17 @@ export class UsersAuthController extends BaseController {
|
|
24 |
);
|
25 |
}
|
26 |
|
27 |
-
register = async (req, res) => {
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
}
|
32 |
-
console.log(`err.message`, err.message);
|
33 |
-
return res.status(500).json({
|
34 |
-
success: false,
|
35 |
-
code: 500,
|
36 |
-
error: err.message,
|
37 |
-
});
|
38 |
-
}
|
39 |
};
|
40 |
|
41 |
login = async (req, res) => {
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
code: number;
|
47 |
-
record?: any;
|
48 |
-
message?: string;
|
49 |
-
} = await this.usersService.comparePassword(email, password);
|
50 |
-
if (!result.success) return res.status(result.code).json(result);
|
51 |
-
let payload = {
|
52 |
-
_id: result.record?._id,
|
53 |
-
name: result.record?.name,
|
54 |
-
email: result.record?.email,
|
55 |
-
number: result.record?.number,
|
56 |
-
role: result.record?.role,
|
57 |
-
};
|
58 |
-
const token = jwtHelper.generateToken(payload);
|
59 |
-
return res.status(result.code).json({
|
60 |
-
success: result.success,
|
61 |
-
token,
|
62 |
-
code: result.code,
|
63 |
-
record: result.record,
|
64 |
-
});
|
65 |
-
} catch (err) {
|
66 |
-
console.log(`err.message`, err.message);
|
67 |
-
return res.status(500).json({
|
68 |
-
success: false,
|
69 |
-
message: err.message,
|
70 |
-
});
|
71 |
-
}
|
72 |
};
|
73 |
}
|
|
|
1 |
import { UsersAuthService } from "../services/users.service";
|
|
|
2 |
import { BaseController } from "../../../../lib/controllers/controller.base";
|
3 |
import { bodyValidator } from "../../../../helpers/validation.helper";
|
4 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
5 |
import { Prefix } from "../../../../lib/decorators/prefix.decorator";
|
6 |
+
import { loginValidationSchema } from "../validation/login.validation";
|
7 |
import { userRegisterSchema } from "src/modules/common/users/validation/user-register.validation";
|
8 |
+
import { Request, Response } from "express";
|
9 |
+
import { IUser } from "src/modules/common/users/models/user.model";
|
10 |
+
import { JsonResponse } from "src/lib/responses/json-response";
|
11 |
|
12 |
@Prefix("/users/auth")
|
13 |
export class UsersAuthController extends BaseController {
|
14 |
+
private authService = new UsersAuthService();
|
15 |
|
16 |
setRoutes(): void {
|
17 |
this.router.post(
|
|
|
26 |
);
|
27 |
}
|
28 |
|
29 |
+
register = async (req: Request, res: Response) => {
|
30 |
+
let user = await this.authService.create(req.body as IUser);
|
31 |
+
return new JsonResponse({
|
32 |
+
data: user,
|
33 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
};
|
35 |
|
36 |
login = async (req, res) => {
|
37 |
+
const { user, token } = await this.authService.login(req.body);
|
38 |
+
return new JsonResponse({
|
39 |
+
data: { user, token },
|
40 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
};
|
42 |
}
|
src/modules/users/auth/services/users.service.ts
CHANGED
@@ -1,37 +1,18 @@
|
|
1 |
-
import {
|
2 |
import bcrypt from "bcrypt";
|
|
|
|
|
|
|
3 |
|
4 |
-
export class UsersAuthService extends
|
5 |
-
async
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
delete result.record.password;
|
15 |
-
|
16 |
-
if (!match)
|
17 |
-
return {
|
18 |
-
success: false,
|
19 |
-
code: 409,
|
20 |
-
message: "password isn't correct",
|
21 |
-
};
|
22 |
-
|
23 |
-
return {
|
24 |
-
success: true,
|
25 |
-
code: 200,
|
26 |
-
record: result.record,
|
27 |
-
};
|
28 |
-
} catch (err) {
|
29 |
-
console.log(`err.message`, err.message);
|
30 |
-
return {
|
31 |
-
success: false,
|
32 |
-
code: 500,
|
33 |
-
error: err.message,
|
34 |
-
};
|
35 |
-
}
|
36 |
}
|
37 |
}
|
|
|
1 |
+
import { BaseUsersService } from "../../../common/users/services/users.base.service";
|
2 |
import bcrypt from "bcrypt";
|
3 |
+
import { ILogin } from "../validation/login.validation";
|
4 |
+
import { HttpError } from "src/lib/error-handling/http-error";
|
5 |
+
import { JwtHelper } from "src/helpers/jwt.helper";
|
6 |
|
7 |
+
export class UsersAuthService extends BaseUsersService {
|
8 |
+
async login(loginRequest: ILogin) {
|
9 |
+
const user = await this.findOneOrFail({ email: loginRequest.email });
|
10 |
+
const isPasswordCorrect = await bcrypt.compare(
|
11 |
+
loginRequest.password,
|
12 |
+
user.password
|
13 |
+
);
|
14 |
+
if (!isPasswordCorrect) throw new HttpError(401, "Incorrect Password");
|
15 |
+
const token = JwtHelper.generateToken({ id: user._id, role: user.role });
|
16 |
+
return { user, token };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
}
|
18 |
}
|
src/modules/users/auth/validation/{user.Validation.ts → login.validation.ts}
RENAMED
File without changes
|