697b0d9ef29a6be53fee6d1551a7da32d7a438fc
One sign-in page for everyone. /login is the only entry point; the
short-lived /admin/login and /staff/login routes are gone, along with the
per-route branding that came with them. Admin, owner, manager and staff see
the same form, post the same {email, password} to the same
POST /api/auth/login, and are never asked to say who they are.
Where somebody lands is decided by the role the BACKEND returns, never by
the URL they arrived at:
owner, manager -> /dashboard
staff -> /floor
roleDestination is the single map, read by all three redirect paths - the
hydrated form, the no-JavaScript form POST, and GuestGuard. GuestGuard
raced the form to a hardcoded /dashboard, so a staff member landed in a
different place depending on which effect fired first; it now resolves
through the same map.
A platform admin authenticates correctly and still gets no session here.
Every surface in this console is tenant-scoped and an admin has no tenant
(auth.go: "ClientID empty means a platform admin"). Measured against a real
admin token: /api/sites 500, /api/visits 500, /api/visitors 500, /api/team
403 "This account does not belong to a company." So the BFF declines to set
the cookie rather than handing out a dashboard of server errors, revokes the
upstream session it will not use, and says so on /login through the existing
fixed-code table. Their surface is Companies in the platform's own web app,
which this console does not link to and does not hand a token - no session
handoff exists between the two, and inventing one would mean putting a
credential in a URL.
No enumeration is given up: a wrong password for an admin is answered
exactly like every other wrong password, so the "wrong console" message only
ever reaches somebody who has already proved they own the account.
Login visuals: the hero carousel now anchors each slide independently -
slide 1 (mascot with bag) to the bottom so the white bag clears the white
caption, slide 2 (selfie booth) to the top so the arch and wordmark are not
cropped by the rounded corner.
Unchanged: the BFF, the sealed httpOnly token cookie, the signed session
cookie, refresh, logout, route protection and the open-redirect guard on
?next=.
Verified against the live local platform with real accounts for all four
roles, plus wrong-password, unknown-email, empty-field, invalid-format and
inactive-user cases, session persistence, a forced token refresh, logout,
and two-tenant isolation.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0161AMotQ8FxGPZ9gFGb5wiK
This is a Next.js project bootstrapped with create-next-app.
Getting Started
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
Description
Languages
TypeScript
95.4%
CSS
2.9%
JavaScript
0.9%
Dockerfile
0.6%
Shell
0.2%