Skip to content

Login page: customization gaps for white-label operators (logo size, heading/subtitle, 2FA toggle, footer/version, pre-auth theming) #519

Description

@maartendra

Summary

We run Bulwark as a white-labelled webmail (web.email.eu, branded email.eu) backed by Stalwart with an external (LDAP/OIDC) directory. Bulwark's branding env (LOGIN_COMPANY_NAME, LOGIN_LOGO_*_URL, theme tokens) gets us most of the way, but a handful of login-page details have no supported configuration today. We currently work around all of them by injecting a <style> at our reverse proxy, which reaches into Bulwark's login DOM and class names — so it needs re-verifying on every Bulwark upgrade. Native config would let us delete the hack.

Filing as one issue since these are all "login page has no config for X"; happy to split if you'd prefer separate issues. Observed on v1.7.6.


1. Logo size is fixed at 64×64

The login logo renders in a fixed w-16 h-16 box with max-w-16 max-h-16 object-contain. Operators who brand with a wordmark (wide) logo get it fitted to 64px wide → ~13px tall, visually tiny. There's no env var or setting for size.

Requested: LOGIN_LOGO_MAX_HEIGHT / LOGIN_LOGO_MAX_WIDTH (or a LOGIN_LOGO_SIZE preset) to control the rendered login-logo box.

2. Heading + subtitle can't be hidden or overridden

The login card renders {appName} as an <h1> and the login.title ("Webmail") as a <p>. When the logo is already a wordmark that reads "email.eu", the heading + subtitle are redundant, but there's no way to turn them off, and the theme sanitizer (color tokens only) can't display:none them.

Requested — make them settable strings rather than show/hide booleans (one knob covers both "hide" and "rename"):

  • LOGIN_HEADING — overrides the login-card heading. Defaults to appName so existing deployments are unchanged. Must be separate from APP_NAME (which is also the tab title + PWA name — you can't blank those to clear the heading).
  • LOGIN_SUBTITLE — overrides the login.title subtitle.

Empty string must mean "render nothing and collapse the spacing", not "fall back to default" (a common trap — value || default defeats it). Unset/absent keeps today's default; explicit "" hides the line.

3. No way to hide the "I have a 2FA code" toggle

The login form shows an "I have a 2FA code" toggle (a <button type="button"> inside the form <fieldset>) that drives the mail server's native TOTP via the structured auth endpoint. For deployments where the mail server delegates auth to an external directory (LDAP/OIDC) and 2FA lives upstream (in the IdP), the server has no TOTP for these accounts, so the toggle only ever leads to a failed login — dead, confusing UI.

Requested: a way to hide it, e.g. LOGIN_SHOW_TOTP=false (default true), or auto-hide when the server/directory advertises no TOTP capability.

4. Footer: configurable, and don't disclose the version to anonymous visitors

The login footer (Company name / Website link / vX.Y.Z) is not configurable, and the version string is shown to unauthenticated visitors. Disclosing the exact build pre-auth is a minor but needless information leak (eases CVE targeting). We currently hide the whole footer.

Requested:

  • Don't render the version string on the unauthenticated login page (or gate it behind a LOGIN_SHOW_VERSION=false, default could stay true).
  • Optionally let operators hide/override the footer links (LOGIN_SHOW_FOOTER, or reuse LOGIN_WEBSITE_URL="" to hide the link).

5. Pre-auth login page doesn't pick up the configured theme

The brand theme (registry.json + <id>.css, color tokens) only loads after login, so the login page — the very first screen a user sees — renders with Bulwark's stock --color-primary (#3b82f6): stock-blue Sign-in button, focus ring, etc. It's the least-branded screen in the product, and inconsistent with both the post-login app and the marketing site. The theme sanitizer is color-tokens-only and doesn't apply pre-auth, so there's no supported way to brand it.

Requested: apply the configured default theme's color tokens on the pre-auth login page too (at minimum --color-primary / --color-primary-foreground / --color-ring, light + dark), or expose them as login env vars.


Why not the theme system / why config

The theme CSS sanitizer only permits :root / .dark selectors (design tokens), so it can't resize an element, hide a line, or reach the pre-auth page. Login-layout + pre-auth theming control needs to live in config. All of the above are runtime-evaluated env vars consistent with Bulwark's existing immutable-infra branding story (LOGIN_COMPANY_NAME, LOGIN_LOGO_*_URL, …). Any subset would help — #3, #4 (version), and #5 are the ones currently forcing the most fragile DOM-coupled workarounds.

Thanks for Bulwark — happy to test patches against our deployment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions