Skip to content

Commit

Permalink
rota verificação de email
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniloCarSan committed Sep 12, 2022
1 parent 2bad342 commit 451b4de
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 29 deletions.
79 changes: 79 additions & 0 deletions app/controllers/auth/send_email_password_reset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package auth

import (
"fmt"
"gotaskapp/app/config"
fail "gotaskapp/app/failures"
"gotaskapp/app/helpers"
"gotaskapp/app/repositories/auth"
"net/http"
"strings"

sentrygin "github.com/getsentry/sentry-go/gin"
"github.com/gin-gonic/gin"
)

var emailRequestPasswordResetbody = `
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Password reset</title>
</head>
<body>
<p>Password reset link <b>Go TaskApp</b></p>
<p>Click this link <a href="{{LINK}}">here</a> to reset your password.</p>
<p>If you have not requested this link, ignore it.</p>
</body>
`

type sendEmailPasswordReset struct {
Email string `form:"email" binding:"required,email"`
}

// Request password reset
func SendEmailPasswordReset(c *gin.Context) {

var form sendEmailPasswordReset

if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

credential, err := auth.SendEmailPasswordReset(form.Email)

if err != nil {
switch err.(type) {
case *fail.DatabaseConnectFailure,
*fail.SqlSelectFailure,
*fail.GenerateJwtTokenFailure:
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.CaptureException(err)
}
helpers.ApiResponse(c, false, http.StatusInternalServerError, "Server internal error", nil)
return
case *fail.SqlSelectNotFoundFailure:
helpers.ApiResponse(c, false, http.StatusNotFound, "email not linked a account", nil)
return
default:
helpers.ApiResponse(c, false, http.StatusInternalServerError, "an unexpected error occurred", nil)
return
}
}

link := fmt.Sprintf("http://%s%s%s", config.APP_HOST_FULL, "/auth/password/reset/", credential.Token)

emailRequestPasswordResetbody = strings.ReplaceAll(emailRequestPasswordResetbody, "{{LINK}}", link)

err = helpers.SendEmail([]string{credential.User.Email}, []string{}, "Password Reset", emailRequestPasswordResetbody)

if err != nil {
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.CaptureException(err)
}
helpers.ApiResponse(c, false, http.StatusInternalServerError, "Server internal error to send email verification", nil)
return
}

helpers.ApiResponse(c, true, http.StatusOK, "A password reset link has been sent to your email, if it's not in your inbox check your span.", nil)
}
80 changes: 80 additions & 0 deletions app/controllers/auth/send_email_verification.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package auth

import (
"fmt"
"gotaskapp/app/config"
fail "gotaskapp/app/failures"
"gotaskapp/app/helpers"
"gotaskapp/app/repositories/auth"
"net/http"
"strings"

sentrygin "github.com/getsentry/sentry-go/gin"
"github.com/gin-gonic/gin"
)

var emailSignUpbody = `
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Link de confirmação da conta</title>
</head>
<body>
<p>Clique neste link <a href="{{LINK}}">aqui</a> para confirmar seu email.</p>
<p>Caso não tenha criado uma conta ignore este email.</p>
</body>
`

type sendEmailVerification struct {
Email string `form:"email" binding:"required,email"`
}

func SendEmailVerification(c *gin.Context) {

var form sendEmailVerification

if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

credential, err := auth.SendEmailVerification(form.Email)

if err != nil {
switch err.(type) {
case *fail.DatabaseConnectFailure,
*fail.SqlSelectFailure,
*fail.GenerateJwtTokenFailure:
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.CaptureException(err)
}
helpers.ApiResponse(c, false, http.StatusInternalServerError, "Server internal error", nil)
return
case *fail.SendEmailVerificationFailure:
helpers.ApiResponse(c, false, http.StatusBadRequest, err.Error(), nil)
return
case *fail.SqlSelectNotFoundFailure:
helpers.ApiResponse(c, false, http.StatusNotFound, "email not linked a account", nil)
return
default:
helpers.ApiResponse(c, false, http.StatusInternalServerError, "an unexpected error occurred", nil)
return
}
}

go func() {
link := fmt.Sprintf("%s%s%s", config.APP_URL, "/auth/email/verify/", credential.Token)

emailSignUpbody = strings.ReplaceAll(emailSignUpbody, "{{LINK}}", link)

err = helpers.SendEmail([]string{credential.User.Email}, []string{}, "Confirmação de email", emailSignUpbody)

if err != nil {
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.CaptureException(err)
}
}
}()

