forked from datawhale/whale-town-end
- 添加用户登录、注册、密码重置功能 - 支持用户名/邮箱/手机号多种登录方式 - 集成GitHub OAuth第三方登录 - 实现bcrypt密码加密存储 - 添加基于角色的权限控制 - 包含完整的数据验证和错误处理
136 lines
4.0 KiB
TypeScript
136 lines
4.0 KiB
TypeScript
/**
|
||
* 登录控制器
|
||
*
|
||
* 功能描述:
|
||
* - 处理登录相关的HTTP请求和响应
|
||
* - 提供RESTful API接口
|
||
* - 数据验证和格式化
|
||
*
|
||
* API端点:
|
||
* - POST /auth/login - 用户登录
|
||
* - POST /auth/register - 用户注册
|
||
* - POST /auth/github - GitHub OAuth登录
|
||
* - POST /auth/forgot-password - 发送密码重置验证码
|
||
* - POST /auth/reset-password - 重置密码
|
||
* - PUT /auth/change-password - 修改密码
|
||
*
|
||
* @author moyin
|
||
* @version 1.0.0
|
||
* @since 2025-12-17
|
||
*/
|
||
|
||
import { Controller, Post, Put, Body, HttpCode, HttpStatus, ValidationPipe, UsePipes, Logger } from '@nestjs/common';
|
||
import { LoginService, ApiResponse, LoginResponse } from './login.service';
|
||
import { LoginDto, RegisterDto, GitHubOAuthDto, ForgotPasswordDto, ResetPasswordDto, ChangePasswordDto } from './login.dto';
|
||
|
||
@Controller('auth')
|
||
export class LoginController {
|
||
private readonly logger = new Logger(LoginController.name);
|
||
|
||
constructor(private readonly loginService: LoginService) {}
|
||
|
||
/**
|
||
* 用户登录
|
||
*
|
||
* @param loginDto 登录数据
|
||
* @returns 登录结果
|
||
*/
|
||
@Post('login')
|
||
@HttpCode(HttpStatus.OK)
|
||
@UsePipes(new ValidationPipe({ transform: true }))
|
||
async login(@Body() loginDto: LoginDto): Promise<ApiResponse<LoginResponse>> {
|
||
return await this.loginService.login({
|
||
identifier: loginDto.identifier,
|
||
password: loginDto.password
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 用户注册
|
||
*
|
||
* @param registerDto 注册数据
|
||
* @returns 注册结果
|
||
*/
|
||
@Post('register')
|
||
@HttpCode(HttpStatus.CREATED)
|
||
@UsePipes(new ValidationPipe({ transform: true }))
|
||
async register(@Body() registerDto: RegisterDto): Promise<ApiResponse<LoginResponse>> {
|
||
return await this.loginService.register({
|
||
username: registerDto.username,
|
||
password: registerDto.password,
|
||
nickname: registerDto.nickname,
|
||
email: registerDto.email,
|
||
phone: registerDto.phone
|
||
});
|
||
}
|
||
|
||
/**
|
||
* GitHub OAuth登录
|
||
*
|
||
* @param githubDto GitHub OAuth数据
|
||
* @returns 登录结果
|
||
*/
|
||
@Post('github')
|
||
@HttpCode(HttpStatus.OK)
|
||
@UsePipes(new ValidationPipe({ transform: true }))
|
||
async githubOAuth(@Body() githubDto: GitHubOAuthDto): Promise<ApiResponse<LoginResponse>> {
|
||
return await this.loginService.githubOAuth({
|
||
github_id: githubDto.github_id,
|
||
username: githubDto.username,
|
||
nickname: githubDto.nickname,
|
||
email: githubDto.email,
|
||
avatar_url: githubDto.avatar_url
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 发送密码重置验证码
|
||
*
|
||
* @param forgotPasswordDto 忘记密码数据
|
||
* @returns 发送结果
|
||
*/
|
||
@Post('forgot-password')
|
||
@HttpCode(HttpStatus.OK)
|
||
@UsePipes(new ValidationPipe({ transform: true }))
|
||
async forgotPassword(@Body() forgotPasswordDto: ForgotPasswordDto): Promise<ApiResponse<{ verification_code?: string }>> {
|
||
return await this.loginService.sendPasswordResetCode(forgotPasswordDto.identifier);
|
||
}
|
||
|
||
/**
|
||
* 重置密码
|
||
*
|
||
* @param resetPasswordDto 重置密码数据
|
||
* @returns 重置结果
|
||
*/
|
||
@Post('reset-password')
|
||
@HttpCode(HttpStatus.OK)
|
||
@UsePipes(new ValidationPipe({ transform: true }))
|
||
async resetPassword(@Body() resetPasswordDto: ResetPasswordDto): Promise<ApiResponse> {
|
||
return await this.loginService.resetPassword({
|
||
identifier: resetPasswordDto.identifier,
|
||
verificationCode: resetPasswordDto.verification_code,
|
||
newPassword: resetPasswordDto.new_password
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 修改密码
|
||
*
|
||
* @param changePasswordDto 修改密码数据
|
||
* @returns 修改结果
|
||
*/
|
||
@Put('change-password')
|
||
@HttpCode(HttpStatus.OK)
|
||
@UsePipes(new ValidationPipe({ transform: true }))
|
||
async changePassword(@Body() changePasswordDto: ChangePasswordDto): Promise<ApiResponse> {
|
||
// 实际应用中应从JWT令牌中获取用户ID
|
||
// 这里为了演示,使用请求体中的用户ID
|
||
const userId = BigInt(changePasswordDto.user_id);
|
||
|
||
return await this.loginService.changePassword(
|
||
userId,
|
||
changePasswordDto.old_password,
|
||
changePasswordDto.new_password
|
||
);
|
||
}
|
||
} |