Compare commits

...

3 Commits

Author SHA1 Message Date
Flea Flicker 85294b108d fix: add skipWaiting/clientsClaim to VitePWA workbox config
CI / Test (pull_request) Successful in 13s
CI / Lint & Typecheck (pull_request) Successful in 25s
CI / Build & Push Docker Image (pull_request) Successful in 50s
Root cause: SW remained in waiting phase after redeploy, serving stale
precached assets. Without skipWaiting/clientsClaim the old SW persisted
and controlled the page even after a new SW was installed.

Fixes blank-page regression where React never mounted on login.
2026-05-27 02:20:41 +00:00
Flea Flicker 4213c1f2e7 docs(UAT_PLAYBOOK.md): add TC-WEB-SSO-ROLE-* test cases for GRO-1822
CI / Test (pull_request) Successful in 15s
CI / Lint & Typecheck (pull_request) Successful in 17s
CI / Build & Push Docker Image (pull_request) Successful in 34s
Add section 5.4.3 covering role-based redirect after SSO login:
- Customer SSO → portal at / (not redirected to /admin)
- Staff SSO → redirect to /admin
- Impersonation bypass via ?sessionId= preserved
- Dev mode unaffected

Refs: GRO-1822
2026-05-27 00:54:07 +00:00
Flea Flicker 505904d8bd fix(App.tsx): check user role before redirecting to /admin
CI / Test (pull_request) Successful in 22s
CI / Lint & Typecheck (pull_request) Successful in 26s
CI / Build & Push Docker Image (pull_request) Successful in 45s
- Staff users (role !== "customer") continue to redirect to /admin
- Customer users (role === "customer") see the portal at / instead
- Impersonation flow via ?sessionId= remains unaffected
- Dev mode (authDisabled=true) unchanged

Refs: GRO-1822
2026-05-27 00:53:16 +00:00
3 changed files with 14 additions and 2 deletions
+9
View File
@@ -98,6 +98,15 @@ export const { signIn, signOut, useSession, changePassword } = authClient;
| TC-WEB-OOBE-4 | Admin panel accessible after setup | After completing OOBE, navigate to admin panel | Admin features accessible | 403 on admin panel, insufficient permissions |
| TC-WEB-OOBE-5 | SSO login during OOBE does not interfere | During fresh OOBE, attempt SSO login before completing setup | SSO login redirected appropriately, setup can still complete | Auto-provision creates staff prematurely, setup flow broken |
### 5.4.3 Role-Based Redirect After SSO Login (GRO-1822)
| # | Scenario | Steps | Pass Criteria | Fail Criteria |
|---|----------|-------|---------------|---------------|
| TC-WEB-SSO-ROLE-1 | Customer SSO redirects to portal | Sign in via Authentik as a **customer** account, return to app root `/` | Customer portal is displayed at `/`; URL stays at `/` | Redirects to `/admin`, customer cannot access portal |
| TC-WEB-SSO-ROLE-2 | Staff SSO redirects to admin | Sign in via Authentik as a **staff** (groomer/manager/receptionist) account, return to app root `/` | Browser redirects to `/admin` | URL stays at `/`, staff cannot reach admin panel |
| TC-WEB-SSO-ROLE-3 | Impersonation bypasses role redirect | Append `?sessionId=<active-impersonation-id>` to any URL | Impersonation session activates; role redirect is skipped | Role redirect runs despite `?sessionId=`, impersonation blocked |
| TC-WEB-SSO-ROLE-4 | Dev mode unaffected | Set `AUTH_DISABLED=true`, load app, select a dev user | Dev login selector works; role redirect logic does not interfere | Dev login broken or redirected incorrectly |
### 5.5 Dashboard
| # | Scenario | Steps | Expected |
+3 -2
View File
@@ -386,9 +386,10 @@ export function App() {
return <Navigate to="/setup" replace />;
}
// Redirect authenticated users to /admin (but preserve impersonation flow via ?sessionId=)
// Redirect authenticated staff (non-customer) users to /admin (but preserve impersonation flow via ?sessionId=)
const searchParams = new URLSearchParams(location.search);
if (!authDisabled && session && !location.pathname.startsWith("/admin") && !searchParams.has("sessionId")) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Better Auth session.user extends Record<string,unknown>; role field is injected by Authentik OIDC
if (!authDisabled && session && (session as any)?.user?.role !== "customer" && !location.pathname.startsWith("/admin") && !searchParams.has("sessionId")) {
return <Navigate to="/admin" replace />;
}
+2
View File
@@ -39,6 +39,8 @@ export default defineConfig({
],
},
workbox: {
skipWaiting: true,
clientsClaim: true,
globPatterns: ["**/*.{js,css,html,ico,png,svg,woff2}"],
navigateFallbackDenylist: [
/^\/api\/auth\//,