npm package: @saleandwin/mfa
Description: Multi-Factor Authentication (MFA) module for framework-ts projects with TOTP support
Author: SaleAndWin
Latest version: 1.0.1

# @saleandwin/mfa

多因子认证 (MFA) 模块，为 framework-ts 项目提供 TOTP 认证功能。

## ✨ 特性

- 🔐 **TOTP 认证** - 支持 Google Authenticator、Authy 等应用
- 🔑 **备用码** - 提供备用恢复码
- 📱 **二维码生成** - 自动生成绑定二维码
- 🛡️ **安全设计** - 密钥加密存储，完整审计日志
- 🚀 **Cloudflare Workers 优化** - 专为 Workers 环境设计
- 📊 **统计分析** - 完整的使用统计和审计功能

## 📦 安装

```bash
npm install @saleandwin/mfa
# 或
pnpm add @saleandwin/mfa
```

## 🚀 快速开始

### 1. 基础配置

```typescript
import { MfaHandler, type MfaConfig, type MfaEnv } from '@saleandwin/mfa';

// 在 Cloudflare Workers 中
export default {
  async fetch(request: Request, env: MfaEnv, ctx: ExecutionContext): Promise<Response> {
    const config: MfaConfig = {
      issuer: 'Your App',
      service_name: 'Your Service',
      totp_window: 1,
      backup_codes_count: 10,
      require_mfa: false
    };

    // 创建 MFA Handler 实例
    const mfaHandler = MfaHandler.createInstance(config, env);
    
    // 处理请求...
  }
};
```

### 2. 数据库初始化

```bash
# 执行数据库迁移
wrangler d1 execute your-database --file=./node_modules/@saleandwin/mfa/migrations.sql
```

## 📖 API 文档

### 核心方法

#### 1. 生成 TOTP 绑定信息

```typescript
const result = await mfaHandler.handleGenerateTotpBinding({
  user_id: 'user-123',
  issuer: 'My App',        // 可选
  service_name: 'My Service' // 可选
});

if (result.success) {
  console.log('绑定信息:', result.data);
  // {
  //   secret: 'JBSWY3DPEHPK3PXP',
  //   qr_code: 'base64-encoded-qr-image',
  //   manual_entry_key: 'JBSW Y3DP EHPK 3PXP',
  //   backup_codes: ['12345678', '87654321', ...]
  // }
}
```

#### 2. 绑定验证

```typescript
const result = await mfaHandler.handleBindVerification({
  user_id: 'user-123',
  secret: 'JBSWY3DPEHPK3PXP',
  verification_code: '123456'
});

if (result.success) {
  console.log('MFA 绑定成功');
}
```

#### 3. 验证码校验

```typescript
const result = await mfaHandler.handleVerifyCode({
  user_id: 'user-123',
  verification_code: '123456' // TOTP 验证码或备用码
});

if (result.valid) {
  console.log('验证成功');
} else {
  console.log('验证失败:', result.error);
}
```

#### 4. 解绑 MFA

```typescript
const result = await mfaHandler.handleUnbindMfa({
  user_id: 'user-123',
  verification_code: '123456' // 可选，用于验证身份
});

if (result.success) {
  console.log('MFA 解绑成功');
}
```

#### 5. 获取 MFA 状态

```typescript
const result = await mfaHandler.handleGetMfaStatus('user-123');

if (result.success) {
  console.log('MFA 状态:', result.data);
  // {
  //   enabled: true,
  //   status: 'enabled',
  //   enabled_at: '2024-01-01T00:00:00.000Z',
  //   last_used_at: '2024-01-01T12:00:00.000Z',
  //   available_backup_codes: 8
  // }
}
```

## 🔧 配置选项

```typescript
interface MfaConfig {
  issuer: string;              // TOTP 发行者名称
  service_name: string;        // 服务名称
  totp_window: number;         // TOTP 时间窗口（默认：1）
  backup_codes_count: number;  // 备用码数量（默认：10）
  require_mfa: boolean;        // 是否强制要求 MFA（默认：false）
}
```

## 🛡️ 安全特性

### 1. 密钥安全
- TOTP 密钥加密存储
- 备用码哈希存储
- 防止密钥泄露

### 2. 验证安全
- 时间窗口验证
- 防重放攻击
- 失败次数限制

### 3. 审计日志
- 完整的操作记录
- IP 地址和用户代理记录
- 成功/失败状态追踪

## 📊 使用场景

### 1. 用户登录增强

```typescript
// 在用户登录后检查是否需要 MFA
const mfaCheck = await mfaHandler.handleCheckMfaRequired(userId);

if (mfaCheck.required) {
  // 要求用户输入 MFA 验证码
  const mfaResult = await mfaHandler.handleVerifyCode({
    user_id: userId,
    verification_code: userInput
  });
  
  if (!mfaResult.valid) {
    return new Response('MFA 验证失败', { status: 401 });
  }
}
```

