common

package
v1.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

smsbao

Index

Constants

View Source
const CacheKeyEmailCode = "emailcode:"
View Source
const (
	// CacheKeySMSCode 短信验证码的缓存key
	CacheKeySMSCode string = "smscode:"
)

Variables

View Source
var ErrEmailSendRateLimited = errors.New("email resend cooldown active, retry in 1 minute")

ErrEmailSendRateLimited is returned by SendVerifyCode when the per-address 1-minute resend cooldown is still active. It is a client-actionable condition (HTTP 429), not an internal failure — callers should branch on it with errors.Is rather than collapsing it onto a generic send-failure code.

Functions

func IsTestCodeEnabled

func IsTestCodeEnabled(cfg *config.Config) bool

IsTestCodeEnabled 仅在非 release 模式且配置了 SMSCode 时返回 true。 release 模式永远返回 false,避免通过配置热更新把测试验证码打开成万能验证码。

func MatchTestCode

func MatchTestCode(cfg *config.Config, code string) bool

MatchTestCode 在 IsTestCodeEnabled 为 true 时,比较用户输入(去空白)与配置的 SMSCode。

func ValidateTestCodeConfig

func ValidateTestCodeConfig(cfg *config.Config) error

ValidateTestCodeConfig 在启动时校验:release 模式下不允许配置 SMSCode。

Types

type AliyunInternationalProvider

type AliyunInternationalProvider struct {
	log.Log
	// contains filtered or unexported fields
}

func (*AliyunInternationalProvider) SendSMS

func (a *AliyunInternationalProvider) SendSMS(ctx context.Context, zone, phone string, code string) error

type AliyunProvider

type AliyunProvider struct {
	log.Log
	// contains filtered or unexported fields
}

func (*AliyunProvider) SendSMS

func (a *AliyunProvider) SendSMS(ctx context.Context, zone, phone string, code string) error

type CodeType

type CodeType int

CodeType 验证码类型

const (
	// CodeTypeRegister 注册
	CodeTypeRegister CodeType = iota
	// CodeTypePayPWD 支付密码
	CodeTypePayPWD
	// CodeTypeForgetLoginPWD 忘记登录密码
	CodeTypeForgetLoginPWD
	// CodeTypeCheckMobile 校验指定手机号是否正确
	CodeTypeCheckMobile
	// DestroyAccount 注销账号
	CodeTypeDestroyAccount
	CodeTypeEmailLogin
	// CodeTypeOIDCBind OIDC 自助绑定 OTP。单独 keyspace 避免与
	// register/login/forget-pwd 等流程的 SMS 计数器串扰。
	CodeTypeOIDCBind
)

type EmailService

type EmailService struct {
	log.Log
	// contains filtered or unexported fields
}

EmailService 邮件服务

func NewEmailService

func NewEmailService(ctx *config.Context, settings SMTPSettingsProvider) *EmailService

NewEmailService 创建邮件服务。

settings 为 nil 时退化到读取 cfg.Support.*(yaml 静态值)。生产路径 应传入 common.EnsureSystemSettings(ctx) 以启用 admin 覆盖。参数显式 强制每个 call site 在 nil(yaml-only)和实际注入之间做出选择,避免 静默漏掉 admin 配置入口。

func (*EmailService) SendHTMLEmail

func (s *EmailService) SendHTMLEmail(ctx context.Context, to, subject, htmlBody string) error

SendHTMLEmail 直接发送一封 HTML 邮件。subject/body 由调用方负责,本方法 不写 Redis、不限速;速率控制由调用方根据业务场景自行处理。

ctx 的 deadline 会传递到 SMTP 层(dial / 投递阶段);调用方设的 ctx 比 SMTP 默认超时(dial 15s + IO 60s)更紧时,会真正生效。

内容仅含 text/html 单一部分,header 也只补 From/To/Subject/MIME-Version/ Content-Type。短 HTML 事务邮件容易被收件方反垃圾静默丢弃 —— 自检/状态类 邮件请改用 SendTransactionalHTML,带 plaintext 兜底和完整事务邮件 header。

func (*EmailService) SendTransactionalHTML added in v1.3.0

func (s *EmailService) SendTransactionalHTML(ctx context.Context, to, subject, htmlBody, plainBody string) error

SendTransactionalHTML 发送带 plaintext 兜底 + 标准事务邮件 header 的邮件。

与 SendHTMLEmail 的区别:

  • 包成 multipart/alternative,plaintext + HTML 双版本
  • 补 Date / Message-ID / Auto-Submitted / List-Unsubscribe 等反垃圾过滤 期望看到的事务邮件特征(故意不发 Precedence: bulk,详见 buildTransactional Message 中的注释 —— 部分 MTA 会把它解释成"不要生成退信",跟本路径用于 诊断的目的相反)

经验验证:阿里云 SMTP → mininglamp.com 这条链路,只发极简 HTML 单一部分 (~300 字节)的测试邮件会被收件方静默丢弃,既不入收件箱也不入垃圾夹也 不退信;同样的链路、同样的凭据,改成 multipart/alternative + 标准 header (~2KB) 后能正常入箱。该方法把这套包装内化,所有"系统自检 / 邀请 / 通知" 类事务邮件应该走这条路径。

