Files

157 lines
6.8 KiB
Markdown

# scouthub-home-fe
Frontend Angular per la gestione organizzativa di Scouthub (creazione gruppi, inviti),
affianca `scouthub-attivita-fe` nello stesso ecosistema. Parla con `scouthub-home-be`
per le API e con Keycloak per l'autenticazione.
Generato con Angular CLI 22.0.7 (vedi output `ng version` più sotto), componenti
standalone (nessun NgModule) e routing con lazy loading per feature.
## Stato del progetto
Implementati: modulo core di autenticazione (login OIDC via Keycloak, contesto
organizzazione, guard di routing), feature `crea-gruppo` (form di creazione gruppo
scout) e feature `inviti` (accettazione di un invito via link pubblico). Il tema
Angular Material è configurato. Non c'è ancora una vera home/dashboard applicativa
(il redirect post-successo va su `/`, che al momento non ha un componente associato).
## Struttura cartelle
```
src/app/
core/ servizi condivisi
auth/
keycloak.provider.ts provideKeycloakAngular() — login OIDC Authorization Code + PKCE
auth.guard.ts authGuard — richiede login, poi organization (non usato in routing
al momento: nessuna rotta protetta è ancora stata definita)
organization-context.service.ts OrganizationContextService — legge il claim "organization" dal token
crea-gruppo/ feature "crea gruppo scout" (/crea-gruppo, lazy-loaded, pubblica: è la
destinazione di chi è autenticato ma senza organization)
inviti/ feature "accetta invito" (/inviti/:token, lazy-loaded, pubblica: un invito
deve essere visualizzabile anche da chi non ha ancora un account)
src/environments/ environment.ts / environment.development.ts
public/
silent-check-sso.html richiesto dal flusso check-sso silenzioso di Keycloak
```
### Modulo di autenticazione
- **Login**: `provideKeycloak` (in `keycloak.provider.ts`) usa il client pubblico
`scouthub-frontend` con Authorization Code Flow + PKCE (comportamento di default di
`keycloak-js` per i public client con `standardFlowEnabled: true`), `onLoad: 'check-sso'`
e refresh automatico del token via `withAutoRefreshToken`.
- **OrganizationContextService** (`core/organization-context.service.ts`): espone
`hasOrganization` / `currentOrganizationId` / `currentOrganizationName` come `Observable`,
derivati dal claim `organization` del token (client scope built-in di Keycloak
Organizations). Se l'utente appartiene a più Organization, la scelta è già stata fatta
da Keycloak durante il login: la SPA vede sempre una sola membership nel token.
- **authGuard** (`core/auth/auth.guard.ts`): se non autenticato avvia `keycloak.login()`;
se autenticato ma senza organization reindirizza a `/crea-gruppo`; altrimenti lascia
proseguire. Non è ancora applicato a nessuna rotta (`crea-gruppo` e `inviti/:token`
sono entrambe pubbliche per costruzione): va aggiunto quando saranno introdotte
rotte riservate a chi ha già una organization.
### Feature `crea-gruppo` (`/crea-gruppo`)
Form a singolo campo ("Nome del gruppo scout", 3-100 caratteri) che chiama
`POST {orgServiceApiBaseUrl}/gruppi`. Un 409 (nome già esistente) mostra il messaggio
del backend e permette di correggere il nome senza reload. Al successo, forza un
refresh del token (`keycloak.updateToken(-1)`, incondizionato: il token corrente non
contiene ancora il nuovo claim `organization`) e poi naviga a `/`.
### Feature `inviti` (`/inviti/:token`)
Rotta pubblica (nessuna autenticazione richiesta per visualizzarla). Al caricamento
chiama `GET {orgServiceApiBaseUrl}/inviti/:token` (endpoint pubblico) e mostra nome
gruppo, ruolo offerto e validità. Se l'invito non è valido (scaduto o già accettato)
non mostra alcuna azione. Se valido, il pulsante "Accetta invito":
- se l'utente non è autenticato, avvia `keycloak.login({ redirectUri: window.location.href })`
— dopo login/registrazione l'utente torna sulla stessa pagina di invito;
- se autenticato, chiama `POST {orgServiceApiBaseUrl}/inviti/:token/accetta`, forza il
refresh del token e naviga a `/`. Errori (409 già accettato, 410 scaduto, 403 email
non corrispondente) mostrano un messaggio dedicato senza reload.
## Prerequisiti
- Node.js 20+
- I servizi dell'ecosistema Scouthub in esecuzione: Keycloak e `scouthub-home-be`
(vedi `docker-compose.yml` e `scouthub-home-be/README.md` nella root del repo)
## Configurazione ambiente
`src/environments/environment.ts` (produzione) e `environment.development.ts` (dev,
usato automaticamente da `ng serve`/`ng build --configuration development`)
espongono:
- `keycloakBaseUrl` — URL base dell'istanza Keycloak (default `http://localhost:8081`,
coerente con `KEYCLOAK_PORT` in `.env` alla root del repo)
- `keycloakRealm` — realm Keycloak (`scouthub`)
- `keycloakClientId` — client pubblico già definito in `keycloak/realm-export.json`
(`scouthub-frontend`)
- `orgServiceApiBaseUrl` — URL base di `scouthub-home-be` (default `http://localhost:8082`)
## Collegare Keycloak in locale
1. Avviare Keycloak (e Postgres) dalla root del repo:
```bash
docker compose up -d keycloak-db keycloak
```
Il realm `scouthub` viene importato automaticamente da `keycloak/realm-export.json`
al primo avvio (`--import-realm`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` che includono
`http://localhost:4200` (usato da `scouthub-attivita-fe`), `http://localhost:4201`
(porta di default di questo progetto, vedi sotto) e le porte di
`scouthub-magazzino-fe`/`scouthub-eventi-fe` — il client è ora condiviso da tutti
e quattro i frontend. Se si cambia porta, aggiornare `keycloak/realm-export.json`
di conseguenza e reimportare il realm (o aggiornarlo da console admin Keycloak).
3. `provideKeycloakAngular()` (`src/app/core/auth/keycloak.provider.ts`) inizializza
il client con `onLoad: 'check-sso'`: all'avvio l'app verifica in un iframe nascosto
se esiste già una sessione Keycloak, senza forzare un redirect immediato per le
pagine pubbliche.
## Collegare scouthub-home-be in locale
1. Avviare `scouthub-home-be` seguendo il suo README (`npm run dev`, porta di default
`8082`).
2. Le richieste verso `orgServiceApiBaseUrl` ricevono automaticamente l'header
`Authorization: Bearer <token>` tramite l'interceptor `includeBearerTokenInterceptor`
di `keycloak-angular`, configurato in `app.config.ts`.
## Development server
Questo progetto usa la porta `4201` (per non collidere con `scouthub-attivita-fe`,
che gira sulla `4200`):
```bash
ng serve
```
Apri il browser su `http://localhost:4201/`.
## Build
```bash
ng build
```
Artefatti di build in `dist/scouthub-home-fe`.
## Test
```bash
ng test
```
Esegue gli unit test con Vitest.
## Versione Angular CLI usata per lo scaffold
```
Angular CLI : 22.0.7
Angular : 22.0.8
Node.js : 24.16.0
Package Manager : npm 11.12.0
Operating System : win32 x64
```