### 2. 敏感操作保护

```typescript
// 在执行敏感操作前要求 MFA 验证
async function handleSensitiveOperation(userId: string, mfaCode: string) {
  const mfaResult = await mfaHandler.handleVerifyCode({
    user_id: userId,
    verification_code: mfaCode
  });
  
  if (!mfaResult.valid) {
    throw new Error('需要 MFA 验证');
  }
  
  // 执行敏感操作...
}
```

## 🔄 与 Auth 模块集成

```typescript
import { AuthHandler } from '@saleandwin/auth';
import { MfaHandler } from '@saleandwin/mfa';

export default {
  async fetch(request: Request, env: any, ctx: ExecutionContext): Promise<Response> {
    const authHandler = AuthHandler.createInstance(authConfig, env);
    const mfaHandler = MfaHandler.createInstance(mfaConfig, env);
    
    // 处理登录
    if (url.pathname === '/auth/login') {
      const loginResult = await authHandler.handleLogin(loginData);
      
      if (loginResult.success) {
        // 检查是否需要 MFA
        const mfaCheck = await mfaHandler.handleCheckMfaRequired(loginResult.data.user.id);
        
        if (mfaCheck.required) {
          return Response.json({
            success: true,
            require_mfa: true,
            user_id: loginResult.data.user.id
          });
        }
      }
      
      return Response.json(loginResult);
    }
    
    // 处理 MFA 验证
    if (url.pathname === '/auth/mfa/verify') {
      const mfaResult = await mfaHandler.handleVerifyCode(mfaData);
      return Response.json(mfaResult);
    }
  }
};
```

## 📱 客户端集成

### 1. 绑定流程

```javascript
// 1. 获取绑定信息
const bindingResponse = await fetch('/mfa/generate-binding', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ user_id: 'user-123' })
});

const bindingData = await bindingResponse.json();

// 2. 显示二维码
const qrImage = document.getElementById('qr-code');
qrImage.src = `data:image/png;base64,${bindingData.data.qr_code}`;

// 3. 显示手动输入密钥
document.getElementById('manual-key').textContent = bindingData.data.manual_entry_key;

// 4. 用户扫码后输入验证码进行绑定
const verifyResponse = await fetch('/mfa/bind-verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    user_id: 'user-123',
    secret: bindingData.data.secret,
    verification_code: userInputCode
  })
});
```

### 2. 验证流程

```javascript
// MFA 验证
const verifyResponse = await fetch('/mfa/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    user_id: 'user-123',
    verification_code: userInputCode
  })
});

const result = await verifyResponse.json();
if (result.valid) {
  // 验证成功，继续操作
} else {
  // 验证失败，显示错误
}
```

## 🧪 测试

```bash
# 运行测试
pnpm test

# 运行测试覆盖率
pnpm test:coverage
```

## � 谷歌验证器支持

MFA 模块完全支持谷歌验证器的多账户管理功能，让用户可以在一个应用中管理多个服务的 TOTP 密钥。

### 核心功能

#### 1. 添加密钥
```typescript
const result = await mfaHandler.handleAddSecret({
  user_id: 'user-123',
  secret_key: 'JBSWY3DPEHPK3PXP',
  label: 'Google',
  issuer: 'Google'
});
```

#### 2. 生成所有验证码
```typescript
const codesResult = await mfaHandler.handleGenerateAllCodes('user-123');

if (codesResult.success) {
  codesResult.codes?.forEach((codeInfo) => {
    console.log(`${codeInfo.label}: ${codeInfo.code} (${codeInfo.remaining_seconds}s)`);
  });
}
```

#### 3. 密钥管理
```typescript
// 获取密钥列表
const secretsResult = await mfaHandler.handleGetUserSecrets('user-123');

// 删除密钥
const deleteResult = await mfaHandler.handleDeleteSecret('user-123', 'secret-id');
```

### 应用场景

- **个人密码管理器** - 用户管理多个账户的 MFA
- **企业应用** - 员工管理工作相关的多个服务
- **开发者工具** - 集成到现有应用中提供 MFA 功能
- **移动应用** - 替代谷歌验证器的功能

### 特性优势

- ✅ **多账户支持** - 一个用户可以管理多个服务的密钥
- ✅ **实时验证码** - 显示当前验证码和剩余时间
- ✅ **标签管理** - 为每个密钥设置有意义的标签
- ✅ **批量生成** - 一次性生成所有账户的验证码
- ✅ **完整 CRUD** - 支持密钥的增删改查操作
- ✅ **安全存储** - 密钥加密存储，完整审计日志

## �📄 许可证

MIT License

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！