Documentation
¶
Overview ¶
Package branding owns the resolved brand assets behind one Handle: the brand logo, the brand URL, and the implementor logo. Each is derived from operator config (the portal logo, an mcpapps platform-info config map, and the implementor logo URL).
A logo may be any image format, and how it reaches a surface depends on what that surface can load. The platform's own HTML pages link it: they are served from the platform's origin under a policy that admits the image host, so an <img> element takes the operator's URL as it is, and the browser caches it across page loads. An MCP App cannot: it runs in a sandboxed iframe on a host that blocks external loads, so its config carries the logo inlined -- an SVG as its own markup, a raster image as a data: URI -- which is what InjectPortalLogo fetches for. pkg/contenttype decides what those fetched bytes are, so a logo is accepted on the same terms as any other content the platform stores.
Construction takes the resolved config values (the portal logo URL, the implementor logo URL, and the names each is shown beside) so the subsystem is constructible and testable without a Platform. It imports the standard library, pkg/contenttype and internal/logsan, never pkg/platform.
InjectPortalLogo is the write seam the caller runs once while assembling the platform-info MCP app. The accessors are the read seams the caller surfaces to its portal/admin consumers: two that render a brand slot's markup and one for the brand URL. Every method is nil-safe, so a caller that never built a Handle still reads empty brand assets. ImageSources is the package function beside them, naming the origins a page's Content-Security-Policy has to admit for that markup to load.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FetchEmailLogoPNG ¶ added in v1.103.1
FetchEmailLogoPNG downloads the raster logo used in notification emails and returns its bytes. Email clients strip inline SVG, so the email logo is a separate raster asset from the logo the portal and MCP Apps render.
The caller resolves this once at startup and hands the bytes to the renderer, which attaches them to each message as an inline (cid:) part. Recipients never fetch the URL themselves, so it need only be reachable from the server.
func ImageSources ¶ added in v1.126.3
ImageSources returns the sources a page's Content-Security-Policy must admit under img-src for brand markup to load: one entry per distinct source across the logo URLs given, and nothing at all when none of them names one. Naming them keeps a page that renders a logo from having to admit every image host on the internet.
It takes the URLs rather than a Handle because the caller that builds a page's policy holds the config already, and a pure function over that config keeps the platform facade from growing another accessor.
Types ¶
type Config ¶
type Config struct {
// PortalLogo is the portal.logo URL. When set and no explicit logo_svg /
// logo_url is present in the app config, InjectPortalLogo fetches and inlines
// it.
PortalLogo string
// ImplementorLogo is the portal.implementor.logo URL. The pages link it, so
// nothing here fetches it; ImplementorLogoHTML renders it as an <img>.
ImplementorLogo string
// BrandName is the resolved portal.brand_name. InjectPortalLogo writes it
// into an app config that names no brand of its own, and it is the alt text
// of a raster brand logo.
BrandName string
// BrandURL is the portal.brand_url the operator configured. It takes
// precedence over the brand_url in the mcpapps platform-info app config,
// which InjectPortalLogo caches only when this is empty.
BrandURL string
// ImplementorName is the resolved portal.implementor.name. It is the alt
// text of a raster implementor logo; this package renders it nowhere else.
ImplementorName string
}
Config carries the resolved brand config values the owner caches from. The caller translates its own config into this shape so this package stays free of the platform's config types.
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle owns the brand assets: the portal / implementor logo URLs it was configured with, the brand name and URL, and the portal logo's fetched bytes once an MCP App has needed them. The markup accessors are pure reads over config. Only InjectPortalLogo fetches, and it caches, so the caller assembles the apps during startup rather than from concurrent request handlers.
func New ¶
New builds a Handle from the resolved brand config. Nothing is fetched here, nor by the markup accessors; only InjectPortalLogo goes to the network, once, for the app config that has to carry the logo inline.
func (*Handle) BrandLogoHTML ¶ added in v1.126.3
BrandLogoHTML returns the brand logo as the markup a brand slot inlines: an <img> element sourced at the configured portal logo URL, or the inline SVG an app config named instead. Empty when no logo is configured or on a nil Handle, which leaves each surface to its own fallback.
The page linking the image rather than carrying it is what keeps a logo of any size off every render, and lets the browser cache it across page loads. The one surface that cannot link it is an MCP App, whose config InjectPortalLogo fills with inlined bytes instead.
func (*Handle) BrandURL ¶
BrandURL returns the resolved brand URL — portal.brand_url when set, otherwise brand_url from the mcpapps platform-info config — or "" if neither is configured or on a nil Handle.
func (*Handle) ImplementorLogoHTML ¶ added in v1.126.3
ImplementorLogoHTML returns the implementor logo as the markup a brand slot inlines: an <img> element sourced at the configured implementor logo URL. Empty when no logo is configured or on a nil Handle, which leaves a configured implementor name rendering on its own.
func (*Handle) InjectPortalLogo ¶
InjectPortalLogo auto-populates the logo in the platform-info app config from the configured portal logo when the operator hasn't set logo_svg or logo_url explicitly. The logo is fetched and inlined so it renders in sandboxed contexts (MCP App iframes) that block external resource loading: an SVG as logo_svg, a raster image as a data: URI under logo_url, which is the key the apps already render through an <img> element. It also caches brand_url from the app config for use by BrandURL(). No-op passthrough on a nil Handle.