Compare commits
3
Commits
91f404ac96
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66bb936dce | ||
|
|
fb5423f625 | ||
|
|
549aef4917 |
+18
-3
@@ -30,13 +30,28 @@ ATTIVITA_BACKEND_PORT=8001
|
||||
MAGAZZINO_BACKEND_PORT=8002
|
||||
EVENTI_BACKEND_PORT=8003
|
||||
|
||||
# Deve coincidere con il secret del client "scouthub-home-be" in keycloak/realm-export.json
|
||||
# URL pubbliche dei servizi, cosi' come raggiungibili dal browser (e da Keycloak per i redirect
|
||||
# OIDC). Di default puntano a localhost sulle porte sopra, per lo sviluppo locale. Quando lo
|
||||
# stack va in produzione dietro un reverse proxy (es. Caddy) con dominio pubblico, sovrascrivere
|
||||
# ognuna con l'URL reale, senza porta (es. https://home.tuodominio.it) - vedi Caddyfile.example
|
||||
# in root per un setup di riferimento con un sottodominio per servizio.
|
||||
KEYCLOAK_PUBLIC_URL=http://localhost:6999
|
||||
HOME_FE_PUBLIC_URL=http://localhost:7000
|
||||
ATTIVITA_FE_PUBLIC_URL=http://localhost:7001
|
||||
MAGAZZINO_FE_PUBLIC_URL=http://localhost:7002
|
||||
EVENTI_FE_PUBLIC_URL=http://localhost:7003
|
||||
HOME_BE_PUBLIC_URL=http://localhost:8000
|
||||
ATTIVITA_BE_PUBLIC_URL=http://localhost:8001
|
||||
MAGAZZINO_BE_PUBLIC_URL=http://localhost:8002
|
||||
EVENTI_BE_PUBLIC_URL=http://localhost:8003
|
||||
|
||||
# Deve coincidere con il secret del client "scouthub-home-be" in keycloak/realm-export.template.json
|
||||
KEYCLOAK_ORG_SERVICE_CLIENT_SECRET=change_me
|
||||
|
||||
# Deve coincidere con il secret del client "scouthub-magazzino-be" in keycloak/realm-export.json
|
||||
# Deve coincidere con il secret del client "scouthub-magazzino-be" in keycloak/realm-export.template.json
|
||||
KEYCLOAK_MAGAZZINO_CLIENT_SECRET=change_me
|
||||
|
||||
# Deve coincidere con il secret del client "scouthub-eventi-be" in keycloak/realm-export.json
|
||||
# Deve coincidere con il secret del client "scouthub-eventi-be" in keycloak/realm-export.template.json
|
||||
# (secret condiviso anche con scouthub-attivita-be e scouthub-magazzino-be, che lo usano per
|
||||
# chiamare POST /eventi/:id/risorse su scouthub-eventi-be)
|
||||
KEYCLOAK_EVENTI_CLIENT_SECRET=change_me
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Deploy stack su Proxmox
|
||||
|
||||
# Deploy automatico dell'intero stack docker-compose sul CT Proxmox dedicato al
|
||||
# deploy. Il runner Gitea gira su un CT diverso: la connessione avviene via SSH.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Deploy via SSH (git pull + docker compose up -d --build)
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.DEPLOY_HOST }}
|
||||
port: ${{ secrets.DEPLOY_PORT }}
|
||||
username: ${{ secrets.DEPLOY_USER }}
|
||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
script: |
|
||||
set -e
|
||||
cd "${{ secrets.DEPLOY_PATH }}"
|
||||
git fetch origin master
|
||||
git reset --hard origin/master
|
||||
docker compose up -d --build --remove-orphans
|
||||
docker image prune -f
|
||||
+43
-21
@@ -25,7 +25,7 @@ services:
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
PORT: ${ATTIVITA_BACKEND_PORT}
|
||||
CORS_ORIGIN: http://localhost:${ATTIVITA_FRONTEND_PORT}
|
||||
CORS_ORIGIN: ${ATTIVITA_FE_PUBLIC_URL}
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/scouthub?schema=public
|
||||
KEYCLOAK_BASE_URL: http://keycloak:8080
|
||||
KEYCLOAK_REALM: scouthub
|
||||
@@ -41,8 +41,8 @@ services:
|
||||
build:
|
||||
context: ./scouthub-attivita-fe
|
||||
args:
|
||||
API_URL: http://localhost:${ATTIVITA_BACKEND_PORT}
|
||||
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
|
||||
API_URL: ${ATTIVITA_BE_PUBLIC_URL}
|
||||
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${ATTIVITA_FRONTEND_PORT}:80"
|
||||
@@ -56,7 +56,7 @@ services:
|
||||
environment:
|
||||
PORT: ${HOME_BACKEND_PORT}
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
|
||||
FRONTEND_BASE_URL: http://localhost:${HOME_FRONTEND_PORT}
|
||||
FRONTEND_BASE_URL: ${HOME_FE_PUBLIC_URL}
|
||||
# Rete interna Docker: la validazione del JWT (JWKS) non controlla l'issuer,
|
||||
# quindi non serve che coincida con l'hostname visto dal browser (localhost:8081).
|
||||
KEYCLOAK_BASE_URL: http://keycloak:8080
|
||||
@@ -75,11 +75,11 @@ services:
|
||||
build:
|
||||
context: ./scouthub-home-fe
|
||||
args:
|
||||
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
|
||||
ORG_SERVICE_API_BASE_URL: http://localhost:${HOME_BACKEND_PORT}
|
||||
ATTIVITA_FE_BASE_URL: http://localhost:${ATTIVITA_FRONTEND_PORT}
|
||||
MAGAZZINO_FE_BASE_URL: http://localhost:${MAGAZZINO_FRONTEND_PORT}
|
||||
EVENTI_FE_BASE_URL: http://localhost:${EVENTI_FRONTEND_PORT}
|
||||
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
|
||||
ORG_SERVICE_API_BASE_URL: ${HOME_BE_PUBLIC_URL}
|
||||
ATTIVITA_FE_BASE_URL: ${ATTIVITA_FE_PUBLIC_URL}
|
||||
MAGAZZINO_FE_BASE_URL: ${MAGAZZINO_FE_PUBLIC_URL}
|
||||
EVENTI_FE_BASE_URL: ${EVENTI_FE_PUBLIC_URL}
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${HOME_FRONTEND_PORT}:80"
|
||||
@@ -109,8 +109,8 @@ services:
|
||||
build:
|
||||
context: ./scouthub-magazzino-fe
|
||||
args:
|
||||
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
|
||||
MAGAZZINO_API_BASE_URL: http://localhost:${MAGAZZINO_BACKEND_PORT}
|
||||
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
|
||||
MAGAZZINO_API_BASE_URL: ${MAGAZZINO_BE_PUBLIC_URL}
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${MAGAZZINO_FRONTEND_PORT}:80"
|
||||
@@ -141,8 +141,8 @@ services:
|
||||
build:
|
||||
context: ./scouthub-eventi-fe
|
||||
args:
|
||||
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
|
||||
EVENTI_API_BASE_URL: http://localhost:${EVENTI_BACKEND_PORT}
|
||||
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
|
||||
EVENTI_API_BASE_URL: ${EVENTI_BE_PUBLIC_URL}
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${EVENTI_FRONTEND_PORT}:80"
|
||||
@@ -159,13 +159,27 @@ services:
|
||||
volumes:
|
||||
- scouthub_keycloak_db_data:/var/lib/postgresql/data
|
||||
|
||||
keycloak-realm-render:
|
||||
image: alpine:3.20
|
||||
restart: "no"
|
||||
entrypoint: ["sh", "/render-realm-template.sh"]
|
||||
environment:
|
||||
HOME_FE_URL: ${HOME_FE_PUBLIC_URL}
|
||||
ATTIVITA_FE_URL: ${ATTIVITA_FE_PUBLIC_URL}
|
||||
MAGAZZINO_FE_URL: ${MAGAZZINO_FE_PUBLIC_URL}
|
||||
EVENTI_FE_URL: ${EVENTI_FE_PUBLIC_URL}
|
||||
volumes:
|
||||
- ./keycloak/realm-export.template.json:/template/realm-export.template.json:ro
|
||||
- ./keycloak/render-realm-template.sh:/render-realm-template.sh:ro
|
||||
- scouthub_keycloak_realm:/rendered
|
||||
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:26.7
|
||||
restart: unless-stopped
|
||||
# --import-realm importa keycloak/realm-export.json solo se il realm non esiste già.
|
||||
# Le correzioni post-import (ruoli service account, protocol mapper "organization") non
|
||||
# coperte dal file JSON sono automatizzate dal servizio one-shot "keycloak-init" sotto,
|
||||
# non più manuali (vedi CLAUDE.md).
|
||||
# --import-realm importa il realm-export.json generato da keycloak-realm-render (a partire
|
||||
# dal template) solo se il realm non esiste già. Le correzioni post-import (ruoli service
|
||||
# account, protocol mapper "organization") non coperte dal file JSON sono automatizzate dal
|
||||
# servizio one-shot "keycloak-init" sotto, non più manuali (vedi CLAUDE.md).
|
||||
command: start-dev --import-realm --health-enabled=true
|
||||
environment:
|
||||
KC_DB: postgres
|
||||
@@ -178,16 +192,23 @@ services:
|
||||
# Verificare con `kc.sh show-config` che i flag richiesti siano invariati nella versione
|
||||
# effettivamente usata: i nomi dei feature flag cambiano tra minor version di Keycloak.
|
||||
KC_FEATURES: organization,admin-fine-grained-authz:v1
|
||||
KC_HOSTNAME: localhost
|
||||
KC_HOSTNAME_PORT: "${KEYCLOAK_PORT}"
|
||||
# KC_HOSTNAME come URL completo (schema+host, es. https://auth.tuodominio.it dietro Caddy
|
||||
# in produzione, http://localhost:6999 in locale): Keycloak lo usa per generare tutti i link
|
||||
# (redirect, well-known, ecc.) visti dal browser. KC_PROXY_HEADERS è necessario perché
|
||||
# Keycloak sta dietro un reverse proxy (Caddy) che termina il TLS e inoltra in http.
|
||||
KC_HOSTNAME: ${KEYCLOAK_PUBLIC_URL}
|
||||
KC_HTTP_ENABLED: "true"
|
||||
KC_PROXY_HEADERS: xforwarded
|
||||
ports:
|
||||
- "${KEYCLOAK_PORT}:8080"
|
||||
volumes:
|
||||
- ./keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json:ro
|
||||
- scouthub_keycloak_realm:/opt/keycloak/data/import:ro
|
||||
- ./keycloak/themes/scouthub:/opt/keycloak/themes/scouthub:ro
|
||||
depends_on:
|
||||
- keycloak-db
|
||||
keycloak-db:
|
||||
condition: service_started
|
||||
keycloak-realm-render:
|
||||
condition: service_completed_successfully
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000 && echo -e 'GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && grep -q '\"status\": \"UP\"' <&3"]
|
||||
interval: 5s
|
||||
@@ -211,3 +232,4 @@ services:
|
||||
volumes:
|
||||
scouthub_db_data:
|
||||
scouthub_keycloak_db_data:
|
||||
scouthub_keycloak_realm:
|
||||
|
||||
+11
-2
@@ -1,8 +1,16 @@
|
||||
# keycloak/realm-export.json
|
||||
# keycloak/realm-export.template.json
|
||||
|
||||
Realm `scouthub` con feature Organizations abilitata, importato automaticamente
|
||||
all'avvio di Keycloak (`--import-realm` nel `docker-compose.yml` alla radice).
|
||||
|
||||
Il file è un **template**: i placeholder `__HOME_FE_URL__`/`__ATTIVITA_FE_URL__`/
|
||||
`__MAGAZZINO_FE_URL__`/`__EVENTI_FE_URL__` (redirect URI, web origins, post-logout
|
||||
redirect del client `scouthub-frontend`) vengono sostituiti a runtime dal servizio
|
||||
one-shot `keycloak-realm-render` con i valori delle variabili `*_FE_PUBLIC_URL` in
|
||||
`.env` (localhost in locale, dominio dietro Caddy in produzione), e il risultato
|
||||
(`realm-export.json`) viene scritto in un volume Docker montato da `keycloak` come
|
||||
cartella di import — non esiste più un `realm-export.json` statico committato.
|
||||
|
||||
Basato su `keycloak/realm.json` (bozza di riferimento), con l'aggiunta del
|
||||
ruolo `admin` richiesto da `POST /gruppi` e `GET /gruppi` in
|
||||
`scouthub-home-be`: creazione/elenco diretti restano riservati ad `admin`,
|
||||
@@ -23,7 +31,8 @@ Contiene già:
|
||||
il suo `clientId`/`secret` devono corrispondere a
|
||||
`KEYCLOAK_ORG_SERVICE_CLIENT_ID`/`_SECRET` in `scouthub-home-be/.env.example`)
|
||||
- il client pubblico `scouthub-frontend` (login utente, condiviso da tutti i
|
||||
frontend Angular del progetto, redirect su `http://localhost:7000-7003/*`)
|
||||
frontend Angular del progetto, redirect sugli URL pubblici configurati in
|
||||
`.env`/`*_FE_PUBLIC_URL`, `http://localhost:7000-7003/*` di default in locale)
|
||||
|
||||
Passi manuali ancora da fare dopo l'import (non automatizzabili in un realm
|
||||
export senza conoscere gli id generati a runtime):
|
||||
|
||||
@@ -76,21 +76,21 @@
|
||||
"standardFlowEnabled": true,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"redirectUris": [
|
||||
"http://localhost:7000/*",
|
||||
"http://localhost:7001/*",
|
||||
"http://localhost:7002/*",
|
||||
"http://localhost:7002/silent-check-sso.html",
|
||||
"http://localhost:7003/*",
|
||||
"http://localhost:7003/silent-check-sso.html"
|
||||
"__HOME_FE_URL__/*",
|
||||
"__ATTIVITA_FE_URL__/*",
|
||||
"__MAGAZZINO_FE_URL__/*",
|
||||
"__MAGAZZINO_FE_URL__/silent-check-sso.html",
|
||||
"__EVENTI_FE_URL__/*",
|
||||
"__EVENTI_FE_URL__/silent-check-sso.html"
|
||||
],
|
||||
"webOrigins": [
|
||||
"http://localhost:7000",
|
||||
"http://localhost:7001",
|
||||
"http://localhost:7002",
|
||||
"http://localhost:7003"
|
||||
"__HOME_FE_URL__",
|
||||
"__ATTIVITA_FE_URL__",
|
||||
"__MAGAZZINO_FE_URL__",
|
||||
"__EVENTI_FE_URL__"
|
||||
],
|
||||
"attributes": {
|
||||
"post.logout.redirect.uris": "http://localhost:7000/*##http://localhost:7001/*##http://localhost:7002/*##http://localhost:7003/*"
|
||||
"post.logout.redirect.uris": "__HOME_FE_URL__/*##__ATTIVITA_FE_URL__/*##__MAGAZZINO_FE_URL__/*##__EVENTI_FE_URL__/*"
|
||||
},
|
||||
"defaultClientScopes": [
|
||||
"openid",
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
# Sostituisce nel template i placeholder __XXX_FE_URL__ con gli URL pubblici reali dei
|
||||
# frontend (localhost in locale, dominio dietro Caddy in produzione — vedi CLAUDE.md/.env.example),
|
||||
# scrivendo il risultato nella cartella di import di Keycloak. Necessario perche' realm-export.json
|
||||
# è statico e --import-realm non supporta variabili d'ambiente nei suoi campi.
|
||||
set -eu
|
||||
|
||||
: "${HOME_FE_URL:?variabile HOME_FE_URL mancante}"
|
||||
: "${ATTIVITA_FE_URL:?variabile ATTIVITA_FE_URL mancante}"
|
||||
: "${MAGAZZINO_FE_URL:?variabile MAGAZZINO_FE_URL mancante}"
|
||||
: "${EVENTI_FE_URL:?variabile EVENTI_FE_URL mancante}"
|
||||
|
||||
mkdir -p /rendered
|
||||
|
||||
sed \
|
||||
-e "s#__HOME_FE_URL__#$HOME_FE_URL#g" \
|
||||
-e "s#__ATTIVITA_FE_URL__#$ATTIVITA_FE_URL#g" \
|
||||
-e "s#__MAGAZZINO_FE_URL__#$MAGAZZINO_FE_URL#g" \
|
||||
-e "s#__EVENTI_FE_URL__#$EVENTI_FE_URL#g" \
|
||||
/template/realm-export.template.json > /rendered/realm-export.json
|
||||
|
||||
echo "[keycloak-realm-render] realm-export.json generato con:"
|
||||
echo " HOME_FE_URL=$HOME_FE_URL"
|
||||
echo " ATTIVITA_FE_URL=$ATTIVITA_FE_URL"
|
||||
echo " MAGAZZINO_FE_URL=$MAGAZZINO_FE_URL"
|
||||
echo " EVENTI_FE_URL=$EVENTI_FE_URL"
|
||||
@@ -106,7 +106,7 @@ 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 condiviso già definito in `keycloak/realm-export.json`
|
||||
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.template.json`
|
||||
(`scouthub-frontend`)
|
||||
- `eventiApiBaseUrl` — URL base di `scouthub-eventi-be` (default `http://localhost:8084`)
|
||||
|
||||
@@ -116,12 +116,14 @@ automaticamente da `ng serve`/`ng build --configuration development`) espongono:
|
||||
```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 anche
|
||||
`http://localhost:4204` (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).
|
||||
Il realm `scouthub` viene importato automaticamente al primo avvio (`--import-realm`) a
|
||||
partire dal template `keycloak/realm-export.template.json`, renderizzato con gli URL
|
||||
pubblici correnti (`*_FE_PUBLIC_URL` in `.env`) dal servizio one-shot
|
||||
`keycloak-realm-render` (vedi `keycloak/README.md`).
|
||||
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` generati dagli URL
|
||||
pubblici configurati in `.env` — se si cambia porta/dominio, basta aggiornare `.env` e
|
||||
rifare `docker compose up`; per un realm già importato in precedenza va comunque
|
||||
aggiornato anche da console admin Keycloak (l'import non sovrascrive un realm esistente).
|
||||
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 subito un redirect di login.
|
||||
|
||||
@@ -87,7 +87,7 @@ 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`
|
||||
- `keycloakClientId` — client pubblico già definito in `keycloak/realm-export.template.json`
|
||||
(`scouthub-frontend`)
|
||||
- `orgServiceApiBaseUrl` — URL base di `scouthub-home-be` (default `http://localhost:8082`)
|
||||
|
||||
@@ -97,14 +97,16 @@ espongono:
|
||||
```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).
|
||||
Il realm `scouthub` viene importato automaticamente al primo avvio (`--import-realm`)
|
||||
a partire dal template `keycloak/realm-export.template.json`, renderizzato con gli URL
|
||||
pubblici correnti (`*_FE_PUBLIC_URL` in `.env`) dal servizio one-shot
|
||||
`keycloak-realm-render` (vedi `keycloak/README.md`).
|
||||
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` generati dagli
|
||||
URL pubblici configurati in `.env` per tutti e quattro i frontend — il client è
|
||||
condiviso. Se si cambia porta/dominio, basta aggiornare `.env` e rifare
|
||||
`docker compose up`; per un cambiamento su un realm già importato in precedenza va
|
||||
comunque aggiornato anche da console admin Keycloak (l'import non sovrascrive un
|
||||
realm esistente).
|
||||
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
|
||||
|
||||
@@ -104,7 +104,7 @@ 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 condiviso già definito in `keycloak/realm-export.json`
|
||||
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.template.json`
|
||||
(`scouthub-frontend`)
|
||||
- `magazzinoApiBaseUrl` — URL base di `scouthub-magazzino-be` (default `http://localhost:8083`)
|
||||
|
||||
@@ -114,12 +114,14 @@ automaticamente da `ng serve`/`ng build --configuration development`) espongono:
|
||||
```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 anche
|
||||
`http://localhost:4203` (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).
|
||||
Il realm `scouthub` viene importato automaticamente al primo avvio (`--import-realm`) a
|
||||
partire dal template `keycloak/realm-export.template.json`, renderizzato con gli URL
|
||||
pubblici correnti (`*_FE_PUBLIC_URL` in `.env`) dal servizio one-shot
|
||||
`keycloak-realm-render` (vedi `keycloak/README.md`).
|
||||
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` generati dagli URL
|
||||
pubblici configurati in `.env` — se si cambia porta/dominio, basta aggiornare `.env` e
|
||||
rifare `docker compose up`; per un realm già importato in precedenza va comunque
|
||||
aggiornato anche da console admin Keycloak (l'import non sovrascrive un realm esistente).
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { environment } from '../../environments/environment';
|
||||
import { MagazzinoVoce } from './magazzino-api.service';
|
||||
|
||||
export interface GruppoMagazzino {
|
||||
id: string;
|
||||
orgId: string;
|
||||
nome: string;
|
||||
parentId: string | null;
|
||||
creatoIl: string;
|
||||
voci: MagazzinoVoce[];
|
||||
// Sempre vuoto sui gruppi restituiti come figli: un solo livello di nesting.
|
||||
figli: GruppoMagazzino[];
|
||||
}
|
||||
|
||||
export interface CreaGruppoMagazzinoInput {
|
||||
nome: string;
|
||||
parentId?: string | null;
|
||||
}
|
||||
|
||||
export interface AggiornaGruppoMagazzinoInput {
|
||||
nome?: string;
|
||||
parentId?: string | null;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class GruppiMagazzinoApiService {
|
||||
private readonly http = inject(HttpClient);
|
||||
|
||||
getGruppi(): Observable<GruppoMagazzino[]> {
|
||||
return this.http.get<GruppoMagazzino[]>(`${environment.magazzinoApiBaseUrl}/gruppi-magazzino`);
|
||||
}
|
||||
|
||||
creaGruppo(input: CreaGruppoMagazzinoInput): Observable<GruppoMagazzino> {
|
||||
return this.http.post<GruppoMagazzino>(`${environment.magazzinoApiBaseUrl}/gruppi-magazzino`, input);
|
||||
}
|
||||
|
||||
aggiornaGruppo(id: string, input: AggiornaGruppoMagazzinoInput): Observable<GruppoMagazzino> {
|
||||
return this.http.put<GruppoMagazzino>(`${environment.magazzinoApiBaseUrl}/gruppi-magazzino/${id}`, input);
|
||||
}
|
||||
|
||||
eliminaGruppo(id: string): Observable<void> {
|
||||
return this.http.delete<void>(`${environment.magazzinoApiBaseUrl}/gruppi-magazzino/${id}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user