nestjs-auth-kit
Version:
A modular and flexible authentication kit for NestJS with JWT, social login, OTP, and password reset.
108 lines (87 loc) • 3.68 kB
text/typescript
import { Inject, Injectable, BadRequestException, InternalServerErrorException, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { OtpService } from './services/otp.service';
import { ForgotPasswordService } from './services/forgot-password.service';
import { AUTH_OPTIONS } from './constants/auth.constants';
import { AuthOptions } from './interfaces/auth-options.interface';
import { RegisterDto } from './dto/register.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { Repository } from 'typeorm';
import * as bcrypt from 'bcrypt';
import { LoginDto } from './dto/login.dto';
()
export class AuthService {
constructor(
private readonly jwtService: JwtService,
private readonly otpService: OtpService,
private readonly forgotPasswordService: ForgotPasswordService,
(AUTH_OPTIONS) private readonly authOptions: AuthOptions,
(User) private readonly userRepository: Repository<User>,
) {}
async register(registerDto: RegisterDto) {
const { email, password, firstName, lastName } = registerDto;
if (!password) {
throw new BadRequestException('Password is required');
}
// Encrypt the password
const hashedPassword = await bcrypt.hash(password, 10);
// Create a new user
const user = this.userRepository.create({
email,
password: hashedPassword,
firstName,
lastName,
});
try {
const newUser = await this.userRepository.save(user);
// Destructure the newUser object to exclude the password
const { password, ...userWithoutPassword } = newUser;
return {
message: 'User created successfully',
user: userWithoutPassword,
};
} catch (error) {
throw new InternalServerErrorException('Failed to create user');
}
}
async login(loginDto: LoginDto) {
const { email, password } = loginDto;
const user = await this.userRepository.findOne({ where: { email } });
if (!user) {
throw new UnauthorizedException('Account not found');
}
if (!password) {
throw new BadRequestException('Password is required');
}
// Validate the password
const isPasswordValid = await bcrypt.compare(password, user.password || '');
if (!isPasswordValid) {
throw new UnauthorizedException('Invalid credentials');
}
const payload = { email: user.email, sub: user.id };
return {
access_token: this.jwtService.sign(payload, {
secret: this.authOptions.jwtSecret,
expiresIn: this.authOptions.jwtExpiration,
}),
};
}
async validateGoogleUser(profile: any) {
// Validate or create user from Google profile
return { email: profile.emails[0].value, userId: profile.id };
}
async validateFacebookUser(profile: any) {
// Validate or create user from Facebook profile
return { email: profile.emails[0].value, userId: profile.id };
}
async sendOtp(email: string) {
return this.otpService.generateOtp(email);
}
async verifyOtp(email: string, otp: string) {
return this.otpService.verifyOtp(email, otp);
}
async resetPassword(email: string, otp: string, newPassword: string) {
return this.forgotPasswordService.resetPassword(email, otp, newPassword);
}
}