commit for push
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.15.1",
|
"class-validator": "^0.15.1",
|
||||||
"joi": "^18.2.3",
|
"joi": "^18.2.3",
|
||||||
|
"ms": "^2.1.3",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"pg": "^8.22.0",
|
"pg": "^8.22.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
"@types/bcrypt": "^6.0.0",
|
"@types/bcrypt": "^6.0.0",
|
||||||
"@types/express": "^5.0.0",
|
"@types/express": "^5.0.0",
|
||||||
"@types/jest": "^30.0.0",
|
"@types/jest": "^30.0.0",
|
||||||
|
"@types/ms": "^2.1.0",
|
||||||
"@types/node": "^22.10.7",
|
"@types/node": "^22.10.7",
|
||||||
"@types/passport-jwt": "^4.0.1",
|
"@types/passport-jwt": "^4.0.1",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
|
|||||||
Generated
+6
@@ -47,6 +47,9 @@ importers:
|
|||||||
joi:
|
joi:
|
||||||
specifier: ^18.2.3
|
specifier: ^18.2.3
|
||||||
version: 18.2.3
|
version: 18.2.3
|
||||||
|
ms:
|
||||||
|
specifier: ^2.1.3
|
||||||
|
version: 2.1.3
|
||||||
passport-jwt:
|
passport-jwt:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
@@ -87,6 +90,9 @@ importers:
|
|||||||
'@types/jest':
|
'@types/jest':
|
||||||
specifier: ^30.0.0
|
specifier: ^30.0.0
|
||||||
version: 30.0.0
|
version: 30.0.0
|
||||||
|
'@types/ms':
|
||||||
|
specifier: ^2.1.0
|
||||||
|
version: 2.1.0
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.10.7
|
specifier: ^22.10.7
|
||||||
version: 22.20.1
|
version: 22.20.1
|
||||||
|
|||||||
@@ -45,4 +45,14 @@ export class AuthController {
|
|||||||
) {
|
) {
|
||||||
return this.authService.checkLoginCredentials(dto);
|
return this.authService.checkLoginCredentials(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('verify-login')
|
||||||
|
@ApiOperation({summary: 'verifies OTP and then login'})
|
||||||
|
@ApiResponse({status: 200, description: 'User Logged in successfully!'})
|
||||||
|
@ApiResponse({status: 400, description: 'Bad Request From The User'})
|
||||||
|
async verifyOtpAndLogin(
|
||||||
|
@Body() verifyOtpDto: VerifyOtpDto
|
||||||
|
) {
|
||||||
|
return this.authService.verifyOtpAndLogin(verifyOtpDto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ import { LoginCredentialDto } from './DTO/login-credential.dto';
|
|||||||
import { UsersService } from 'src/users/users.service';
|
import { UsersService } from 'src/users/users.service';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
|
import ms from 'ms';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@@ -20,7 +21,7 @@ export class AuthService {
|
|||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly OtpRepository: OtpRepository,
|
private readonly OtpRepository: OtpRepository,
|
||||||
private readonly userService: UsersService,
|
private readonly userService: UsersService,
|
||||||
private readonly jwtService: JwtService
|
private readonly jwtService: JwtService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async sendOTP(phone: string) {
|
async sendOTP(phone: string) {
|
||||||
@@ -43,7 +44,6 @@ export class AuthService {
|
|||||||
{ status: OtpStatus.EXPIRED },
|
{ status: OtpStatus.EXPIRED },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
await this.OtpRepository.save(
|
await this.OtpRepository.save(
|
||||||
this.OtpRepository.create({
|
this.OtpRepository.create({
|
||||||
phoneNumber: phone,
|
phoneNumber: phone,
|
||||||
@@ -123,9 +123,46 @@ export class AuthService {
|
|||||||
await this.sendOTP(phoneNumber);
|
await this.sendOTP(phoneNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
// async VerifyOtpAndLogin(dto: VerifyOtpDto) {
|
async verifyOtpAndLogin(dto: VerifyOtpDto) {
|
||||||
// await this.verifyOTP(dto);
|
await this.verifyOTP(dto);
|
||||||
|
|
||||||
// const user = await this.userService.findOneByPhoneOrFail(dto.phoneNumber);
|
const user = await this.userService.findUserWithRolesByPhoneOrFail(
|
||||||
// }
|
dto.phoneNumber,
|
||||||
|
);
|
||||||
|
|
||||||
|
const roles = user.roles.map((r) => r.role);
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
sub: user.id,
|
||||||
|
phone: user.phone,
|
||||||
|
roles,
|
||||||
|
};
|
||||||
|
|
||||||
|
const accessToken = await this.jwtService.signAsync(payload, {
|
||||||
|
secret: this.configService.getOrThrow<string>('JWT_ACCESS_SECRET'),
|
||||||
|
expiresIn: this.configService.getOrThrow<string>(
|
||||||
|
'JWT_ACCESS_EXPIRES',
|
||||||
|
) as ms.StringValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
const refreshToken = await this.jwtService.signAsync(payload, {
|
||||||
|
secret: this.configService.getOrThrow<string>('JWT_REFRESH_SECRET'),
|
||||||
|
expiresIn: this.configService.getOrThrow<string>(
|
||||||
|
'JWT_REFRESH_EXPIRES',
|
||||||
|
) as ms.StringValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.userService.updateRefreshToken(user.id, refreshToken);
|
||||||
|
|
||||||
|
return {
|
||||||
|
user: {
|
||||||
|
userId: user.id,
|
||||||
|
username: user.firstName + ' ' + user.lastName,
|
||||||
|
userPhone: user.phone,
|
||||||
|
userEmail: user.email,
|
||||||
|
},
|
||||||
|
accessToken,
|
||||||
|
refreshToken,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,28 @@
|
|||||||
import { Repository } from "typeorm";
|
import { Repository } from 'typeorm';
|
||||||
import { User } from "../entities/user.entity";
|
import { User } from '../entities/user.entity';
|
||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Injectable } from "@nestjs/common";
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserRepository extends Repository<User> {
|
export class UserRepository extends Repository<User> {
|
||||||
constructor(@InjectRepository(User) userRepository: Repository<User>) {
|
constructor(@InjectRepository(User) userRepository: Repository<User>) {
|
||||||
super(userRepository.target, userRepository.manager, userRepository.queryRunner);
|
super(
|
||||||
}
|
userRepository.target,
|
||||||
}
|
userRepository.manager,
|
||||||
|
userRepository.queryRunner,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
findUserWithRolesByPhone(phone: string): Promise<User | null> {
|
||||||
|
return this.createQueryBuilder('users')
|
||||||
|
.leftJoinAndSelect('users.roles', 'roles')
|
||||||
|
.where("users.phone = :phone", {phone})
|
||||||
|
.select(
|
||||||
|
[
|
||||||
|
'users',
|
||||||
|
'roles.id',
|
||||||
|
'roles.role'
|
||||||
|
]
|
||||||
|
).getOne();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ export class UsersService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findOneByPhoneOrFail(phone: string): Promise<User> {
|
async findOneByPhoneOrFail(phone: string): Promise<User> {
|
||||||
const user = await this.userRepository.findOne({ where: { phone } });
|
const user = await this.userRepository.findOne({
|
||||||
|
where: { phone },
|
||||||
|
relations: {
|
||||||
|
roles: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new NotFoundException(UserMessages.USER_NOT_FOUND);
|
throw new NotFoundException(UserMessages.USER_NOT_FOUND);
|
||||||
@@ -39,6 +44,22 @@ export class UsersService {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findUserWithRolesByPhoneOrFail(phone: string): Promise<User> {
|
||||||
|
const user = await this.userRepository.findUserWithRolesByPhone(phone);
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
throw new NotFoundException(UserMessages.USER_NOT_FOUND);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateRefreshToken(id: string, newRefreshToken: string) {
|
||||||
|
const user = await this.findOneOrFail(id);
|
||||||
|
|
||||||
|
user.refreshToken = newRefreshToken;
|
||||||
|
await this.userRepository.save(user);
|
||||||
|
}
|
||||||
|
|
||||||
async createUser(userDto: CreateUserDto): Promise<User> {
|
async createUser(userDto: CreateUserDto): Promise<User> {
|
||||||
const existingUser = await this.userRepository.findOne({
|
const existingUser = await this.userRepository.findOne({
|
||||||
where: [
|
where: [
|
||||||
|
|||||||
Reference in New Issue
Block a user