fix: convert auth flows from SSE to standard HTTP to fix session cookies
Some checks failed
CI / Deploy / test (pull_request) Successful in 33s
CI / Deploy / lint (pull_request) Failing after 38s
CI / Deploy / deploy (pull_request) Has been skipped

Datastar's NewSSE() flushes HTTP headers before SCS's session middleware
can attach the Set-Cookie header, so the session cookie never reaches the
browser after login/register/logout.

Convert login, register, and logout to standard HTML forms with HTTP
redirects, which lets SCS write cookies normally. Also fix return_url
capture on the login page (was never being stored in the session).

Add handler tests covering login, register, and logout flows.
This commit is contained in:
Ryan Hamamura
2026-03-11 10:10:28 -10:00
parent 8573e87bf6
commit 72d31fd143
7 changed files with 424 additions and 102 deletions

View File

@@ -1,45 +1,39 @@
package pages
import (
"github.com/ryanhamamura/games/features/common/layouts"
"github.com/starfederation/datastar-go/datastar"
)
import "github.com/ryanhamamura/games/features/common/layouts"
templ LoginPage() {
templ LoginPage(errorMsg string) {
@layouts.Base("Login") {
<main class="max-w-sm mx-auto mt-8 text-center" data-signals="{username: '', password: '', error: ''}">
<main class="max-w-sm mx-auto mt-8 text-center">
<h1 class="text-3xl font-bold">Login</h1>
<p class="mb-4">Sign in to your account</p>
<div data-show="$error != ''" class="alert alert-error mb-4" data-text="$error"></div>
<div>
if errorMsg != "" {
<div class="alert alert-error mb-4">{ errorMsg }</div>
}
<form method="POST" action="/auth/login">
<fieldset class="fieldset">
<label class="label" for="username">Username</label>
<input
class="input input-bordered w-full"
id="username"
name="username"
type="text"
placeholder="Enter your username"
data-bind="username"
data-on:keydown={ "evt.key === 'Enter' && " + datastar.PostSSE("/auth/login") }
autofocus
/>
autofocus
/>
<label class="label" for="password">Password</label>
<input
class="input input-bordered w-full"
id="password"
name="password"
type="password"
placeholder="Enter your password"
data-bind="password"
data-on:keydown={ "evt.key === 'Enter' && " + datastar.PostSSE("/auth/login") }
/>
</fieldset>
<button
class="btn btn-primary w-full"
data-on:click={ datastar.PostSSE("/auth/login") }
>
<button type="submit" class="btn btn-primary w-full">
Login
</button>
</div>
</form>
<p>
Don't have an account? <a class="link" href="/register">Register</a>
</p>

View File

@@ -1,54 +1,47 @@
package pages
import (
"github.com/ryanhamamura/games/features/common/layouts"
"github.com/starfederation/datastar-go/datastar"
)
import "github.com/ryanhamamura/games/features/common/layouts"
templ RegisterPage() {
templ RegisterPage(errorMsg string) {
@layouts.Base("Register") {
<main class="max-w-sm mx-auto mt-8 text-center" data-signals="{username: '', password: '', confirm: '', error: ''}">
<main class="max-w-sm mx-auto mt-8 text-center">
<h1 class="text-3xl font-bold">Register</h1>
<p class="mb-4">Create a new account</p>
<div data-show="$error != ''" class="alert alert-error mb-4" data-text="$error"></div>
<div>
if errorMsg != "" {
<div class="alert alert-error mb-4">{ errorMsg }</div>
}
<form method="POST" action="/auth/register">
<fieldset class="fieldset">
<label class="label" for="username">Username</label>
<input
class="input input-bordered w-full"
id="username"
name="username"
type="text"
placeholder="Choose a username"
data-bind="username"
data-on:keydown={ "evt.key === 'Enter' && " + datastar.PostSSE("/auth/register") }
autofocus
/>
autofocus
/>
<label class="label" for="password">Password</label>
<input
class="input input-bordered w-full"
id="password"
name="password"
type="password"
placeholder="Choose a password (min 8 chars)"
data-bind="password"
data-on:keydown={ "evt.key === 'Enter' && " + datastar.PostSSE("/auth/register") }
/>
/>
<label class="label" for="confirm">Confirm Password</label>
<input
class="input input-bordered w-full"
id="confirm"
name="confirm"
type="password"
placeholder="Confirm your password"
data-bind="confirm"
data-on:keydown={ "evt.key === 'Enter' && " + datastar.PostSSE("/auth/register") }
/>
</fieldset>
<button
class="btn btn-primary w-full"
data-on:click={ datastar.PostSSE("/auth/register") }
>
<button type="submit" class="btn btn-primary w-full">
Register
</button>
</div>
</form>
<p>
Already have an account? <a class="link" href="/login">Login</a>
</p>