npm package: @saleandwin/auth
Description: Authentication center for framework-ts projects with OAuth, email, and password support
Author: SaleAndWin
Latest version: 2.2.0

# @saleandwin/auth

企业级认证中心模块，为 framework-ts 项目提供完整的用户认证和授权解决方案。支持游客登录和角色权限管理。

## ✨ 特性

### 🔐 多种认证方式
- **邮箱密码登录** - 传统的用户名密码认证
- **Magic Link** - 无密码邮箱链接登录
- **OAuth 登录** - 支持 Google、GitHub、Microsoft、Discord、Twitter
- **游客登录** - 无需注册的临时用户体验 🆕

### 🛡️ 安全可靠
- **密码加密** - bcrypt 哈希算法
- **JWT 令牌** - 安全的访问控制
- **会话管理** - 自动过期和刷新机制
- **输入验证** - Zod 严格类型验证
- **速率限制** - 防暴力破解保护

### 👥 角色权限系统 🆕
- **等级制权限** - 基于数字等级的简单权限控制
- **预设角色** - 游客、用户、管理员、超级管理员
- **灵活分配** - 支持角色过期时间设置
- **权限检查** - 角色名称和等级双重检查

### 📧 邮件集成
- **Resend 集成** - 专业的邮件发送服务
- **邮箱验证** - 自动发送验证码
- **Magic Link** - 一键登录链接
- **响应式模板** - 美观的 HTML 邮件模板

### 💾 数据库优化
- **Cloudflare D1** - 边缘数据库优化
- **类型安全** - 完整的 TypeScript 支持
- **高性能查询** - 优化的 SQL 语句
- **自动清理** - 过期数据自动清理

## Architecture

The library follows a clean architecture pattern:

```
Handler -> Service -> Table
```

- **Handler**: HTTP request handling for Next.js routes
- **Service**: Business logic, validation, and data processing
- **Table**: Database access layer with prepared statements

## 📦 安装

```bash
npm install @saleandwin/auth
# 或
pnpm add @saleandwin/auth
# 或
yarn add @saleandwin/auth
```

## 🚀 快速开始

### 1. 基础配置

```typescript
import { AuthHandler, type AuthConfig, type AuthEnv } from '@saleandwin/auth';

// 在 Cloudflare Workers 中
export default {
  async fetch(request: Request, env: AuthEnv, ctx: ExecutionContext): Promise<Response> {
    const config: AuthConfig = {
      jwt_secret: env.JWT_SECRET,
      jwt_expires_in: '7d',
      session_duration: 7 * 24 * 60 * 60, // 7天
      magic_link_duration: 30 * 60, // 30分钟
      verification_code_duration: 10 * 60, // 10分钟
      password_reset_duration: 60 * 60, // 1小时
      oauth_providers: {
        google: {
          client_id: env.GOOGLE_CLIENT_ID,
          client_secret: env.GOOGLE_CLIENT_SECRET,
          redirect_uri: 'https://yourapp.com/auth/callback/google'
        }
      },
      email: {
        api_key: env.RESEND_API_KEY,
        from_email: 'noreply@yourapp.com',
        from_name: 'Your App'
      }
    };

    // 注入环境变量（包含 DB）
    const authHandler = AuthHandler.createInstance(config, env);

    // 处理请求...
  }
};
```

### 2. 数据库设置

```bash
# 使用 Cloudflare D1 CLI
wrangler d1 execute your-database --file=./node_modules/@saleandwin/auth/migrations.sql

# 或直接执行 SQL
cat ./node_modules/@saleandwin/auth/migrations.sql | sqlite3 your-database.db
```

### 3. 环境变量

```env
# 必需配置
AUTH_JWT_SECRET=your-super-secret-jwt-key-at-least-32-characters
RESEND_API_KEY=re_your_resend_api_key
FROM_EMAIL=noreply@yourapp.com
FROM_NAME=Your App Name

# OAuth 配置（可选）
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
```

### 4. 用户注册

```typescript
const result = await authHandler.handleRegister({
  email: 'user@example.com',
  name: 'John Doe',
  password: 'SecurePassword123'
});

if (result.success) {
  console.log('注册成功:', result.user);
  console.log('访问令牌:', result.access_token);
} else {
  console.error('注册失败:', result.error);
}
```

### 5. 用户登录

```typescript
const result = await authHandler.handleLogin({
  email: 'user@example.com',
  password: 'SecurePassword123'
});

if (result.success) {
  console.log('登录成功:', result.user);
  console.log('访问令牌:', result.access_token);
} else {
  console.error('登录失败:', result.error);
}
```

### 6. 游客登录 🆕

```typescript
const result = await authHandler.handleGuestLogin({
  device_id: 'device_123', // 可选
  session_duration: 86400   // 可选，默认24小时
});

if (result.success) {
  console.log('游客登录成功:', result.user);
  console.log('用户类型:', result.user.user_type); // 'guest'
}
```

