75 lines
2.9 KiB
Markdown
75 lines
2.9 KiB
Markdown
# SPQ Page Architecture & Auth Flow
|
|
|
|
## Page layout
|
|
|
|
```
|
|
/ (index.html) — login page (NO redirect — root lands here directly)
|
|
dashboard.html — main dashboard (auth-guarded: no user → redirects to /)
|
|
appointments.html, customers.html, repair-orders.html — sub-pages (auth-guarded)
|
|
```
|
|
|
|
## Why index.html = login page
|
|
|
|
When `index.html` was the dashboard and `login.html` was a separate page, stale/expired PocketBase tokens in localStorage caused an infinite redirect loop:
|
|
|
|
1. User visits `/` → `index.html` (dashboard) → `onAuthStateChanged` → SDK sees stale token as valid → stays
|
|
2. First PocketBase API call fails (401) → SDK clears auth → `onChange(null)` fires → redirect to `login.html`
|
|
3. `login.html` loads → SDK reads token from localStorage again (still there, client-side JWT expiry check says valid) → `onAuthStateChanged(user)` → redirect to `index.html`
|
|
4. Loop!
|
|
|
|
Making `index.html` the login page eliminates the bounce: unauthorized users see the login form directly, authorized users get one clean redirect to `dashboard.html`.
|
|
|
|
## Auth guard pattern (in every page JS)
|
|
|
|
```js
|
|
onAuthStateChanged(auth, (user) => {
|
|
if (user) {
|
|
// initialize page
|
|
} else {
|
|
window.location.href = 'index.html'; // redirect to login
|
|
}
|
|
});
|
|
```
|
|
|
|
**login.js** (login page):
|
|
```js
|
|
onAuthStateChanged(auth, (user) => {
|
|
if (user) {
|
|
window.location.href = 'dashboard.html'; // already logged in → dashboard
|
|
}
|
|
// If no user, stay on login page
|
|
});
|
|
```
|
|
|
|
## PocketBase auth flow
|
|
|
|
The `pocketbase.js` adapter:
|
|
- Creates PocketBase client pointed at `window.location.origin` (same-origin, through nginx `/api/` proxy)
|
|
- `onAuthStateChanged` fires initial state synchronously via `auth.currentUser` getter (reads from `pb.authStore`)
|
|
- Then registers `pb.authStore.onChange` for future changes
|
|
- `authStore` reads from localStorage key `pocketbase_auth`
|
|
|
|
## When renaming/moving pages
|
|
|
|
All references are relative (`dashboard.html`, not absolute paths). Files to update:
|
|
|
|
| File | What to change |
|
|
|------|---------------|
|
|
| `login.js` | Login success redirect → `dashboard.html` |
|
|
| `dashboard.js`, `main.js`, `appointments.js`, `customers.js`, `repair-orders.js` | Auth fail redirect → `index.html` |
|
|
| `shared/header-functionality.js` | Logout redirect → `index.html` |
|
|
| `index.html` (login page body) | Post-login redirects → `dashboard.html?cb=...` |
|
|
| `appointments.html`, `repair-orders.html`, `customers.html` | Nav links → `dashboard.html` |
|
|
| `dashboard.html` | Nav self-links → `dashboard.html` |
|
|
| `customers.js` | Quote links → `dashboard.html?quoteId=...` |
|
|
|
|
Total: ~28 references across 13 files.
|
|
|
|
## nginx note
|
|
|
|
Home nginx `server_name` must include the domain the VPS sends in `Host` header. If the VPS proxies `shopproquote.graj-media.com` with `Host: graj-media.com`, add it as an alias:
|
|
|
|
```
|
|
server_name grajmedia.duckdns.org graj-media.com shopproquote.graj-media.com;
|
|
```
|