Skip to main content

Settings and Audit (SuperAdmin)

The tenant dashboard exposes an operator settings area at /dashboard/amministrazione/settings/*, gated by IsSuperAdminGuard. Each page is backed by a cookie-authenticated controller; sensitive endpoints re-check the SuperAdmin role server-side. The raw JSON config editor lives at /dashboard/amministrazione/configurazione-tecnica and is deliberately excluded from the navigation surfaces.

Feature flags​

Page/dashboard/amministrazione/settings/feature-flags
APIGET/POST /api/v1/admin/feature-flags
AccessRead is anonymous (login bootstrap); save requires Admin

The page loads the whole flag list and batch-saves it — every toggle on the page is posted in one request. Protected flags (_system_* keys and enable_subscriptions once the subscriptions cutover marker is committed) are skipped silently when their value is unchanged and rejected with errors.general.permissionDenied when a real change is attempted, so an unrelated batch never bricks the page.

Feature flags are audited entities (FeatureFlag : BaseAuditEntity), so every value change is captured by the audit trail with actor and timestamps. See Feature Flags for the flag list and semantics.

API tokens​

Page/dashboard/amministrazione/settings/token-api
API/api/v1/api-tokens
AccessSuperAdmin only
  • Create a token with a name, one or more permissions (scopes), allowed origins (comma-separated; * disables origin pinning) and an optional expiresAt.
  • The plaintext token is shown once, at creation. The database stores only a SHA-256 hash plus an 8-character prefix (TokenPrefix) used for identification.
  • Origin enforcement is strict: a token without AllowedOrigins is rejected, and a request whose Origin is not in the list is refused even if the token is valid.
  • Edit updates name/permissions/origins/expiry/active state; revoke deletes the token record. lastUsedAt and expiresAt are visible in the table.

Tenant-side public-API tokens (native blog reader, sitemap, integrations) are managed from the CLI with flo instance api-token ls|create|grant|revoke <id>.

Webhooks​

Page/dashboard/amministrazione/settings/webhook
API/api/v1/webhook-configs
AccessSuperAdmin only

Webhooks dispatch external workflows (GitHub Actions / GitLab pipelines) when dynamic entities change:

  • Provider: GitHub, GitLab, or Generic; target Repository, WorkflowFile, and Branch.
  • Events: comma-separated create,update,delete,publish; an empty list fires on every event. Additional workflow InputsJson can be attached.
  • Auth token: encrypted at rest with ASP.NET Data Protection (Flo.Webhook.AuthToken.v1); never returned in clear text.
  • Delivery log: each config tracks LastTriggeredAt, LastTriggerStatus, LastTriggerError, and TriggerCount. POST /{id}/trigger and POST /{id}/test run a manual delivery from the UI (SuperAdmin only).

CORS origins​

Page/dashboard/amministrazione/settings/origini-cors
API/api/v1/cors-origins
AccessSuperAdmin only

Origins are stored in the database and enforced by the backend's dynamic CORS policy instead of static configuration. Operators can create, update, and delete origins; each entry has an active flag and a description. GET /active returns the effective list and POST /initialize seeds the default local development origins (localhost:4200, 4201, 8080, 10001, 10002). Frontend origins for Cloudflare Pages tenants are normally inserted automatically at provisioning time.

Audit trail​

Page/dashboard/amministrazione/settings/audit-trail
API/api/v1/audit-logs
AccessRead: Admin+ (IP addresses: SuperAdmin only)
  • Append-only: ApplicationDbContext rejects updates and deletes of AuditLog rows; only the AuditLogService maintenance paths may modify them.
  • Automatic capture: entity changes are staged in the same transaction as the change itself, with actor, action (Created/Modified/Deleted), entity name/ID, old/new values, and timestamp. AuditLog itself is never audited and machine-only writes are excluded.
  • Retention: default 730 days, configurable 30–3650 via GET/PUT /retention. DELETE /purge?retentionDays= removes older entries (minimum 30).
  • Entity history: GET /entity/{entityName}/{entityId} returns the full change history of one record; the UI expands each row to show old/new JSON.
  • Exports: GET /export-query downloads the filtered query as JSON (capped at 50,000 entries); GET /export/user/{userId} is the GDPR Article 15 export (SuperAdmin only).
  • Tombstones: GDPR anonymization (POST /anonymize/user/{userId}, Article 17) and purges append an audit tombstone recording the maintenance action, its count, and details, so the log stays self-describing after data is redacted.
  • Salt chain: anonymization hashing uses AUDIT_HASH_SALTS (comma-separated chain, latest salt current) with AuditLog:HashSalt as fallback; the CLI secret rotation appends new salts without invalidating old hashes.

Auth events (login failures)​

Page/dashboard/amministrazione/settings/accessi-errori
API/api/v1/auth-events
AccessSuperAdmin only

Records social-login failures from two sources: server (rejected Google/Apple exchanges) and client (the login page reports browser-side failures — blocked popup, adblock — through an anonymous fire-and-forget POST /client). The GET endpoint filters by method (google/apple), reason, source, and date range, and returns pages of 50 entries. Client reports accept only allow-listed reasons and never trust body-supplied IP/user-agent.

Login providers​

Page/dashboard/amministrazione/settings/provider-accesso
API/api/v1/external-auth-settings
AccessSuperAdmin only

Stores the Google and Apple Client IDs used by social login. No client secrets are stored in the tenant database — only the public identifiers, upserted per provider.

Email templates​

Page/dashboard/amministrazione/settings/template-email
APIGET /api/v1/newsletter/templates/*
AccessSuperAdmin (operational-notification permission for listing)

Lists the transactional email templates known to the renderer with base name, language, and placeholder variables, and renders a live HTML preview for any template. Templates themselves live on disk in the application image; the page is a read-only inspection surface. See Email Configuration for providers and senders.

Email delivery log​

Page/dashboard/amministrazione/settings/log-consegna-email
API/api/v1/email-delivery-logs
AccessSuperAdmin only

A single grid across every email provider, merging the local delivery log (written by every send path) with live provider analytics. Filters: date range, status, provider, recipient, send-job ID, and channel; paginated at 25 rows. GET /availability drives the Settings tab visibility and is always enabled.

Config editor​

Page/dashboard/amministrazione/configurazione-tecnica
API/api/v1/config-editor
AccessSuperAdmin only

Raw JSON editing for three files: theme (flo.theme.json), brand-config (flo.configs.json), and whitelabel (<env>.config.json). The service validates JSON before writing, creates a timestamped .bak.<yyyyMMddHHmmss> backup before every save, and keeps the 5 most recent backups. File keys are allow-listed and path traversal is rejected. All reads and writes are lease-guarded: on a DR standby the page is read-only (see Failover and Disaster Recovery).

App logs​

Page/dashboard/amministrazione/settings/log
API/api/v1/logs
AccessSuperAdmin only

Server-side log viewer over the application's rolling Serilog files:

  • Periods: 24h, 48h, 72h, 1w (default), 1m, all.
  • Filters: log levels (VRB, DBG, INF, WRN, ERR, FTL), free-text search, request path, and source context; newest-first with paging (max 5,000 rows per query).
  • Per-user view: GET /user/{userId}.
  • Exports: CSV (/export/csv) and JSON (/export/json).
  • GET /diagnostic reports where the log files live on the container filesystem.

For container-level logs (blue/green/Traefik/Postgres) use the CLI: flo logs app|db|proxy|errors|days|day|raw <id>.