### 7. 角色权限检查 🆕

```typescript
// 检查用户是否有特定角色
const hasRole = await authHandler.handleCheckRole(userId, 'admin');
console.log('是否为管理员:', hasRole.data.has_role);

// 检查用户角色等级
const hasLevel = await authHandler.handleCheckRoleLevel(userId, 80);
console.log('是否达到管理员等级:', hasLevel.data.has_min_level);
```

## 📚 完整 API 文档

### AuthHandler 方法

#### 👤 用户管理
```typescript
// 用户注册
handleRegister(data: CreateUserRequest): Promise<AuthResponse>

// 用户登录
handleLogin(data: LoginRequest, clientInfo?: ClientInfo): Promise<AuthResponse>

// 游客登录 🆕
handleGuestLogin(data: GuestLoginRequest): Promise<AuthResponse>

// 用户登出
handleLogout(sessionId: string): Promise<AuthResponse>

// 更新用户信息
handleUpdateUser(userId: string, data: UpdateUserRequest): Promise<AuthResponse>

// 修改密码
handleChangePassword(userId: string, data: ChangePasswordRequest): Promise<AuthResponse>
```

#### 🎫 会话管理
```typescript
// 验证会话
handleValidateSession(token: string): Promise<AuthResponse>

// 刷新会话
handleRefreshSession(refreshToken: string): Promise<AuthResponse>
```

#### ✨ Magic Link
```typescript
// 发送 Magic Link
handleSendMagicLink(data: MagicLinkRequest): Promise<AuthResponse>

// 验证 Magic Link
handleVerifyMagicLink(token: string): Promise<AuthResponse>
```

#### 🔗 OAuth
```typescript
// OAuth 登录
handleOAuthLogin(data: OAuthLoginRequest, clientInfo?: ClientInfo): Promise<AuthResponse>
```

#### 👥 角色权限 🆕
```typescript
// 检查用户角色
handleCheckRole(userId: string, roleName: string): Promise<AuthResponse>

// 检查角色等级
handleCheckRoleLevel(userId: string, minLevel: number): Promise<AuthResponse>
```

### 数据类型

#### 用户类型
```typescript
interface User {
  id: string;
  email?: string;           // 游客用户可以没有邮箱
  email_verified: boolean;
  name?: string;
  avatar_url?: string;
  user_type: 'user' | 'guest'; // 🆕 用户类型
  is_active: boolean;
  created_at: string;
  updated_at: string;
  last_login_at?: string;
  login_count: number;
  expires_at?: string;      // 🆕 游客用户过期时间
}
```

#### 角色类型 🆕
```typescript
interface Role {
  id: string;
  name: string;           // 'super_admin', 'admin', 'user', 'guest'
  display_name: string;   // '超级管理员', '管理员', '注册用户', '游客用户'
  description?: string;
  level: number;          // 权限等级：100, 80, 50, 10
  is_system: boolean;     // 是否为系统角色
  is_active: boolean;
  created_at: string;
  updated_at: string;
}
```

#### 请求类型
```typescript
// 游客登录请求 🆕
interface GuestLoginRequest {
  device_id?: string;      // 设备标识
  session_duration?: number; // 会话持续时间（秒）
}

// 游客升级请求 🆕
interface GuestUpgradeRequest {
  email: string;
  name?: string;
  password?: string;
}

// 角色分配请求 🆕
interface AssignRoleRequest {
  user_id: string;
  role_ids: string[];
  expires_at?: string;
}
```
## 🗄️ 数据库设置

### 1. 运行迁移脚本

```bash
# 使用 Cloudflare D1 CLI
wrangler d1 execute your-database --file=./node_modules/@saleandwin/auth/migrations.sql

# 或直接执行 SQL
cat ./node_modules/@saleandwin/auth/migrations.sql | sqlite3 your-database.db
```

### 2. 数据库表结构

#### 核心表
- **users** - 用户表（支持游客用户）
- **sessions** - 会话表
- **oauth_accounts** - OAuth 账户表
- **email_verifications** - 邮箱验证表

#### 角色权限表 🆕
- **roles** - 角色表（预设4个系统角色）
- **user_roles** - 用户角色关联表

#### 预设角色
| 角色名 | 显示名称 | 等级 | 描述 |
|--------|----------|------|------|
| super_admin | 超级管理员 | 100 | 拥有最高权限 |
| admin | 管理员 | 80 | 系统管理权限 |
| user | 注册用户 | 50 | 普通用户权限 |
| guest | 游客用户 | 10 | 基础浏览权限 |

## ⚙️ 配置选项

