feat: expose PWA, app identity, and extension directory keys in JSON config #312

This commit is contained in:
Linus Rath
2026-05-21 23:35:58 +02:00
parent 9b22ef810e
commit fc5f6f43d6
58 changed files with 159 additions and 130 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
// run.
//
// Each entry has one of three states: 'pending' (user installed, waiting for
// admin), 'approved' (admin signed off), 'denied' (admin refused kept so we
// admin), 'approved' (admin signed off), 'denied' (admin refused - kept so we
// don't keep asking).
import { readFile, writeFile, rename } from 'node:fs/promises';
+1 -1
View File
@@ -155,7 +155,7 @@ async function loadDevPlugin(pluginDir: string): Promise<DevPluginEntry | null>
// Hash from the exact bytes the bundle endpoint will serve so the client's
// verifyBundle check passes. For src/ sources that means running esbuild
// here too slightly more work per manifest list, but unavoidable since
// here too - slightly more work per manifest list, but unavoidable since
// the source hash wouldn't match the served bundle.
let bundleHash: string;
try {
+1 -1
View File
@@ -8,7 +8,7 @@
// The keypair lives at `data/admin/plugin-signing.key` (PEM-encoded
// PKCS#8 private, mode 0600) and is generated lazily on first use. Operators
// who want to pin the key out-of-band can drop a pre-generated PEM at that
// path before first boot the loader just reads what's there.
// path before first boot - the loader just reads what's there.
import { generateKeyPairSync, createPrivateKey, createPublicKey, sign as nodeSign, KeyObject } from 'node:crypto';
import { readFile, writeFile, chmod } from 'node:fs/promises';
+6
View File
@@ -128,11 +128,16 @@ export interface AuditEntry {
/** Config keys that map to environment variables */
export const CONFIG_ENV_MAP: Record<string, { envVar: string; fileEnvVar?: string; type: 'string' | 'boolean' | 'url' | 'enum' | 'json'; defaultValue: unknown; enumValues?: string[] }> = {
appName: { envVar: 'APP_NAME', type: 'string', defaultValue: 'Webmail' },
appShortName: { envVar: 'APP_SHORT_NAME', type: 'string', defaultValue: '' },
appDescription: { envVar: 'APP_DESCRIPTION', type: 'string', defaultValue: '' },
jmapServerUrl: { envVar: 'JMAP_SERVER_URL', type: 'url', defaultValue: '' },
stalwartFeaturesEnabled: { envVar: 'STALWART_FEATURES', type: 'boolean', defaultValue: true },
demoMode: { envVar: 'DEMO_MODE', type: 'boolean', defaultValue: false },
devMode: { envVar: 'DEV_MOCK_JMAP', type: 'boolean', defaultValue: false },
faviconUrl: { envVar: 'FAVICON_URL', type: 'url', defaultValue: '/branding/Bulwark_Favicon.svg' },
pwaIconUrl: { envVar: 'PWA_ICON_URL', type: 'url', defaultValue: '' },
pwaThemeColor: { envVar: 'PWA_THEME_COLOR', type: 'string', defaultValue: '#ffffff' },
pwaBackgroundColor: { envVar: 'PWA_BACKGROUND_COLOR', type: 'string', defaultValue: '#ffffff' },
appLogoLightUrl: { envVar: 'APP_LOGO_LIGHT_URL', type: 'url', defaultValue: '' },
appLogoDarkUrl: { envVar: 'APP_LOGO_DARK_URL', type: 'url', defaultValue: '' },
loginLogoLightUrl: { envVar: 'LOGIN_LOGO_LIGHT_URL', type: 'url', defaultValue: '/branding/Bulwark_Logo_Color.svg' },
@@ -159,6 +164,7 @@ export const CONFIG_ENV_MAP: Record<string, { envVar: string; fileEnvVar?: strin
logFormat: { envVar: 'LOG_FORMAT', type: 'enum', defaultValue: 'text', enumValues: ['text', 'json'] },
logLevel: { envVar: 'LOG_LEVEL', type: 'enum', defaultValue: 'info', enumValues: ['error', 'warn', 'info', 'debug'] },
sessionSecret: { envVar: 'SESSION_SECRET', fileEnvVar: 'SESSION_SECRET_FILE', type: 'string', defaultValue: '' },
extensionDirectoryUrl: { envVar: 'EXTENSION_DIRECTORY_URL', type: 'url', defaultValue: 'https://extensions.bulwarkmail.org' },
};
/** Keys that should never be exposed to the client config endpoint */