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/*"],
|