Skip to content

Commit 210b743

Browse files
committed
updated
1 parent 200762b commit 210b743

17 files changed

+677
-29
lines changed

config/default.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import (
77
)
88

99
type Config struct {
10-
DBUri string `mapstructure:"MONGODB_LOCAL_URI"`
11-
RedisUri string `mapstructure:"REDIS_URL"`
12-
Port string `mapstructure:"PORT"`
10+
DBUri string `mapstructure:"MONGODB_LOCAL_URI"`
11+
RedisUri string `mapstructure:"REDIS_URL"`
12+
Port string `mapstructure:"PORT"`
13+
1314
AccessTokenPrivateKey string `mapstructure:"ACCESS_TOKEN_PRIVATE_KEY"`
1415
AccessTokenPublicKey string `mapstructure:"ACCESS_TOKEN_PUBLIC_KEY"`
1516
RefreshTokenPrivateKey string `mapstructure:"REFRESH_TOKEN_PRIVATE_KEY"`
@@ -18,6 +19,14 @@ type Config struct {
1819
RefreshTokenExpiresIn time.Duration `mapstructure:"REFRESH_TOKEN_EXPIRED_IN"`
1920
AccessTokenMaxAge int `mapstructure:"ACCESS_TOKEN_MAXAGE"`
2021
RefreshTokenMaxAge int `mapstructure:"REFRESH_TOKEN_MAXAGE"`
22+
23+
Origin string `mapstructure:"CLIENT_ORIGIN"`
24+
25+
EmailFrom string `mapstructure:"EMAIL_FROM"`
26+
SMTPHost string `mapstructure:"SMTP_HOST"`
27+
SMTPPass string `mapstructure:"SMTP_PASS"`
28+
SMTPPort int `mapstructure:"SMTP_PORT"`
29+
SMTPUser string `mapstructure:"SMTP_USER"`
2130
}
2231

2332
func LoadConfig(path string) (config Config, err error) {

controllers/auth.controller.go

+67-3
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
package controllers
22

33
import (
4+
"context"
45
"fmt"
6+
"log"
57
"net/http"
68
"strings"
79

810
"github.com/gin-gonic/gin"
11+
"github.com/thanhpk/randstr"
912
"github.com/wpcodevo/golang-mongodb/config"
1013
"github.com/wpcodevo/golang-mongodb/models"
1114
"github.com/wpcodevo/golang-mongodb/services"
1215
"github.com/wpcodevo/golang-mongodb/utils"
16+
"go.mongodb.org/mongo-driver/bson"
1317
"go.mongodb.org/mongo-driver/mongo"
1418
)
1519

1620
type AuthController struct {
1721
authService services.AuthService
1822
userService services.UserService
23+
ctx context.Context
24+
collection *mongo.Collection
1925
}
2026

21-
func NewAuthController(authService services.AuthService, userService services.UserService) AuthController {
22-
return AuthController{authService, userService}
27+
func NewAuthController(authService services.AuthService, userService services.UserService, ctx context.Context, collection *mongo.Collection) AuthController {
28+
return AuthController{authService, userService, ctx, collection}
2329
}
2430

2531
func (ac *AuthController) SignUpUser(ctx *gin.Context) {
@@ -46,7 +52,36 @@ func (ac *AuthController) SignUpUser(ctx *gin.Context) {
4652
return
4753
}
4854

49-
ctx.JSON(http.StatusCreated, gin.H{"status": "success", "data": gin.H{"user": models.FilteredResponse(newUser)}})
55+
config, err := config.LoadConfig(".")
56+
if err != nil {
57+
log.Fatal("Could not load config", err)
58+
}
59+
60+
// Generate Verification Code
61+
code := randstr.String(20)
62+
63+
verificationCode := utils.Encode(code)
64+
65+
// Update User in Database
66+
ac.userService.UpdateUserById(newUser.ID.Hex(), "verificationCode", verificationCode)
67+
68+
var firstName = newUser.Name
69+
70+
if strings.Contains(firstName, " ") {
71+
firstName = strings.Split(firstName, " ")[1]
72+
}
73+
74+
// 👇 Send Email
75+
emailData := utils.EmailData{
76+
URL: config.Origin + "/verifyemail/" + code,
77+
FirstName: firstName,
78+
Subject: "Your account verification code",
79+
}
80+
81+
utils.SendEmail(newUser, &emailData)
82+
83+
message := "We sent an email with a verification code to " + user.Email
84+
ctx.JSON(http.StatusCreated, gin.H{"status": "success", "message": message})
5085
}
5186

5287
func (ac *AuthController) SignInUser(ctx *gin.Context) {
@@ -67,6 +102,11 @@ func (ac *AuthController) SignInUser(ctx *gin.Context) {
67102
return
68103
}
69104

105+
if !user.Verified {
106+
ctx.JSON(http.StatusUnauthorized, gin.H{"status": "fail", "message": "You are not verified, please verify your email to login"})
107+
return
108+
}
109+
70110
if err := utils.VerifyPassword(user.Password, credentials.Password); err != nil {
71111
ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": "Invalid email or Password"})
72112
return
@@ -137,3 +177,27 @@ func (ac *AuthController) LogoutUser(ctx *gin.Context) {
137177

138178
ctx.JSON(http.StatusOK, gin.H{"status": "success"})
139179
}
180+
181+
func (ac *AuthController) VerifyEmail(ctx *gin.Context) {
182+
183+
code := ctx.Params.ByName("verificationCode")
184+
verificationCode := utils.Encode(code)
185+
186+
query := bson.D{{Key: "verificationCode", Value: verificationCode}}
187+
update := bson.D{{Key: "$set", Value: bson.D{{Key: "verified", Value: true}}}, {Key: "$unset", Value: bson.D{{Key: "verificationCode", Value: ""}}}}
188+
result, err := ac.collection.UpdateOne(ac.ctx, query, update)
189+
if err != nil {
190+
ctx.JSON(http.StatusForbidden, gin.H{"status": "success", "message": err.Error()})
191+
return
192+
}
193+
194+
if result.MatchedCount == 0 {
195+
ctx.JSON(http.StatusForbidden, gin.H{"status": "success", "message": "Could not verify email address"})
196+
return
197+
}
198+
199+
fmt.Println(result)
200+
201+
ctx.JSON(http.StatusOK, gin.H{"status": "success", "message": "Email verified successfully"})
202+
203+
}

example.env

+9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ MONGODB_LOCAL_URI=mongodb://root:password123@localhost:6000
77

88
REDIS_URL=localhost:6379
99

10+
CLIENT_ORIGIN=http://localhost:3000
11+
12+
EMAIL_FROM=admin@admin.com
13+
SMTP_HOST=smtp.mailtrap.io
14+
SMTP_USER=
15+
SMTP_PASS=
16+
SMTP_PORT=587
17+
18+
1019
ACCESS_TOKEN_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCUEFJQkFBSkJBTzVIKytVM0xrWC91SlRvRHhWN01CUURXSTdGU0l0VXNjbGFFKzlaUUg5Q2VpOGIxcUVmCnJxR0hSVDVWUis4c3UxVWtCUVpZTER3MnN3RTVWbjg5c0ZVQ0F3RUFBUUpCQUw4ZjRBMUlDSWEvQ2ZmdWR3TGMKNzRCdCtwOXg0TEZaZXMwdHdtV3Vha3hub3NaV0w4eVpSTUJpRmI4a25VL0hwb3piTnNxMmN1ZU9wKzVWdGRXNApiTlVDSVFENm9JdWxqcHdrZTFGY1VPaldnaXRQSjNnbFBma3NHVFBhdFYwYnJJVVI5d0loQVBOanJ1enB4ckhsCkUxRmJxeGtUNFZ5bWhCOU1HazU0Wk1jWnVjSmZOcjBUQWlFQWhML3UxOVZPdlVBWVd6Wjc3Y3JxMTdWSFBTcXoKUlhsZjd2TnJpdEg1ZGdjQ0lRRHR5QmFPdUxuNDlIOFIvZ2ZEZ1V1cjg3YWl5UHZ1YStxeEpXMzQrb0tFNXdJZwpQbG1KYXZsbW9jUG4rTkVRdGhLcTZuZFVYRGpXTTlTbktQQTVlUDZSUEs0PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==
1120

1221
ACCESS_TOKEN_PUBLIC_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTzVIKytVM0xrWC91SlRvRHhWN01CUURXSTdGU0l0VQpzY2xhRSs5WlFIOUNlaThiMXFFZnJxR0hSVDVWUis4c3UxVWtCUVpZTER3MnN3RTVWbjg5c0ZVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==

go.mod

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ require (
2525
github.com/golang/snappy v0.0.1 // indirect
2626
github.com/hashicorp/hcl v1.0.0 // indirect
2727
github.com/json-iterator/go v1.1.12 // indirect
28+
github.com/k3a/html2text v1.0.8 // indirect
2829
github.com/klauspost/compress v1.13.6 // indirect
2930
github.com/leodido/go-urn v1.2.1 // indirect
3031
github.com/magiconair/properties v1.8.6 // indirect
@@ -40,6 +41,7 @@ require (
4041
github.com/spf13/jwalterweatherman v1.1.0 // indirect
4142
github.com/spf13/pflag v1.0.5 // indirect
4243
github.com/subosito/gotenv v1.2.0 // indirect
44+
github.com/thanhpk/randstr v1.0.4 // indirect
4345
github.com/ugorji/go/codec v1.2.7 // indirect
4446
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
4547
github.com/xdg-go/scram v1.0.2 // indirect
@@ -49,6 +51,8 @@ require (
4951
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a // indirect
5052
golang.org/x/text v0.3.7 // indirect
5153
google.golang.org/protobuf v1.28.0 // indirect
54+
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
55+
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
5256
gopkg.in/ini.v1 v1.66.4 // indirect
5357
gopkg.in/yaml.v2 v2.4.0 // indirect
5458
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect

go.sum

+13
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
153153
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
154154
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
155155
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
156+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
156157
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
157158
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
158159
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -165,6 +166,9 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
165166
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
166167
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
167168
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
169+
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
170+
github.com/k3a/html2text v1.0.8 h1:rVanLhKilpnJUJs/CNKWzMC4YaQINGxK0rSG8ssmnV0=
171+
github.com/k3a/html2text v1.0.8/go.mod h1:ieEXykM67iT8lTvEWBh6fhpH4B23kB9OMKPdIBmgUqA=
168172
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
169173
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
170174
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
@@ -214,6 +218,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
214218
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
215219
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
216220
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
221+
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
222+
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
217223
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
218224
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
219225
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
@@ -235,6 +241,8 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT
235241
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
236242
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
237243
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
244+
github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo=
245+
github.com/thanhpk/randstr v1.0.4/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U=
238246
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
239247
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
240248
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@@ -422,6 +430,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
422430
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
423431
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
424432
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
433+
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
425434
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
426435
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
427436
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -561,13 +570,17 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
561570
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
562571
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
563572
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
573+
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
574+
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
564575
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
565576
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
566577
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
567578
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
568579
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
569580
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
570581
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
582+
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
583+
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
571584
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
572585
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
573586
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func init() {
7676
authCollection = mongoclient.Database("golang_mongodb").Collection("users")
7777
userService = services.NewUserServiceImpl(authCollection, ctx)
7878
authService = services.NewAuthService(authCollection, ctx)
79-
AuthController = controllers.NewAuthController(authService, userService)
79+
AuthController = controllers.NewAuthController(authService, userService, ctx, authCollection)
8080
AuthRouteController = routes.NewAuthRouteController(AuthController)
8181

8282
UserController = controllers.NewUserController(userService)
@@ -103,7 +103,7 @@ func main() {
103103
}
104104

105105
corsConfig := cors.DefaultConfig()
106-
corsConfig.AllowOrigins = []string{"http://localhost:8000", "http://localhost:3000"}
106+
corsConfig.AllowOrigins = []string{config.Origin}
107107
corsConfig.AllowCredentials = true
108108

109109
server.Use(cors.New(corsConfig))

models/user.model.go

+19-17
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import (
88

99
// 👈 SignUpInput struct
1010
type SignUpInput struct {
11-
Name string `json:"name" bson:"name" binding:"required"`
12-
Email string `json:"email" bson:"email" binding:"required"`
13-
Password string `json:"password" bson:"password" binding:"required,min=8"`
14-
PasswordConfirm string `json:"passwordConfirm" bson:"passwordConfirm,omitempty" binding:"required"`
15-
Role string `json:"role" bson:"role"`
16-
Verified bool `json:"verified" bson:"verified"`
17-
CreatedAt time.Time `json:"created_at" bson:"created_at"`
18-
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
11+
Name string `json:"name" bson:"name" binding:"required"`
12+
Email string `json:"email" bson:"email" binding:"required"`
13+
Password string `json:"password" bson:"password" binding:"required,min=8"`
14+
PasswordConfirm string `json:"passwordConfirm" bson:"passwordConfirm,omitempty" binding:"required"`
15+
Role string `json:"role" bson:"role"`
16+
VerificationCode string `json:"verificationCode,omitempty" bson:"verificationCode,omitempty"`
17+
Verified bool `json:"verified" bson:"verified"`
18+
CreatedAt time.Time `json:"created_at" bson:"created_at"`
19+
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
1920
}
2021

2122
// 👈 SignInInput struct
@@ -26,15 +27,16 @@ type SignInInput struct {
2627

2728
// 👈 DBResponse struct
2829
type DBResponse struct {
29-
ID primitive.ObjectID `json:"id" bson:"_id"`
30-
Name string `json:"name" bson:"name"`
31-
Email string `json:"email" bson:"email"`
32-
Password string `json:"password" bson:"password"`
33-
PasswordConfirm string `json:"passwordConfirm,omitempty" bson:"passwordConfirm,omitempty"`
34-
Role string `json:"role" bson:"role"`
35-
Verified bool `json:"verified" bson:"verified"`
36-
CreatedAt time.Time `json:"created_at" bson:"created_at"`
37-
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
30+
ID primitive.ObjectID `json:"id" bson:"_id"`
31+
Name string `json:"name" bson:"name"`
32+
Email string `json:"email" bson:"email"`
33+
Password string `json:"password" bson:"password"`
34+
PasswordConfirm string `json:"passwordConfirm,omitempty" bson:"passwordConfirm,omitempty"`
35+
Role string `json:"role" bson:"role"`
36+
VerificationCode string `json:"verificationCode,omitempty" bson:"verificationCode"`
37+
Verified bool `json:"verified" bson:"verified"`
38+
CreatedAt time.Time `json:"created_at" bson:"created_at"`
39+
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
3840
}
3941

4042
// 👈 UserResponse struct

routes/auth.routes.go

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ func (rc *AuthRouteController) AuthRoute(rg *gin.RouterGroup, userService servic
2222
router.POST("/login", rc.authController.SignInUser)
2323
router.GET("/refresh", rc.authController.RefreshAccessToken)
2424
router.GET("/logout", middleware.DeserializeUser(userService), rc.authController.LogoutUser)
25+
router.GET("/verifyemail/:verificationCode", rc.authController.VerifyEmail)
2526
}

services/auth.service.impl.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (uc *AuthServiceImpl) SignUpUser(user *models.SignUpInput) (*models.DBRespo
2727
user.UpdatedAt = user.CreatedAt
2828
user.Email = strings.ToLower(user.Email)
2929
user.PasswordConfirm = ""
30-
user.Verified = true
30+
user.Verified = false
3131
user.Role = "user"
3232

3333
hashedPassword, _ := utils.HashPassword(user.Password)

services/user.service.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package services
33
import "github.com/wpcodevo/golang-mongodb/models"
44

55
type UserService interface {
6-
FindUserById(string) (*models.DBResponse, error)
7-
FindUserByEmail(string) (*models.DBResponse, error)
6+
FindUserById(id string) (*models.DBResponse, error)
7+
FindUserByEmail(email string) (*models.DBResponse, error)
8+
UpdateUserById(id string, field string, value string) (*models.DBResponse, error)
9+
UpdateOne(field string, value interface{}) (*models.DBResponse, error)
810
}

services/user.service.impl.go

+30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package services
22

33
import (
44
"context"
5+
"fmt"
56
"strings"
67

78
"github.com/wpcodevo/golang-mongodb/models"
@@ -52,3 +53,32 @@ func (us *UserServiceImpl) FindUserByEmail(email string) (*models.DBResponse, er
5253

5354
return user, nil
5455
}
56+
57+
func (uc *UserServiceImpl) UpdateUserById(id string, field string, value string) (*models.DBResponse, error) {
58+
userId, _ := primitive.ObjectIDFromHex(id)
59+
query := bson.D{{Key: "_id", Value: userId}}
60+
update := bson.D{{Key: "$set", Value: bson.D{{Key: field, Value: value}}}}
61+
result, err := uc.collection.UpdateOne(uc.ctx, query, update)
62+
63+
fmt.Print(result.ModifiedCount)
64+
if err != nil {
65+
fmt.Print(err)
66+
return &models.DBResponse{}, err
67+
}
68+
69+
return &models.DBResponse{}, nil
70+
}
71+
72+
func (uc *UserServiceImpl) UpdateOne(field string, value interface{}) (*models.DBResponse, error) {
73+
query := bson.D{{Key: field, Value: value}}
74+
update := bson.D{{Key: "$set", Value: bson.D{{Key: field, Value: value}}}}
75+
result, err := uc.collection.UpdateOne(uc.ctx, query, update)
76+
77+
fmt.Print(result.ModifiedCount)
78+
if err != nil {
79+
fmt.Print(err)
80+
return &models.DBResponse{}, err
81+
}
82+
83+
return &models.DBResponse{}, nil
84+
}

0 commit comments

Comments
 (0)