Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:block-unblock-account #194

Merged
merged 4 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions src/modules/user/user.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,29 @@ import decrypt, { encrypt } from "~/utils/crypto";
import { OTP_MESSAGES } from "../otp/otp.messages";
import { USER_MESSAGES } from "./user.messages";
import {

BlockBody,

ListAccountQuery,

LoginRequestBody,
LogoutReqBody,
RefreshTokenReqBody,
RegisterReqBody,
TokenPayload,
UpdateMeReqBody,
UserResponseAfterCheckEmailOrPhone,
} from "./user.requests";
import User from "./user.schema";
import usersService from "./user.services";

UserResponseAfterCheckEmailOrPhone
} from './user.requests'
import User from './user.schema'
import usersService from './user.services'


import adminService from "../admin/admin.services";
import { UserList } from "~/constants/user.type";
import { UserRole } from "./user.enum";


export const registerController = async (
req: Request<ParamsDictionary, any, RegisterReqBody>,
res: Response,
Expand Down Expand Up @@ -254,9 +262,56 @@ export const refreshTokenController = async (

return res.json({
message: USER_MESSAGES.REFRESH_TOKEN_SUCCESSFULLY,
data: { access_token },
});
};

data: { access_token }
})
}

export const blockAccountController = async (
req: Request<ParamsDictionary, any, BlockBody>,
res: Response
) => {
console.log(req.cookies['refresh_token'])
await usersService.logout(req.cookies['refresh_token'])
res.clearCookie('refresh_token')
try {
const reason = req.body.description_reason
const picture_image_prove = req.body.picture_image_prove
const timeBlock = new Date()
const user_id = req.body._id
await usersService.blockAccount(
user_id,
reason,
picture_image_prove,
timeBlock
)
return res.json({
message: USER_MESSAGES.USER_HAS_BEEN_BLOCKED
})
} catch (error) {
return res.status(400).json({
message: 'Bad request'
})
}
}

export const unblockAccountController = async (
req: Request<ParamsDictionary, any, BlockBody>,
res: Response
) => {
try {
const user_id = req.body._id
await usersService.unblockAccount(user_id)
return res.json({
message: USER_MESSAGES.USER_UNBLOCK_SUCCESSFULLY
})
} catch (error) {
return res.status(400).json({
message: 'Bad request'
})
}
}


export const getListUserController = async (req: Request, res: Response) => {
const query = req.queryListAccount as ListAccountQuery;
Expand Down Expand Up @@ -344,3 +399,4 @@ export const getListUserController = async (req: Request, res: Response) => {
});
}
};

9 changes: 7 additions & 2 deletions src/modules/user/user.messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,14 @@ export const USER_MESSAGES = {
WRONG_PASS_5_TIMES: "Entered wrong password over 5 times!",

//token
REFRESH_TOKEN_IS_REQUIRED: "Refresh token is required",
OTP_IS_INCORRECT: "OTP is incorrect",

REFRESH_TOKEN_IS_REQUIRED: 'Refresh token is required',
OTP_IS_INCORRECT: 'OTP is incorrect',
// block
USER_HAS_BEEN_BLOCKED: 'user has been blocked',
USER_UNBLOCK_SUCCESSFULLY: 'user unblock successfully'

//don't have permission
DONT_HAVE_PERMISSION: `You don't have permission`,
} as const;

55 changes: 30 additions & 25 deletions src/modules/user/user.middlewares.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import "dotenv/config";
import { NextFunction, Request, Response } from "express";
import { ParamsDictionary } from "express-serve-static-core";
import { ParamSchema, checkSchema } from "express-validator";
import { JsonWebTokenError } from "jsonwebtoken";
import { capitalize, escape } from "lodash";
import { ObjectId } from "mongodb";
import validator from "validator";
import { HTTP_STATUS } from "~/constants/httpStatus";
import databaseService from "~/database/database.services";
import { ErrorEntity, ErrorWithStatus } from "~/errors/errors.entityError";
import { USER_MESSAGES } from "~/modules/user/user.messages";
import { isDeveloperAgent } from "~/utils/agent";
import { encrypt, hashPassword } from "~/utils/crypto";
import { verifyToken } from "~/utils/jwt";
import { isValidPhoneNumberForCountry, validate } from "~/utils/validation";
import { OTP_STATUS } from "../otp/otp.enum";
import { OTP_MESSAGES } from "../otp/otp.messages";
import otpService from "../otp/otp.services";
import { NoticeUser, UserRole, UserVerifyStatus } from "./user.enum";
import { LoginRequestBody, TokenPayload } from "./user.requests";
import usersService from "./user.services";
import { StatusCodes } from "http-status-codes";

import 'dotenv/config'
import { NextFunction, Request, Response } from 'express'
import { ParamsDictionary } from 'express-serve-static-core'
import { ParamSchema, checkSchema } from 'express-validator'
import { JsonWebTokenError } from 'jsonwebtoken'
import { capitalize, escape } from 'lodash'
import { ObjectId } from 'mongodb'
import validator from 'validator'
import { HTTP_STATUS } from '~/constants/httpStatus'
import databaseService from '~/database/database.services'
import { ErrorEntity, ErrorWithStatus } from '~/errors/errors.entityError'
import { USER_MESSAGES } from '~/modules/user/user.messages'
import { isDeveloperAgent } from '~/utils/agent'
import { encrypt, hashPassword } from '~/utils/crypto'
import { verifyToken } from '~/utils/jwt'
import { isValidPhoneNumberForCountry, validate } from '~/utils/validation'
import { OTP_STATUS } from '../otp/otp.enum'
import { OTP_MESSAGES } from '../otp/otp.messages'
import otpService from '../otp/otp.services'
import { NoticeUser, Subscription, UserVerifyStatus, UserRole, } from './user.enum'
import { LoginRequestBody, TokenPayload } from './user.requests'
import usersService from './user.services'
import { StatusCodes } from 'http-status-codes'
import { numberToEnum } from "~/utils/handler";


