Skip to content

fix(otp): respect minimum_password_length when generating dummy password#2503

Open
abhijeet-rane wants to merge 1 commit intosupabase:masterfrom
abhijeet-rane:fix/otp-signup-respects-min-password-length
Open

fix(otp): respect minimum_password_length when generating dummy password#2503
abhijeet-rane wants to merge 1 commit intosupabase:masterfrom
abhijeet-rane:fix/otp-signup-respects-min-password-length

Conversation

@abhijeet-rane
Copy link
Copy Markdown

What kind of change does this PR introduce?

Bug fix.

What is the current behavior?

signInWithOtp({ email }) and signInWithOtp({ phone }) return 422 Unprocessable Entity with a WeakPasswordError when GOTRUE_PASSWORD_MIN_LENGTH is configured above the hardcoded temporary-password lengths (33 for magic link, 64 for SMS OTP), even though the caller never supplies a password.

Closes #2456.

Reproduction

  1. Set minimum_password_length = 100 in config.toml under [auth]
  2. Enable OTP signup via enable_signup = true under [auth.email]
  3. Call signInWithOtp({ email: "test@example.com" })
  4. Receive 422 Unprocessable Entity with "Password should be at least 100 characters"

Root cause

Both MagicLink (email OTP) and SmsOtp (phone OTP) generate a temporary password for new users and then invoke Signup, which calls checkPasswordStrength and enforces config.Password.MinLength. The generated passwords are hardcoded at 33 and 64 characters respectively, so any MinLength above those values breaks OTP signup.

What is the new behavior?

The generated password length is now min(max(base, config.Password.MinLength), MaxPasswordLength) where base is the previous hardcoded value (33 or 64) and MaxPasswordLength is the existing 72-char bcrypt ceiling. This preserves existing behavior when MinLength ≤ base and satisfies strength validation for realistic higher values.

Admin and invite flows (admin.go, verify.go) also generate temporary passwords but bypass checkPasswordStrength, so they are unaffected and intentionally not changed.

Additional context

  • Added regression test TestOtpRespectsMinPasswordLength in internal/api/otp_test.go
  • make test passes locally against Postgres 15 (TestOtp, TestSignup, TestVerify, TestRecover, TestMagicLink, TestPasswordStrengthChecks all green)
  • No API changes, no migration required

MagicLink (email OTP) and SmsOtp (phone OTP) signup generate a temporary
password for new users and then invoke Signup, which validates the
password against config.Password.MinLength. The hardcoded lengths (33
and 64) caused a 422 WeakPasswordError whenever GOTRUE_PASSWORD_MIN_LENGTH
was configured above those values, even though the caller never supplied
a password.

Generate a password that is at least config.Password.MinLength, clamped
to MaxPasswordLength (72) to stay within bcrypt's limit.

Closes supabase#2456

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OTP signup fails with 422 when minimum_password_length is high

1 participant