Эх сурвалжийг харах

feat(auth): 添加谷歌验证器绑定功能

- 在 AuthController 中添加 handleConfirmBinding 方法处理绑定确认- 在 AuthService 中实现 handleConfirmBinding 方法逻辑
- 在 UsersService 中添加 handleConfirmBinding 方法处理用户绑定确认
- 优化 binding 方法,增加密码验证逻辑
wuyi 1 жил өмнө
parent
commit
b9229e8986

+ 6 - 0
src/auth/auth.controller.ts

@@ -37,6 +37,12 @@ export class AuthController {
         return await this.authService.bindingGoogleTwoFactorValidate(username, password)
     }
 
+    @Public()
+    @Post('/handleConfirmBinding')
+    async handleConfirmBinding(@Body() { username, password, bindingCode }) {
+        return await this.authService.handleConfirmBinding(username, password, bindingCode)
+    }
+
     @Get('/admin/user/:userId/token')
     @HasRoles(Role.Admin)
     async getToken(@Param('userId') userId: string) {

+ 6 - 1
src/auth/auth.service.ts

@@ -5,6 +5,7 @@ import { UsersService } from '../users/users.service'
 import { Role } from 'src/model/role.enum'
 import { UserRegisterDto } from 'src/users/dto/user-register.dto'
 import { generateKey } from '../utils/authenticator'
+import { string } from 'yup'
 
 @Injectable()
 export class AuthService {
@@ -61,7 +62,11 @@ export class AuthService {
     }
 
     async bindingGoogleTwoFactorValidate(username: string, password: string) {
-        return await this.usersService.binding(username)
+        return await this.usersService.binding(username, password)
+    }
+
+    async handleConfirmBinding(username: string, password: string, bindingCode: string) {
+        return await this.usersService.handleConfirmBinding(username, password,bindingCode)
     }
 
     async getToken(id: number) {

+ 32 - 3
src/users/users.service.ts

@@ -25,6 +25,7 @@ import { PageRequest } from '../common/dto/page-request'
 import { endOfDay, startOfDay } from 'date-fns'
 import { BalanceRecord, BalanceType } from '../balance/entities/balance-record.entities'
 import { generateKey, generatePasscodes, verifyPasscode } from '../utils/authenticator'
+import { string } from 'yup'
 
 @Injectable()
 export class UsersService implements OnModuleInit {
@@ -134,11 +135,18 @@ export class UsersService implements OnModuleInit {
         return user
     }
 
-    public async binding(username: string) {
+    public async binding(username: string, password: string) {
         const users = await this.userRepository.findOneBy({ username })
-        if (users.twoFactorCode) {
-            return 'success'
+        if (!users) {
+            throw new UnauthorizedException('Username and password doesn\'t match')
+        }
+        const isMatch = await this.hashingService.compare(password, users.password)
+        if (!isMatch) {
+            throw new UnauthorizedException('Username and password doesn\'t match')
         }
+        // if (users.twoFactorCode) {
+        //     return 'success'
+        // }
         const key = await generateKey(username)
         console.log('key', key)
         users.twoFactorCode = key.secret
@@ -147,6 +155,27 @@ export class UsersService implements OnModuleInit {
         return key.url
     }
 
+    public async handleConfirmBinding(username: string, password: string, bindingCode: string) {
+        const users = await this.userRepository.findOneBy({ username })
+        if (!users) {
+            throw new UnauthorizedException('Username and password doesn\'t match')
+        }
+        const isMatch = await this.hashingService.compare(password, users.password)
+        if (!isMatch) {
+            throw new UnauthorizedException('Username and password doesn\'t match')
+        }
+        if (users.twoFactorCode === null || users.twoFactorCode === '') {
+            throw new UnauthorizedException('请绑定谷歌验证器获取认证码.')
+        } else {
+            const verified = await verifyPasscode(users.twoFactorCode, bindingCode)
+            if (verified) {
+                return 'success'
+            } else {
+                throw new UnauthorizedException('认证码错误,请重试.')
+            }
+        }
+    }
+
     public async create(userDto: UserCreateDto): Promise<IUsers> {
         try {
             if (userDto.password) {