package auth import "errors" // Sentinel errors emitted by Service methods. Handlers translate them // into HTTP responses; callers in tests can match on them with // errors.Is. var ( // ErrChallengeNotFound is returned when a confirm-email-code request // references a challenge_id that does not exist, has already been // consumed, or has expired. Returned as a single sentinel because the // API surface deliberately does not differentiate between these cases // — distinguishing them would leak whether a challenge_id was ever // valid, which is signal an attacker should not have. ErrChallengeNotFound = errors.New("auth: challenge is not redeemable") // ErrTooManyAttempts is returned when confirm-email-code increments // the attempts counter past the configured ceiling. The challenge row // remains in the database with its incremented counter so further // attempts on the same challenge_id continue to fail with the same // error until the row expires. ErrTooManyAttempts = errors.New("auth: too many attempts") // ErrCodeMismatch is returned when the supplied code does not match // the stored bcrypt hash. The challenge stays un-consumed so the user // can try again — bounded by ErrTooManyAttempts. ErrCodeMismatch = errors.New("auth: code is incorrect") // ErrEmailPermanentlyBlocked is returned by SendEmailCode when the // supplied email maps to an existing account whose `permanent_block` // column is true. This is the only path that does not return an // opaque success shape. ErrEmailPermanentlyBlocked = errors.New("auth: email is permanently blocked") // ErrSessionNotFound is returned by GetSession (and the revoke // helpers in their look-it-up-after-zero-rows fallback) when the // device_session_id does not name a row in `device_sessions`. ErrSessionNotFound = errors.New("auth: session not found") )