feat: updade workspace
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { Body, Controller, Inject, Post, Res, ValidationPipe } from '@nestjs/common';
|
||||
import type { Response } from 'express';
|
||||
import { ok } from '../common/api-response.js';
|
||||
import { AuthService } from './auth.service.js';
|
||||
import { LoginDto } from './dto/login.dto.js';
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor(@Inject(AuthService) private readonly authService: AuthService) {}
|
||||
|
||||
@Post('login')
|
||||
async login(
|
||||
@Body(new ValidationPipe({ expectedType: LoginDto, whitelist: true, forbidNonWhitelisted: true })) dto: LoginDto,
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
const result = await this.authService.login(dto.username, dto.password);
|
||||
response.cookie('okr_token', result.token, {
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
secure: false,
|
||||
maxAge: 2 * 60 * 60 * 1000,
|
||||
});
|
||||
return ok(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PrismaModule } from '../prisma/prisma.module.js';
|
||||
import { AuthController } from './auth.controller.js';
|
||||
import { AuthService } from './auth.service.js';
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [AuthController],
|
||||
providers: [AuthService],
|
||||
})
|
||||
export class AuthModule {}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { PrismaService } from '../prisma/prisma.service.js';
|
||||
|
||||
export interface LoginResult {
|
||||
token: string;
|
||||
user: {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
username: string;
|
||||
role: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
constructor(
|
||||
@Inject(PrismaService) private readonly prisma: PrismaService,
|
||||
@Inject(JwtService) private readonly jwtService: JwtService,
|
||||
) {}
|
||||
|
||||
async login(usernameOrEmail: string, password: string): Promise<LoginResult> {
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
OR: [{ username: usernameOrEmail }, { email: usernameOrEmail }],
|
||||
},
|
||||
});
|
||||
if (user === null) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
const validPassword = await bcrypt.compare(password, user.passwordHash);
|
||||
if (!validPassword) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
const token = await this.jwtService.signAsync({
|
||||
sub: user.id,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
name: user.name,
|
||||
});
|
||||
|
||||
return {
|
||||
token,
|
||||
user: {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { IsString, MinLength } from 'class-validator';
|
||||
|
||||
export class LoginDto {
|
||||
@IsString()
|
||||
username!: string;
|
||||
|
||||
@IsString()
|
||||
@MinLength(8)
|
||||
password!: string;
|
||||
}
|
||||
Reference in New Issue
Block a user