Documentation
¶
Index ¶
Constants ¶
View Source
const ( EmailChannel OtpChannel = "email" SMSChannel OtpChannel = "sms" AccountVerification OtpPurpose = "account_verification" ResetPassword OtpPurpose = "reset_password" )
Variables ¶
View Source
var (
NotFoundOTP = errors.New("could not found the request otp")
)
Functions ¶
Types ¶
type Options ¶
type Options struct {
PhoneTarget *phonenumber.PhoneNumber
EmailTarget *email.Email
Localizer *l10n.Localizer
Purpose OtpPurpose
Otp string
}
type OtpChannel ¶
type OtpChannel string
func (OtpChannel) String ¶
func (c OtpChannel) String() string
type OtpPurpose ¶
type OtpPurpose string
func (OtpPurpose) String ¶
func (o OtpPurpose) String() string
type OtpStoreModel ¶
type Sender ¶
type Sender struct {
// contains filtered or unexported fields
}
func (Sender) GenRandOTP ¶
type StoreProvider ¶
type StoreProvider interface {
// StoreOtp stores a hashed OTP and returns a unique verification ID.
// Creates a new entry with attempt counter initialized to 1.
//
// The caller must persist the returned ID (e.g., in user session or database)
// for later verification. The OTP automatically expires after ExpiresAfter.
//
// Parameters:
// otpHash: Hashed/encrypted OTP value (never store plaintext OTPs)
// purpose: Context for OTP generation (login, password_reset, etc.)
// channel: Delivery method (email, sms, etc.)
// ExpiresAfter: Duration after which OTP becomes invalid
//
// Returns:
// id: Unique identifier for this OTP entry; required for all subsequent operations
// err: Storage error (nil if successful)
StoreOtp(ctx context.Context, otpHash string, purpose OtpPurpose, channel OtpChannel, expiresAfter time.Duration) (id string, err error)
// GetOtp retrieves the complete OTP entry for the given ID.
// Returns nil if the entry doesn't exist or has expired.
//
// Use this method to inspect OTP metadata (purpose, channel, expiry)
// without performing verification. For security, the returned model
// should contain only the hashed OTP, not the plaintext value.
GetOtp(ctx context.Context, id string) (*OtpStoreModel, error)
// RemoveOtp deletes an OTP entry immediately.
// Typically called after successful verification or when explicitly
// invalidating an OTP (e.g., user requests new OTP).
//
// Removing a non-existent entry should not return an error.
RemoveOtp(ctx context.Context, id string) error
// IncrementAttemptCounter increments the attempt counter for an entry.
// The counter starts at 1 when StoreOtp is called and increments up to
// the specified limit. Once the limit is reached, no further increments occur.
//
// Non-existent entries return attempts=0 with limitReached=true (no error).
//
// Example (limit=2):
// 1. StoreOtp() → attempts=1, limitReached=false
// 2. IncrementAttemptCounter() → attempts=2, limitReached=false
// 3. IncrementAttemptCounter() → attempts=2, limitReached=true
// (counter stops at limit, no further increments)
//
// Returns:
// attempts: Current attempt count (never exceeds limit)
// limitReached: True if attempt limit has been reached
// err: Error if operation fails (nil for non-existent entries)
IncrementAttemptCounter(ctx context.Context, id string, limit int) (attempts int, limitReached bool, err error)
}
StoreProvider defines operations for secure OTP storage and attempt tracking. Implementations must handle OTP lifecycle: creation, retrieval, verification, and automatic cleanup after expiration.
func NewDBStore ¶
func NewDBStore(db *database.Service) StoreProvider
func NewRedisStore ¶
func NewRedisStore(redis *redis.Client) StoreProvider
Click to show internal directories.
Click to hide internal directories.