Spaces:
Running
Running
Commit
·
484fdbc
1
Parent(s):
677259a
feat: crud service
Browse files- src/common/enums/authenticatable-type.enum.ts +4 -0
- src/common/enums/fitness-goal.enum.ts +5 -0
- src/common/enums/fitness-level.enum.ts +5 -0
- src/common/enums/gender.enum.ts +4 -0
- src/common/enums/injury.enum.ts +7 -0
- src/common/enums/preferred-day.enum.ts +9 -0
- src/common/enums/preferred-equipment.enum.ts +7 -0
- src/{modules/console/admins/enums/roles.enum.ts → common/enums/role.enum.ts} +0 -0
- src/common/enums/workout-place.enum.ts +5 -0
- src/{modules/common/templates → common}/models/template.model.ts +0 -0
- src/common/models/user.model.ts +103 -0
- src/{modules/common/users → common}/services/users.base.service.ts +2 -2
- src/{modules/common/users/validation → common/validations}/user-register.validation.ts +9 -12
- src/configs/config.ts +1 -1
- src/configs/env.ts +0 -25
- src/helpers/jwt.helper.ts +14 -14
- src/helpers/pagination.ts +11 -0
- src/lib/responses/json-response.ts +13 -15
- src/lib/services/crud.service.ts +68 -0
- src/modules/common/users/enums/roles.enum.ts +0 -45
- src/modules/common/users/models/user.model.ts +0 -90
- src/modules/console/admins/controllers/admins.controller.ts +48 -24
- src/modules/console/admins/models/admin.model.ts +3 -7
- src/modules/console/admins/services/admins.service.ts +3 -266
- src/modules/console/admins/validations/create-admin.validation.ts +1 -1
- src/modules/console/users/controllers/users.controller.ts +5 -3
- src/modules/console/users/services/users.service.ts +3 -2
- src/modules/users/auth/controllers/auth.controller.ts +7 -6
- src/modules/users/auth/services/users.service.ts +8 -2
- tsconfig.json +0 -1
src/common/enums/authenticatable-type.enum.ts
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum AuthenticatableType {
|
2 |
+
USER = "user",
|
3 |
+
ADMIN = "admin",
|
4 |
+
}
|
src/common/enums/fitness-goal.enum.ts
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum FitnessGoal {
|
2 |
+
LOSE_WEIGHT = "lose weight",
|
3 |
+
GAIN_MUSCLE = "gain muscle",
|
4 |
+
GET_FITTER = "get fitter",
|
5 |
+
}
|
src/common/enums/fitness-level.enum.ts
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum FitnessLevel {
|
2 |
+
BEGINNER = "beginner",
|
3 |
+
INTERMEDIATE = "intermediate",
|
4 |
+
ADVANCED = "advanced",
|
5 |
+
}
|
src/common/enums/gender.enum.ts
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum Gender {
|
2 |
+
MALE = "male",
|
3 |
+
FEMALE = "female",
|
4 |
+
}
|
src/common/enums/injury.enum.ts
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum Injury {
|
2 |
+
NECK = "neck",
|
3 |
+
SHOULDERS = "shoulders",
|
4 |
+
BACK = "back",
|
5 |
+
ARMS = "arms",
|
6 |
+
KNEES = "knees",
|
7 |
+
}
|
src/common/enums/preferred-day.enum.ts
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum PreferredDay {
|
2 |
+
SATURDAY = "saturday",
|
3 |
+
SUNDAY = "sunday",
|
4 |
+
MONDAY = "monday",
|
5 |
+
TUESDAY = "tuesday",
|
6 |
+
WEDNESDAY = "wednesday",
|
7 |
+
THURSDAY = "thursday",
|
8 |
+
FRIDAY = "friday",
|
9 |
+
}
|
src/common/enums/preferred-equipment.enum.ts
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum PreferredEquipment {
|
2 |
+
BARBELLS = "barbells",
|
3 |
+
DUMBBELLS = "dumbbells",
|
4 |
+
GYM_MACHINES = "gym machines",
|
5 |
+
RESISTANCE_BAND = "resistance band",
|
6 |
+
BODYWEIGHT = "bodyweight",
|
7 |
+
}
|
src/{modules/console/admins/enums/roles.enum.ts → common/enums/role.enum.ts}
RENAMED
File without changes
|
src/common/enums/workout-place.enum.ts
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export enum WorkoutPlace {
|
2 |
+
GYM = "gym",
|
3 |
+
HOME = "home",
|
4 |
+
BOTH = "both",
|
5 |
+
}
|
src/{modules/common/templates → common}/models/template.model.ts
RENAMED
File without changes
|
src/common/models/user.model.ts
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import mongoose from "mongoose";
|
2 |
+
import bcrypt from "bcrypt";
|
3 |
+
import { AuthenticatableType } from "@common/enums/authenticatable-type.enum";
|
4 |
+
import { FitnessGoal } from "@common/enums/fitness-goal.enum";
|
5 |
+
import { FitnessLevel } from "@common/enums/fitness-level.enum";
|
6 |
+
import { Gender } from "@common/enums/gender.enum";
|
7 |
+
import { Injury } from "@common/enums/injury.enum";
|
8 |
+
import { PreferredDay } from "@common/enums/preferred-day.enum";
|
9 |
+
import { PreferredEquipment } from "@common/enums/preferred-equipment.enum";
|
10 |
+
import { WorkoutPlace } from "@common/enums/workout-place.enum";
|
11 |
+
export const saltrounds = 5;
|
12 |
+
const { Schema } = mongoose;
|
13 |
+
|
14 |
+
export interface IUser {
|
15 |
+
name: string;
|
16 |
+
email: string;
|
17 |
+
password: string;
|
18 |
+
image: object;
|
19 |
+
role: AuthenticatableType;
|
20 |
+
gender: string;
|
21 |
+
dob: Date;
|
22 |
+
height: number;
|
23 |
+
weight: number;
|
24 |
+
fitness_level: string;
|
25 |
+
preferences: {
|
26 |
+
fitness_goal: FitnessGoal;
|
27 |
+
target_weight: number;
|
28 |
+
workout_frequency: number;
|
29 |
+
preferred_days: [PreferredDay];
|
30 |
+
workout_place: WorkoutPlace;
|
31 |
+
preferred_equipment: [PreferredEquipment];
|
32 |
+
};
|
33 |
+
injuries: [Injury];
|
34 |
+
}
|
35 |
+
|
36 |
+
const userSchema = new Schema({
|
37 |
+
name: { type: String, required: true },
|
38 |
+
email: { type: String, required: true, unique: true, dropDups: true },
|
39 |
+
password: { type: String, required: true },
|
40 |
+
image: { type: Object },
|
41 |
+
gender: {
|
42 |
+
type: String,
|
43 |
+
enum: Gender,
|
44 |
+
required: true,
|
45 |
+
},
|
46 |
+
height: { type: Number, required: true },
|
47 |
+
weight: { type: Number, required: true },
|
48 |
+
fitness_level: {
|
49 |
+
type: String,
|
50 |
+
enum: FitnessLevel,
|
51 |
+
required: true,
|
52 |
+
},
|
53 |
+
preferences: {
|
54 |
+
fitness_goal: {
|
55 |
+
type: String,
|
56 |
+
enum: FitnessGoal,
|
57 |
+
required: true,
|
58 |
+
},
|
59 |
+
target_weight: { type: Number, required: true },
|
60 |
+
workout_frequency: { type: Number, required: true },
|
61 |
+
preferred_days: [
|
62 |
+
{
|
63 |
+
type: String,
|
64 |
+
enum: PreferredDay,
|
65 |
+
required: true,
|
66 |
+
},
|
67 |
+
],
|
68 |
+
workout_place: {
|
69 |
+
type: String,
|
70 |
+
enum: WorkoutPlace,
|
71 |
+
required: true,
|
72 |
+
},
|
73 |
+
preferred_equipment: [
|
74 |
+
{
|
75 |
+
type: String,
|
76 |
+
enum: PreferredEquipment,
|
77 |
+
required: true,
|
78 |
+
},
|
79 |
+
],
|
80 |
+
},
|
81 |
+
injuries: [
|
82 |
+
{
|
83 |
+
type: String,
|
84 |
+
enum: Injury,
|
85 |
+
required: true,
|
86 |
+
},
|
87 |
+
],
|
88 |
+
dob: { type: Date },
|
89 |
+
role: {
|
90 |
+
type: String,
|
91 |
+
enum: AuthenticatableType,
|
92 |
+
default: AuthenticatableType.USER,
|
93 |
+
},
|
94 |
+
});
|
95 |
+
|
96 |
+
userSchema.pre("save", async function (next) {
|
97 |
+
this.password = await bcrypt.hash(this.password, saltrounds);
|
98 |
+
next();
|
99 |
+
});
|
100 |
+
|
101 |
+
export type UserDocument = IUser & mongoose.Document;
|
102 |
+
|
103 |
+
export const userModel = mongoose.model<UserDocument>("users", userSchema);
|
src/{modules/common/users → common}/services/users.base.service.ts
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
-
import { FilterQuery
|
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>) {
|
|
|
1 |
+
import { FilterQuery } from "mongoose";
|
|
|
2 |
import { HttpError } from "src/lib/error-handling/http-error";
|
3 |
+
import { UserDocument, userModel, IUser } from "../models/user.model";
|
4 |
|
5 |
export abstract class BaseUsersService {
|
6 |
async findOne(filterObject: FilterQuery<UserDocument>) {
|
src/{modules/common/users/validation → common/validations}/user-register.validation.ts
RENAMED
@@ -1,14 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import * as joi from "joi";
|
2 |
-
import {
|
3 |
-
Role,
|
4 |
-
Gender,
|
5 |
-
FitnessLevel,
|
6 |
-
FitnessGoal,
|
7 |
-
WorkoutPlace,
|
8 |
-
PreferredDay,
|
9 |
-
PreferredEquipment,
|
10 |
-
Injury,
|
11 |
-
} from "../enums/roles.enum";
|
12 |
import { createSchema } from "src/helpers/create-schema";
|
13 |
|
14 |
export interface IUserRegister {
|
@@ -34,7 +32,6 @@ export interface IUserRegister {
|
|
34 |
};
|
35 |
injuries: string[];
|
36 |
dob?: Date;
|
37 |
-
role?: Role;
|
38 |
}
|
39 |
|
40 |
export const userRegisterKeys = {
|
@@ -185,7 +182,7 @@ export const userRegisterKeys = {
|
|
185 |
}),
|
186 |
role: joi
|
187 |
.string()
|
188 |
-
.valid(...Object.values(
|
189 |
.optional()
|
190 |
.messages({
|
191 |
"string.base": "please enter a valid role",
|
|
|
1 |
+
import { AuthenticatableType } from "@common/enums/authenticatable-type.enum";
|
2 |
+
import { FitnessGoal } from "@common/enums/fitness-goal.enum";
|
3 |
+
import { FitnessLevel } from "@common/enums/fitness-level.enum";
|
4 |
+
import { Gender } from "@common/enums/gender.enum";
|
5 |
+
import { Injury } from "@common/enums/injury.enum";
|
6 |
+
import { PreferredDay } from "@common/enums/preferred-day.enum";
|
7 |
+
import { PreferredEquipment } from "@common/enums/preferred-equipment.enum";
|
8 |
+
import { WorkoutPlace } from "@common/enums/workout-place.enum";
|
9 |
import * as joi from "joi";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
import { createSchema } from "src/helpers/create-schema";
|
11 |
|
12 |
export interface IUserRegister {
|
|
|
32 |
};
|
33 |
injuries: string[];
|
34 |
dob?: Date;
|
|
|
35 |
}
|
36 |
|
37 |
export const userRegisterKeys = {
|
|
|
182 |
}),
|
183 |
role: joi
|
184 |
.string()
|
185 |
+
.valid(...Object.values(AuthenticatableType))
|
186 |
.optional()
|
187 |
.messages({
|
188 |
"string.base": "please enter a valid role",
|
src/configs/config.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
import { Env } from "./env";
|
2 |
import dotenv from "dotenv";
|
|
|
3 |
dotenv.config();
|
4 |
|
5 |
export interface Config {
|
|
|
|
|
1 |
import dotenv from "dotenv";
|
2 |
+
import { Env } from "src/lib/env/env";
|
3 |
dotenv.config();
|
4 |
|
5 |
export interface Config {
|
src/configs/env.ts
DELETED
@@ -1,25 +0,0 @@
|
|
1 |
-
export class EnvValue {
|
2 |
-
constructor(public value: string | number | boolean) {}
|
3 |
-
|
4 |
-
toString(): string {
|
5 |
-
return String(this.value);
|
6 |
-
}
|
7 |
-
toNumber(): number {
|
8 |
-
return Number(this.value);
|
9 |
-
}
|
10 |
-
toBoolean(): boolean {
|
11 |
-
return this.value === "true";
|
12 |
-
}
|
13 |
-
}
|
14 |
-
|
15 |
-
export class Env {
|
16 |
-
static get(key: string, defaultValue?: string | number | boolean): EnvValue {
|
17 |
-
const value = process.env[key] || defaultValue;
|
18 |
-
|
19 |
-
if (!value) {
|
20 |
-
throw new Error(`Environment variable ${key} not found`);
|
21 |
-
}
|
22 |
-
|
23 |
-
return new EnvValue(value);
|
24 |
-
}
|
25 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/helpers/jwt.helper.ts
CHANGED
@@ -12,23 +12,23 @@ export class JwtHelper {
|
|
12 |
return (req: any, res: any, next: any) => {
|
13 |
let authHeader = req.headers["authorization"];
|
14 |
const token = authHeader && authHeader.split(" ")[1];
|
15 |
-
if (token) {
|
16 |
-
jwt.verify(token, config.jwt.secret, (err: any, tokenData: any) => {
|
17 |
-
if (err)
|
18 |
-
return res
|
19 |
-
.status(403)
|
20 |
-
.json({ success: false, code: 403, message: "Invalid Token!" });
|
21 |
-
if (!role.includes(tokenData.role))
|
22 |
-
return res
|
23 |
-
.status(401)
|
24 |
-
.json({ success: false, code: 401, message: "Unauthorized" });
|
25 |
-
req.tokenData = tokenData;
|
26 |
-
next();
|
27 |
-
});
|
28 |
-
} else
|
29 |
return res
|
30 |
.status(401)
|
31 |
.json({ success: false, code: 401, message: "Unauthorized" });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
};
|
33 |
}
|
34 |
}
|
|
|
12 |
return (req: any, res: any, next: any) => {
|
13 |
let authHeader = req.headers["authorization"];
|
14 |
const token = authHeader && authHeader.split(" ")[1];
|
15 |
+
if (!token) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
return res
|
17 |
.status(401)
|
18 |
.json({ success: false, code: 401, message: "Unauthorized" });
|
19 |
+
}
|
20 |
+
jwt.verify(token, config.jwt.secret, (err: any, tokenData: any) => {
|
21 |
+
if (err)
|
22 |
+
return res
|
23 |
+
.status(403)
|
24 |
+
.json({ success: false, code: 403, message: "Invalid Token!" });
|
25 |
+
if (!role.includes(tokenData.role))
|
26 |
+
return res
|
27 |
+
.status(401)
|
28 |
+
.json({ success: false, code: 401, message: "Unauthorized" });
|
29 |
+
req.tokenData = tokenData;
|
30 |
+
next();
|
31 |
+
});
|
32 |
};
|
33 |
}
|
34 |
}
|
src/helpers/pagination.ts
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Request } from "express";
|
2 |
+
|
3 |
+
export const parsePaginationQuery = (query: Request["query"]) => {
|
4 |
+
const limit = query.take && parseInt(query.limit as string);
|
5 |
+
const skip = query.skip && parseInt(query.skip as string);
|
6 |
+
|
7 |
+
return {
|
8 |
+
limit,
|
9 |
+
skip,
|
10 |
+
};
|
11 |
+
};
|
src/lib/responses/json-response.ts
CHANGED
@@ -1,23 +1,21 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
total: number;
|
7 |
page: number;
|
8 |
perPage: number;
|
9 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
constructor(props: {
|
12 |
-
status?: number;
|
13 |
-
message?: string;
|
14 |
-
data?: Record<string, any> | Record<string, any>[];
|
15 |
-
meta?: {
|
16 |
-
total: number;
|
17 |
-
page: number;
|
18 |
-
perPage: number;
|
19 |
-
};
|
20 |
-
}) {
|
21 |
this.status = props.status || 200;
|
22 |
this.message = props.message || "Success";
|
23 |
this.data = props.data || {};
|
|
|
1 |
+
interface JsonResponseProps {
|
2 |
+
status?: number;
|
3 |
+
message?: string;
|
4 |
+
data?: Record<string, any> | Record<string, any>[];
|
5 |
+
meta?: {
|
6 |
total: number;
|
7 |
page: number;
|
8 |
perPage: number;
|
9 |
};
|
10 |
+
}
|
11 |
+
|
12 |
+
export class JsonResponse {
|
13 |
+
public status: JsonResponseProps["status"];
|
14 |
+
public message: JsonResponseProps["message"];
|
15 |
+
public data: JsonResponseProps["data"];
|
16 |
+
public meta?: JsonResponseProps["meta"];
|
17 |
|
18 |
+
constructor(props: JsonResponseProps) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
this.status = props.status || 200;
|
20 |
this.message = props.message || "Success";
|
21 |
this.data = props.data || {};
|
src/lib/services/crud.service.ts
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { HttpError } from "@lib/error-handling/http-error";
|
2 |
+
import { AnyKeys, Document, FilterQuery, Model } from "mongoose";
|
3 |
+
|
4 |
+
export const CrudService = <ModelDoc extends Document>(
|
5 |
+
model: Model<ModelDoc>
|
6 |
+
) => {
|
7 |
+
return class CrudServiceClass {
|
8 |
+
protected model: Model<ModelDoc> = model;
|
9 |
+
|
10 |
+
async create(data: AnyKeys<ModelDoc>): Promise<ModelDoc> {
|
11 |
+
return this.model.create(data);
|
12 |
+
}
|
13 |
+
|
14 |
+
async update(
|
15 |
+
filter: FilterQuery<ModelDoc>,
|
16 |
+
data: AnyKeys<ModelDoc>
|
17 |
+
): Promise<ModelDoc> {
|
18 |
+
return this.model.findOneAndUpdate(filter, data, { new: true });
|
19 |
+
}
|
20 |
+
|
21 |
+
async delete(filter: FilterQuery<ModelDoc>): Promise<ModelDoc> {
|
22 |
+
return this.model.findOneAndDelete(filter);
|
23 |
+
}
|
24 |
+
|
25 |
+
async list(
|
26 |
+
filter: FilterQuery<ModelDoc>,
|
27 |
+
paginationOptions: {
|
28 |
+
limit?: number;
|
29 |
+
skip?: number;
|
30 |
+
} = {
|
31 |
+
limit: 10,
|
32 |
+
skip: 0,
|
33 |
+
}
|
34 |
+
): Promise<{
|
35 |
+
docs: ModelDoc[];
|
36 |
+
paginationData: {
|
37 |
+
total: number;
|
38 |
+
page: number;
|
39 |
+
perPage: number;
|
40 |
+
};
|
41 |
+
}> {
|
42 |
+
const docs = await this.model
|
43 |
+
.find(filter)
|
44 |
+
.limit(paginationOptions.limit)
|
45 |
+
.skip(paginationOptions.skip);
|
46 |
+
|
47 |
+
const total = await this.model.countDocuments(filter);
|
48 |
+
const paginationData = {
|
49 |
+
total: total,
|
50 |
+
page: paginationOptions.skip,
|
51 |
+
perPage: paginationOptions.limit,
|
52 |
+
};
|
53 |
+
|
54 |
+
return { docs, paginationData };
|
55 |
+
}
|
56 |
+
|
57 |
+
async findOne(filter: FilterQuery<ModelDoc>): Promise<ModelDoc | null> {
|
58 |
+
return this.model.findOne(filter);
|
59 |
+
}
|
60 |
+
|
61 |
+
async findOneOrFail(filter: FilterQuery<ModelDoc>): Promise<ModelDoc> {
|
62 |
+
const document = await this.findOne(filter);
|
63 |
+
if (!document) throw new HttpError(404, "No Matching Result Found.");
|
64 |
+
|
65 |
+
return document;
|
66 |
+
}
|
67 |
+
};
|
68 |
+
};
|
src/modules/common/users/enums/roles.enum.ts
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
export enum Role {
|
2 |
-
USER = "user"
|
3 |
-
}
|
4 |
-
export enum Gender {
|
5 |
-
MALE = "male",
|
6 |
-
FEMALE = "female"
|
7 |
-
}
|
8 |
-
export enum FitnessLevel {
|
9 |
-
BEGINNER = "beginner",
|
10 |
-
INTERMEDIATE = "intermediate",
|
11 |
-
ADVANCED = "advanced"
|
12 |
-
}
|
13 |
-
export enum FitnessGoal {
|
14 |
-
LOSE_WEIGHT = "lose weight",
|
15 |
-
GAIN_MUSCLE = "gain muscle",
|
16 |
-
GET_FITTER = "get fitter"
|
17 |
-
}
|
18 |
-
export enum WorkoutPlace {
|
19 |
-
GYM = "gym",
|
20 |
-
HOME = "home",
|
21 |
-
BOTH = "both"
|
22 |
-
}
|
23 |
-
export enum PreferredDay {
|
24 |
-
SATURDAY = "saturday",
|
25 |
-
SUNDAY = "sunday",
|
26 |
-
MONDAY = "monday",
|
27 |
-
TUESDAY = "tuesday",
|
28 |
-
WEDNESDAY = "wednesday",
|
29 |
-
THURSDAY = "thursday",
|
30 |
-
FRIDAY = "friday"
|
31 |
-
}
|
32 |
-
export enum PreferredEquipment {
|
33 |
-
BARBELLS = "barbells",
|
34 |
-
DUMBBELLS = "dumbbells",
|
35 |
-
GYM_MACHINES = "gym machines",
|
36 |
-
RESISTANCE_BAND = "resistance band",
|
37 |
-
BODYWEIGHT = "bodyweight"
|
38 |
-
}
|
39 |
-
export enum Injury {
|
40 |
-
NECK = "neck",
|
41 |
-
SHOULDERS = "shoulders",
|
42 |
-
BACK = "back",
|
43 |
-
ARMS = "arms",
|
44 |
-
KNEES = "knees"
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/modules/common/users/models/user.model.ts
DELETED
@@ -1,90 +0,0 @@
|
|
1 |
-
import mongoose from "mongoose";
|
2 |
-
import bcrypt from "bcrypt";
|
3 |
-
export const saltrounds = 5;
|
4 |
-
import { Role, Gender, FitnessLevel, FitnessGoal, WorkoutPlace, PreferredDay, PreferredEquipment, Injury } from "../enums/roles.enum";
|
5 |
-
const { Schema } = mongoose;
|
6 |
-
|
7 |
-
export interface IUser {
|
8 |
-
name: string;
|
9 |
-
email: string;
|
10 |
-
password: string;
|
11 |
-
image: object;
|
12 |
-
role: Role;
|
13 |
-
gender: string;
|
14 |
-
dob: Date;
|
15 |
-
height: number;
|
16 |
-
weight: number;
|
17 |
-
fitness_level: string;
|
18 |
-
preferences: {
|
19 |
-
fitness_goal: FitnessGoal;
|
20 |
-
target_weight: number;
|
21 |
-
workout_frequency: number;
|
22 |
-
preferred_days: [PreferredDay];
|
23 |
-
workout_place: WorkoutPlace;
|
24 |
-
preferred_equipment: [PreferredEquipment];
|
25 |
-
};
|
26 |
-
injuries: [Injury];
|
27 |
-
}
|
28 |
-
|
29 |
-
const userSchema = new Schema({
|
30 |
-
name: { type: String, required: true },
|
31 |
-
email: { type: String, required: true, unique: true, dropDups: true },
|
32 |
-
password: { type: String, required: true },
|
33 |
-
image: { type: Object },
|
34 |
-
gender: {
|
35 |
-
type: String,
|
36 |
-
enum: Gender,
|
37 |
-
required: true
|
38 |
-
},
|
39 |
-
height: { type: Number, required: true },
|
40 |
-
weight: { type: Number, required: true },
|
41 |
-
fitness_level: {
|
42 |
-
type: String,
|
43 |
-
enum: FitnessLevel,
|
44 |
-
required: true
|
45 |
-
},
|
46 |
-
preferences: {
|
47 |
-
fitness_goal: {
|
48 |
-
type: String,
|
49 |
-
enum: FitnessGoal,
|
50 |
-
required: true
|
51 |
-
},
|
52 |
-
target_weight: { type: Number, required: true },
|
53 |
-
workout_frequency: { type: Number, required: true },
|
54 |
-
preferred_days: [{
|
55 |
-
type: String,
|
56 |
-
enum: PreferredDay,
|
57 |
-
required: true
|
58 |
-
}],
|
59 |
-
workout_place: {
|
60 |
-
type: String,
|
61 |
-
enum: WorkoutPlace,
|
62 |
-
required: true
|
63 |
-
},
|
64 |
-
preferred_equipment: [{
|
65 |
-
type: String,
|
66 |
-
enum: PreferredEquipment,
|
67 |
-
required: true
|
68 |
-
}]
|
69 |
-
},
|
70 |
-
injuries: [{
|
71 |
-
type: String,
|
72 |
-
enum: Injury,
|
73 |
-
required: true
|
74 |
-
}],
|
75 |
-
dob: { type: Date },
|
76 |
-
role: {
|
77 |
-
type: String,
|
78 |
-
enum: Role,
|
79 |
-
default: Role.USER
|
80 |
-
}
|
81 |
-
});
|
82 |
-
|
83 |
-
userSchema.pre("save", async function (next) {
|
84 |
-
this.password = await bcrypt.hash(this.password, saltrounds);
|
85 |
-
next();
|
86 |
-
});
|
87 |
-
|
88 |
-
export type UserDocument = IUser & mongoose.Document;
|
89 |
-
|
90 |
-
export const userModel = mongoose.model<IUser>("users", userSchema);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/modules/console/admins/controllers/admins.controller.ts
CHANGED
@@ -1,13 +1,12 @@
|
|
|
|
|
|
|
|
|
|
1 |
import { Request, Response, Router } from "express";
|
2 |
-
import { BaseController } from "../../../../lib/controllers/controller.base";
|
3 |
import { AdminsService } from "../services/admins.service";
|
4 |
import { createAdminSchema } from "../validations/create-admin.validation";
|
5 |
-
import {
|
6 |
-
|
7 |
-
paramsValidator,
|
8 |
-
} from "../../../../helpers/validation.helper";
|
9 |
-
import { asyncHandler } from "../../../../helpers/async-handler";
|
10 |
-
import { Prefix } from "../../../../lib/decorators/prefix.decorator";
|
11 |
|
12 |
@Prefix("/console/admins")
|
13 |
export class AdminsController extends BaseController {
|
@@ -34,36 +33,61 @@ export class AdminsController extends BaseController {
|
|
34 |
);
|
35 |
}
|
36 |
|
37 |
-
list = (
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
46 |
};
|
47 |
|
48 |
get = async (req: Request, res: Response) => {
|
49 |
-
const data = await this.adminsService.
|
50 |
_id: req.params.id,
|
51 |
});
|
52 |
-
|
|
|
|
|
|
|
53 |
};
|
54 |
|
55 |
create = async (req: Request, res: Response) => {
|
56 |
-
const
|
57 |
-
|
|
|
|
|
|
|
58 |
};
|
59 |
|
60 |
update = async (req: Request, res: Response) => {
|
61 |
-
const
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
};
|
64 |
|
65 |
delete = async (req: Request, res: Response) => {
|
66 |
-
const
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
};
|
69 |
}
|
|
|
1 |
+
import { asyncHandler } from "@helpers/async-handler";
|
2 |
+
import { paramsValidator, bodyValidator } from "@helpers/validation.helper";
|
3 |
+
import { BaseController } from "@lib/controllers/controller.base";
|
4 |
+
import { Prefix } from "@lib/decorators/prefix.decorator";
|
5 |
import { Request, Response, Router } from "express";
|
|
|
6 |
import { AdminsService } from "../services/admins.service";
|
7 |
import { createAdminSchema } from "../validations/create-admin.validation";
|
8 |
+
import { parsePaginationQuery } from "@helpers/pagination";
|
9 |
+
import { JsonResponse } from "@lib/responses/json-response";
|
|
|
|
|
|
|
|
|
10 |
|
11 |
@Prefix("/console/admins")
|
12 |
export class AdminsController extends BaseController {
|
|
|
33 |
);
|
34 |
}
|
35 |
|
36 |
+
list = async (req: Request, res: Response) => {
|
37 |
+
const paginationQuery = parsePaginationQuery(req.query);
|
38 |
+
const { docs, paginationData } = await this.adminsService.list(
|
39 |
+
{},
|
40 |
+
paginationQuery
|
41 |
+
);
|
42 |
+
const response = new JsonResponse({
|
43 |
+
data: docs,
|
44 |
+
meta: paginationData,
|
45 |
+
});
|
46 |
+
return res.json(response);
|
47 |
};
|
48 |
|
49 |
get = async (req: Request, res: Response) => {
|
50 |
+
const data = await this.adminsService.findOneOrFail({
|
51 |
_id: req.params.id,
|
52 |
});
|
53 |
+
const response = new JsonResponse({
|
54 |
+
data,
|
55 |
+
});
|
56 |
+
res.json(response);
|
57 |
};
|
58 |
|
59 |
create = async (req: Request, res: Response) => {
|
60 |
+
const admin = await this.adminsService.create(req.body);
|
61 |
+
const response = new JsonResponse({
|
62 |
+
data: admin,
|
63 |
+
});
|
64 |
+
res.json(response);
|
65 |
};
|
66 |
|
67 |
update = async (req: Request, res: Response) => {
|
68 |
+
const admin = await this.adminsService.update(
|
69 |
+
{
|
70 |
+
_id: req.params.id,
|
71 |
+
},
|
72 |
+
req.body
|
73 |
+
);
|
74 |
+
|
75 |
+
const response = new JsonResponse({
|
76 |
+
data: admin,
|
77 |
+
});
|
78 |
+
|
79 |
+
res.json(response);
|
80 |
};
|
81 |
|
82 |
delete = async (req: Request, res: Response) => {
|
83 |
+
const admin = await this.adminsService.delete({
|
84 |
+
_id: req.params.id,
|
85 |
+
});
|
86 |
+
|
87 |
+
const response = new JsonResponse({
|
88 |
+
data: admin,
|
89 |
+
});
|
90 |
+
|
91 |
+
res.json(response);
|
92 |
};
|
93 |
}
|
src/modules/console/admins/models/admin.model.ts
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
import mongoose from "mongoose";
|
2 |
import bcrypt from "bcrypt";
|
3 |
-
import { Role } from "../enums/roles.enum";
|
4 |
import { config } from "../../../../configs/config";
|
5 |
const { Schema } = mongoose;
|
6 |
|
@@ -9,7 +8,6 @@ export interface IAdmin {
|
|
9 |
email: string;
|
10 |
password: string;
|
11 |
image: object;
|
12 |
-
role: Role;
|
13 |
gender: string;
|
14 |
dob: Date;
|
15 |
}
|
@@ -19,10 +17,6 @@ const AdminSchema = new Schema({
|
|
19 |
email: { type: String, required: true, unique: true, dropDups: true },
|
20 |
password: { type: String, required: true },
|
21 |
image: { type: Object, default: {} },
|
22 |
-
role: {
|
23 |
-
type: String,
|
24 |
-
enum: Role,
|
25 |
-
},
|
26 |
gender: { type: String, required: true },
|
27 |
dob: { type: Date },
|
28 |
});
|
@@ -32,4 +26,6 @@ AdminSchema.pre("save", async function (next) {
|
|
32 |
next();
|
33 |
});
|
34 |
|
35 |
-
export
|
|
|
|
|
|
1 |
import mongoose from "mongoose";
|
2 |
import bcrypt from "bcrypt";
|
|
|
3 |
import { config } from "../../../../configs/config";
|
4 |
const { Schema } = mongoose;
|
5 |
|
|
|
8 |
email: string;
|
9 |
password: string;
|
10 |
image: object;
|
|
|
11 |
gender: string;
|
12 |
dob: Date;
|
13 |
}
|
|
|
17 |
email: { type: String, required: true, unique: true, dropDups: true },
|
18 |
password: { type: String, required: true },
|
19 |
image: { type: Object, default: {} },
|
|
|
|
|
|
|
|
|
20 |
gender: { type: String, required: true },
|
21 |
dob: { type: Date },
|
22 |
});
|
|
|
26 |
next();
|
27 |
});
|
28 |
|
29 |
+
export type AdminDocument = mongoose.Document & IAdmin;
|
30 |
+
|
31 |
+
export const Admin = mongoose.model<AdminDocument>("admins", AdminSchema);
|
src/modules/console/admins/services/admins.service.ts
CHANGED
@@ -1,267 +1,4 @@
|
|
1 |
-
import
|
2 |
-
import {
|
3 |
-
import { config } from "../../../../configs/config";
|
4 |
-
import { FilterQuery } from "mongoose";
|
5 |
|
6 |
-
export class AdminsService {
|
7 |
-
async find(filterObject) {
|
8 |
-
try {
|
9 |
-
const resultObject = await Admin.findOne(filterObject).lean();
|
10 |
-
|
11 |
-
if (!resultObject)
|
12 |
-
return {
|
13 |
-
success: false,
|
14 |
-
code: 404,
|
15 |
-
error: "No Matching Result Found.",
|
16 |
-
};
|
17 |
-
|
18 |
-
return {
|
19 |
-
success: true,
|
20 |
-
code: 200,
|
21 |
-
record: resultObject,
|
22 |
-
};
|
23 |
-
} catch (err) {
|
24 |
-
console.log(`err.message`, err.message);
|
25 |
-
return {
|
26 |
-
success: false,
|
27 |
-
code: 500,
|
28 |
-
error: "Unexpected Error Happened.",
|
29 |
-
};
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
async get(filterObject: FilterQuery<IAdmin>) {
|
34 |
-
try {
|
35 |
-
const resultObject = await Admin.findOne(filterObject)
|
36 |
-
.lean()
|
37 |
-
.select("-password");
|
38 |
-
if (!resultObject)
|
39 |
-
return {
|
40 |
-
success: false,
|
41 |
-
code: 404,
|
42 |
-
error: "No Matching Result Found.",
|
43 |
-
};
|
44 |
-
return {
|
45 |
-
success: true,
|
46 |
-
code: 200,
|
47 |
-
record: resultObject,
|
48 |
-
};
|
49 |
-
} catch (err) {
|
50 |
-
console.log(`err.message`, err.message);
|
51 |
-
return {
|
52 |
-
success: false,
|
53 |
-
code: 500,
|
54 |
-
error: "Unexpected Error Happened.",
|
55 |
-
};
|
56 |
-
}
|
57 |
-
}
|
58 |
-
|
59 |
-
async list(filterObject) {
|
60 |
-
try {
|
61 |
-
const resultArray = await Admin.find(filterObject)
|
62 |
-
.lean()
|
63 |
-
.select("-password");
|
64 |
-
|
65 |
-
if (!resultArray)
|
66 |
-
return {
|
67 |
-
success: false,
|
68 |
-
code: 404,
|
69 |
-
error: "No Matching Result Found.",
|
70 |
-
};
|
71 |
-
const count = await Admin.countDocuments(filterObject);
|
72 |
-
return {
|
73 |
-
success: true,
|
74 |
-
code: 200,
|
75 |
-
record: resultArray,
|
76 |
-
count,
|
77 |
-
};
|
78 |
-
} catch (err) {
|
79 |
-
console.log(`err.message`, err.message);
|
80 |
-
return {
|
81 |
-
success: false,
|
82 |
-
code: 500,
|
83 |
-
error: "Unexpected Error Happened.",
|
84 |
-
};
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
async create(formObject) {
|
89 |
-
try {
|
90 |
-
if (formObject.email) formObject.email = formObject.email.toLowerCase();
|
91 |
-
const resultObject = new Admin(formObject);
|
92 |
-
await resultObject.save();
|
93 |
-
|
94 |
-
if (!resultObject)
|
95 |
-
return {
|
96 |
-
success: false,
|
97 |
-
code: 500,
|
98 |
-
error: "Unexpected Error Happened.",
|
99 |
-
};
|
100 |
-
|
101 |
-
return {
|
102 |
-
success: true,
|
103 |
-
code: 201,
|
104 |
-
record: resultObject,
|
105 |
-
};
|
106 |
-
} catch (err) {
|
107 |
-
console.log(`err.message`, err.message);
|
108 |
-
return {
|
109 |
-
success: false,
|
110 |
-
code: 500,
|
111 |
-
error: "Unexpected Error Happened.",
|
112 |
-
};
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
async update(_id, formObject) {
|
117 |
-
try {
|
118 |
-
const existingObject = await this.find({ _id });
|
119 |
-
if (!existingObject.success)
|
120 |
-
return {
|
121 |
-
success: false,
|
122 |
-
code: 404,
|
123 |
-
error: "No Matching Result Found.",
|
124 |
-
};
|
125 |
-
if (formObject.email) {
|
126 |
-
formObject.email = formObject.email.toLowerCase();
|
127 |
-
const duplicate = await this.find({ email: formObject.email });
|
128 |
-
if (
|
129 |
-
duplicate.success &&
|
130 |
-
duplicate.record._id.toString() !=
|
131 |
-
existingObject.record._id.toString()
|
132 |
-
)
|
133 |
-
return {
|
134 |
-
success: false,
|
135 |
-
error: "This Email is taken by another user",
|
136 |
-
code: 409,
|
137 |
-
};
|
138 |
-
}
|
139 |
-
|
140 |
-
const resultObject = await Admin.findByIdAndUpdate({ _id }, formObject);
|
141 |
-
|
142 |
-
if (!resultObject)
|
143 |
-
return {
|
144 |
-
success: false,
|
145 |
-
code: 500,
|
146 |
-
error: "Unexpected Error Happened.",
|
147 |
-
};
|
148 |
-
|
149 |
-
return {
|
150 |
-
success: true,
|
151 |
-
code: 200,
|
152 |
-
record: resultObject,
|
153 |
-
};
|
154 |
-
} catch (err) {
|
155 |
-
console.log(`err.message`, err.message);
|
156 |
-
return {
|
157 |
-
success: false,
|
158 |
-
code: 500,
|
159 |
-
error: "Unexpected Error Happened.",
|
160 |
-
};
|
161 |
-
}
|
162 |
-
}
|
163 |
-
|
164 |
-
async remove(_id) {
|
165 |
-
try {
|
166 |
-
const resultObject = await Admin.findByIdAndDelete({ _id });
|
167 |
-
if (!resultObject)
|
168 |
-
return {
|
169 |
-
success: false,
|
170 |
-
code: 404,
|
171 |
-
error: "No Matching Result Found.",
|
172 |
-
};
|
173 |
-
|
174 |
-
return {
|
175 |
-
success: true,
|
176 |
-
code: 200,
|
177 |
-
};
|
178 |
-
} catch (err) {
|
179 |
-
console.log(`err.message`, err.message);
|
180 |
-
return {
|
181 |
-
success: false,
|
182 |
-
code: 500,
|
183 |
-
error: "Unexpected Error Happened.",
|
184 |
-
};
|
185 |
-
}
|
186 |
-
}
|
187 |
-
|
188 |
-
async comparePassword(emailString, passwordString) {
|
189 |
-
try {
|
190 |
-
emailString = emailString.toLowerCase();
|
191 |
-
const existingObject = await this.find({ email: emailString });
|
192 |
-
|
193 |
-
if (!existingObject.success)
|
194 |
-
return {
|
195 |
-
success: false,
|
196 |
-
code: 404,
|
197 |
-
error: "No Matching Result Found.",
|
198 |
-
};
|
199 |
-
|
200 |
-
const matchingPasswords = await bcrypt.compare(
|
201 |
-
passwordString,
|
202 |
-
existingObject.record.password
|
203 |
-
);
|
204 |
-
if (!matchingPasswords)
|
205 |
-
return {
|
206 |
-
success: false,
|
207 |
-
code: 409,
|
208 |
-
error: "Incorrect Password.",
|
209 |
-
};
|
210 |
-
|
211 |
-
return {
|
212 |
-
success: true,
|
213 |
-
record: existingObject.record,
|
214 |
-
code: 200,
|
215 |
-
};
|
216 |
-
} catch (err) {
|
217 |
-
console.log(`err.message`, err.message);
|
218 |
-
return {
|
219 |
-
success: false,
|
220 |
-
code: 500,
|
221 |
-
error: "Unexpected Error Happened.",
|
222 |
-
};
|
223 |
-
}
|
224 |
-
}
|
225 |
-
|
226 |
-
async resetPassword(emailString, newPasswordString) {
|
227 |
-
try {
|
228 |
-
emailString = emailString.toLowerCase();
|
229 |
-
const existingObject = await this.find({ email: emailString });
|
230 |
-
|
231 |
-
if (!existingObject.success)
|
232 |
-
return {
|
233 |
-
success: false,
|
234 |
-
code: 404,
|
235 |
-
error: "No Matching Result Found.",
|
236 |
-
};
|
237 |
-
|
238 |
-
const hashedPassword = await bcrypt.hash(
|
239 |
-
newPasswordString,
|
240 |
-
config.saltRounds
|
241 |
-
);
|
242 |
-
const resultObject = await Admin.findOneAndUpdate(
|
243 |
-
{ email: emailString },
|
244 |
-
{ password: hashedPassword }
|
245 |
-
);
|
246 |
-
|
247 |
-
if (!resultObject)
|
248 |
-
return {
|
249 |
-
success: false,
|
250 |
-
code: 500,
|
251 |
-
error: "Unexpected Error Happened.",
|
252 |
-
};
|
253 |
-
|
254 |
-
return {
|
255 |
-
success: true,
|
256 |
-
code: 200,
|
257 |
-
};
|
258 |
-
} catch (err) {
|
259 |
-
console.log(`err.message`, err.message);
|
260 |
-
return {
|
261 |
-
success: false,
|
262 |
-
code: 500,
|
263 |
-
error: "Unexpected Error Happened.",
|
264 |
-
};
|
265 |
-
}
|
266 |
-
}
|
267 |
-
}
|
|
|
1 |
+
import { Admin } from "../models/admin.model";
|
2 |
+
import { CrudService } from "@lib/services/crud.service";
|
|
|
|
|
3 |
|
4 |
+
export class AdminsService extends CrudService(Admin) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/modules/console/admins/validations/create-admin.validation.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
|
|
1 |
import * as joi from "joi";
|
2 |
-
import { Role } from "../enums/roles.enum";
|
3 |
import { createSchema } from "src/helpers/create-schema";
|
4 |
|
5 |
export interface ICreateAdmin {
|
|
|
1 |
+
import { Role } from "@common/enums/role.enum";
|
2 |
import * as joi from "joi";
|
|
|
3 |
import { createSchema } from "src/helpers/create-schema";
|
4 |
|
5 |
export interface ICreateAdmin {
|
src/modules/console/users/controllers/users.controller.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
import { userRegisterSchema } from "src/
|
2 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
3 |
import { JwtHelper } from "../../../../helpers/jwt.helper";
|
4 |
import { bodyValidator } from "../../../../helpers/validation.helper";
|
@@ -6,6 +6,7 @@ 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 |
|
@@ -22,10 +23,11 @@ export class AdminUsersController extends BaseController {
|
|
22 |
);
|
23 |
}
|
24 |
|
25 |
-
create = async (req, res) => {
|
26 |
let user = await this.usersService.create(req.body);
|
27 |
-
|
28 |
data: user,
|
29 |
});
|
|
|
30 |
};
|
31 |
}
|
|
|
1 |
+
import { userRegisterSchema } from "src/common/validations/user-register.validation";
|
2 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
3 |
import { JwtHelper } from "../../../../helpers/jwt.helper";
|
4 |
import { bodyValidator } from "../../../../helpers/validation.helper";
|
|
|
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 |
+
import { Request, Response } from "express";
|
10 |
|
11 |
const allowedRoles = ["superAdmin", "admin"];
|
12 |
|
|
|
23 |
);
|
24 |
}
|
25 |
|
26 |
+
create = async (req: Request, res: Response) => {
|
27 |
let user = await this.usersService.create(req.body);
|
28 |
+
const response = new JsonResponse({
|
29 |
data: user,
|
30 |
});
|
31 |
+
return res.json(response);
|
32 |
};
|
33 |
}
|
src/modules/console/users/services/users.service.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1 |
-
import {
|
|
|
2 |
|
3 |
-
export class UsersService extends
|
|
|
1 |
+
import { userModel } from "@common/models/user.model";
|
2 |
+
import { CrudService } from "@lib/services/crud.service";
|
3 |
|
4 |
+
export class UsersService extends CrudService(userModel) {}
|
src/modules/users/auth/controllers/auth.controller.ts
CHANGED
@@ -4,10 +4,9 @@ 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 {
|
@@ -27,16 +26,18 @@ export class UsersAuthController extends BaseController {
|
|
27 |
}
|
28 |
|
29 |
register = async (req: Request, res: Response) => {
|
30 |
-
|
31 |
-
|
32 |
data: user,
|
33 |
});
|
|
|
34 |
};
|
35 |
|
36 |
-
login = async (req, res) => {
|
37 |
const { user, token } = await this.authService.login(req.body);
|
38 |
-
|
39 |
data: { user, token },
|
40 |
});
|
|
|
41 |
};
|
42 |
}
|
|
|
4 |
import { asyncHandler } from "../../../../helpers/async-handler";
|
5 |
import { Prefix } from "../../../../lib/decorators/prefix.decorator";
|
6 |
import { loginValidationSchema } from "../validation/login.validation";
|
|
|
7 |
import { Request, Response } from "express";
|
|
|
8 |
import { JsonResponse } from "src/lib/responses/json-response";
|
9 |
+
import { userRegisterSchema, IUserRegister } from "src/common/validations/user-register.validation";
|
10 |
|
11 |
@Prefix("/users/auth")
|
12 |
export class UsersAuthController extends BaseController {
|
|
|
26 |
}
|
27 |
|
28 |
register = async (req: Request, res: Response) => {
|
29 |
+
const user = await this.authService.register(req.body as IUserRegister);
|
30 |
+
const response = new JsonResponse({
|
31 |
data: user,
|
32 |
});
|
33 |
+
return res.json(response);
|
34 |
};
|
35 |
|
36 |
+
login = async (req: Request, res: Response) => {
|
37 |
const { user, token } = await this.authService.login(req.body);
|
38 |
+
const response = new JsonResponse({
|
39 |
data: { user, token },
|
40 |
});
|
41 |
+
return res.json(response);
|
42 |
};
|
43 |
}
|
src/modules/users/auth/services/users.service.ts
CHANGED
@@ -1,10 +1,16 @@
|
|
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(
|
|
|
|
|
1 |
import bcrypt from "bcrypt";
|
2 |
import { ILogin } from "../validation/login.validation";
|
3 |
import { HttpError } from "src/lib/error-handling/http-error";
|
4 |
import { JwtHelper } from "src/helpers/jwt.helper";
|
5 |
+
import { userModel } from "src/common/models/user.model";
|
6 |
+
import { IUserRegister } from "src/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 |
+
}
|
13 |
|
|
|
14 |
async login(loginRequest: ILogin) {
|
15 |
const user = await this.findOneOrFail({ email: loginRequest.email });
|
16 |
const isPasswordCorrect = await bcrypt.compare(
|
tsconfig.json
CHANGED
@@ -10,7 +10,6 @@
|
|
10 |
"experimentalDecorators": true,
|
11 |
"baseUrl": ".",
|
12 |
"paths": {
|
13 |
-
"src/*": ["src/*"],
|
14 |
"@lib/*": ["src/lib/*"],
|
15 |
"@common/*": ["src/common/*"],
|
16 |
"@configs/*": ["src/configs/*"],
|
|
|
10 |
"experimentalDecorators": true,
|
11 |
"baseUrl": ".",
|
12 |
"paths": {
|
|
|
13 |
"@lib/*": ["src/lib/*"],
|
14 |
"@common/*": ["src/common/*"],
|
15 |
"@configs/*": ["src/configs/*"],
|