diff --git a/server/handlers/verify_email.go b/server/handlers/verify_email.go index 91a2128..452820f 100644 --- a/server/handlers/verify_email.go +++ b/server/handlers/verify_email.go @@ -24,21 +24,22 @@ import ( // It verifies email based on JWT token in query string func VerifyEmailHandler() gin.HandlerFunc { return func(c *gin.Context) { + redirectURL := strings.TrimSpace(c.Query("redirect_uri")) errorRes := gin.H{ - "error": "invalid_token", + "error": "token is required", } tokenInQuery := c.Query("token") if tokenInQuery == "" { log.Debug("Token is empty") - c.JSON(400, errorRes) + utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes)) return } verificationRequest, err := db.Provider.GetVerificationRequestByToken(c, tokenInQuery) if err != nil { log.Debug("Error getting verification request: ", err) - errorRes["error_description"] = err.Error() - c.JSON(400, errorRes) + errorRes["error"] = err.Error() + utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes)) return } @@ -47,23 +48,23 @@ func VerifyEmailHandler() gin.HandlerFunc { claim, err := token.ParseJWTToken(tokenInQuery) if err != nil { log.Debug("Error parsing token: ", err) - errorRes["error_description"] = err.Error() - c.JSON(400, errorRes) + errorRes["error"] = err.Error() + utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes)) return } if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil { log.Debug("Error validating jwt claims: ", err) - errorRes["error_description"] = err.Error() - c.JSON(400, errorRes) + errorRes["error"] = err.Error() + utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes)) return } user, err := db.Provider.GetUserByEmail(c, verificationRequest.Email) if err != nil { log.Debug("Error getting user: ", err) - errorRes["error_description"] = err.Error() - c.JSON(400, errorRes) + errorRes["error"] = err.Error() + utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes)) return } @@ -79,7 +80,6 @@ func VerifyEmailHandler() gin.HandlerFunc { db.Provider.DeleteVerificationRequest(c, verificationRequest) state := strings.TrimSpace(c.Query("state")) - redirectURL := strings.TrimSpace(c.Query("redirect_uri")) rolesString := strings.TrimSpace(c.Query("roles")) var roles []string if rolesString == "" { @@ -125,8 +125,8 @@ func VerifyEmailHandler() gin.HandlerFunc { authToken, err := token.CreateAuthToken(c, user, roles, scope, loginMethod, nonce, code) if err != nil { log.Debug("Error creating auth token: ", err) - errorRes["error_description"] = err.Error() - c.JSON(500, errorRes) + errorRes["error"] = err.Error() + utils.HandleRedirectORJsonResponse(c, http.StatusInternalServerError, errorRes, generateRedirectURL(redirectURL, errorRes)) return } @@ -135,7 +135,7 @@ func VerifyEmailHandler() gin.HandlerFunc { // if code != "" { // if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil { // log.Debug("Error setting code state ", err) - // errorRes["error_description"] = err.Error() + // errorRes["error"] = err.Error() // c.JSON(500, errorRes) // return // } @@ -189,3 +189,21 @@ func VerifyEmailHandler() gin.HandlerFunc { c.Redirect(http.StatusTemporaryRedirect, redirectURL) } } + +func generateRedirectURL(url string, res map[string]interface{}) string { + redirectURL := url + if redirectURL == "" { + return "" + } + var paramsArr []string + for key, value := range res { + paramsArr = append(paramsArr, key+"="+value.(string)) + } + params := strings.Join(paramsArr, "&") + if strings.Contains(redirectURL, "?") { + redirectURL = redirectURL + "&" + params + } else { + redirectURL = redirectURL + "?" + strings.TrimPrefix(params, "&") + } + return redirectURL +} diff --git a/server/resolvers/magic_link_login.go b/server/resolvers/magic_link_login.go index bcc7ce2..5ce90c8 100644 --- a/server/resolvers/magic_link_login.go +++ b/server/resolvers/magic_link_login.go @@ -224,7 +224,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu go email.SendEmail([]string{params.Email}, constants.VerificationTypeMagicLinkLogin, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), - "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), + "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL), }) } diff --git a/server/resolvers/resend_verify_email.go b/server/resolvers/resend_verify_email.go index c58a034..6c94024 100644 --- a/server/resolvers/resend_verify_email.go +++ b/server/resolvers/resend_verify_email.go @@ -83,7 +83,7 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma go email.SendEmail([]string{params.Email}, params.Identifier, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), - "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), + "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, verificationRequest.RedirectURI), }) res = &model.Response{ diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index 433f801..757efeb 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -227,7 +227,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR email.SendEmail([]string{params.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), - "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), + "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL), }) utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) }() diff --git a/server/resolvers/update_profile.go b/server/resolvers/update_profile.go index ed8a8d4..da74258 100644 --- a/server/resolvers/update_profile.go +++ b/server/resolvers/update_profile.go @@ -259,7 +259,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) go email.SendEmail([]string{user.Email}, verificationType, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), - "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), + "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL), }) } diff --git a/server/resolvers/update_user.go b/server/resolvers/update_user.go index 9cc769a..bd61428 100644 --- a/server/resolvers/update_user.go +++ b/server/resolvers/update_user.go @@ -164,7 +164,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod go email.SendEmail([]string{user.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), - "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), + "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL), }) } diff --git a/server/utils/common.go b/server/utils/common.go index 216cc73..3110b11 100644 --- a/server/utils/common.go +++ b/server/utils/common.go @@ -82,7 +82,7 @@ func GetOrganization() map[string]interface{} { // GetForgotPasswordURL to get url for given token and hostname func GetForgotPasswordURL(token, redirectURI string) string { - verificationURL := redirectURI + "?token=" + token + verificationURL := redirectURI + "?token=" + token + "&redirect_uri=" + redirectURI return verificationURL } @@ -92,6 +92,6 @@ func GetInviteVerificationURL(verificationURL, token, redirectURI string) string } // GetEmailVerificationURL to get url for invite email verification -func GetEmailVerificationURL(token, hostname string) string { - return hostname + "/verify_email?token=" + token +func GetEmailVerificationURL(token, hostname, redirectURI string) string { + return hostname + "/verify_email?token=" + token + "&redirect_uri=" + redirectURI } diff --git a/server/utils/response.go b/server/utils/response.go new file mode 100644 index 0000000..c8c1b4a --- /dev/null +++ b/server/utils/response.go @@ -0,0 +1,17 @@ +package utils + +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" +) + +// HandleRedirectORJsonResponse handles the response based on redirectURL +func HandleRedirectORJsonResponse(c *gin.Context, httpResponse int, response map[string]interface{}, redirectURL string) { + if strings.TrimSpace(redirectURL) == "" { + c.JSON(httpResponse, response) + } else { + c.Redirect(http.StatusTemporaryRedirect, redirectURL) + } +}