made register and login apis for host

This commit is contained in:
2025-11-12 16:03:57 +05:30
parent 5399c8b987
commit c0e58fe1ce
24 changed files with 2052 additions and 163 deletions

View File

@@ -2,10 +2,13 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../common/database/prisma.service';
import { CreateHostDto, UpdateHostDto } from '../dto/host.dto';
import * as bcrypt from 'bcryptjs';
import ApiError from '../../../common/utils/helper/ApiError';
import { User } from '@prisma/client';
@Injectable()
export class HostService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) { }
async createHost(data: CreateHostDto) {
return this.prisma.user.create({ data });
@@ -17,7 +20,9 @@ export class HostService {
async getHostById(id: number) {
const host = await this.prisma.user.findUnique({ where: { id } });
if (!host || host.roleXid !== 3) throw new Error('Host not found');
if (!host || host.roleXid !== 4) {
throw new ApiError(404, 'Host not found');
}
return host;
}
@@ -31,4 +36,111 @@ export class HostService {
async deleteHost(id: number) {
return this.prisma.user.delete({ where: { id } });
}
async getHostByEmail(email: string): Promise<User> {
return this.prisma.user.findUnique({ where: { emailAddress: email } });
}
async verifyHostOtp(email: string, otp: string): Promise<boolean> {
const user = await this.prisma.user.findUnique({
where: { emailAddress: email },
select: {
id: true,
emailAddress: true,
UserOtp: {
where: { isActive: true, isVerified: false },
orderBy: { createdAt: 'desc' },
take: 1,
},
},
});
if (!user) {
throw new ApiError(404, 'User not found.');
}
const userOtp = user.UserOtp[0];
if (!userOtp) {
throw new ApiError(400, 'No OTP found.');
}
if (new Date() > userOtp.expiresOn) {
throw new ApiError(400, 'OTP has expired.');
}
const isMatch = await bcrypt.compare(otp, userOtp.otpCode);
if (!isMatch) {
throw new ApiError(400, 'Invalid OTP.');
}
await this.prisma.userOtp.update({
where: { id: userOtp.id },
data: {
isVerified: true,
verifiedOn: new Date(),
isActive: false,
},
});
return true;
}
async loginForHost(emailAddress: string, userPassword: string) {
const existingUser = await this.prisma.user.findUnique({
where: { emailAddress: emailAddress },
});
if (!existingUser) {
throw new ApiError(404, 'User not found');
}
if (existingUser.roleXid !== 4) {
throw new ApiError(403, 'Access denied. Not a host user.');
}
const matchPassword = await bcrypt.compare(userPassword, existingUser.userPassword);
if (!matchPassword) {
throw new ApiError(401, 'Invalid credentials');
}
return existingUser;
}
async createHostUser(email: string) {
const newUser = await this.prisma.user.create({
data: { emailAddress: email, roleXid: 4 },
});
return newUser;
}
async createPassword(user_xid: number, password: string): Promise<boolean> {
// Find user by id
const user = await this.prisma.user.findUnique({
where: { id: user_xid },
select: { id: true, emailAddress: true, userPassword: true },
});
if (!user) {
throw new ApiError(404, 'User not found');
}
// Check if password already exists
if (user.userPassword) {
throw new ApiError(400, 'Password already exists. Use update password instead.');
}
// Hash the password
const saltRounds = parseInt(process.env.SALT_ROUNDS || '10', 10);
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Update user with hashed password
await this.prisma.user.update({
where: { id: user.id },
data: { userPassword: hashedPassword },
});
return true;
}
}

View File

@@ -0,0 +1,159 @@
import { PrismaClient } from "@prisma/client";
import jwt, { JwtPayload } from "jsonwebtoken";
import moment from "moment";
import config from "../../../config/config";
const prisma = new PrismaClient();
export class TokenService {
private generateToken(
user_xid: number,
expiresIn: Date,
type: string,
secret: string
): { token: string; expires: Date } {
const token = jwt.sign(
{
sub: user_xid,
iat: moment().unix(),
exp: moment(expiresIn).unix(),
type,
},
secret
);
return { token, expires: expiresIn };
}
async generateAuthToken(
user_xid: number,
): Promise<{
access: { token: string; expires: Date };
refresh: { token: string; expires: Date };
}> {
const accessTokenExpires = moment()
.add(config.jwt.accessExpirationMinutes, "minutes")
.toDate();
const refreshTokenExpires = moment()
.add(config.jwt.refreshExpirationDays, "days")
.toDate();
const accessToken = this.generateToken(
user_xid,
accessTokenExpires,
"access",
config.jwt.secret
);
const refreshToken = this.generateToken(
user_xid,
refreshTokenExpires,
"refresh",
config.jwt.secret
);
await prisma.token.create({
data: {
token: refreshToken.token,
expiringAt: refreshToken.expires,
tokenType: "refresh",
isBlackListed: false,
user: {
connect: { id: user_xid },
},
},
});
return {
access: accessToken,
refresh: refreshToken,
};
}
async generateAuthTokenAdmin(
user_xid: number
): Promise<{
access: { token: string; expires: Date };
refresh: { token: string; expires: Date };
}> {
const accessTokenExpires = moment()
.add(config.jwt.accessExpirationMinutes, "minutes")
.toDate();
const refreshTokenExpires = moment()
.add(config.jwt.refreshExpirationDays, "days")
.toDate();
const accessToken = this.generateToken(
user_xid,
accessTokenExpires,
"access",
config.jwt.secret
);
const refreshToken = this.generateToken(
user_xid,
refreshTokenExpires,
"refresh",
config.jwt.secret
);
await prisma.token.create({
data: {
token: refreshToken.token,
expiringAt: refreshToken.expires,
tokenType: "refresh",
isBlackListed: false,
user: {
connect: { id: user_xid },
},
},
});
return {
access: accessToken,
refresh: refreshToken,
};
}
async revokeToken(user_xid: number, deviceId: string): Promise<boolean> {
const existingToken = await prisma.token.findFirst({
where: {
id: user_xid,
deviceId,
},
});
if (!existingToken) return false;
await prisma.token.delete({ where: { id: existingToken.id } });
return true;
}
async isTokenBlackListed(token: string): Promise<boolean> {
const existing = await prisma.token.findUnique({
where: { token },
});
return existing ? true : false;
}
async verifyRefreshToken(
token: string
): Promise<string | JwtPayload | null> {
try {
return jwt.verify(token, config.jwt.secret);
} catch {
return null;
}
}
async decodeToken(token: string): Promise<string | JwtPayload | null> {
try {
return jwt.decode(token);
} catch {
return null;
}
}
}