# 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 ` 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 ```