MCPcopy Create free account
hub / github.com/bytebase/bytebase / verifyEmailCode

Method verifyEmailCode

backend/api/v1/auth_service.go:1786–1808  ·  view source on GitHub ↗

verifyEmailCode checks a submitted code against the stored row. Enforces expiry, attempt limit (5), and constant-time hash compare. On successful match, deletes the row (one-time use) and returns it so the caller can use its captured workspace context (e.g. for gate checks and workspace assignment o

(ctx context.Context, email string, purpose storepb.EmailVerificationCodePurpose, submittedCode string)

Source from the content-addressed store, hash-verified

1784// caller can use its captured workspace context (e.g. for gate checks and
1785// workspace assignment on the email-code signup path).
1786func (s *AuthService) verifyEmailCode(ctx context.Context, email string, purpose storepb.EmailVerificationCodePurpose, submittedCode string) (*store.EmailVerificationCodeMessage, error) {
1787 row, err := s.store.GetEmailVerificationCode(ctx, email, purpose)
1788 if err != nil {
1789 return nil, connect.NewError(connect.CodeInternal, errors.Wrapf(err, "failed to get email verification code"))
1790 }
1791 if row == nil {
1792 return nil, connect.NewError(connect.CodeUnauthenticated, errors.Errorf("invalid or expired code"))
1793 }
1794 if time.Now().After(row.ExpiresAt) {
1795 _ = s.store.DeleteEmailVerificationCodeIfMatch(ctx, email, purpose, row.CodeHash)
1796 return nil, connect.NewError(connect.CodeUnauthenticated, errors.Errorf("invalid or expired code"))
1797 }
1798 if row.Attempts >= emailCodeMaxAttempts {
1799 _ = s.store.DeleteEmailVerificationCodeIfMatch(ctx, email, purpose, row.CodeHash)
1800 return nil, connect.NewError(connect.CodeUnauthenticated, errors.Errorf("too many attempts"))
1801 }
1802 if subtle.ConstantTimeCompare([]byte(s.hashEmailCode(submittedCode)), []byte(row.CodeHash)) != 1 {
1803 _ = s.store.IncrementEmailVerificationCodeAttempts(ctx, email, purpose)
1804 return nil, connect.NewError(connect.CodeUnauthenticated, errors.Errorf("invalid or expired code"))
1805 }
1806 _ = s.store.DeleteEmailVerificationCodeIfMatch(ctx, email, purpose, row.CodeHash)
1807 return row, nil
1808}
1809
1810// authenticateEmailCodeLogin handles the email + 6-digit code flow.
1811// Existing users: verify code → return user (downstream pipeline handles workspace-level gates).

Callers 2

ResetPasswordMethod · 0.95

Calls 5

hashEmailCodeMethod · 0.95
ErrorfMethod · 0.80

Tested by

no test coverage detected