all repos

onasty @ 7236f0c

a one-time notes service

onasty/internal/transport/http/apiv1/auth.go (view raw)

Smirnov Oleksandr Smirnov Oleksandr
ss2316544@gmail.com
feat: reset password (#110)..., 1 year ago
1
package apiv1
2
3
import (
4
	"net/http"
5
	"time"
6
7
	"github.com/gin-gonic/gin"
8
	"github.com/olexsmir/onasty/internal/dtos"
9
)
10
11
type signUpRequest struct {
12
	Username string `json:"username"`
13
	Email    string `json:"email"`
14
	Password string `json:"password"`
15
}
16
17
func (a *APIV1) signUpHandler(c *gin.Context) {
18
	var req signUpRequest
19
	if err := c.ShouldBindJSON(&req); err != nil {
20
		newError(c, http.StatusBadRequest, "invalid request")
21
		return
22
	}
23
24
	if _, err := a.usersrv.SignUp(c.Request.Context(), dtos.SignUp{
25
		Username:    req.Username,
26
		Email:       req.Email,
27
		Password:    req.Password,
28
		CreatedAt:   time.Now(),
29
		LastLoginAt: time.Now(),
30
	}); err != nil {
31
		errorResponse(c, err)
32
		return
33
	}
34
35
	c.Status(http.StatusCreated)
36
}
37
38
type signInRequest struct {
39
	Email    string `json:"email"`
40
	Password string `json:"password"`
41
}
42
43
type signInResponse struct {
44
	AccessToken  string `json:"access_token"`
45
	RefreshToken string `json:"refresh_token"`
46
}
47
48
func (a *APIV1) signInHandler(c *gin.Context) {
49
	var req signInRequest
50
	if err := c.ShouldBindJSON(&req); err != nil {
51
		newError(c, http.StatusBadRequest, "invalid request")
52
		return
53
	}
54
55
	toks, err := a.usersrv.SignIn(c.Request.Context(), dtos.SignIn{
56
		Email:    req.Email,
57
		Password: req.Password,
58
	})
59
	if err != nil {
60
		errorResponse(c, err)
61
		return
62
	}
63
64
	c.JSON(http.StatusOK, signInResponse{
65
		AccessToken:  toks.Access,
66
		RefreshToken: toks.Refresh,
67
	})
68
}
69
70
type refreshTokenRequest struct {
71
	RefreshToken string `json:"refresh_token"`
72
}
73
74
func (a *APIV1) refreshTokensHandler(c *gin.Context) {
75
	var req refreshTokenRequest
76
	if err := c.ShouldBindJSON(&req); err != nil {
77
		newError(c, http.StatusBadRequest, "invalid request")
78
		return
79
	}
80
81
	toks, err := a.usersrv.RefreshTokens(c.Request.Context(), req.RefreshToken)
82
	if err != nil {
83
		errorResponse(c, err)
84
		return
85
	}
86
87
	c.JSON(http.StatusOK, signInResponse{
88
		AccessToken:  toks.Access,
89
		RefreshToken: toks.Refresh,
90
	})
91
}
92
93
func (a *APIV1) verifyHandler(c *gin.Context) {
94
	if err := a.usersrv.Verify(c.Request.Context(), c.Param("token")); err != nil {
95
		errorResponse(c, err)
96
		return
97
	}
98
99
	c.String(http.StatusOK, "email verified")
100
}
101
102
func (a *APIV1) resendVerificationEmailHandler(c *gin.Context) {
103
	var req signInRequest
104
	if err := c.ShouldBindJSON(&req); err != nil {
105
		newError(c, http.StatusBadRequest, "invalid request")
106
		return
107
	}
108
109
	if err := a.usersrv.ResendVerificationEmail(
110
		c.Request.Context(),
111
		dtos.SignIn{
112
			Email:    req.Email,
113
			Password: req.Password,
114
		}); err != nil {
115
		errorResponse(c, err)
116
		return
117
	}
118
119
	c.Status(http.StatusOK)
120
}
121
122
type requestResetPasswordRequest struct {
123
	Email string `json:"email"`
124
}
125
126
func (a *APIV1) requestResetPasswordHandler(c *gin.Context) {
127
	var req requestResetPasswordRequest
128
	if err := c.ShouldBindJSON(&req); err != nil {
129
		newError(c, http.StatusBadRequest, "invalid request")
130
		return
131
	}
132
133
	if err := a.usersrv.RequestPasswordReset(c.Request.Context(), dtos.RequestResetPassword{
134
		Email: req.Email,
135
	}); err != nil {
136
		errorResponse(c, err)
137
		return
138
	}
139
140
	c.Status(http.StatusOK)
141
}
142
143
type resetPasswordRequest struct {
144
	Password string `json:"password"`
145
}
146
147
func (a *APIV1) resetPasswordHandler(c *gin.Context) {
148
	var req resetPasswordRequest
149
	if err := c.ShouldBindJSON(&req); err != nil {
150
		newError(c, http.StatusBadRequest, "invalid request")
151
		return
152
	}
153
154
	if err := a.usersrv.ResetPassword(
155
		c.Request.Context(),
156
		dtos.ResetPassword{
157
			Token:       c.Param("token"),
158
			NewPassword: req.Password,
159
		},
160
	); err != nil {
161
		errorResponse(c, err)
162
		return
163
	}
164
165
	c.Status(http.StatusOK)
166
}
167
168
func (a *APIV1) logOutHandler(c *gin.Context) {
169
	if err := a.usersrv.Logout(c.Request.Context(), a.getUserID(c)); err != nil {
170
		errorResponse(c, err)
171
		return
172
	}
173
174
	c.Status(http.StatusNoContent)
175
}
176
177
type changePasswordRequest struct {
178
	CurrentPassword string `json:"current_password"`
179
	NewPassword     string `json:"new_password"`
180
}
181
182
func (a *APIV1) changePasswordHandler(c *gin.Context) {
183
	var req changePasswordRequest
184
	if err := c.ShouldBindJSON(&req); err != nil {
185
		newError(c, http.StatusBadRequest, "invalid request")
186
		return
187
	}
188
189
	if err := a.usersrv.ChangePassword(
190
		c.Request.Context(),
191
		a.getUserID(c),
192
		dtos.ChangeUserPassword{
193
			CurrentPassword: req.CurrentPassword,
194
			NewPassword:     req.NewPassword,
195
		}); err != nil {
196
		errorResponse(c, err)
197
		return
198
	}
199
200
	c.Status(http.StatusOK)
201
}
202
203
func (a *APIV1) oauthLoginHandler(c *gin.Context) {
204
	url, err := a.usersrv.GetOAuthURL(c.Param("provider"))
205
	if err != nil {
206
		errorResponse(c, err)
207
		return
208
	}
209
210
	c.Redirect(http.StatusSeeOther, url)
211
}
212
213
func (a *APIV1) oauthCallbackHandler(c *gin.Context) {
214
	tokens, err := a.usersrv.HandleOAuthLogin(
215
		c.Request.Context(),
216
		c.Param("provider"),
217
		c.Query("code"),
218
	)
219
	if err != nil {
220
		errorResponse(c, err)
221
		return
222
	}
223
224
	c.JSON(http.StatusOK, signInResponse{
225
		AccessToken:  tokens.Access,
226
		RefreshToken: tokens.Refresh,
227
	})
228
}