```typescript
interface AuthConfig {
  // 必需配置
  jwt_secret: string;

  // 会话配置
  session_duration?: number;        // 会话持续时间（秒）
  max_login_attempts?: number;      // 最大登录尝试次数
  lockout_duration?: number;        // 锁定持续时间（秒）

  // 验证配置
  password_reset_duration?: number;     // 密码重置有效期
  email_verification_duration?: number; // 邮箱验证有效期
  magic_link_duration?: number;         // Magic Link 有效期

  // OAuth 配置
  oauth?: {
    google?: OAuthProviderConfig;
    github?: OAuthProviderConfig;
    microsoft?: OAuthProviderConfig;
    discord?: OAuthProviderConfig;
    twitter?: OAuthProviderConfig;
  };

  // 邮件配置
  email?: {
    resend_api_key: string;
    from_email: string;
    from_name?: string;
  };
}

interface OAuthProviderConfig {
  client_id: string;
  client_secret: string;
  redirect_uri: string;
  scope?: string;
}
```
  "password": "SecurePassword123",
  "remember_me": false
}
```

### Get Current User
```http
GET /api/auth/me
Authorization: Bearer <access_token>
```

### Update User Profile
```http
PUT /api/auth/me
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "name": "Updated Name",
  "avatar_url": "https://example.com/avatar.jpg"
}
```

### Send Email Verification
```http
POST /api/auth/send-verification
Content-Type: application/json

{
  "email": "user@example.com"
}
```

### Verify Email
```http
POST /api/auth/verify-email
Content-Type: application/json

{
  "code": "123456"
}
```

### Send Magic Link
```http
POST /api/auth/magic-link
Content-Type: application/json

{
  "email": "user@example.com",
  "redirect_uri": "https://yourapp.com/dashboard"
}
```

### Change Password
```http
POST /api/auth/change-password
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "current_password": "OldPassword123",
  "new_password": "NewPassword123"
}
```

### Logout
```http
POST /api/auth/logout
Authorization: Bearer <access_token>
```

## 🔧 Next.js 集成示例

### API 路由示例

```typescript
// app/api/auth/register/route.ts
import { AuthHandler } from '@saleandwin/auth';
import { NextRequest, NextResponse } from 'next/server';
import { authConfig } from '@/lib/auth-config';

export async function POST(request: NextRequest) {
  try {
    const authHandler = await AuthHandler.createInstance(authConfig);
    const data = await request.json();

    const result = await authHandler.handleRegister(data);

    if (result.success) {
      return NextResponse.json(result, { status: 201 });
    } else {
      return NextResponse.json(result, { status: 400 });
    }
  } catch (error) {
    return NextResponse.json(
      { success: false, error: '服务器内部错误' },
      { status: 500 }
    );
  }
}
```

### 中间件权限控制

```typescript
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { AuthHandler } from '@saleandwin/auth';

export async function middleware(request: NextRequest) {
  // 检查管理员路由权限
  if (request.nextUrl.pathname.startsWith('/dashboard/admin')) {
    const token = request.cookies.get('auth-token')?.value;
    if (!token) return NextResponse.redirect(new URL('/login', request.url));

    const authHandler = await AuthHandler.createInstance(authConfig);
    const roleCheck = await authHandler.handleCheckRoleLevel(userId, 80);

    if (!roleCheck.data?.has_min_level) {
      return NextResponse.redirect(new URL('/dashboard', request.url));
    }
  }

  return NextResponse.next();
}
```

## 📖 使用示例

详细的使用示例请查看 `examples/` 目录：

- **[Next.js 基础集成](./examples/nextjs-basic.md)** - 完整的 Next.js 项目集成示例
- **[角色权限管理](./examples/role-management.md)** - 角色权限系统的使用方法
- **[游客登录功能](./examples/guest-login.md)** - 游客登录的完整实现

## 🛡️ 安全最佳实践

1. **密码安全**: 使用强密码策略，密码使用 bcrypt 加密
2. **会话管理**: 定期刷新令牌，设置合理的过期时间
3. **输入验证**: 所有输入都经过 Zod 验证
4. **错误处理**: 不暴露敏感信息的错误消息
5. **速率限制**: 实施登录尝试限制和锁定机制
6. **HTTPS**: 生产环境必须使用 HTTPS
7. **环境变量**: 敏感配置使用环境变量存储

## 🔄 错误处理

所有 API 方法都返回统一的响应格式：

```typescript
interface AuthResponse {
  success: boolean;
  user?: User;
  session?: SessionInfo;
  access_token?: string;
  refresh_token?: string;
  expires_in?: number;
  message?: string;
  error?: string;
  data?: any; // 通用数据字段
}
```

## 🚀 开发

```bash
# 安装依赖
pnpm install

# 运行测试
pnpm test

# 构建
pnpm build

# 类型检查
pnpm type-check
```

## 📄 许可证

MIT

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！

## 📞 支持

如有问题，请通过以下方式联系：

- 提交 [GitHub Issue](https://github.com/your-repo/issues)
- 查看 [文档示例](./examples/)
- 参考 [最佳实践](#-安全最佳实践)