Refactor code for otp

This commit is contained in:
Lakhan Samani
2023-07-13 11:39:22 +05:30
committed by catusax
parent 85ca0f09bf
commit 2f849b8f0c
33 changed files with 277 additions and 696 deletions

View File

@@ -8,7 +8,7 @@ import (
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@@ -17,9 +17,9 @@ import (
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/smsproviders"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/smsproviders"
"github.com/authorizerdev/authorizer/server/validators"
)
@@ -133,8 +133,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
}
user := models.User{
Email: emailInput,
PhoneNumber: &mobile,
Email: emailInput,
PhoneNumber: &mobile,
}
user.Roles = strings.Join(inputRoles, ",")
@@ -179,7 +179,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
log.Debug("MFA service not enabled: ", err)
isMFAEnforced = false
}
if isMFAEnforced {
user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
}
@@ -197,11 +197,11 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
log.Debug("Failed to add user: ", err)
return res, err
}
if !disablePhoneVerification {
duration, _ := time.ParseDuration("10m")
smsCode := utils.GenerateOTP()
smsBody := strings.Builder{}
smsBody.WriteString("Your verification code is: ")
smsBody.WriteString(smsCode)
@@ -213,10 +213,10 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
}
go func() {
db.Provider.UpsertSMSRequest(ctx, &models.SMSVerificationRequest{
PhoneNumber: mobile,
Code: smsCode,
CodeExpiresAt: time.Now().Add(duration).Unix(),
db.Provider.UpsertOTP(ctx, &models.OTP{
PhoneNumber: mobile,
Otp: smsCode,
ExpiresAt: time.Now().Add(duration).Unix(),
})
smsproviders.SendSMS(mobile, smsBody.String())
}()

View File

@@ -1,62 +0,0 @@
package resolvers
import (
"fmt"
"context"
"time"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/db"
log "github.com/sirupsen/logrus"
)
func VerifyMobileResolver(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) {
var res *model.AuthResponse
_, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
smsVerificationRequest, err := db.Provider.GetCodeByPhone(ctx, params.PhoneNumber)
if err != nil {
log.Debug("Failed to get sms request by phone: ", err)
return res, err
}
if smsVerificationRequest.Code != params.Code {
log.Debug("Failed to verify request: bad credentials")
return res, fmt.Errorf(`bad credentials`)
}
expiresIn := smsVerificationRequest.CodeExpiresAt - time.Now().Unix()
if expiresIn < 0 {
log.Debug("Failed to verify sms request: Timeout")
return res, fmt.Errorf("time expired")
}
res = &model.AuthResponse{
Message: "successful",
}
user, err := db.Provider.GetUserByPhoneNumber(ctx, params.PhoneNumber)
if user.PhoneNumberVerifiedAt == nil {
now := time.Now().Unix()
user.PhoneNumberVerifiedAt = &now
}
_, err = db.Provider.UpdateUser(ctx, *user)
if err != nil {
log.Debug("Failed to update user: ", err)
return res, err
}
err = db.Provider.DeleteSMSRequest(ctx, smsVerificationRequest)
if err != nil {
log.Debug("Failed to delete sms request: ", err.Error())
}
return res, err
}

View File

@@ -27,47 +27,53 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod
log.Debug("Failed to get GinContext: ", err)
return res, err
}
mfaSession, err := cookie.GetMfaSession(gc)
if err != nil {
log.Debug("Failed to get otp request by email: ", err)
return res, fmt.Errorf(`invalid session: %s`, err.Error())
if refs.StringValue(params.Email) == "" && refs.StringValue(params.PhoneNumber) == "" {
log.Debug("Email or phone number is required")
return res, fmt.Errorf(`email or phone_number is required`)
}
if _, err := memorystore.Provider.GetMfaSession(params.Email, mfaSession); err != nil {
log.Debug("Failed to get mfa session: ", err)
return res, fmt.Errorf(`invalid session: %s`, err.Error())
currentField := models.FieldNameEmail
if refs.StringValue(params.Email) == "" {
currentField = models.FieldNamePhoneNumber
}
otp, err := db.Provider.GetOTPByEmail(ctx, params.Email)
if err != nil {
log.Debug("Failed to get otp request by email: ", err)
return res, fmt.Errorf(`invalid email: %s`, err.Error())
var otp *models.OTP
if currentField == models.FieldNameEmail {
otp, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email))
} else {
otp, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
}
if otp == nil && err != nil {
log.Debugf("Failed to get otp request for %s: %s", currentField, err.Error())
return res, fmt.Errorf(`invalid %s: %s`, currentField, err.Error())
}
if params.Otp != otp.Otp {
log.Debug("Failed to verify otp request: Incorrect value")
return res, fmt.Errorf(`invalid otp`)
}
expiresIn := otp.ExpiresAt - time.Now().Unix()
if expiresIn < 0 {
log.Debug("Failed to verify otp request: Timeout")
return res, fmt.Errorf("otp expired")
}
user, err := db.Provider.GetUserByEmail(ctx, params.Email)
if err != nil {
var user models.User
if currentField == models.FieldNameEmail {
user, err = db.Provider.GetUserByEmail(ctx, refs.StringValue(params.Email))
} else {
// TODO fix after refs of db providers are fixed
var u *models.User
u, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
user = *u
}
if user.ID == "" && err != nil {
log.Debug("Failed to get user by email: ", err)
return res, err
}
isSignUp := user.EmailVerifiedAt == nil
isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil
// TODO - Add Login method in DB when we introduce OTP for social media login
loginMethod := constants.AuthRecipeMethodBasicAuth
if currentField == models.FieldNamePhoneNumber {
loginMethod = constants.AuthRecipeMethodMobileOTP
}
roles := strings.Split(user.Roles, ",")
scope := []string{"openid", "email", "profile"}
code := ""