Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita54eca3

Browse files
committed
updated
1 parented3e66a commita54eca3

File tree

5 files changed

+208
-14
lines changed

5 files changed

+208
-14
lines changed

‎controllers/auth.controller.go

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package controllers
22

33
import (
4+
"log"
45
"net/http"
56
"strings"
67
"time"
@@ -85,7 +86,7 @@ func (ac *AuthController) SignUpUser(ctx *gin.Context) {
8586
Subject:"Your account verification code",
8687
}
8788

88-
utils.SendEmail(&newUser,&emailData)
89+
utils.SendEmail(&newUser,&emailData,"verificationCode.html")
8990

9091
message:="We sent an email with a verification code to "+newUser.Email
9192
ctx.JSON(http.StatusCreated, gin.H{"status":"success","message":message})
@@ -161,3 +162,92 @@ func (ac *AuthController) VerifyEmail(ctx *gin.Context) {
161162

162163
ctx.JSON(http.StatusOK, gin.H{"status":"success","message":"Email verified successfully"})
163164
}
165+
166+
func (ac*AuthController)ForgotPassword(ctx*gin.Context) {
167+
varpayload*models.ForgotPasswordInput
168+
169+
iferr:=ctx.ShouldBindJSON(&payload);err!=nil {
170+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
171+
return
172+
}
173+
174+
message:="You will receive a reset email if user with that email exist"
175+
176+
varuser models.User
177+
result:=ac.DB.First(&user,"email = ?",strings.ToLower(payload.Email))
178+
ifresult.Error!=nil {
179+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":"Invalid email or Password"})
180+
return
181+
}
182+
183+
if!user.Verified {
184+
ctx.JSON(http.StatusUnauthorized, gin.H{"status":"error","message":"Account not verified"})
185+
return
186+
}
187+
188+
config,err:=initializers.LoadConfig(".")
189+
iferr!=nil {
190+
log.Fatal("Could not load config",err)
191+
}
192+
193+
// Generate Verification Code
194+
resetToken:=randstr.String(20)
195+
196+
passwordResetToken:=utils.Encode(resetToken)
197+
user.PasswordResetToken=passwordResetToken
198+
user.PasswordResetAt=time.Now().Add(time.Minute*15)
199+
ac.DB.Save(&user)
200+
201+
varfirstName=user.Name
202+
203+
ifstrings.Contains(firstName," ") {
204+
firstName=strings.Split(firstName," ")[1]
205+
}
206+
207+
// 👇 Send Email
208+
emailData:= utils.EmailData{
209+
URL:config.ClientOrigin+"/forgotPassword/"+resetToken,
210+
FirstName:firstName,
211+
Subject:"Your password reset token (valid for 10min)",
212+
}
213+
214+
utils.SendEmail(&user,&emailData,"resetPassword.html")
215+
216+
ctx.JSON(http.StatusOK, gin.H{"status":"success","message":message})
217+
}
218+
219+
func (ac*AuthController)ResetPassword(ctx*gin.Context) {
220+
varpayload*models.ResetPasswordInput
221+
resetToken:=ctx.Params.ByName("resetToken")
222+
223+
iferr:=ctx.ShouldBindJSON(&payload);err!=nil {
224+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
225+
return
226+
}
227+
228+
ifpayload.Password!=payload.PasswordConfirm {
229+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":"Passwords do not match"})
230+
return
231+
}
232+
233+
hashedPassword,_:=utils.HashPassword(payload.Password)
234+
235+
passwordResetToken:=utils.Encode(resetToken)
236+
237+
varupdatedUser models.User
238+
result:=ac.DB.First(&updatedUser,"password_reset_token = ?",passwordResetToken)
239+
ifresult.Error!=nil {
240+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":"Invalid verification code or user doesn't exists"})
241+
return
242+
}
243+
244+
updatedUser.Password=hashedPassword
245+
updatedUser.PasswordResetToken=""
246+
ac.DB.Save(&updatedUser)
247+
248+
ctx.SetCookie("access_token","",-1,"/","localhost",false,true)
249+
ctx.SetCookie("refresh_token","",-1,"/","localhost",false,true)
250+
ctx.SetCookie("logged_in","",-1,"/","localhost",false,true)
251+
252+
ctx.JSON(http.StatusOK, gin.H{"status":"success","message":"Password data updated successfully"})
253+
}

‎models/user.model.go

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ import (
77
)
88

99
typeUserstruct {
10-
ID uuid.UUID`gorm:"type:uuid;default:uuid_generate_v4();primary_key"`
11-
Namestring`gorm:"type:varchar(255);not null"`
12-
Emailstring`gorm:"uniqueIndex;not null"`
13-
Passwordstring`gorm:"not null"`
14-
Rolestring`gorm:"type:varchar(255);not null"`
15-
Providerstring`gorm:"not null"`
16-
Photostring`gorm:"not null"`
17-
VerificationCodestring
18-
Verifiedbool`gorm:"not null"`
19-
CreatedAt time.Time`gorm:"not null"`
20-
UpdatedAt time.Time`gorm:"not null"`
10+
ID uuid.UUID`gorm:"type:uuid;default:uuid_generate_v4();primary_key"`
11+
Namestring`gorm:"type:varchar(255);not null"`
12+
Emailstring`gorm:"uniqueIndex;not null"`
13+
Passwordstring`gorm:"not null"`
14+
Rolestring`gorm:"type:varchar(255);not null"`
15+
Providerstring`gorm:"not null"`
16+
Photostring`gorm:"not null"`
17+
VerificationCodestring
18+
PasswordResetTokenstring
19+
PasswordResetAt time.Time
20+
Verifiedbool`gorm:"not null"`
21+
CreatedAt time.Time`gorm:"not null"`
22+
UpdatedAt time.Time`gorm:"not null"`
2123
}
2224

2325
typeSignUpInputstruct {
@@ -43,3 +45,14 @@ type UserResponse struct {
4345
CreatedAt time.Time`json:"created_at"`
4446
UpdatedAt time.Time`json:"updated_at"`
4547
}
48+
49+
// 👈 ForgotPasswordInput struct
50+
typeForgotPasswordInputstruct {
51+
Emailstring`json:"email" binding:"required"`
52+
}
53+
54+
// 👈 ResetPasswordInput struct
55+
typeResetPasswordInputstruct {
56+
Passwordstring`json:"password" binding:"required"`
57+
PasswordConfirmstring`json:"passwordConfirm" binding:"required"`
58+
}

‎routes/auth.routes.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ func (rc *AuthRouteController) AuthRoute(rg *gin.RouterGroup) {
2121
router.POST("/login",rc.authController.SignInUser)
2222
router.GET("/logout",middleware.DeserializeUser(),rc.authController.LogoutUser)
2323
router.GET("/verifyemail/:verificationCode",rc.authController.VerifyEmail)
24+
router.POST("/forgotpassword",rc.authController.ForgotPassword)
25+
router.PATCH("/resetpassword/:resetToken",rc.authController.ResetPassword)
2426
}

‎templates/resetPassword.html

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<metaname="viewport"content="width=device-width, initial-scale=1.0"/>
5+
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"/>
6+
{{template "styles" .}}
7+
<title>{{ .Subject}}</title>
8+
</head>
9+
<body>
10+
<table
11+
role="presentation"
12+
border="0"
13+
cellpadding="0"
14+
cellspacing="0"
15+
class="body"
16+
>
17+
<tr>
18+
<td>&nbsp;</td>
19+
<tdclass="container">
20+
<divclass="content">
21+
<!-- START CENTERED WHITE CONTAINER -->
22+
<tablerole="presentation"class="main">
23+
<!-- START MAIN CONTENT AREA -->
24+
<tr>
25+
<tdclass="wrapper">
26+
<table
27+
role="presentation"
28+
border="0"
29+
cellpadding="0"
30+
cellspacing="0"
31+
>
32+
<tr>
33+
<td>
34+
<p>Hi {{ .FirstName}},</p>
35+
<p>
36+
Forgot password? Send a PATCH request to with your
37+
password and passwordConfirm to {{.URL}}
38+
</p>
39+
<table
40+
role="presentation"
41+
border="0"
42+
cellpadding="0"
43+
cellspacing="0"
44+
class="btn btn-primary"
45+
>
46+
<tbody>
47+
<tr>
48+
<tdalign="left">
49+
<table
50+
role="presentation"
51+
border="0"
52+
cellpadding="0"
53+
cellspacing="0"
54+
>
55+
<tbody>
56+
<tr>
57+
<td>
58+
<ahref="{{.URL}}"target="_blank"
59+
>Reset password</a
60+
>
61+
</td>
62+
</tr>
63+
</tbody>
64+
</table>
65+
</td>
66+
</tr>
67+
</tbody>
68+
</table>
69+
<p>
70+
If you didn't forget your password, please ignore this
71+
email
72+
</p>
73+
<p>Good luck! Codevo CEO.</p>
74+
</td>
75+
</tr>
76+
</table>
77+
</td>
78+
</tr>
79+
80+
<!-- END MAIN CONTENT AREA -->
81+
</table>
82+
<!-- END CENTERED WHITE CONTAINER -->
83+
</div>
84+
</td>
85+
<td>&nbsp;</td>
86+
</tr>
87+
</table>
88+
</body>
89+
</html>

‎utils/email.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func ParseTemplateDir(dir string) (*template.Template, error) {
4141
returntemplate.ParseFiles(paths...)
4242
}
4343

44-
funcSendEmail(user*models.User,data*EmailData) {
44+
funcSendEmail(user*models.User,data*EmailData,emailTempstring) {
4545
config,err:=initializers.LoadConfig(".")
4646

4747
iferr!=nil {
@@ -63,7 +63,7 @@ func SendEmail(user *models.User, data *EmailData) {
6363
log.Fatal("Could not parse template",err)
6464
}
6565

66-
template.ExecuteTemplate(&body,"verificationCode.html",&data)
66+
template.ExecuteTemplate(&body,emailTemp,&data)
6767

6868
m:=gomail.NewMessage()
6969

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp