import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import axios, { AxiosInstance } from 'axios'; /** * Identity Service 客户端 * 用于调用 identity-service 的 API */ @Injectable() export class IdentityClientService { private readonly logger = new Logger(IdentityClientService.name); private readonly httpClient: AxiosInstance; constructor(private readonly configService: ConfigService) { const baseUrl = this.configService.get('IDENTITY_SERVICE_URL', 'http://localhost:3001'); this.httpClient = axios.create({ baseURL: baseUrl, timeout: 10000, }); this.logger.log(`Identity client initialized: ${baseUrl}`); } /** * 验证用户的 TOTP 码 * * @param userId 用户 ID * @param totpCode TOTP 验证码 * @param token JWT token (用于认证) * @returns 验证是否成功 */ async verifyTotp(userId: string, totpCode: string, token: string): Promise { try { this.logger.log(`验证 TOTP: userId=${userId}`); const response = await this.httpClient.post( '/totp/verify', { code: totpCode }, { headers: { Authorization: `Bearer ${token}`, }, }, ); const valid = response.data?.valid ?? false; this.logger.log(`TOTP 验证结果: userId=${userId}, valid=${valid}`); return valid; } catch (error: any) { this.logger.error(`TOTP 验证失败: userId=${userId}, error=${error.message}`); // 如果是 identity-service 返回的错误 if (error.response) { const status = error.response.status; const message = error.response.data?.message || 'TOTP 验证失败'; if (status === 400 || status === 401) { throw new HttpException(message, HttpStatus.BAD_REQUEST); } } // 网络错误或其他错误 throw new HttpException('TOTP 验证服务不可用', HttpStatus.SERVICE_UNAVAILABLE); } } /** * 检查用户是否启用了 TOTP * * @param userId 用户 ID * @param token JWT token * @returns 是否启用 TOTP */ async isTotpEnabled(userId: string, token: string): Promise { try { this.logger.log(`检查 TOTP 状态: userId=${userId}`); const response = await this.httpClient.get('/totp/status', { headers: { Authorization: `Bearer ${token}`, }, }); const isEnabled = response.data?.isEnabled ?? false; this.logger.log(`TOTP 状态: userId=${userId}, enabled=${isEnabled}`); return isEnabled; } catch (error: any) { this.logger.error(`获取 TOTP 状态失败: userId=${userId}, error=${error.message}`); // 如果获取状态失败,假设未启用 TOTP(允许操作继续) return false; } } }