helpers.ApiResponse(c, true, http.StatusOK, "A link has been sent to your email, if it's not in your inbox check your box span.", nil)
}
9 changes: 7 additions & 2 deletions app/controllers/auth/sign_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,19 @@ func SignIn(c *gin.Context) {
}
helpers.ApiResponseError(c, http.StatusInternalServerError, "SERVER_INTERNAL_ERROR", "Server internal error", nil)
return
case *fail.SignInFailure:
case *fail.EmailNotVerifiedFailure:
helpers.ApiResponseError(c, http.StatusBadRequest, "EMAIL_NOT_VERIFIED", "Email not verified", nil)
return
case
*fail.SignInFailure,
*fail.SqlSelectNotFoundFailure:
helpers.ApiResponseError(c, http.StatusUnauthorized, "EMAIL_OR_PASSWORD_INVALID", "email or password invalid", nil)
return
default:
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.CaptureException(err)
}
helpers.ApiResponseError(c, http.StatusInternalServerError, "SERVER_INTERNAL_ERROR", "Server internal error", nil)
helpers.ApiResponseError(c, http.StatusInternalServerError, "SERVER_INTERNAL_ERROR", err.Error(), nil)
return
}
}
Expand Down
37 changes: 11 additions & 26 deletions app/controllers/auth/sign_up.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,19 @@
package auth

import (
"fmt"
"bytes"
"encoding/json"
"gotaskapp/app/config"
"gotaskapp/app/entities"
fail "gotaskapp/app/failures"
"gotaskapp/app/helpers"
"gotaskapp/app/repositories/auth"
"net/http"
"strings"

sentrygin "github.com/getsentry/sentry-go/gin"
"github.com/gin-gonic/gin"
)

var emailSignUpbody = `
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Link de confirmação da conta</title>
</head>
<body>
<p>Obrigago por criar uma conta no <b>Go TaskApp</b></p>
<p>Clique neste link <a href="{{LINK}}">aqui</a> para confirmar seu email.</p>
<p>Caso não tenha criado uma conta ignore este email.</p>
</body>
`

type signUp struct {
Firstname string `form:"firstname" binding:"required,alpha"`
Lastname string `form:"lastname" binding:"required,alpha"`
Expand All @@ -51,7 +38,7 @@ func SignUp(c *gin.Context) {
Password: form.Password,
}

credential, err := auth.SignUp(user)
_, err := auth.SignUp(user)

if err != nil {
switch err.(type) {
Expand All @@ -78,17 +65,15 @@ func SignUp(c *gin.Context) {
}

go func() {
link := fmt.Sprintf("%s%s%s", config.APP_URL, "/auth/email/verify/", credential.Token)

emailSignUpbody = strings.ReplaceAll(emailSignUpbody, "{{LINK}}", link)
// Send email verification
body, _ := json.Marshal(
map[string]string{
"email": form.Email,
},
)
payload := bytes.NewBuffer(body)

err = helpers.SendEmail([]string{user.Email}, []string{}, "Confirmação de email", emailSignUpbody)

if err != nil {
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.CaptureException(err)
}
}
http.Post(config.APP_URL+"/auth/send/email/verification", "application/json", payload)
}()

helpers.ApiResponse(
Expand Down
18 changes: 18 additions & 0 deletions app/failures/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,21 @@ type SignUpFailure struct {
func (e *SignUpFailure) Error() string {
return e.M
}

type EmailNotVerifiedFailure struct {
M string
E error
}

func (e *EmailNotVerifiedFailure) Error() string {
return e.M
}

type SendEmailVerificationFailure struct {
M string
E error
}

func (e *SendEmailVerificationFailure) Error() string {
return e.M
}
39 changes: 39 additions & 0 deletions app/repositories/auth/send_email_verification.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package auth

import (
"gotaskapp/app/database"
"gotaskapp/app/entities"
fail "gotaskapp/app/failures"
"gotaskapp/app/security"
"time"
)

func SendEmailVerification(email string) (entities.Credential, error) {

datasources, err := database.Datasources()

if err != nil {
return entities.Credential{}, err
}

user, err := datasources.User.ByEmail(email)

if err != nil {
return entities.Credential{}, err
}

if user.IsEmailVerified() {
return entities.Credential{}, &fail.SendEmailVerificationFailure{M: "The email " + user.Email + " has already been verified.", E: err}
}

token, err := security.GenerateJwtToken(user.ID, time.Hour*6)

if err != nil {
return entities.Credential{}, &fail.GenerateJwtTokenFailure{M: "error generate jwt token", E: err}
}

return entities.Credential{
User: user,
Token: token,
}, nil
}
2 changes: 1 addition & 1 deletion app/repositories/auth/sign_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func SigIn(auth entities.Auth) (entities.Credential, error) {
}

if !user.IsEmailVerified() {
return entities.Credential{}, &fail.SignInFailure{M: "email no verified", E: err}
return entities.Credential{}, &fail.EmailNotVerifiedFailure{M: "The email " + auth.Email + " unverified, please check your inbox.", E: err}
}

token, err := security.GenerateJwtToken(user.ID, time.Hour*365)
Expand Down

0 comments on commit 451b4de

Please sign in to comment.