//! Prevent db injection, XSS attack
export const paramSchema: ParamSchema = {
customSanitizer: {
Expand Down Expand Up @@ -284,7 +286,9 @@ export const loginValidator = validate(

if (
user.notice === NoticeUser.Banned ||
user.reasonBanned !== ""
user.reasonBanned !== '' ||
user.block === Subscription.True

) {
throw new ErrorWithStatus({
message: USER_MESSAGES.ACCOUNT_IS_BANNED,
Expand Down Expand Up @@ -369,7 +373,8 @@ export const loginValidator = validate(

if (
user.notice === NoticeUser.Banned ||
user.reasonBanned !== ""
user.reasonBanned !== '' ||
user.block === Subscription.True
) {
throw new ErrorWithStatus({
message: USER_MESSAGES.ACCOUNT_IS_BANNED,
Expand Down
11 changes: 9 additions & 2 deletions src/modules/user/user.requests.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ObjectId } from 'mongodb'
import { JwtPayload } from "jsonwebtoken";
import {
Subscription,
Expand Down Expand Up @@ -79,8 +80,14 @@ export type LogoutReqBody = {
};

export type RefreshTokenReqBody = {
refresh_token: string;
};
refresh_token: string
}
export interface BlockBody {
_id: ObjectId
description_reason?: string
picture_image_prove?: string
refresh_token: string
}

export type ListAccountQuery = {
page?: number;
Expand Down
15 changes: 13 additions & 2 deletions src/modules/user/user.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Router } from "express";
import { cronJobFake } from "~/utils/cronJobFake";
import { wrapAsync } from "~/utils/handler";
import {
blockAccountController,
changePasswordController,
forgotPasswordController,
getListUserController,
Expand All @@ -14,6 +15,7 @@ import {
resetPasswordController,
searchAccountController,
sendVerifyAccountOTPController,
unblockAccountController,
updateMeController,
verifyAccountController,
verifyForgotPasswordTokenController,
Expand Down Expand Up @@ -232,8 +234,17 @@ usersRouter.post(
usersRouter.post(
"/refresh-token",
refreshTokenCookieValidator,
wrapAsync(refreshTokenController),
);
wrapAsync(refreshTokenController)
)

usersRouter.post(
'/block',
accessTokenValidator,
refreshTokenCookieValidator,
wrapAsync(blockAccountController)
)

usersRouter.post('/unblock', wrapAsync(unblockAccountController))

usersRouter.get(
"/list-account",
Expand Down
97 changes: 55 additions & 42 deletions src/modules/user/user.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,69 @@ import {
interface UserType {
_id?: ObjectId;
// username: string
first_name: string;
last_name: string;
phone_number?: string;
password: string;
email?: string;
role?: UserRole;
created_at?: Date;
updated_at?: Date;
status?: UserVerifyStatus;
notice?: NoticeUser;
wrongPasswordTimes?: number;
reasonBanned?: string;
avatar_url?: string;
subscription: Subscription;
first_name: string
last_name: string
phone_number?: string
password: string
email?: string
role?: UserRole
created_at?: Date
updated_at?: Date
status?: UserVerifyStatus
notice?: NoticeUser
block?: Subscription
reasonBlocked?: string
picture_image_prove?: string
block_time?: Date
wrongPasswordTimes?: number
reasonBanned?: string
avatar_url?: string
subscription: Subscription
}

export default class User {
_id?: ObjectId;
// username: string
first_name: string;
last_name: string;
phone_number: string;
password: string;
email: string;
role: UserRole;
created_at: Date;
updated_at: Date;
status: UserVerifyStatus;
notice: NoticeUser;
wrongPasswordTimes?: number;
reasonBanned?: string;
avatar_url: string;
subscription: Subscription;
first_name: string
last_name: string
phone_number: string
password: string
email: string
role: UserRole
created_at: Date
updated_at: Date
status: UserVerifyStatus
notice: NoticeUser
block: Subscription
reasonBlocked?: string
picture_image_prove?: string
block_time: Date
wrongPasswordTimes?: number
reasonBanned?: string
avatar_url: string
subscription: Subscription

constructor(user: UserType) {
const date = new Date();
this._id = user._id || new ObjectId();
// this.username = user.username || ''
this.first_name = user.first_name || "";
this.last_name = user.last_name || "";
this.phone_number = user.phone_number || "";
this.password = user.password;
this.email = user.email || "";
this.role = user.role || UserRole.Customer;
this.created_at = user.created_at || date;
this.updated_at = user.updated_at || date;
this.status = user.status || UserVerifyStatus.Unverified;
this.notice = NoticeUser.Active;
this.wrongPasswordTimes = 0;
this.reasonBanned = user.reasonBanned || "";
this.avatar_url = user.avatar_url || "";
this.subscription = user.subscription || Subscription.False;
this.first_name = user.first_name || ''
this.last_name = user.last_name || ''
this.phone_number = user.phone_number || ''
this.password = user.password
this.email = user.email || ''
this.role = user.role || UserRole.Customer
this.created_at = user.created_at || date
this.updated_at = user.updated_at || date
this.status = user.status || UserVerifyStatus.Unverified
this.notice = NoticeUser.Active
this.block = Subscription.False
this.reasonBlocked = user.reasonBlocked || ''
this.picture_image_prove = user.picture_image_prove || ''
this.block_time = user.block_time || date
this.wrongPasswordTimes = 0
this.reasonBanned = user.reasonBanned || ''
this.avatar_url = user.avatar_url || ''
this.subscription = user.subscription || Subscription.False
}
}
Loading