after claude code
This commit is contained in:
138
src/modules/auth/auth.service.ts
Normal file
138
src/modules/auth/auth.service.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
import {
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
BadRequestException,
|
||||
ConflictException,
|
||||
} from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { UsersService } from '../users/users.service';
|
||||
import { LoginDto, RegisterDto, AuthResponseDto } from './dto';
|
||||
import { JwtPayload } from './interfaces/jwt-payload.interface';
|
||||
import { UserRole } from '../users/entities/user.entity';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
private readonly BCRYPT_ROUNDS = 10;
|
||||
|
||||
constructor(
|
||||
private readonly usersService: UsersService,
|
||||
private readonly jwtService: JwtService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Validate user credentials (used by LocalStrategy)
|
||||
*/
|
||||
async validateUser(email: string, password: string): Promise<any> {
|
||||
const user = await this.usersService.findByEmail(email);
|
||||
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
if (!user.isActive) {
|
||||
throw new UnauthorizedException('User account is inactive');
|
||||
}
|
||||
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password);
|
||||
|
||||
if (!isPasswordValid) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
// Return user without password
|
||||
const { password: _, ...result } = user;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new user
|
||||
*/
|
||||
async register(registerDto: RegisterDto): Promise<AuthResponseDto> {
|
||||
// Check if user already exists
|
||||
const existingUser = await this.usersService.findByEmail(registerDto.email);
|
||||
|
||||
if (existingUser) {
|
||||
throw new ConflictException('Email already registered');
|
||||
}
|
||||
|
||||
// Hash password
|
||||
const hashedPassword = await this.hashPassword(registerDto.password);
|
||||
|
||||
// Create user with default role if not provided
|
||||
const user = await this.usersService.create({
|
||||
...registerDto,
|
||||
password: hashedPassword,
|
||||
roles: registerDto.roles || [UserRole.USER],
|
||||
});
|
||||
|
||||
// Generate JWT and return
|
||||
return this.login(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Login user and generate JWT
|
||||
*/
|
||||
async login(user: any): Promise<AuthResponseDto> {
|
||||
const payload: JwtPayload = {
|
||||
sub: user.id,
|
||||
email: user.email,
|
||||
roles: user.roles || [],
|
||||
};
|
||||
|
||||
return {
|
||||
access_token: this.jwtService.sign(payload),
|
||||
user: {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
roles: user.roles,
|
||||
isActive: user.isActive,
|
||||
createdAt: user.createdAt,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate JWT token
|
||||
*/
|
||||
async validateToken(token: string): Promise<any> {
|
||||
try {
|
||||
const payload = this.jwtService.verify(token);
|
||||
return payload;
|
||||
} catch (error) {
|
||||
throw new UnauthorizedException('Invalid or expired token');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh access token
|
||||
*/
|
||||
async refreshToken(userId: string): Promise<AuthResponseDto> {
|
||||
const user = await this.usersService.findOne(userId);
|
||||
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('User not found');
|
||||
}
|
||||
|
||||
if (!user.isActive) {
|
||||
throw new UnauthorizedException('User account is inactive');
|
||||
}
|
||||
|
||||
return this.login(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash password using bcrypt
|
||||
*/
|
||||
private async hashPassword(password: string): Promise<string> {
|
||||
return bcrypt.hash(password, this.BCRYPT_ROUNDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify password hash
|
||||
*/
|
||||
async verifyPassword(password: string, hash: string): Promise<boolean> {
|
||||
return bcrypt.compare(password, hash);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user