plainBody 必须由调用方提供(避免依赖脆弱的"从 HTML strip 标签"启发式)。 htmlBody 为空时,plaintext 仍会被发出(降级体验,但通路工作)。

func (*EmailService) SendVerifyCode

func (s *EmailService) SendVerifyCode(ctx context.Context, email string, codeType CodeType, lang string) error

SendVerifyCode 发送验证码。

主题/正文由 emailtmpl 按 lang 渲染(外置 per-lang 模板,issue #221);走 SendTransactionalHTML 而非极简 sendEmail —— 验证码是高价值事务邮件,带 plaintext 兜底 + 标准事务邮件 header 可显著降低被反垃圾静默丢弃的概率。

func (*EmailService) Verify

func (s *EmailService) Verify(ctx context.Context, email, code string, codeType CodeType) error

Verify 验证验证码(验证成功后销毁缓存)

type IEmailService

type IEmailService interface {
	// 发送验证码。lang 为收件人内容语言(BCP-47),用于渲染主题与正文;
	// 调用方通常传 i18n.OutboundLanguage(ctx),其会兜底到 OCTO_DEFAULT_LANGUAGE。
	SendVerifyCode(ctx context.Context, email string, codeType CodeType, lang string) error
	// 验证验证码(销毁缓存)
	Verify(ctx context.Context, email, code string, codeType CodeType) error
	// SendHTMLEmail 发送一封 HTML 邮件(不走频率限制 / 验证码缓存,由调用方自己控制)
	SendHTMLEmail(ctx context.Context, to, subject, htmlBody string) error
	// SendTransactionalHTML 发送一封带 plaintext 兜底 + 标准事务邮件 header 的邮件。
	// 收件方反垃圾过滤对极简 HTML-only 事务邮件常常静默丢弃;这条路径包成
	// multipart/alternative,补上 Date / Message-ID / Auto-Submitted /
	// List-Unsubscribe 等 header,显著降低被丢的概率。
	SendTransactionalHTML(ctx context.Context, to, subject, htmlBody, plainBody string) error
}

IEmailService 邮件服务接口

type ISMSProvider

type ISMSProvider interface {
	SendSMS(ctx context.Context, zone, phone string, code string) error
}

func NewAliyunInternationalProvider

func NewAliyunInternationalProvider(ctx *config.Context) ISMSProvider

NewAliyunInternationalProvider 创建短信服务

func NewAliyunProvider

func NewAliyunProvider(ctx *config.Context) ISMSProvider

NewAliyunProvider 创建短信服务

func NewSmsbaoProvider

func NewSmsbaoProvider(ctx *config.Context) ISMSProvider

NewSmsbaoProvider 创建短信服务

func NewUnismsProvider

func NewUnismsProvider(ctx *config.Context) ISMSProvider

NewUnismsProvider 创建短信服务

type ISMSService

type ISMSService interface {
	// 发送验证码
	SendVerifyCode(ctx context.Context, zone, phone string, codeType CodeType) error
	// 验证验证码(销毁缓存)
	Verify(ctx context.Context, zone, phone, code string, codeType CodeType) error
}

ISMSService ISMSService

type SMSService

type SMSService struct {
	log.Log
	// contains filtered or unexported fields
}

SMSService 短信服务

func NewSMSService

func NewSMSService(ctx *config.Context) *SMSService

NewSMSService 创建短信服务

func (*SMSService) SendVerifyCode

func (s *SMSService) SendVerifyCode(ctx context.Context, zone, phone string, codeType CodeType) error

SendVerifyCode 发送验证码

func (*SMSService) Verify

func (s *SMSService) Verify(ctx context.Context, zone, phone, code string, codeType CodeType) error

Verify 验证验证码

type SMTPSettingsProvider added in v1.3.0

type SMTPSettingsProvider interface {
	SupportEmail() string
	SupportEmailSmtp() string
	SupportEmailPwd() string
}

SMTPSettingsProvider exposes the admin-tunable SMTP config to EmailService without creating an import dependency on modules/common (which itself imports modules/base/common — a cycle if we depended back). Any type that implements these three getters can drive the email sender; the production implementation lives in modules/common.SystemSettings.

type SmsbaoProvider

type SmsbaoProvider struct {
	log.Log
	// contains filtered or unexported fields
}

func (*SmsbaoProvider) SendSMS

func (u *SmsbaoProvider) SendSMS(ctx context.Context, zone, phone string, code string) error

type UnismsProvider

type UnismsProvider struct {
	log.Log
	// contains filtered or unexported fields
}

func (*UnismsProvider) SendSMS

func (u *UnismsProvider) SendSMS(ctx context.Context, zone, phone string, code string) error

Directories

Path Synopsis
Package emailtmpl renders outbound transactional email (subject + HTML + plaintext) from per-language templates embedded at build time.
Package emailtmpl renders outbound transactional email (subject + HTML + plaintext) from per-language templates embedded at build time.
Package msgtmpl renders outbound IM / push message bodies from per-language template sets embedded at build time.
Package msgtmpl renders outbound IM / push message bodies from per-language template sets embedded at build time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL