openapi: 3.0.3 info: title: Pixel Game Server - Auth API description: 像素游戏服务器用户认证API接口文档 - 包含验证码登录功能、邮箱冲突检测、验证码冷却优化和邮件模板修复 version: 1.1.3 contact: name: API Support email: support@example.com license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: http://localhost:3000 description: 开发环境 tags: - name: app description: 应用状态相关接口 - name: auth description: 用户认证相关接口 - name: admin description: 管理员后台相关接口 - name: user-management description: 用户管理相关接口 paths: /: get: tags: - app summary: 获取应用状态 description: 返回应用的基本运行状态信息,用于健康检查和监控 operationId: getAppStatus responses: '200': description: 应用状态获取成功 content: application/json: schema: $ref: '#/components/schemas/AppStatusResponse' example: service: Pixel Game Server version: 1.0.0 status: running timestamp: "2025-12-25T08:00:00.000Z" uptime: 3600 environment: development storage_mode: database /auth/login: post: tags: - auth summary: 用户登录 description: 支持用户名、邮箱或手机号登录 operationId: login requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LoginDto' example: identifier: testuser password: password123 responses: '200': description: 登录成功 content: application/json: schema: $ref: '#/components/schemas/LoginResponse' example: success: true data: user: id: "1" username: testuser nickname: 测试用户 email: test@example.com phone: "+8613800138000" avatar_url: https://example.com/avatar.jpg role: 1 created_at: "2025-12-17T10:00:00.000Z" access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... is_new_user: false message: 登录成功 message: 登录成功 '400': description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: 用户名或密码错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/register: post: tags: - auth summary: 用户注册 description: 创建新用户账户。如果提供邮箱,需要先调用发送验证码接口获取验证码。发送验证码接口会自动检查邮箱是否已被注册,避免向已存在邮箱发送验证码。 operationId: register requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterDto' example: username: newuser password: password123 nickname: 新用户 email: newuser@example.com phone: "+8613800138001" responses: '201': description: 注册成功 content: application/json: schema: $ref: '#/components/schemas/RegisterResponse' '400': description: 请求参数错误或验证码错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: validation_error: summary: 参数验证错误 value: success: false message: "密码必须包含字母和数字,长度8-128字符" error_code: "REGISTER_FAILED" verification_code_error: summary: 验证码错误 value: success: false message: "验证码不存在或已过期" error_code: "REGISTER_FAILED" '409': description: 资源冲突 - 用户名、邮箱或手机号已存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: username_exists: summary: 用户名已存在 value: success: false message: "用户名已存在" error_code: "REGISTER_FAILED" email_exists: summary: 邮箱已存在 value: success: false message: "邮箱已存在" error_code: "REGISTER_FAILED" phone_exists: summary: 手机号已存在 value: success: false message: "手机号已存在" error_code: "REGISTER_FAILED" /auth/github: post: tags: - auth summary: GitHub OAuth登录 description: 使用GitHub账户登录或注册 operationId: githubOAuth requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GitHubOAuthDto' example: github_id: "12345678" username: octocat nickname: The Octocat email: octocat@github.com avatar_url: https://github.com/images/error/octocat_happy.gif responses: '200': description: GitHub登录成功 content: application/json: schema: $ref: '#/components/schemas/GitHubOAuthResponse' '400': description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: GitHub认证失败 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/forgot-password: post: tags: - auth summary: 发送密码重置验证码 description: 向用户邮箱或手机发送密码重置验证码 operationId: forgotPassword requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ForgotPasswordDto' example: identifier: test@example.com responses: '200': description: 验证码发送成功 content: application/json: schema: $ref: '#/components/schemas/ForgotPasswordResponse' '400': description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: 用户不存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/reset-password: post: tags: - auth summary: 重置密码 description: 使用验证码重置用户密码 operationId: resetPassword requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ResetPasswordDto' example: identifier: test@example.com verification_code: "123456" new_password: newpassword123 responses: '200': description: 密码重置成功 content: application/json: schema: $ref: '#/components/schemas/CommonResponse' '400': description: 请求参数错误或验证码无效 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: 用户不存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/change-password: put: tags: - auth summary: 修改密码 description: 用户修改自己的密码(需要提供旧密码) operationId: changePassword requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ChangePasswordDto' example: user_id: "1" old_password: oldpassword123 new_password: newpassword123 responses: '200': description: 密码修改成功 content: application/json: schema: $ref: '#/components/schemas/CommonResponse' '400': description: 请求参数错误或旧密码不正确 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: 用户不存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/send-email-verification: post: tags: - auth summary: 发送邮箱验证码 description: 向指定邮箱发送验证码。如果邮箱已被注册,将返回冲突错误。 operationId: sendEmailVerification requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendEmailVerificationDto' example: email: test@example.com responses: '200': description: 验证码发送成功(真实发送模式) content: application/json: schema: $ref: '#/components/schemas/EmailVerificationResponse' '206': description: 测试模式:验证码已生成但未真实发送 content: application/json: schema: $ref: '#/components/schemas/TestModeEmailVerificationResponse' '400': description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: 邮箱已被注册 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false message: "邮箱已被注册,请使用其他邮箱或直接登录" error_code: "SEND_EMAIL_VERIFICATION_FAILED" '429': description: 发送频率过高 content: application/json: schema: $ref: '#/components/schemas/ThrottleErrorResponse' /auth/verify-email: post: tags: - auth summary: 验证邮箱验证码 description: 使用验证码验证邮箱 operationId: verifyEmail requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EmailVerificationDto' example: email: test@example.com verification_code: "123456" responses: '200': description: 邮箱验证成功 content: application/json: schema: $ref: '#/components/schemas/CommonResponse' '400': description: 验证码错误或已过期 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/resend-email-verification: post: tags: - auth summary: 重新发送邮箱验证码 description: 重新向指定邮箱发送验证码 operationId: resendEmailVerification requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendEmailVerificationDto' example: email: test@example.com responses: '200': description: 验证码重新发送成功 content: application/json: schema: $ref: '#/components/schemas/EmailVerificationResponse' '206': description: 测试模式:验证码已生成但未真实发送 content: application/json: schema: $ref: '#/components/schemas/TestModeEmailVerificationResponse' '400': description: 邮箱已验证或用户不存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '429': description: 发送频率过高 content: application/json: schema: $ref: '#/components/schemas/ThrottleErrorResponse' /auth/verification-code-login: post: tags: - auth summary: 验证码登录 description: 使用邮箱或手机号和验证码进行登录,无需密码 operationId: verificationCodeLogin requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VerificationCodeLoginDto' example: identifier: test@example.com verification_code: "123456" responses: '200': description: 验证码登录成功 content: application/json: schema: $ref: '#/components/schemas/LoginResponse' '400': description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: 验证码错误或已过期 content: application/json: schema: $ref: '#/components/schemas/VerificationCodeLoginErrorResponse' '404': description: 用户不存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/send-login-verification-code: post: tags: - auth summary: 发送登录验证码 description: 向用户邮箱或手机发送登录验证码。邮件内容使用专门的登录验证码模板,标题为"登录验证码",内容说明用于登录验证而非密码重置。 operationId: sendLoginVerificationCode requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendLoginVerificationCodeDto' example: identifier: test@example.com responses: '200': description: 验证码发送成功 content: application/json: schema: $ref: '#/components/schemas/EmailVerificationResponse' '206': description: 测试模式:验证码已生成但未真实发送 content: application/json: schema: $ref: '#/components/schemas/TestModeEmailVerificationResponse' '400': description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: 用户不存在 content: application/json: schema: $ref: '#/components/schemas/SendLoginCodeErrorResponse' '429': description: 发送频率过高 content: application/json: schema: $ref: '#/components/schemas/ThrottleErrorResponse' /auth/debug-verification-code: post: tags: - auth summary: 调试验证码信息 description: 获取验证码的详细调试信息(仅开发环境) operationId: debugVerificationCode requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendEmailVerificationDto' example: email: test@example.com responses: '200': description: 调试信息获取成功 content: application/json: schema: $ref: '#/components/schemas/DebugVerificationCodeResponse' /auth/debug-clear-throttle: post: tags: - auth summary: 清除限流记录 description: 清除所有限流记录(仅开发环境使用) operationId: clearThrottle responses: '200': description: 限流记录已清除 content: application/json: schema: $ref: '#/components/schemas/CommonResponse' components: schemas: AppStatusResponse: type: object properties: service: type: string description: 服务名称 example: Pixel Game Server version: type: string description: 版本号 example: 1.0.0 status: type: string description: 运行状态 example: running timestamp: type: string format: date-time description: 当前时间戳 example: "2025-12-25T08:00:00.000Z" uptime: type: integer description: 运行时间(秒) example: 3600 environment: type: string description: 运行环境 example: development storage_mode: type: string description: 存储模式 example: database LoginDto: type: object required: - identifier - password properties: identifier: type: string description: 登录标识符,支持用户名、邮箱或手机号 minLength: 1 maxLength: 100 example: testuser password: type: string description: 用户密码 minLength: 1 maxLength: 128 example: password123 RegisterDto: type: object required: - username - password - nickname properties: username: type: string description: 用户名,只能包含字母、数字和下划线 minLength: 1 maxLength: 50 pattern: '^[a-zA-Z0-9_]+$' example: testuser password: type: string description: 密码,必须包含字母和数字,长度8-128字符 minLength: 8 maxLength: 128 pattern: '^(?=.*[a-zA-Z])(?=.*\d)' example: password123 nickname: type: string description: 用户昵称 minLength: 1 maxLength: 50 example: 测试用户 email: type: string format: email description: 邮箱地址(可选) example: test@example.com phone: type: string description: 手机号码(可选) example: "+8613800138000" GitHubOAuthDto: type: object required: - github_id - username - nickname properties: github_id: type: string description: GitHub用户ID minLength: 1 maxLength: 100 example: "12345678" username: type: string description: GitHub用户名 minLength: 1 maxLength: 50 example: octocat nickname: type: string description: GitHub显示名称 minLength: 1 maxLength: 50 example: The Octocat email: type: string format: email description: GitHub邮箱地址(可选) example: octocat@github.com avatar_url: type: string description: GitHub头像URL(可选) example: https://github.com/images/error/octocat_happy.gif ForgotPasswordDto: type: object required: - identifier properties: identifier: type: string description: 邮箱或手机号 minLength: 1 maxLength: 100 example: test@example.com ResetPasswordDto: type: object required: - identifier - verification_code - new_password properties: identifier: type: string description: 邮箱或手机号 minLength: 1 maxLength: 100 example: test@example.com verification_code: type: string description: 6位数字验证码 pattern: '^\d{6}$' example: "123456" new_password: type: string description: 新密码,必须包含字母和数字,长度8-128字符 minLength: 8 maxLength: 128 pattern: '^(?=.*[a-zA-Z])(?=.*\d)' example: newpassword123 ChangePasswordDto: type: object required: - user_id - old_password - new_password properties: user_id: type: string description: 用户ID(实际应用中应从JWT令牌中获取) example: "1" old_password: type: string description: 当前密码 minLength: 1 maxLength: 128 example: oldpassword123 new_password: type: string description: 新密码,必须包含字母和数字,长度8-128字符 minLength: 8 maxLength: 128 pattern: '^(?=.*[a-zA-Z])(?=.*\d)' example: newpassword123 SendEmailVerificationDto: type: object required: - email properties: email: type: string format: email description: 邮箱地址 example: test@example.com EmailVerificationDto: type: object required: - email - verification_code properties: email: type: string format: email description: 邮箱地址 example: test@example.com verification_code: type: string description: 6位数字验证码 pattern: '^\d{6}$' example: "123456" VerificationCodeLoginDto: type: object required: - identifier - verification_code properties: identifier: type: string description: 登录标识符(邮箱或手机号) minLength: 1 maxLength: 100 example: test@example.com verification_code: type: string description: 6位数字验证码 pattern: '^\d{6}$' example: "123456" SendLoginVerificationCodeDto: type: object required: - identifier properties: identifier: type: string description: 邮箱或手机号 minLength: 1 maxLength: 100 example: test@example.com UserInfo: type: object properties: id: type: string description: 用户ID example: "1" username: type: string description: 用户名 example: testuser nickname: type: string description: 用户昵称 example: 测试用户 email: type: string format: email description: 邮箱地址 example: test@example.com phone: type: string description: 手机号码 example: "+8613800138000" avatar_url: type: string description: 头像URL example: https://example.com/avatar.jpg role: type: integer description: 用户角色 example: 1 created_at: type: string format: date-time description: 创建时间 example: "2025-12-17T10:00:00.000Z" LoginResponseData: type: object properties: user: $ref: '#/components/schemas/UserInfo' access_token: type: string description: 访问令牌 example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... refresh_token: type: string description: 刷新令牌 example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... is_new_user: type: boolean description: 是否为新用户 example: false message: type: string description: 响应消息 example: 登录成功 LoginResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true data: $ref: '#/components/schemas/LoginResponseData' message: type: string description: 响应消息 example: 登录成功 RegisterResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true data: $ref: '#/components/schemas/LoginResponseData' message: type: string description: 响应消息 example: 注册成功 GitHubOAuthResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true data: $ref: '#/components/schemas/LoginResponseData' message: type: string description: 响应消息 example: GitHub登录成功 ForgotPasswordResponseData: type: object properties: verification_code: type: string description: 验证码(仅用于演示,实际应用中不应返回) example: "123456" ForgotPasswordResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true data: $ref: '#/components/schemas/ForgotPasswordResponseData' message: type: string description: 响应消息 example: 验证码已发送,请查收 CommonResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true message: type: string description: 响应消息 example: 操作成功 ErrorResponse: type: object properties: success: type: boolean description: 请求是否成功 example: false message: type: string description: 错误消息 example: 操作失败 error_code: type: string description: 错误代码 example: OPERATION_FAILED EmailVerificationResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true data: type: object properties: sent_to: type: string description: 发送目标 example: test@example.com expires_in: type: integer description: 过期时间(秒) example: 300 is_test_mode: type: boolean description: 是否为测试模式 example: false message: type: string description: 响应消息 example: 验证码已发送,请查收邮件 TestModeEmailVerificationResponse: type: object properties: success: type: boolean description: 请求是否成功 example: false data: type: object properties: verification_code: type: string description: 验证码(仅测试模式) example: "123456" sent_to: type: string description: 发送目标 example: test@example.com expires_in: type: integer description: 过期时间(秒) example: 300 is_test_mode: type: boolean description: 是否为测试模式 example: true message: type: string description: 响应消息 example: 测试模式:验证码已生成但未真实发送 error_code: type: string description: 错误代码 example: TEST_MODE_ONLY VerificationCodeLoginErrorResponse: type: object properties: success: type: boolean description: 请求是否成功 example: false message: type: string description: 错误消息 example: 验证码错误或已过期 error_code: type: string description: 错误代码 example: VERIFICATION_CODE_LOGIN_FAILED SendLoginCodeErrorResponse: type: object properties: success: type: boolean description: 请求是否成功 example: false message: type: string description: 错误消息 example: 用户不存在 error_code: type: string description: 错误代码 example: SEND_LOGIN_CODE_FAILED ThrottleErrorResponse: type: object properties: success: type: boolean description: 请求是否成功 example: false message: type: string description: 错误消息 example: 请求过于频繁,请稍后再试 error_code: type: string description: 错误代码 example: TOO_MANY_REQUESTS throttle_info: type: object properties: limit: type: integer description: 限制次数 example: 1 window_seconds: type: integer description: 时间窗口(秒) example: 60 current_requests: type: integer description: 当前请求次数 example: 1 reset_time: type: string format: date-time description: 重置时间 example: "2025-12-25T08:01:00.000Z" DebugVerificationCodeResponse: type: object properties: success: type: boolean description: 请求是否成功 example: true data: type: object properties: key: type: string description: Redis键名 example: verification_code:email_verification:test@example.com exists: type: boolean description: 是否存在 example: true ttl: type: integer description: 剩余生存时间(秒) example: 290 rawData: type: string description: 原始数据 example: '{"code":"123456","createdAt":1766649341250}' parsedData: type: object description: 解析后的数据 properties: code: type: string example: "123456" createdAt: type: integer example: 1766649341250 currentTime: type: integer description: 当前时间戳 example: 1766649341250