Skip to content

Commit

Permalink
fix: add twilio verify support on mfa (#1714)
Browse files Browse the repository at this point in the history
## What kind of change does this PR introduce?

As per title, we need to add a separate check when `verify` with Twilio
Verify as the OTP is stored with Twilio verify and not stored by
Supabase Auth. Supabase Auth will need to make a HTTP request to Twilio,
via `VerifyOTP` and have Twilio tell it whether the code was correct.
  • Loading branch information
J0 authored Oct 9, 2024
1 parent 56e3d33 commit aeb5d8f
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 4 deletions.
22 changes: 18 additions & 4 deletions internal/api/mfa.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,25 @@ func (a *API) verifyPhoneFactor(w http.ResponseWriter, r *http.Request, params *
}
return unprocessableEntityError(ErrorCodeMFAChallengeExpired, "MFA challenge %v has expired, verify against another challenge or create a new challenge.", challenge.ID)
}
otpCode, shouldReEncrypt, err := challenge.GetOtpCode(config.Security.DBEncryption.DecryptionKeys, config.Security.DBEncryption.Encrypt, config.Security.DBEncryption.EncryptionKeyID)
if err != nil {
return internalServerError("Database error verifying MFA TOTP secret").WithInternalError(err)
var valid bool
var otpCode string
var shouldReEncrypt bool
if config.Sms.IsTwilioVerifyProvider() {
smsProvider, err := sms_provider.GetSmsProvider(*config)
if err != nil {
return internalServerError("Failed to get SMS provider").WithInternalError(err)
}
if err := smsProvider.VerifyOTP(factor.Phone.String(), params.Code); err != nil {
return forbiddenError(ErrorCodeOTPExpired, "Token has expired or is invalid").WithInternalError(err)
}
valid = true
} else {
otpCode, shouldReEncrypt, err = challenge.GetOtpCode(config.Security.DBEncryption.DecryptionKeys, config.Security.DBEncryption.Encrypt, config.Security.DBEncryption.EncryptionKeyID)
if err != nil {
return internalServerError("Database error verifying MFA TOTP secret").WithInternalError(err)
}
valid = subtle.ConstantTimeCompare([]byte(otpCode), []byte(params.Code)) == 1
}
valid := subtle.ConstantTimeCompare([]byte(otpCode), []byte(params.Code)) == 1
if config.Hook.MFAVerificationAttempt.Enabled {
input := hooks.MFAVerificationAttemptInput{
UserID: user.ID,
Expand Down
3 changes: 3 additions & 0 deletions internal/api/phone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func (t *TestSmsProvider) SendMessage(phone, message, channel, otp string) (stri
t.SentMessages += 1
return "", nil
}
func (t *TestSmsProvider) VerifyOTP(phone, otp string) error {
return nil
}

func TestPhone(t *testing.T) {
api, config, err := setupAPIForTest()
Expand Down
4 changes: 4 additions & 0 deletions internal/api/sms_provider/messagebird.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,7 @@ func (t *MessagebirdProvider) SendSms(phone string, message string) (string, err

return resp.ID, nil
}

func (t *MessagebirdProvider) VerifyOTP(phone, code string) error {
return fmt.Errorf("VerifyOTP is not supported for Messagebird")
}
1 change: 1 addition & 0 deletions internal/api/sms_provider/sms_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func init() {

type SmsProvider interface {
SendMessage(phone, message, channel, otp string) (string, error)
VerifyOTP(phone, token string) error
}

func GetSmsProvider(config conf.GlobalConfiguration) (SmsProvider, error) {
Expand Down
3 changes: 3 additions & 0 deletions internal/api/sms_provider/textlocal.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ func (t *TextlocalProvider) SendSms(phone string, message string) (string, error

return messageID, nil
}
func (t *TextlocalProvider) VerifyOTP(phone, code string) error {
return fmt.Errorf("VerifyOTP is not supported for Textlocal")
}
3 changes: 3 additions & 0 deletions internal/api/sms_provider/twilio.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,6 @@ func (t *TwilioProvider) SendSms(phone, message, channel, otp string) (string, e

return resp.MessageSID, nil
}
func (t *TwilioProvider) VerifyOTP(phone, code string) error {
return fmt.Errorf("VerifyOTP is not supported for Twilio")
}
4 changes: 4 additions & 0 deletions internal/api/sms_provider/vonage.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,7 @@ func (t *VonageProvider) SendSms(phone string, message string) (string, error) {

return resp.Messages[0].MessageID, nil
}

func (t *VonageProvider) VerifyOTP(phone, code string) error {
return fmt.Errorf("VerifyOTP is not supported for Vonage")
}

0 comments on commit aeb5d8f

Please sign in to comment.