From d5df743d8a1009680bdeeec7752cf00ad8095dc5 Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Fri, 6 Feb 2026 10:37:42 +0100 Subject: [PATCH] Onboarding: improve password flow (#27246) --- server/http_auth.go | 38 ++++++++++++++++++++++----------- tests/config-onboarding.spec.ts | 9 +------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/server/http_auth.go b/server/http_auth.go index 70090cb32..537f1bb14 100644 --- a/server/http_auth.go +++ b/server/http_auth.go @@ -55,6 +55,13 @@ func updatePasswordHandler(authObject auth.Auth) http.HandlerFunc { http.Error(w, err.Error(), http.StatusInternalServerError) return } + + // auto-login: set auth cookie + if err := setAuthCookie(authObject, w); err != nil { + http.Error(w, "Failed to generate JWT token.", http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusCreated) } } @@ -103,6 +110,24 @@ func authStatusHandler(authObject auth.Auth) http.HandlerFunc { } } +func setAuthCookie(authObject auth.Auth, w http.ResponseWriter) error { + lifetime := time.Hour * 24 * 90 // 90 day valid + tokenString, err := authObject.GenerateJwtToken(lifetime) + if err != nil { + return err + } + + http.SetCookie(w, &http.Cookie{ + Name: authCookieName, + Value: tokenString, + Path: "/", + HttpOnly: true, + Expires: time.Now().Add(lifetime), + SameSite: http.SameSiteStrictMode, + }) + return nil +} + func loginHandler(authObject auth.Auth) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if authObject.GetAuthMode() == auth.Locked { @@ -121,21 +146,10 @@ func loginHandler(authObject auth.Auth) http.HandlerFunc { return } - lifetime := time.Hour * 24 * 90 // 90 day valid - tokenString, err := authObject.GenerateJwtToken(lifetime) - if err != nil { + if err := setAuthCookie(authObject, w); err != nil { http.Error(w, "Failed to generate JWT token.", http.StatusInternalServerError) return } - - http.SetCookie(w, &http.Cookie{ - Name: authCookieName, - Value: tokenString, - Path: "/", - HttpOnly: true, - Expires: time.Now().Add(lifetime), - SameSite: http.SameSiteStrictMode, - }) } } diff --git a/tests/config-onboarding.spec.ts b/tests/config-onboarding.spec.ts index 74fd61ba1..c859513a3 100644 --- a/tests/config-onboarding.spec.ts +++ b/tests/config-onboarding.spec.ts @@ -29,14 +29,7 @@ test.describe("onboarding", async () => { await expect(page.locator("body")).toContainText("Hello aboard!"); await page.getByRole("link", { name: "Let's start configuration" }).click(); - // login - const login = page.getByTestId("login-modal"); - await expectModalVisible(login); - await login.getByLabel("Administrator Password").fill(PASSWORD); - await login.getByRole("button", { name: "Login" }).click(); - await expectModalHidden(login); - - // config page + // config page (already logged in from password creation) await expect(page.getByRole("heading", { name: "Configuration" })).toBeVisible(); await expect(page.getByTestId("welcome-banner")).toBeVisible(); await expect(page.getByTestId("welcome-banner")).toContainText("Start with creating a");