← All tests

R4.2 — Impersonation E2E PROD

2026-04-29 on prod. Admin-initiated tenant_user impersonation, end-to-end across 5 repos. NIX support clicks "Sign in as" on a tenant user in Cpanel → backend issues a 30-min JWT with an imp claim referencing a new commerce.impersonation_sessions row, sets the shared nix_session cookie on .nixtech.app, returns a redirect URL → admin lands on the tenant subdomain authenticated as the target user, with a sticky amber banner on top of every authed page (Cafe, Commerce, Outdoor) carrying their admin email + an "End impersonation" button. Tenant-side end and admin-side revoke both mark the row ended_at + ended_by, after which the cookie's JWT no longer authenticates anywhere.

9/9 R4.2 prod checks passed.

All R4.2 prod checks (9)

Cafe dashboard with impersonation bannerSticky amber banner at the top of every authed Cafe page during impersonation. Carries the admin email + "End impersonation" button posting to /cafe/api/auth/end-impersonation (which proxies to the backend and clears the cookie).
99/99 total prod tests green — no regressions from this push.
test-r4-2-prod.mjs (NEW)9/9
test-r4-1-prod.mjs9/9
test-phase1-prod.mjs11/11
test-receipt-preview-prod.mjs6/6
test-r2-followups3-prod.mjs7/7
test-r2-followups2-prod.mjs11/11
test-r2-followups-prod.mjs19/19
test-nix-os-r2-4b-prod.mjs12/12
test-nix-os-70-2-prod.mjs10/10
test-cafe-followups-prod.mjs5/5

What's new — code surface (5 repos)

nix-outdoor-sales-backend @ ac9ac06:
  migrations/20260429200000_commerce_impersonation_sessions.ts
  migrate.js                                       — idempotent entry, ran against
                                                     prod Supabase pre-test (created table)
  src/admin/impersonation.service.ts               — start/end/revoke/list/findActive
  src/admin/impersonation.route.ts                 — POST /admin/tenants/:t/users/:u/impersonate
                                                     GET  /admin/impersonations/active
                                                     DELETE /admin/impersonations/:id
  src/tenant/tenant.auth.route.ts                  — POST /tenant/auth/end-impersonation
                                                     /me response surfaces impersonation
  src/tenant/tenant.auth.middleware.ts             — validates imp claim on every request
  src/authentication/auth.middleware.ts            — Outdoor's middleware does the same
                                                     for /outdoor/* routes
  src/authentication/auth.route.ts                 — /auth/me surfaces impersonation
  src/app.ts                                       — mounts admin impersonation router

nix-cafe @ 40a2154:
  lib/db/schema.ts                                 — Drizzle schema for the new table
  lib/auth.ts                                      — auth() validates session row,
                                                     exposes session.user.impersonation
  components/impersonation-banner.tsx              — server component, sticky amber bar
  app/api/auth/end-impersonation/route.ts          — Next API route forwards form POST
                                                     to backend (cross-origin form workaround)
  app/(authed)/layout.tsx                          — renders banner when impersonating

nix-commerce @ fc86998:
  src/stores/auth.js                               — ssoCookie mode + probeSsoCookie + impersonation
  src/main.js                                      — probes cookie before app mount so admin
                                                     lands here without localStorage tokens
  src/App.vue                                      — banner mounted at root
  src/components/ImpersonationBanner.vue           — Vue version of the banner

nix-outdoor-sales-frontend @ 176a7c0:
  src/stores/authStore.js                          — already had ssoCookie; gained impersonation
  src/layout/AppLayout.vue                         — banner mounted above layout-wrapper
  src/components/ImpersonationBanner.vue           — Vue banner

nix-outdoor-sales-admin @ b6b647c (Cpanel):
  src/api/client.js                                — startImpersonation (withCredentials so
                                                     browser accepts cross-origin Set-Cookie)
                                                     + listActive + revoke helpers
  src/views/TenantDetailView.vue                   — "Sign in as" button per user row;
                                                     opens redirectUrl in a new tab
  src/views/ActiveImpersonationsView.vue           — NEW — live sessions table + revoke
                                                     with 30s auto-refresh
  src/router/index.js                              — /impersonations route
  src/layouts/AdminLayout.vue                      — sidebar entry under Support

D:/NIX Software/:
  test-r4-2-prod.mjs                               — NEW E2E (9 checks)

R4 sub-phase status

R4.1 ─ Multi-shop activation E2E              ✓ shipped (2026-04-29)
R4.x ─ Carried-forward follow-ups bundle      ✓ shipped (2026-04-29)
R4.2 ─ Impersonation                           ✓ shipped (2026-04-29)
R4.3 ─ Per-product usage endpoint              pending (next)
R4.4 ─ Drop legacy tenant_limits/plan_code     pending (last)