moahmedwafy commited on
Commit
ceebe5b
·
unverified ·
2 Parent(s): e9affa5 cefba2c

Merge pull request #29 from Modarb-Ai-Trainer:feat/admin-auth

Browse files
src/common/models/user.model.ts CHANGED
@@ -100,4 +100,4 @@ userSchema.pre("save", async function (next) {
100
 
101
  export type UserDocument = IUser & mongoose.Document;
102
 
103
- export const userModel = mongoose.model<UserDocument>("userse", userSchema);
 
100
 
101
  export type UserDocument = IUser & mongoose.Document;
102
 
103
+ export const User = mongoose.model<UserDocument>("users", userSchema);
src/helpers/jwt.helper.ts CHANGED
@@ -1,8 +1,9 @@
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,
8
  });
 
1
  import jwt from "jsonwebtoken";
2
  import { config } from "../configs/config";
3
+ import { IJwtLoginPayload } from "@common/interfaces/jwt-payload.interface";
4
 
5
  export class JwtHelper {
6
+ static generateToken(payload: IJwtLoginPayload) {
7
  return jwt.sign(payload, config.jwt.secret, {
8
  expiresIn: config.jwt.expiresIn,
9
  });
src/lib/guards/gen-guard.ts ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { IJwtLoginPayload } from "@common/interfaces/jwt-payload.interface";
2
+ import { JwtPayload, verify } from "jsonwebtoken";
3
+ import { HttpError } from "@lib/error-handling/http-error";
4
+ import { NextFunction, Request, Response } from "express";
5
+ import { config } from "@configs/config";
6
+
7
+ type OptionalIfUndefined<T> = [T] extends [undefined]
8
+ ? (args?: T) => void
9
+ : (args: T) => void;
10
+
11
+ export const genGuard =
12
+ <T = undefined>(
13
+ validationMethod?: (
14
+ validationArgs: T,
15
+ payload: IJwtLoginPayload,
16
+ req: Request,
17
+ res: Response
18
+ ) => boolean | Promise<boolean>
19
+ ): OptionalIfUndefined<T> =>
20
+ (args: T) =>
21
+ async (req: Request, res: Response, next: NextFunction) => {
22
+ // get token from cookie
23
+ const token = req.headers.authorization?.split(" ")[1];
24
+ let payload: IJwtLoginPayload;
25
+
26
+ // validate token
27
+ if (!token) {
28
+ throw new HttpError(401, "Unauthorized");
29
+ }
30
+
31
+ try {
32
+ payload = verify(token, config.jwt.secret);
33
+ } catch (err) {
34
+ throw new HttpError(401, "Unauthorized");
35
+ }
36
+
37
+ if (
38
+ validationMethod &&
39
+ !(await validationMethod(args, payload, req, res))
40
+ ) {
41
+ throw new HttpError(401, "Unauthorized");
42
+ }
43
+
44
+ // inject payload in request
45
+ (req as unknown as { jwtPayload: JwtPayload }).jwtPayload = payload;
46
+
47
+ // go on
48
+ next();
49
+ };
src/modules/console/common/guards/admins.guard.ts CHANGED
@@ -1,45 +1,23 @@
1
- import { JwtPayload, verify } from "jsonwebtoken";
2
- import { Request } from "express";
3
  import { Role } from "@common/enums/role.enum";
4
- import { HttpError } from "@lib/error-handling/http-error";
5
- import { config } from "@configs/config";
6
  import { IJwtLoginPayload } from "@common/interfaces/jwt-payload.interface";
 
7
 
8
  type AdminGuardMiddlewareProps = {
9
  roles?: Role[];
10
  };
11
 
12
- export const AdminGuardMiddleware =
13
- (props?: AdminGuardMiddlewareProps) => (req: Request, res, next) => {
14
- // get token from cookie
15
- const token = req.headers.authorization?.split(" ")[1];
16
- let payload: IJwtLoginPayload;
17
-
18
- // validate token
19
- if (!token) {
20
- throw new HttpError(401, "Unauthorized");
21
- }
22
-
23
- try {
24
- payload = verify(token, config.jwt.secret);
25
- } catch (err) {
26
- throw new HttpError(401, "Unauthorized");
27
- }
28
-
29
  if (payload.type !== "admin") {
30
- throw new HttpError(401, "Unauthorized");
31
  }
32
 
33
- // check roles
34
- if (props?.roles && props?.roles.length > 0) {
35
- if (!props.roles.includes(payload.role)) {
36
- throw new HttpError(401, "Unauthorized");
37
  }
38
  }
39
 
40
- // inject payload in request
41
- (req as unknown as { jwtPayload: JwtPayload }).jwtPayload = payload;
42
-
43
- // go on
44
- next();
45
- };
 
 
 
1
  import { Role } from "@common/enums/role.enum";
 
 
2
  import { IJwtLoginPayload } from "@common/interfaces/jwt-payload.interface";
3
+ import { genGuard } from "@lib/guards/gen-guard";
4
 
5
  type AdminGuardMiddlewareProps = {
6
  roles?: Role[];
7
  };
8
 
9
+ export const AdminGuardMiddleware = genGuard(
10
+ async (args: AdminGuardMiddlewareProps, payload: IJwtLoginPayload) => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  if (payload.type !== "admin") {
12
+ return false;
13
  }
14
 
15
+ if (args?.roles && args?.roles.length > 0) {
16
+ if (!args.roles.includes(payload.role)) {
17
+ return false;
 
18
  }
19
  }
20
 
21
+ return true;
22
+ }
23
+ );
 
 
 
src/modules/console/modules/auth/controllers/auth.controller.ts ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { asyncHandler } from "@helpers/async-handler";
2
+ import { serialize } from "@helpers/serialize";
3
+ import { bodyValidator } from "@helpers/validation.helper";
4
+ import { BaseController } from "@lib/controllers/controller.base";
5
+ import { Prefix } from "@lib/decorators/prefix.decorator";
6
+ import { JsonResponse } from "@lib/responses/json-response";
7
+ import { Request, Response } from "express";
8
+ import { loginValidationSchema } from "modules/users/modules/auth/validation/login.validation";
9
+ import { ConsoleAuthService } from "../services/auth.service";
10
+ import { AdminSerialization } from "modules/console/common/serializers/admin.serialization";
11
+
12
+ @Prefix("/console/auth")
13
+ export class ConsoleAuthController extends BaseController {
14
+ private authService = new ConsoleAuthService();
15
+
16
+ public setRoutes(): void {
17
+ this.router.post(
18
+ "/login",
19
+ bodyValidator(loginValidationSchema),
20
+ asyncHandler(this.login)
21
+ );
22
+ }
23
+
24
+ login = async (req: Request, res: Response): Promise<Response> => {
25
+ const { admin, token } = await this.authService.login(req.body);
26
+
27
+ return JsonResponse.success(
28
+ {
29
+ data: { admin: serialize(admin, AdminSerialization), token },
30
+ },
31
+ res
32
+ );
33
+ };
34
+ }
src/modules/console/modules/auth/services/auth.service.ts ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { CrudService } from "@lib/services/crud.service";
2
+ import { Admin } from "modules/console/common/models/admin.model";
3
+ import { ILogin } from "modules/users/modules/auth/validation/login.validation";
4
+ import bcrypt from "bcrypt";
5
+ import { HttpError } from "@lib/error-handling/http-error";
6
+ import { JwtHelper } from "@helpers/jwt.helper";
7
+
8
+ export class ConsoleAuthService extends CrudService(Admin) {
9
+ async login(loginRequest: ILogin) {
10
+ const admin = await this.findOneOrFail({ email: loginRequest.email });
11
+ const isPasswordCorrect = await bcrypt.compare(
12
+ loginRequest.password,
13
+ admin.password
14
+ );
15
+ if (!isPasswordCorrect) throw new HttpError(401, "Incorrect Password");
16
+ const token = JwtHelper.generateToken({
17
+ id: admin._id,
18
+ email: admin.email,
19
+ name: admin.name,
20
+ type: "admin",
21
+ role: admin.role,
22
+ });
23
+ return { admin: admin, token };
24
+ }
25
+ }
src/modules/console/modules/users/services/users.service.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { userModel } from "@common/models/user.model";
2
  import { CrudService } from "@lib/services/crud.service";
3
 
4
- export class UsersService extends CrudService(userModel) {}
 
1
+ import { User } from "@common/models/user.model";
2
  import { CrudService } from "@lib/services/crud.service";
3
 
4
+ export class UsersService extends CrudService(User) {}
src/modules/users/common/guards/users.guard.ts CHANGED
@@ -1,34 +1,6 @@
1
- import { JwtPayload, verify } from "jsonwebtoken";
2
- import { Request } from "express";
3
- import { HttpError } from "@lib/error-handling/http-error";
4
- import { config } from "@configs/config";
5
  import { IJwtLoginPayload } from "@common/interfaces/jwt-payload.interface";
 
6
 
7
- export const UsersGuardMiddleware =
8
- () => (req: Request, res, next) => {
9
- // get token from cookie
10
- const token = req.headers.authorization?.split(" ")[1];
11
- let payload: IJwtLoginPayload;
12
-
13
- // validate token
14
- if (!token) {
15
- throw new HttpError(401, "Unauthorized");
16
- }
17
-
18
- try {
19
- payload = verify(token, config.jwt.secret);
20
- } catch (err) {
21
- throw new HttpError(401, "Unauthorized");
22
- }
23
-
24
- if (payload.type !== "user") {
25
- throw new HttpError(401, "Unauthorized");
26
- }
27
-
28
-
29
- // inject payload in request
30
- (req as unknown as { jwtPayload: JwtPayload }).jwtPayload = payload;
31
-
32
- // go on
33
- next();
34
- };
 
 
 
 
 
1
  import { IJwtLoginPayload } from "@common/interfaces/jwt-payload.interface";
2
+ import { genGuard } from "@lib/guards/gen-guard";
3
 
4
+ export const UsersGuardMiddleware = genGuard(
5
+ async (args, payload: IJwtLoginPayload) => payload.type === "user"
6
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/modules/users/modules/auth/services/users-auth.service.ts CHANGED
@@ -2,11 +2,11 @@ import bcrypt from "bcrypt";
2
  import { ILogin } from "../validation/login.validation";
3
  import { HttpError } from "@lib/error-handling/http-error";
4
  import { JwtHelper } from "@helpers/jwt.helper";
5
- import { userModel } from "@common/models/user.model";
6
  import { IUserRegister } from "@common/validations/user-register.validation";
7
  import { CrudService } from "@lib/services/crud.service";
8
 
9
- export class UsersAuthService extends CrudService(userModel) {
10
  async register(createParams: IUserRegister) {
11
  return this.create(createParams);
12
  }
@@ -18,7 +18,12 @@ export class UsersAuthService extends CrudService(userModel) {
18
  user.password
19
  );
20
  if (!isPasswordCorrect) throw new HttpError(401, "Incorrect Password");
21
- const token = JwtHelper.generateToken({ id: user._id, role: user.role });
 
 
 
 
 
22
  return { user, token };
23
  }
24
  }
 
2
  import { ILogin } from "../validation/login.validation";
3
  import { HttpError } from "@lib/error-handling/http-error";
4
  import { JwtHelper } from "@helpers/jwt.helper";
5
+ import { User } from "@common/models/user.model";
6
  import { IUserRegister } from "@common/validations/user-register.validation";
7
  import { CrudService } from "@lib/services/crud.service";
8
 
9
+ export class UsersAuthService extends CrudService(User) {
10
  async register(createParams: IUserRegister) {
11
  return this.create(createParams);
12
  }
 
18
  user.password
19
  );
20
  if (!isPasswordCorrect) throw new HttpError(401, "Incorrect Password");
21
+ const token = JwtHelper.generateToken({
22
+ id: user._id,
23
+ email: user.email,
24
+ name: user.name,
25
+ type: "user",
26
+ });
27
  return { user, token };
28
  }
