all repos

onasty @ 757b945

a one-time notes service

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

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