156 lines
6.7 KiB
Markdown
156 lines
6.7 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
|
|
sia `http://localhost:4200` (usato da `scouthub-attivita-fe`) sia
|
|
`http://localhost:4201` (porta di default di questo progetto, vedi sotto) — 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
|
|
```
|