Merge pull request #372 from catusax/main

feat: add mfa session to secure otp login
This commit is contained in:
Lakhan Samani
2023-08-03 12:34:39 +05:30
committed by GitHub
10 changed files with 206 additions and 10 deletions

View File

@@ -113,16 +113,25 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
// If email service is not enabled continue the process in any way
if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isEmailServiceEnabled && !isMFADisabled {
otp := utils.GenerateOTP()
expires := time.Now().Add(1 * time.Minute).Unix()
otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{
Email: user.Email,
Otp: otp,
ExpiresAt: time.Now().Add(1 * time.Minute).Unix(),
ExpiresAt: expires,
})
if err != nil {
log.Debug("Failed to add otp: ", err)
return nil, err
}
mfaSession := uuid.NewString()
err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires)
if err != nil {
log.Debug("Failed to add mfasession: ", err)
return nil, err
}
cookie.SetMfaSession(gc, mfaSession)
go func() {
// exec it as go routine so that we can reduce the api latency
go email.SendEmail([]string{params.Email}, constants.VerificationTypeOTP, map[string]interface{}{

View File

@@ -122,15 +122,25 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m
smsBody := strings.Builder{}
smsBody.WriteString("Your verification code is: ")
smsBody.WriteString(smsCode)
expires := time.Now().Add(duration).Unix()
_, err := db.Provider.UpsertOTP(ctx, &models.OTP{
PhoneNumber: params.PhoneNumber,
Otp: smsCode,
ExpiresAt: time.Now().Add(duration).Unix(),
ExpiresAt: expires,
})
if err != nil {
log.Debug("error while upserting OTP: ", err.Error())
return nil, err
}
mfaSession := uuid.NewString()
err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires)
if err != nil {
log.Debug("Failed to add mfasession: ", err)
return nil, err
}
cookie.SetMfaSession(gc, mfaSession)
go func() {
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
smsproviders.SendSMS(params.PhoneNumber, smsBody.String())

View File

@@ -27,6 +27,13 @@ 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`)
@@ -66,6 +73,12 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod
log.Debug("Failed to get user by email or phone number: ", err)
return res, err
}
if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil {
log.Debug("Failed to get mfa session: ", err)
return res, fmt.Errorf(`invalid session: %s`, err.Error())
}
isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil
// TODO - Add Login method in DB when we introduce OTP for social media login
loginMethod := constants.AuthRecipeMethodBasicAuth