29
  }
src/modules/users/modules/auth/services/users.service.ts CHANGED
@@ -2,11 +2,11 @@ import bcrypt from "bcrypt";
2
  import { ILogin } from "../validation/login.validation";
3
  import { HttpError } from "@lib/error-handling/http-error";
4
  import { JwtHelper } from "@helpers/jwt.helper";
5
- import { userModel } from "@common/models/user.model";
6
  import { IUserRegister } from "@common/validations/user-register.validation";
7
  import { CrudService } from "@lib/services/crud.service";
8
 
9
- export class UsersAuthService extends CrudService(userModel) {
10
  async register(createParams: IUserRegister) {
11
  return this.create(createParams);
12
  }
@@ -18,7 +18,12 @@ export class UsersAuthService extends CrudService(userModel) {
18
  user.password
19
  );
20
  if (!isPasswordCorrect) throw new HttpError(401, "Incorrect Password");
21
- const token = JwtHelper.generateToken({ id: user._id, role: user.role });
 
 
 
 
 
22
  return { user, token };
23
  }
24
  }
 
2
  import { ILogin } from "../validation/login.validation";
3
  import { HttpError } from "@lib/error-handling/http-error";
4
  import { JwtHelper } from "@helpers/jwt.helper";
5
+ import { User } from "@common/models/user.model";
6
  import { IUserRegister } from "@common/validations/user-register.validation";
7
  import { CrudService } from "@lib/services/crud.service";
8
 
9
+ export class UsersAuthService extends CrudService(User) {
10
  async register(createParams: IUserRegister) {
11
  return this.create(createParams);
12
  }
 
18
  user.password
19
  );
20
  if (!isPasswordCorrect) throw new HttpError(401, "Incorrect Password");
21
+ const token = JwtHelper.generateToken({
22
+ id: user._id,
23
+ email: user.email,
24
+ name: user.name,
25
+ type: "user",
26
+ });
27
  return { user, token };
28
  }
29
  }