Skip to content

feat(messaging/auth): 短信基建(SMS provider + messaging sms channel)+ 手机号 OTP 首登/重置 #2780

Description

@os-zhuang

背景

#2766(PR #2771)接入了 better-auth phoneNumber 插件,但只开了手机号+密码登录sendOTP 显式抛 NOT_SUPPORTED,因为平台目前没有任何短信发送能力——NotificationChannel 类型里声明了 'sms'packages/spec/src/contracts/notification-service.ts:19),但 service-messaging 没有 sms channel 实现,也没有短信 provider 抽象。

无邮箱员工目前的密码找回只能靠管理员 set-user-password。OTP 首登/自助重置需要这块基建。

诉求

  1. 短信 provider 抽象与对接:参照 email channel 的模式(packages/services/service-messaging/src/email-channel.ts,在 provider service 存在时注册 channel),定义 sender surface + 至少一个 provider 实现(阿里云短信 / Twilio,配置走 service-settings 模式)。
  2. messaging sms channel:注册进 messaging-service-plugin.ts 的可插拔 channel 体系,notify(channels:['sms']) 可用。
  3. auth 侧接线auth-manager.tsphoneNumber({ sendOTP }) 从抛错改为经 sms channel 发送,打开:
    • POST /phone-number/send-otp + /phone-number/verify(OTP 登录/验证)
    • POST /phone-number/request-password-reset + /phone-number/reset-password(自助重置)
  4. 导入联动/admin/import-usersinvite 策略对有手机号的行支持"短信邀请"变体(无邮箱员工也能走首登自设密码路径)。

安全要求(必须与功能同 PR)

  • OTP 端点限流 + 按号码冷却(SMS pumping 成本滥用是邮件渠道没有的攻击面);OTP 尝试次数上限(better-auth allowedAttempts)。
  • OTP/验证码绝不落日志。
  • 占位邮箱用户(placeholder.invalid)的短信路径与邮件拦截逻辑对齐。

相关

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions