mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-15 16:42:15 +00:00
feat(branding): customize application identity
This commit is contained in:
+7
-1
@@ -236,7 +236,13 @@ environment (`PULSE_REPORT_PROVIDER_BRAND_DISPLAY_NAME`,
|
||||
model each client runtime has its own settings, so the override is
|
||||
per-client; in shared-process mode the settings override applies
|
||||
instance-wide, so all organizations share one brand (usually yours). Branding
|
||||
requires the `white_label` entitlement on the licence.
|
||||
requires the `white_label` entitlement on the licence. Entitled administrators
|
||||
can edit the settings-based display name and bounded inline PNG, JPEG, or GIF
|
||||
under **Settings → System → General → Appearance**. That override is used by
|
||||
both generated reports and the authenticated application header; the browser
|
||||
title follows the configured display name. Without the entitlement, the
|
||||
runtime returns and renders the built-in Pulse identity even if branding
|
||||
settings remain stored.
|
||||
|
||||
Scheduled reports are tenant-local. In provider-hosted MSP, each client
|
||||
runtime stores its own schedules in `report_schedules.json`, writes generated
|
||||
|
||||
@@ -8711,3 +8711,22 @@ to configure a public URL. `TestContract_SSOProviderResponseBaseURLNeverGuessesL
|
||||
in `internal/api/contract_test.go` pins the precedence, the request fallback,
|
||||
the trusted-proxy gate on forwarded headers, and the empty-rather-than-wrong
|
||||
behavior.
|
||||
|
||||
### Runtime branding is a narrow presentation contract
|
||||
|
||||
`GET /api/runtime/branding` is the authenticated `monitoring:read` boundary
|
||||
for application-shell branding. It returns only `enabled`, `displayName`, and
|
||||
the validated inline `logoDataUrl`; it never returns the system settings
|
||||
document, filesystem logo paths, provider credentials, or licence material.
|
||||
The handler returns the canonical disabled/empty shape unless the request's
|
||||
active licence service grants `white_label`, even when `reportBranding`
|
||||
remains persisted.
|
||||
|
||||
The settings write contract remains `reportBranding` on
|
||||
`POST /api/system/settings/update`, protected by `settings:write` and the
|
||||
existing bounded display-name, base64, and PNG/JPEG/GIF validation. The
|
||||
runtime read normalizes valid image bytes to a canonical data URL and omits an
|
||||
invalid or unknown image without discarding a valid display name.
|
||||
`internal/api/runtime_branding_test.go` and
|
||||
`internal/api/route_inventory_test.go` pin the entitlement, shape, image, and
|
||||
route contracts.
|
||||
|
||||
@@ -5502,3 +5502,22 @@ as the card. `settingsArchitecture.test.ts` pins the guidance owner, the absent
|
||||
localhost literal, and the corrected post-save copy; the rendered fallbacks and
|
||||
copy affordances are covered by
|
||||
`frontend-modern/src/components/Settings/__tests__/SSOProvidersPanel.test.tsx`.
|
||||
|
||||
### Entitled application branding stays app-shell-owned
|
||||
|
||||
`frontend-modern/src/stores/systemSettings.ts` owns the narrow reactive
|
||||
runtime-brand payload loaded during authenticated bootstrap. The shared
|
||||
`frontend-modern/src/AppLayout.tsx` shell is the only owner of applying that
|
||||
payload to the centered header lockup and route-aware browser title. A custom
|
||||
bounded banner logo replaces the built-in mark; a non-empty display name
|
||||
replaces the Pulse wordmark, while a logo with an empty display name may stand
|
||||
alone. Kiosk mode keeps its existing hidden-header behavior.
|
||||
|
||||
The Appearance surface edits the already-canonical `reportBranding` object
|
||||
through `BrandingSettingsCard`; it accepts PNG, JPEG, or GIF files no larger
|
||||
than the persisted inline-logo boundary, previews the exact saved material,
|
||||
marks the shared settings form dirty, and provides an explicit remove action.
|
||||
It must not create a page-local branding cache or render configured values
|
||||
when `white_label` is unavailable. Focused proofs live in
|
||||
`BrandingSettingsCard.test.tsx`, `AppLayout.test.tsx`, and
|
||||
`stores/__tests__/systemSettings.test.ts`.
|
||||
|
||||
@@ -1789,3 +1789,22 @@ already enforces scopes server-side and no backend behaviour changed.
|
||||
Regression coverage: the `Issue1650` cases in
|
||||
`frontend-modern/src/utils/__tests__/securityScorePresentation.test.ts` and
|
||||
`frontend-modern/src/components/__tests__/SecurityWarning.test.tsx`.
|
||||
|
||||
### Runtime branding reveals presentation material only after entitlement
|
||||
|
||||
The authenticated application header cannot depend on the admin-only full
|
||||
system-settings response, so `/api/runtime/branding` is deliberately readable
|
||||
with `monitoring:read`. That wider read authority is safe only because the
|
||||
payload is a strict allowlist of three presentation fields and the server
|
||||
fails closed: without the active `white_label` entitlement it returns
|
||||
`enabled: false` with empty name and logo values. It never exposes
|
||||
`logoPath`, other settings, environment values, licence records, or storage
|
||||
locations.
|
||||
|
||||
Brand mutations remain behind `settings:write` and the existing report-brand
|
||||
validation rejects unsupported keys, newlines, oversized base64, malformed
|
||||
base64, and formats outside PNG/JPEG/GIF. Browser rendering consumes only the
|
||||
server-filtered runtime payload; hiding controls or checking a client-side
|
||||
capability is not treated as the authorization boundary.
|
||||
`internal/api/runtime_branding_test.go` proves the no-entitlement non-leakage
|
||||
and image normalization.
|
||||
|
||||
@@ -4818,3 +4818,12 @@ only for a session that can reach settings, using the single
|
||||
handoff, demo organization suppression, and platform-page route carriage in
|
||||
`frontend-modern/src/App.tsx` are unchanged; nothing about backup, restore, or
|
||||
recovery routing keys off banner visibility.
|
||||
|
||||
The persisted `reportBranding` object remains adjacent tenant/runtime
|
||||
configuration rather than storage inventory or recovery state. The
|
||||
application-header extension reuses that same object and does not create a
|
||||
second logo artifact, database table, or backup surface. Existing system
|
||||
configuration export/restore therefore carries the display name and bounded
|
||||
inline logo exactly as it already carries report branding. Runtime reads
|
||||
through `/api/runtime/branding` are read-only and entitlement-filtered; they do
|
||||
not mutate, relocate, or synthesize persisted branding state.
|
||||
|
||||
Reference in New Issue
Block a user