55 lines
2.3 KiB
Go
55 lines
2.3 KiB
Go
package usecase
|
|
|
|
import "context"
|
|
|
|
// TOTPUseCase manages business-tier RFC 6238 TOTP enrollment and verification.
|
|
//
|
|
// The contract mirrors identity-member-design.md §5.8: enrollment is split in
|
|
// two steps (start → confirm) so the secret is only committed after the user
|
|
// proves possession; backup codes are returned exactly once on confirmation
|
|
// and replenished via RegenerateBackupCodes.
|
|
type TOTPUseCase interface {
|
|
// StartEnroll generates a fresh secret, stashes it in a short-lived cache,
|
|
// and returns the otpauth URL for QR rendering. Calling it twice replaces
|
|
// the staged secret.
|
|
StartEnroll(ctx context.Context, tenantID, uid, account string) (*EnrollStartDTO, error)
|
|
|
|
// ConfirmEnroll validates the first user-supplied code against the staged
|
|
// secret, persists the encrypted secret on the profile, and returns the
|
|
// plaintext backup codes (only returned here once).
|
|
ConfirmEnroll(ctx context.Context, tenantID, uid, code string) ([]string, error)
|
|
|
|
// VerifyCode validates a code (TOTP or backup) for step-up. Backup codes
|
|
// are single-use; replays of a successful TOTP code are rejected.
|
|
VerifyCode(ctx context.Context, tenantID, uid, code string) error
|
|
|
|
// Disable clears the secret and backup codes; intended to be guarded by a
|
|
// step-up token in the logic layer.
|
|
Disable(ctx context.Context, tenantID, uid string) error
|
|
|
|
// RegenerateBackupCodes replaces existing backup codes with a new batch.
|
|
RegenerateBackupCodes(ctx context.Context, tenantID, uid string) ([]string, error)
|
|
|
|
// Status reports the current enrollment state for UI/admin views.
|
|
Status(ctx context.Context, tenantID, uid string) (*TOTPStatusDTO, error)
|
|
}
|
|
|
|
// EnrollStartDTO is returned by TOTPUseCase.StartEnroll. Secret material is
|
|
// never returned in plaintext outside the otpauth URL.
|
|
type EnrollStartDTO struct {
|
|
OtpauthURL string `json:"otpauth_url"`
|
|
Issuer string `json:"issuer"`
|
|
Account string `json:"account"`
|
|
Digits int `json:"digits"`
|
|
PeriodSec int `json:"period_seconds"`
|
|
ExpiresIn int `json:"expires_in"`
|
|
}
|
|
|
|
// TOTPStatusDTO reports whether TOTP is active for the member and how many
|
|
// backup codes remain unused.
|
|
type TOTPStatusDTO struct {
|
|
Enrolled bool `json:"enrolled"`
|
|
EnrolledAt int64 `json:"enrolled_at,omitempty"`
|
|
BackupCodesRemaining int `json:"backup_codes_remaining"`
|
|
}
|