2026-05-20 13:03:59 +00:00
|
|
|
package domain
|
|
|
|
|
|
|
|
|
|
import "strings"
|
|
|
|
|
|
|
|
|
|
// RedisKey is the member module Redis key prefix. The package-level helpers
|
|
|
|
|
// (Get*RedisKey) are the supported way to compose keys; direct string
|
|
|
|
|
// concatenation should be avoided so the layout stays auditable.
|
|
|
|
|
type RedisKey string
|
|
|
|
|
|
|
|
|
|
// Key prefixes for the member module. Layout matches identity-member-design.md
|
|
|
|
|
// section 14 (Redis Key 命名).
|
|
|
|
|
const (
|
|
|
|
|
OTPChallengeRedisKey RedisKey = "member:otp:challenge"
|
|
|
|
|
VerifyRateRedisKey RedisKey = "member:verify:rate"
|
|
|
|
|
VerifyDailyRedisKey RedisKey = "member:verify:daily"
|
|
|
|
|
TOTPEnrollRedisKey RedisKey = "member:totp:enroll"
|
|
|
|
|
TOTPUsedRedisKey RedisKey = "member:totp:used"
|
2026-05-20 23:51:22 +00:00
|
|
|
MemberSeqRedisKey RedisKey = "member:seq"
|
2026-05-20 13:03:59 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// With appends colon-separated parts to the key.
|
|
|
|
|
func (key RedisKey) With(parts ...string) RedisKey {
|
|
|
|
|
if len(parts) == 0 {
|
|
|
|
|
return key
|
|
|
|
|
}
|
|
|
|
|
return RedisKey(string(key) + ":" + strings.Join(parts, ":"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// String returns the raw key.
|
|
|
|
|
func (key RedisKey) String() string {
|
|
|
|
|
return string(key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOTPChallengeRedisKey returns the challenge-state Redis key.
|
|
|
|
|
func GetOTPChallengeRedisKey(challengeID string) string {
|
|
|
|
|
return OTPChallengeRedisKey.With(challengeID).String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOTPAttemptsRedisKey returns the per-challenge failed-attempt counter key.
|
|
|
|
|
func GetOTPAttemptsRedisKey(challengeID string) string {
|
|
|
|
|
return OTPChallengeRedisKey.With(challengeID, "attempts").String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetVerifyRateRedisKey returns the resend cooldown key.
|
|
|
|
|
func GetVerifyRateRedisKey(tenantID, uid, kind string) string {
|
|
|
|
|
return VerifyRateRedisKey.With(tenantID, uid, kind).String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetVerifyDailyRedisKey returns the daily verification cap counter key.
|
|
|
|
|
func GetVerifyDailyRedisKey(tenantID, uid, kind string) string {
|
|
|
|
|
return VerifyDailyRedisKey.With(tenantID, uid, kind).String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetTOTPEnrollRedisKey returns the staged-secret cache key.
|
|
|
|
|
func GetTOTPEnrollRedisKey(tenantID, uid string) string {
|
|
|
|
|
return TOTPEnrollRedisKey.With(tenantID, uid).String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetTOTPUsedRedisKey returns the replay-protection key for a verified timestep.
|
|
|
|
|
func GetTOTPUsedRedisKey(tenantID, uid, timestep string) string {
|
|
|
|
|
return TOTPUsedRedisKey.With(tenantID, uid, timestep).String()
|
|
|
|
|
}
|
2026-05-20 23:51:22 +00:00
|
|
|
|
|
|
|
|
// GetMemberSeqRedisKey returns the UID sequence counter key for a tenant.
|
|
|
|
|
func GetMemberSeqRedisKey(tenantID string) string {
|
|
|
|
|
return MemberSeqRedisKey.With(tenantID).String()
|
|
|
|
|
}
|