Skip to content

Commit d09b347

Browse files
Migrated more auth forms.
1 parent 7819fea commit d09b347

File tree

8 files changed

+264
-82
lines changed

8 files changed

+264
-82
lines changed

pkg/handlers/auth.go

Lines changed: 21 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,15 @@ import (
1717
"github.com/mikestefanello/pagoda/pkg/redirect"
1818
"github.com/mikestefanello/pagoda/pkg/routenames"
1919
"github.com/mikestefanello/pagoda/pkg/services"
20+
"github.com/mikestefanello/pagoda/pkg/ui"
2021
"github.com/mikestefanello/pagoda/templates"
2122
)
2223

2324
const (
24-
routeNameForgotPassword = "forgot_password"
25-
routeNameForgotPasswordSubmit = "forgot_password.submit"
26-
routeNameLogin = "login"
27-
routeNameLoginSubmit = "login.submit"
28-
routeNameLogout = "logout"
29-
routeNameRegister = "register"
30-
routeNameRegisterSubmit = "register.submit"
31-
routeNameResetPassword = "reset_password"
32-
routeNameResetPasswordSubmit = "reset_password.submit"
33-
routeNameVerifyEmail = "verify_email"
25+
routeNameLogout = "logout"
26+
routeNameResetPassword = "reset_password"
27+
routeNameResetPasswordSubmit = "reset_password.submit"
28+
routeNameVerifyEmail = "verify_email"
3429
)
3530

