From 260b87e9b75189131fde43ea974de520a59ff557 Mon Sep 17 00:00:00 2001 From: Sabine Maennel <5292683+sabinem@users.noreply.github.com> Date: Sat, 5 Sep 2026 07:31:13 +0200 Subject: [PATCH 1/4] feat(frontend): people can change their own password MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The header's monogram and name now link to a new /account page, whose one action hands the user to Keycloak's update-password screen and brings them back afterwards. Before this there was no way to change a password from Hackagon at all: the credential lives in Keycloak and nothing in the app pointed at it. No backend change, and none is possible — the Go service has no password surface (no credential RPC anywhere in api/proto, no Keycloak admin client), so this is an OIDC round trip rather than an RPC: kc_action=UPDATE_PASSWORD on the authorize URL, carried there by Auth.js's third signIn argument, which leaves state, nonce and PKCE to Auth.js. Success and Cancel both come back through the callback with a valid code, so there is no error path to handle — and no confirmation banner either, since Auth.js consumes kc_action_status before the page reloads and a banner shown regardless would congratulate someone who had cancelled. Self-service reset stays impossible: the realm sets resetPasswordAllowed false because smtpServer is empty. The page says so plainly rather than leaving a locked-out user to guess. --- .../src/lib/components/layout/NavBar.svelte | 32 ++++++- .../src/lib/components/layout/NavBar.test.ts | 24 +++++ .../frontend/src/lib/utils/account.test.ts | 47 ++++++++++ components/frontend/src/lib/utils/account.ts | 47 ++++++++++ .../src/routes/(app)/account/+page.svelte | 92 +++++++++++++++++++ 5 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 components/frontend/src/lib/utils/account.test.ts create mode 100644 components/frontend/src/lib/utils/account.ts create mode 100644 components/frontend/src/routes/(app)/account/+page.svelte diff --git a/components/frontend/src/lib/components/layout/NavBar.svelte b/components/frontend/src/lib/components/layout/NavBar.svelte index 02d91dd2..9c148f8b 100644 --- a/components/frontend/src/lib/components/layout/NavBar.svelte +++ b/components/frontend/src/lib/components/layout/NavBar.svelte @@ -10,7 +10,11 @@ import { safeReturnTo } from '$lib/utils/returnTo'; // The header carries identity, theme and sign-out — no administration entry. - // That moved to the dashboard's Manage platform section, which is the single + // Identity doubles as the way to the account page: the monogram and name link + // there rather than the bar growing a third control. Clicking your own name is + // where people already look for it, and it is what keeps the bar inside 320px + // and keeps a rare action from sitting beside a common one. + // Administration moved to the dashboard's Manage platform section, the single // place the platform pages are offered from. The trade is deliberate: from // inside a hackathon an admin now returns to the dashboard first, via the // wordmark, rather than jumping straight there from the header — on a phone @@ -65,6 +69,8 @@ $page.url.pathname === '/' || $page.url.pathname.startsWith('/dashboard') ); + const onAccount = $derived($page.url.pathname.startsWith('/account')); + // The row vocabulary is SidebarNavSection's, so the two navigations read as // one system rather than drifting into separate dialects of the same idea. const ROW = @@ -161,18 +167,26 @@ -
+ + + Your account -
+ + + + +

+ Forgotten your password? There is no self-service reset yet — ask a platform + administrator to set a new one for you. +

+ + From af846fbc2fe2b755a1ff7f246cb96aaf44434fba Mon Sep 17 00:00:00 2001 From: Sabine Maennel <5292683+sabinem@users.noreply.github.com> Date: Fri, 11 Sep 2026 06:33:14 +0200 Subject: [PATCH 2/4] docs(frontend): record why the password page needs no Keycloak change Two comments, no code. The first says that UPDATE_PASSWORD being enabled on the realm already is precisely why this page needed no realm change. The fact was in the comment; the consequence was not, and it is the thing a reviewer asks about first. The second records who may set a new password for somebody locked out, and why it is deliberately nobody else: a Keycloak credential is platform-wide while a casbin role is per-hackathon, so a hackathon owner's reset could not be contained to their own event. --- components/frontend/src/lib/utils/account.ts | 8 +++++--- .../frontend/src/routes/(app)/account/+page.svelte | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/components/frontend/src/lib/utils/account.ts b/components/frontend/src/lib/utils/account.ts index 7cac6f73..d2d136bb 100644 --- a/components/frontend/src/lib/utils/account.ts +++ b/components/frontend/src/lib/utils/account.ts @@ -23,9 +23,11 @@ import { signIn } from "@auth/sveltekit/client" /** * Keycloak's application-initiated action for setting a new password. Enabled - * as a required action on the realm, which is the precondition Keycloak checks - * before honouring it — with it disabled, Keycloak logs a warning and ignores - * the parameter, and the user would land on a plain sign-in instead. + * as a required action on the realm already, which is the precondition Keycloak + * checks before honouring it — with it disabled, Keycloak logs a warning and + * ignores the parameter, and the user would land on a plain sign-in instead. + * + * That it is already enabled is why this page needs no Keycloak change at all. */ export const UPDATE_PASSWORD_ACTION = "UPDATE_PASSWORD" diff --git a/components/frontend/src/routes/(app)/account/+page.svelte b/components/frontend/src/routes/(app)/account/+page.svelte index 4ffe4514..ca3868cd 100644 --- a/components/frontend/src/routes/(app)/account/+page.svelte +++ b/components/frontend/src/routes/(app)/account/+page.svelte @@ -81,9 +81,13 @@ - +

Forgotten your password? There is no self-service reset yet — ask a platform administrator to set a new one for you. From 80ee8149c253b3fb1dc91b7a8f37d2812ef06925 Mon Sep 17 00:00:00 2001 From: Sabine Maennel <5292683+sabinem@users.noreply.github.com> Date: Fri, 11 Sep 2026 07:35:52 +0200 Subject: [PATCH 3/4] chore: update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55b6ff33..26b1689c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,12 @@ written while it was being built. See [RELEASING.md](RELEASING.md). ### Added +- You can now change your own password. Your name in the top right opens a new + Account page, whose Change password button takes you to the sign-in service + and brings you back. It asks you to sign in once more on the way, which is + what proves it is you. Forgetting a password is still not self-service, so + the page says to ask a platform administrator instead. + ### Changed - Following an invitation link into a private hackathon now admits you straight From a100a64781133c001e6bd6ac863a94546d4c5a36 Mon Sep 17 00:00:00 2001 From: Sabine Maennel <5292683+sabinem@users.noreply.github.com> Date: Fri, 11 Sep 2026 07:43:18 +0200 Subject: [PATCH 4/4] chore: format changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26b1689c..e7432aaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,8 +21,8 @@ written while it was being built. See [RELEASING.md](RELEASING.md). - You can now change your own password. Your name in the top right opens a new Account page, whose Change password button takes you to the sign-in service and brings you back. It asks you to sign in once more on the way, which is - what proves it is you. Forgetting a password is still not self-service, so - the page says to ask a platform administrator instead. + what proves it is you. Forgetting a password is still not self-service, so the + page says to ask a platform administrator instead. ### Changed