Reviewed-on: #20 Co-authored-by: Patrick Müller <mail@pmueller.me> Co-committed-by: Patrick Müller <mail@pmueller.me>
This commit was merged in pull request #20.
This commit is contained in:
@@ -17,9 +17,35 @@ No linter is configured in this project.
|
||||
|
||||
Angular 18 single-page app for managing calendar events for the "Nachklang" organization. Uses Angular Material for UI, RxJS for async data, and reactive forms. No NgRx — state lives in component local variables.
|
||||
|
||||
**Environments:**
|
||||
- Dev: `http://localhost:3000` (expects backend running locally)
|
||||
- Prod: `https://api.nachklang.art`
|
||||
**Environments** (`src/environments/`): `apiUrl` and `adminAppUrl`.
|
||||
- Dev: `http://localhost:3000` (expects backend running locally) / `http://localhost:3002`
|
||||
- Prod: `https://api.nachklang.art` / `https://admin.nachklang.art`
|
||||
|
||||
## Authentication
|
||||
|
||||
**This app has no login form and no accounts of its own.** Since the auth cutover
|
||||
(`docs/calendar-auth-migration.md` in the API repo) it shares one identity with the tickets,
|
||||
feedback and admin apps: accounts live in the admin app, and the session is an httpOnly
|
||||
cookie on `.nachklang.art` that the *API's* host sets. Consequences that cannot be designed
|
||||
around:
|
||||
|
||||
- `withCredentials: true` is mandatory on every call (`api.service.ts` sets it once). Without
|
||||
it the browser sends no cookie and the API answers 401.
|
||||
- This app can never read or verify the session. It calls `GET /admin/me` and believes the
|
||||
answer; the API's `requireAppAccess('calendar')` is the actual gate.
|
||||
- 401 and 403 mean different things and must not be collapsed. 401 means "nobody is signed
|
||||
in" and is the only one worth redirecting to the login page - redirecting on 403 produces a
|
||||
loop where signing in succeeds and lands straight back on the refusal. See `failure` in
|
||||
`admin.component.ts`.
|
||||
- Sign-out ends the session for *all four* apps; there is only one.
|
||||
|
||||
The dev server must be reachable at a port the API trusts. `ng serve` defaults to 4200, which
|
||||
is in better-auth's dev `localhostOrigins` and in the admin app's
|
||||
`NEXT_PUBLIC_ALLOWED_REDIRECT_ORIGINS`; another port fails sign-out and the return redirect,
|
||||
not the sign-in.
|
||||
|
||||
**The public calendar stays anonymous.** `GET /calendar/events/public/json` needs no session
|
||||
at all, because nachklang.art reads it to show the next upcoming event.
|
||||
|
||||
**Routing** (`app.routing.ts`):
|
||||
- `/` → `LandingpageComponent`
|
||||
@@ -27,8 +53,9 @@ Angular 18 single-page app for managing calendar events for the "Nachklang" orga
|
||||
- `**` → `NotfoundComponent`
|
||||
|
||||
**Service layer** (`src/app/services/`):
|
||||
- `api.service.ts` — all HTTP calls to the backend REST API; session credentials are passed as query params (`sessionId`, `sessionKey`)
|
||||
- `utils.service.ts` — localStorage helpers for persisting session and user data
|
||||
- `api.service.ts` — all HTTP calls to the backend REST API; carries the session cookie via `withCredentials`, holds no credential itself
|
||||
- `admin-auth.service.ts` — where signing in happens: the admin app's login URL (with a `?redirect=` back here) and sign-out
|
||||
- `utils.service.ts` — caches the signed-in user's display name for unsaved draft rows. Cosmetic only; the server takes the author from the session
|
||||
|
||||
**Data models** (`src/app/models/`): `Event`, `User`, `Session`
|
||||
|
||||
@@ -36,4 +63,10 @@ Angular 18 single-page app for managing calendar events for the "Nachklang" orga
|
||||
|
||||
**Calendar-specific behavior:** Birthday calendar auto-sets recurrence to YEARLY. Events have a `status` field (`DRAFT` / `DELETED`).
|
||||
|
||||
**Session lifecycle:** `checkSession()` is called on `AdminComponent` init; on failure it redirects to `/`.
|
||||
**Session lifecycle:** `AdminComponent` calls `me()` on init. 401 redirects to the admin app's
|
||||
login carrying this URL as the return target; 403 (or a signed-in account without the
|
||||
`calendar` permission) shows a refusal with Reload/Sign out; anything else shows "cannot be
|
||||
reached". None of those three redirect, on purpose.
|
||||
|
||||
**Dead since the cutover:** the unrouted `LoginComponent`. `src/app/models/session.ts` is
|
||||
gone; there is no session type here any more, because this app never handles one.
|
||||
|
||||
Reference in New Issue
Block a user