owpengram-server/internal/store/code.go

64 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package store
import (
"context"
"time"
)
const PhoneCodePurposeChangePhone = "change_phone"
// PhoneCode 是一条验证码记录(与某次 sendCode 的 phone_code_hash 或邮箱验证键关联)。
// Purpose/UserID/AuthKeyID/SessionID 为已登录敏感操作提供作用域;登录验证码保持零值。
type PhoneCode struct {
Phone string
Code string
Channel string
Purpose string
UserID int64
AuthKeyID [8]byte
SessionID int64
Email string
PendingEmail string
Attempts int
MaxAttempts int
VerifiedEmail bool
RequireSignUp bool
LoginEmailHash string
}
// PhoneCodeScope 标识已登录敏感操作的一次性验证码作用域。SessionID 故意不在
// 作用域内:同一 perm auth key 等待验证码期间允许重建 MTProto session。
// 登录/注册验证码没有 Purpose/UserID/AuthKeyID保持非 scoped 行为。
type PhoneCodeScope struct {
Purpose string
UserID int64
AuthKeyID [8]byte
Phone string
}
func (c PhoneCode) Scope() PhoneCodeScope {
return PhoneCodeScope{
Purpose: c.Purpose,
UserID: c.UserID,
AuthKeyID: c.AuthKeyID,
Phone: c.Phone,
}
}
func (s PhoneCodeScope) Valid() bool {
return s.Purpose != "" && s.UserID != 0 && s.AuthKeyID != ([8]byte{}) && s.Phone != ""
}
// CodeStore 暂存验证码phone_code_hash → 作用域 + 手机号 + 验证码,带 TTL。
// 实现见 store/memory测试替身、store/redisstore。
type CodeStore interface {
// Set 对 scoped code 必须原子替换同作用域旧 hash保证单作用域至多一个
// 活跃验证码;普通登录码仍按 hash 独立保存。
Set(ctx context.Context, phoneCodeHash string, code PhoneCode, ttl time.Duration) error
Get(ctx context.Context, phoneCodeHash string) (PhoneCode, bool, error)
Update(ctx context.Context, phoneCodeHash string, code PhoneCode) error
Del(ctx context.Context, phoneCodeHash string) error
// ConsumeScoped 仅当 hash 仍是 scope 的当前活跃 hash 时原子读取并删除;
// 并发调用至多一个返回 found=true。
ConsumeScoped(ctx context.Context, phoneCodeHash string, scope PhoneCodeScope) (PhoneCode, bool, error)
}