3631
type (
@@ -41,25 +36,6 @@ type (
4136
*services.TemplateRenderer
4237
}
4338

44-
forgotPasswordForm struct {
45-
Email string `form:"email" validate:"required,email"`
46-
form.Submission
47-
}
48-
49-
loginForm struct {
50-
Email string `form:"email" validate:"required,email"`
51-
Password string `form:"password" validate:"required"`
52-
form.Submission
53-
}
54-
55-
registerForm struct {
56-
Name string `form:"name" validate:"required"`
57-
Email string `form:"email" validate:"required,email"`
58-
Password string `form:"password" validate:"required"`
59-
ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"`
60-
form.Submission
61-
}
62-
6339
resetPasswordForm struct {
6440
Password string `form:"password" validate:"required"`
6541
ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"`
@@ -84,12 +60,12 @@ func (h *Auth) Routes(g *echo.Group) {
8460
g.GET("/email/verify/:token", h.VerifyEmail).Name = routeNameVerifyEmail
8561

8662
noAuth := g.Group("/user", middleware.RequireNoAuthentication())
87-
noAuth.GET("/login", h.LoginPage).Name = routeNameLogin
88-
noAuth.POST("/login", h.LoginSubmit).Name = routeNameLoginSubmit
89-
noAuth.GET("/register", h.RegisterPage).Name = routeNameRegister
90-
noAuth.POST("/register", h.RegisterSubmit).Name = routeNameRegisterSubmit
91-
noAuth.GET("/password", h.ForgotPasswordPage).Name = routeNameForgotPassword
92-
noAuth.POST("/password", h.ForgotPasswordSubmit).Name = routeNameForgotPasswordSubmit
63+
noAuth.GET("/login", h.LoginPage).Name = routenames.Login
64+
noAuth.POST("/login", h.LoginSubmit).Name = routenames.LoginSubmit
65+
noAuth.GET("/register", h.RegisterPage).Name = routenames.Register
66+
noAuth.POST("/register", h.RegisterSubmit).Name = routenames.RegisterSubmit
67+
noAuth.GET("/password", h.ForgotPasswordPage).Name = routenames.ForgotPassword
68+
noAuth.POST("/password", h.ForgotPasswordSubmit).Name = routenames.ForgotPasswordSubmit
9369

9470
resetGroup := noAuth.Group("/password/reset",
9571
middleware.LoadUser(h.orm),
@@ -100,17 +76,11 @@ func (h *Auth) Routes(g *echo.Group) {
10076
}
10177

10278
func (h *Auth) ForgotPasswordPage(ctx echo.Context) error {
103-
p := page.New(ctx)
104-
p.Layout = templates.LayoutAuth
105-
p.Name = templates.PageForgotPassword
106-
p.Title = "Forgot password"
107-
p.Form = form.Get[forgotPasswordForm](ctx)
108-
109-
return h.RenderPage(ctx, p)
79+
return ui.ForgotPassword(ctx, form.Get[ui.ForgotPasswordForm](ctx))
11080
}
11181

11282
func (h *Auth) ForgotPasswordSubmit(ctx echo.Context) error {
113-
var input forgotPasswordForm
83+
var input ui.ForgotPasswordForm
11484

11585
succeed := func() error {
11686
form.Clear(ctx)
@@ -169,17 +139,11 @@ func (h *Auth) ForgotPasswordSubmit(ctx echo.Context) error {
169139
}
170140

171141
func (h *Auth) LoginPage(ctx echo.Context) error {
172-
p := page.New(ctx)
173-
p.Layout = templates.LayoutAuth
174-
p.Name = templates.PageLogin
175-
p.Title = "Log in"
176-
p.Form = form.Get[loginForm](ctx)
177-
178-
return h.RenderPage(ctx, p)
142+
return ui.Login(ctx, form.Get[ui.LoginForm](ctx))
179143
}
180144

181145
func (h *Auth) LoginSubmit(ctx echo.Context) error {
182-
var input loginForm
146+
var input ui.LoginForm
183147

184148
authFailed := func() error {
185149
input.SetFieldError("Email", "")
@@ -224,7 +188,7 @@ func (h *Auth) LoginSubmit(ctx echo.Context) error {
224188
return fail(err, "unable to log in user")
225189
}
226190

227-
msg.Success(ctx, fmt.Sprintf("Welcome back, <strong>%s</strong>. You are now logged in.", u.Name))
191+
msg.Success(ctx, fmt.Sprintf("Welcome back, %s. You are now logged in.", u.Name))
228192

229193
return redirect.New(ctx).
230194
Route(routenames.Home).
@@ -243,17 +207,11 @@ func (h *Auth) Logout(ctx echo.Context) error {
243207
}
244208

245209
func (h *Auth) RegisterPage(ctx echo.Context) error {
246-
p := page.New(ctx)
247-
p.Layout = templates.LayoutAuth
248-
p.Name = templates.PageRegister
249-
p.Title = "Register"
250-
p.Form = form.Get[registerForm](ctx)
251-
252-
return h.RenderPage(ctx, p)
210+
return ui.Register(ctx, form.Get[ui.RegisterForm](ctx))
253211
}
254212

255213
func (h *Auth) RegisterSubmit(ctx echo.Context) error {
256-
var input registerForm
214+
var input ui.RegisterForm
257215

258216
err := form.Submit(ctx, &input)
259217

@@ -288,7 +246,7 @@ func (h *Auth) RegisterSubmit(ctx echo.Context) error {
288246
case *ent.ConstraintError:
289247
msg.Warning(ctx, "A user with this email address already exists. Please log in.")
290248
return redirect.New(ctx).
291-
Route(routeNameLogin).
249+
Route(routenames.Login).
292250
Go()
293251
default:
294252
return fail(err, "unable to create user")
@@ -303,7 +261,7 @@ func (h *Auth) RegisterSubmit(ctx echo.Context) error {
303261
)
304262
msg.Info(ctx, "Your account has been created.")
305263
return redirect.New(ctx).
306-
Route(routeNameLogin).
264+
Route(routenames.Login).
307265
Go()
308266
}
309267

@@ -398,7 +356,7 @@ func (h *Auth) ResetPasswordSubmit(ctx echo.Context) error {
398356

399357
msg.Success(ctx, "Your password has been updated.")
400358
return redirect.New(ctx).
401-
Route(routeNameLogin).
359+
Route(routenames.Login).
402360
Go()
403361
}
404362

pkg/redirect/redirect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type Redirect struct {
2424
func New(ctx echo.Context) *Redirect {
2525
return &Redirect{
2626
ctx: ctx,
27-
status: http.StatusFound,
27+
status: http.StatusTemporaryRedirect,
2828
}
2929
}
3030

pkg/routenames/names.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package routenames
2+
3+
const (
4+
Home = "home"
5+
Contact = "contact"
6+
ContactSubmit = "contact.submit"
7+
Login = "login"
8+
LoginSubmit = "login.submit"
9+
Register = "register"
10+
RegisterSubmit = "register.submit"
11+
ForgotPassword = "forgot_password"
12+
ForgotPasswordSubmit = "forgot_password.submit"
13+
)

pkg/ui/components.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,18 @@ func footer(r *request) Node {
224224
`)),
225225
}
226226
}
227+
228+
func button(class, label string) Node {
229+
return Button(
230+
Class("button "+class),
231+
Text(label),
232+
)
233+
}
234+
235+
func buttonLink(href, class, label string) Node {
236+
return A(
237+
Href(href),
238+
Class("button "+class),
239+
Text(label),
240+
)
241+
}

pkg/ui/form.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import (
88

99
type (
1010
input struct {
11-
form form.Form
12-
formField string
13-
name string
14-
inputType string
15-
label string
16-
value string
11+
form form.Form
12+
formField string
13+
name string
14+
inputType string
15+
label string
16+
value string
17+
placeholder string
1718
}
1819

1920
radios struct {
@@ -39,16 +40,18 @@ type (
3940
}
4041
)
4142

42-
func formSubmit(label string) Node {
43+
func formControlGroup(controls ...Node) Node {
44+
g := make(Group, 0, len(controls))
45+
for _, control := range controls {
46+
g = append(g, Div(
47+
Class("control"),
48+
control,
49+
))
50+
}
51+
4352
return Div(
4453
Class("field is-grouped"),
45-
Div(
46-
Class("control"),
47-
Button(
48-
Class("button is-link"),
49-
Text(label),
50-
),
51-
),
54+
g,
5255
)
5356
}
5457

@@ -113,6 +116,7 @@ func formInput(el input) Node {
113116
ID(el.name),
114117
Name(el.name),
115118
Type(el.inputType),
119+
If(el.placeholder != "", Placeholder(el.placeholder)),
116120
Class("input "+formFieldStatusClass(el.form, el.formField)),
117121
Value(el.value),
118122
),

pkg/ui/forms.go

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ type (
1616
Message string `form:"message" validate:"required"`
1717
form.Submission
1818
}
19+
20+
LoginForm struct {
21+
Email string `form:"email" validate:"required,email"`
22+
Password string `form:"password" validate:"required"`
23+
form.Submission
24+
}
25+
26+
RegisterForm struct {
27+
Name string `form:"name" validate:"required"`
28+
Email string `form:"email" validate:"required,email"`
29+
Password string `form:"password" validate:"required"`
30+
ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"`
31+
form.Submission
32+
}
33+
34+
ForgotPasswordForm struct {
35+
Email string `form:"email" validate:"required,email"`
36+
form.Submission
37+
}
1938
)
2039

2140
func (f *ContactForm) render(r *request) Node {
@@ -50,7 +69,108 @@ func (f *ContactForm) render(r *request) Node {
5069
label: "Message",
5170
value: f.Message,
5271
}),
53-
formSubmit("Submit"),
72+
formControlGroup(
73+
button("is-link", "Submit"),
74+
),
75+
csrf(r),
76+
)
77+
}
78+
79+
func (f *LoginForm) render(r *request) Node {
80+
return Form(
81+
ID("login"),
82+
Method(http.MethodPost),
83+
Attr("hx-boost", "true"),
84+
Action(r.path(routenames.LoginSubmit)),
85+
flashMessages(r),
86+
formInput(input{
87+
form: f,
88+
formField: "Email",
89+
name: "email",
90+
inputType: "email",
91+
label: "Email address",
92+
value: f.Email,
93+
}),
94+
formInput(input{
95+
form: f,
96+
formField: "Password",
97+
name: "password",
98+
inputType: "password",
99+
label: "Password",
100+
placeholder: "******",
101+
}),
102+
formControlGroup(
103+
button("is-link", "Login"),
104+
buttonLink(r.path(routenames.Home), "is-light", "Cancel"),
105+
),
106+
csrf(r),
107+
)
108+
}
109+
110+
func (f *RegisterForm) render(r *request) Node {
111+
return Form(
112+
ID("register"),
113+
Method(http.MethodPost),
114+
Attr("hx-boost", "true"),
115+
Action(r.path(routenames.RegisterSubmit)),
116+
formInput(input{
117+
form: f,
118+
formField: "Name",
119+
name: "name",
120+
inputType: "text",
121+
label: "Name",
122+
value: f.Name,
123+
}),
124+
formInput(input{
125+
form: f,
126+
formField: "Email",
127+
name: "email",
128+
inputType: "email",
129+
label: "Email address",
130+
value: f.Email,
131+
}),
132+
formInput(input{
133+
form: f,
134+
formField: "Password",
135+
name: "password",
136+
inputType: "password",
137+
label: "Password",
138+
placeholder: "******",
139+
}),
140+
formInput(input{
141+
form: f,
142+
formField: "PasswordConfirm",
143+
name: "password-confirm",
144+
inputType: "password",
145+
label: "Confirm password",
146+
placeholder: "******",
147+
}),
148+
formControlGroup(
149+
button("is-primary", "Register"),
150+
buttonLink(r.path(routenames.Home), "is-light", "Cancel"),
151+
),
152+
csrf(r),
153+
)
154+
}
155+
156+
func (f *ForgotPasswordForm) render(r *request) Node {
157+
return Form(
158+
ID("forgot-password"),
159+
Method(http.MethodPost),
160+
Attr("hx-boost", "true"),
161+
Action(r.path(routenames.ForgotPasswordSubmit)),
162+
formInput(input{
163+
form: f,
164+
formField: "Email",
165+
name: "email",
166+
inputType: "email",
167+
label: "Email address",
168+
value: f.Email,
169+
}),
170+
formControlGroup(
171+
button("is-primary", "Reset password"),
172+
buttonLink(r.path(routenames.Home), "is-light", "Cancel"),
173+
),
54174
csrf(r),
55175
)
56176
}

0 commit comments

Comments
 (0)