216 lines
8.9 KiB
TypeScript
216 lines
8.9 KiB
TypeScript
import { Request } from "express";
|
|
import rateLimit from "express-rate-limit";
|
|
import { inject } from "inversify";
|
|
import { controller, httpGet, httpPatch, httpPost, queryParam, request, requestBody } from "inversify-express-utils";
|
|
import { HydratedDocument } from "mongoose";
|
|
|
|
import { ChangeEmailDTO, UpdateUserDTO, VerifyEmailDTO } from "./DTO/userUpdate.dto";
|
|
import { IUser } from "./models/Abstraction/IUser";
|
|
import { UserService } from "./user.service";
|
|
import { HttpStatus } from "../../common";
|
|
import { BaseController } from "../../common/base/controller";
|
|
import { ApiAuth, ApiBody, ApiFile, ApiModel, ApiOperation, ApiQuery, ApiResponse, ApiTags } from "../../common/decorator/swggerDocs";
|
|
import { AuthMessage } from "../../common/enums/message.enum";
|
|
import { OrderStatusQuery } from "../../common/types/query.type";
|
|
import { appConfig } from "../../core/config/app.config";
|
|
import { Guard } from "../../core/middlewares/guard.middleware";
|
|
import { ValidationMiddleware } from "../../core/middlewares/validator.middleware";
|
|
import { IOCTYPES } from "../../IOC/ioc.types";
|
|
import { UploadService } from "../../utils/upload.service";
|
|
import { AddressService } from "../address/address.service";
|
|
import { AuthService } from "../auth/auth.service";
|
|
import { AuthDTO } from "../auth/DTO/Auth.dto";
|
|
import { AuthCheckOtpDTO } from "../auth/DTO/AuthCheckOtp.dto";
|
|
import { TokenDto } from "../auth/DTO/Token.dto";
|
|
import { OrderService } from "../order/order.service";
|
|
|
|
@controller("/user")
|
|
@ApiTags("User")
|
|
class UserController extends BaseController {
|
|
@inject(IOCTYPES.UserService) userService: UserService;
|
|
@inject(IOCTYPES.AuthService) authService: AuthService;
|
|
@inject(IOCTYPES.OrderService) orderService: OrderService;
|
|
@inject(IOCTYPES.AddressService) addressService: AddressService;
|
|
|
|
/**
|
|
*
|
|
* @param authDto
|
|
* @returns
|
|
*/
|
|
@ApiOperation("Authenticate to send OTP code")
|
|
@ApiResponse("Successful", 200, { message: AuthMessage.OtpSentToNo, phone: "09122569856" })
|
|
@ApiResponse("BadRequest", 400, { details: ["فرمت موبایل اشتباه است"] })
|
|
@ApiModel(AuthDTO)
|
|
@ApiBody("Authenticate with phone or email")
|
|
@httpPost("/authenticate", rateLimit(appConfig.rate), ValidationMiddleware.validateInput(AuthDTO))
|
|
async authUser(@requestBody() authDto: AuthDTO) {
|
|
const data = await this.authService.authenticate(authDto, "user");
|
|
return this.response({ data }, HttpStatus.Ok);
|
|
}
|
|
/**
|
|
*
|
|
* @param loginOtpDto
|
|
*/
|
|
@ApiOperation("login user -> check sent OTP and generate the token")
|
|
@ApiResponse("Successful login", 200, { message: AuthMessage.SuccessLogin, Accesstoken: "tokenValue", refreshToken: "tokenValue" })
|
|
@ApiModel(AuthCheckOtpDTO)
|
|
@ApiBody("login user with otp code")
|
|
@httpPost("/login/otp", rateLimit(appConfig.rate), ValidationMiddleware.validateInput(AuthCheckOtpDTO))
|
|
async loginOtp(@requestBody() loginOtpDto: AuthCheckOtpDTO) {
|
|
const data = await this.authService.loginOtpS(loginOtpDto, "user");
|
|
return this.response({ data }, HttpStatus.Created);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param refreshToken
|
|
* @returns
|
|
*/
|
|
@ApiOperation("check the refresh token and generate access token base on that")
|
|
@ApiResponse("Successful", 200, { accessToken: "tokenValue", refreshToken: "tokenValue" })
|
|
@ApiResponse("unauthorized", 401, { message: AuthMessage.TokenExpired })
|
|
@ApiResponse("notFound", 404, { message: AuthMessage.TokenNotFound })
|
|
@ApiModel(TokenDto)
|
|
@httpPost("/token", rateLimit(appConfig.rate), ValidationMiddleware.validateInput(TokenDto))
|
|
public async refreshTokens(@requestBody() refreshToken: TokenDto) {
|
|
const data = await this.authService.refreshTokensS(refreshToken);
|
|
//return new tokens
|
|
return this.response({ data }, HttpStatus.Created);
|
|
}
|
|
/**
|
|
*
|
|
* @param req
|
|
* @returns
|
|
*/
|
|
@ApiOperation("logout the user based on the sent authorization token")
|
|
@ApiResponse("Successful", 200, { message: AuthMessage.LoggedOut })
|
|
@ApiAuth()
|
|
@httpPost("/logout", rateLimit(appConfig.rate), Guard.authUser())
|
|
public async logout(@request() req: Request) {
|
|
//this is maybe user or seller based on token
|
|
const user = req.user as IUser;
|
|
const data = await this.authService.logoutS(user._id.toString());
|
|
//return logout message
|
|
return this.response({ data });
|
|
}
|
|
|
|
@ApiOperation("get current logged in user info ")
|
|
@ApiResponse("successful", 200)
|
|
@ApiAuth()
|
|
@httpGet("/profile", Guard.authUser())
|
|
public async userProfile(@request() req: Request) {
|
|
const user = req.user as HydratedDocument<IUser>;
|
|
const data = await this.userService.getProfile(user);
|
|
return this.response(data);
|
|
}
|
|
|
|
@ApiOperation("update fields of the user with its current session")
|
|
@ApiResponse("successful", HttpStatus.Created)
|
|
@ApiModel(UpdateUserDTO)
|
|
@ApiAuth()
|
|
@httpPatch("/profile", Guard.authUser(), ValidationMiddleware.validateInput(UpdateUserDTO))
|
|
async updateUserProfile(@requestBody() updateUserDto: UpdateUserDTO, @request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.userService.updateUserProfileS(updateUserDto, user._id.toString());
|
|
return this.response({ data }, HttpStatus.Created);
|
|
}
|
|
|
|
@ApiOperation("change email of current session user")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiModel(ChangeEmailDTO)
|
|
@ApiAuth()
|
|
@httpPost("/profile/email/change", rateLimit(appConfig.rate), Guard.authUser(), ValidationMiddleware.validateInput(ChangeEmailDTO))
|
|
public async changeEmail(@requestBody() changeEmailDto: ChangeEmailDTO, @request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.authService.changeUserEmail(changeEmailDto, user._id.toString());
|
|
return this.response(data);
|
|
}
|
|
|
|
@ApiOperation("verify email of current session user")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiModel(VerifyEmailDTO)
|
|
@ApiAuth()
|
|
@httpPost("/profile/email/verify", rateLimit(appConfig.rate), Guard.authUser(), ValidationMiddleware.validateInput(VerifyEmailDTO))
|
|
public async verifyUserEmail(@requestBody() verifyEmailDto: VerifyEmailDTO, @request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.authService.verifyUserEmail(verifyEmailDto, user._id.toString());
|
|
return this.response(data);
|
|
}
|
|
|
|
@ApiOperation("get current logged in user address ")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiAuth()
|
|
@httpGet("/profile/address", Guard.authUser())
|
|
public async getUserAddress(@request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.addressService.getUserAddress(user.address.toString());
|
|
return this.response({ address: data });
|
|
}
|
|
|
|
@ApiOperation("get current logged in user comments ")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiAuth()
|
|
@httpGet("/profile/comments", Guard.authUser())
|
|
public async getUserComments(@request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.userService.getUserComments(user._id.toString());
|
|
return this.response(data);
|
|
}
|
|
|
|
@ApiOperation("get current logged in user questions ")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiAuth()
|
|
@httpGet("/profile/questions", Guard.authUser())
|
|
public async getUserQuestions(@request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.userService.getUserQuestions(user._id.toString());
|
|
return this.response(data);
|
|
}
|
|
|
|
@ApiOperation("get current logged in user product wishlist ")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiAuth()
|
|
@httpGet("/profile/wishlist", Guard.authUser())
|
|
public async getUserWishList(@request() req: Request) {
|
|
const user = req.user as IUser;
|
|
const data = await this.userService.getUserWishList(user._id.toString());
|
|
return this.response(data);
|
|
}
|
|
|
|
//###########################################
|
|
//order
|
|
@ApiOperation("get current logged in user order ")
|
|
@ApiResponse("successful", HttpStatus.Ok)
|
|
@ApiQuery("status", "the status of order ==> can be = Delivered | Cancelled | Processing | Returned | Shipped")
|
|
@ApiAuth()
|
|
@httpGet("/profile/orders", Guard.authUser())
|
|
public async getUserOrders(@request() req: Request, @queryParam("status") status: string) {
|
|
const statusQuery = status as OrderStatusQuery;
|
|
const user = req.user as IUser;
|
|
const data = await this.orderService.getUserOrders(user._id.toString(), statusQuery);
|
|
return this.response(data);
|
|
}
|
|
|
|
//uploader
|
|
@ApiOperation("Upload a user info image")
|
|
@ApiResponse("File uploaded successfully", HttpStatus.Accepted)
|
|
@ApiFile("image")
|
|
@ApiAuth()
|
|
@httpPost("/image/upload", Guard.authUser(), UploadService.single("image", "user-profile"))
|
|
public async uploadImage(@request() req: Request) {
|
|
// eslint-disable-next-line no-undef
|
|
const file = req.file as Express.MulterS3.File;
|
|
const data = {
|
|
message: "file uploaded!",
|
|
url: {
|
|
size: file?.size,
|
|
url: file?.location,
|
|
type: file?.mimetype,
|
|
},
|
|
};
|
|
return this.response({ data }, HttpStatus.Accepted);
|
|
}
|
|
}
|
|
|
|
export { UserController };
|