88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import {
|
||
BadRequestException,
|
||
Body,
|
||
Controller,
|
||
NotImplementedException,
|
||
Post,
|
||
Request,
|
||
Res,
|
||
UseGuards,
|
||
} from '@nestjs/common';
|
||
import { LoginByPasswordDto } from './dto/login.dto';
|
||
import { AuthService } from './auth.service';
|
||
import { UserSessionService } from 'src/auth/service/user-session.service';
|
||
import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
|
||
import { Response } from 'express';
|
||
import { UserService } from 'src/user/user.service';
|
||
import { AuthGuard } from './guards/auth.guard';
|
||
import { SmsLoginDto } from './dto/sms-login.dto';
|
||
import { SmsService } from 'src/sms/sms.service';
|
||
import { UserSession } from 'src/auth/entity/user-session.entity';
|
||
|
||
@Controller('auth')
|
||
export class AuthController {
|
||
constructor(
|
||
private readonly authService: AuthService,
|
||
private readonly userService: UserService,
|
||
private readonly userSessionService: UserSessionService,
|
||
private readonly smsService: SmsService,
|
||
) { }
|
||
|
||
private setUserSession(res: Response, session: UserSession) {
|
||
res.cookie('session', session.sessionId, {
|
||
httpOnly: true,
|
||
secure: process.env.NODE_ENV === 'production',
|
||
sameSite: 'lax',
|
||
// 永不过期,不用设置maxAge
|
||
path: '/',
|
||
})
|
||
}
|
||
|
||
@Post('login/password')
|
||
async loginByPassword(
|
||
@Body() loginDto: LoginByPasswordDto,
|
||
@Res({ passthrough: true }) res: Response,
|
||
) {
|
||
const { identifier, password } = loginDto;
|
||
const session = await this.authService.loginWithPassword(identifier, password);
|
||
this.setUserSession(res, session);
|
||
return {
|
||
user: await this.userService.findById(session.userId),
|
||
};
|
||
}
|
||
|
||
@Post('login/sms')
|
||
async loginBySms(
|
||
@Body() dto: SmsLoginDto,
|
||
@Res({ passthrough: true }) res: Response,
|
||
) {
|
||
const { phone, code } = dto;
|
||
await this.smsService.checkSms(phone, 'login', code);
|
||
// 验证通过,(注册并)登陆
|
||
const session = await this.authService.loginWithPhone(phone);
|
||
this.setUserSession(res, session);
|
||
return {
|
||
user: await this.userService.findById(session.userId),
|
||
}
|
||
}
|
||
|
||
@Post('passkey/login/options')
|
||
async loginByPasskeyOptions() {
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
@Post('passkey/login')
|
||
async loginByPasskey() {
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
@UseGuards(AuthGuard)
|
||
@Post('logout')
|
||
async logout(@Request() req) {
|
||
const { userId, sessionId } = req.user;
|
||
await this.userSessionService.invalidateSession(userId, sessionId);
|
||
|
||
return true;
|
||
}
|
||
}
|