Merge pull request #520 from maartendra/feat/login-show-totp-version
feat(login): add LOGIN_SHOW_TOTP and LOGIN_SHOW_VERSION config flags
This commit is contained in:
@@ -133,7 +133,7 @@ export default function LoginPage() {
|
||||
const isMobileHandoff = Boolean(mobileRedirectUri);
|
||||
const { login, loginDemo, isLoading, error, clearError, isAuthenticated } = useAuthStore();
|
||||
const { theme, setTheme, initializeTheme } = useThemeStore(useShallow((s) => ({ theme: s.theme, setTheme: s.setTheme, initializeTheme: s.initializeTheme })));
|
||||
const { appName, jmapServerUrl: configuredServerUrl, oauthEnabled, oauthOnly, oauthClientId: globalOauthClientId, oauthIssuerUrl: globalOauthIssuerUrl, oauthScopes, rememberMeEnabled, devMode, demoMode, loginLogoLightUrl, loginLogoDarkUrl, loginCompanyName, loginImprintUrl, loginPrivacyPolicyUrl, loginWebsiteUrl, loginLogoMaxHeight, loginLogoMaxWidth, loginShowHeading, loginShowSubtitle, isLoading: configLoading, error: configError, autoSsoEnabled, embeddedMode: _embeddedMode, allowCustomJmapEndpoint, jmapServers, jmapServerAutoPickByDomain } = useConfig();
|
||||
const { appName, jmapServerUrl: configuredServerUrl, oauthEnabled, oauthOnly, oauthClientId: globalOauthClientId, oauthIssuerUrl: globalOauthIssuerUrl, oauthScopes, rememberMeEnabled, devMode, demoMode, loginLogoLightUrl, loginLogoDarkUrl, loginCompanyName, loginImprintUrl, loginPrivacyPolicyUrl, loginWebsiteUrl, loginLogoMaxHeight, loginLogoMaxWidth, loginShowHeading, loginShowSubtitle, loginShowTotp, loginShowVersion, isLoading: configLoading, error: configError, autoSsoEnabled, embeddedMode: _embeddedMode, allowCustomJmapEndpoint, jmapServers, jmapServerAutoPickByDomain } = useConfig();
|
||||
const resolvedTheme = useThemeStore((s) => s.resolvedTheme);
|
||||
|
||||
// Login logo sizing: when a max height/width is configured, drop the fixed
|
||||
@@ -822,7 +822,7 @@ export default function LoginPage() {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<VersionBadge />
|
||||
{loginShowVersion && <VersionBadge />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1154,8 +1154,12 @@ export default function LoginPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 2FA toggle / field */}
|
||||
{/* 2FA toggle / field. The manual toggle can be hidden via
|
||||
LOGIN_SHOW_TOTP (loginShowTotp) for deployments whose mail
|
||||
server has no per-account TOTP (auth delegated to an
|
||||
external directory); server-required TOTP still shows. */}
|
||||
{!showTotpField ? (
|
||||
loginShowTotp ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
@@ -1167,6 +1171,7 @@ export default function LoginPage() {
|
||||
<Shield className="w-3.5 h-3.5" />
|
||||
{t("totp_toggle")}
|
||||
</button>
|
||||
) : null
|
||||
) : (
|
||||
<div className="space-y-1.5">
|
||||
<label htmlFor="totp" className="block text-sm font-medium text-foreground">
|
||||
@@ -1361,7 +1366,7 @@ export default function LoginPage() {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<VersionBadge />
|
||||
{loginShowVersion && <VersionBadge />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -78,6 +78,8 @@ export async function GET(request: NextRequest) {
|
||||
loginLogoMaxWidth: configManager.get<string>('loginLogoMaxWidth', ''),
|
||||
loginShowHeading: configManager.get<boolean>('loginShowHeading', true),
|
||||
loginShowSubtitle: configManager.get<boolean>('loginShowSubtitle', true),
|
||||
loginShowTotp: configManager.get<boolean>('loginShowTotp', true),
|
||||
loginShowVersion: configManager.get<boolean>('loginShowVersion', true),
|
||||
demoMode: configManager.get<boolean>('demoMode', false),
|
||||
allowCustomJmapEndpoint: configManager.get<boolean>('allowCustomJmapEndpoint', false),
|
||||
jmapServers: redactJmapServers(parseJmapServers(configManager.get<unknown>('jmapServers', []))),
|
||||
|
||||
@@ -30,6 +30,8 @@ interface ConfigData {
|
||||
loginLogoMaxWidth: string;
|
||||
loginShowHeading: boolean;
|
||||
loginShowSubtitle: boolean;
|
||||
loginShowTotp: boolean;
|
||||
loginShowVersion: boolean;
|
||||
demoMode: boolean;
|
||||
autoSsoEnabled: boolean;
|
||||
allowCustomJmapEndpoint: boolean;
|
||||
@@ -113,6 +115,8 @@ export function useConfig(): AppConfig {
|
||||
loginLogoMaxWidth: configCache?.loginLogoMaxWidth || '',
|
||||
loginShowHeading: configCache?.loginShowHeading ?? true,
|
||||
loginShowSubtitle: configCache?.loginShowSubtitle ?? true,
|
||||
loginShowTotp: configCache?.loginShowTotp ?? true,
|
||||
loginShowVersion: configCache?.loginShowVersion ?? true,
|
||||
demoMode: configCache?.demoMode || false,
|
||||
autoSsoEnabled: configCache?.autoSsoEnabled || false,
|
||||
allowCustomJmapEndpoint: configCache?.allowCustomJmapEndpoint || false,
|
||||
@@ -152,6 +156,8 @@ export function useConfig(): AppConfig {
|
||||
loginLogoMaxWidth: configCache.loginLogoMaxWidth,
|
||||
loginShowHeading: configCache.loginShowHeading,
|
||||
loginShowSubtitle: configCache.loginShowSubtitle,
|
||||
loginShowTotp: configCache.loginShowTotp,
|
||||
loginShowVersion: configCache.loginShowVersion,
|
||||
demoMode: configCache.demoMode,
|
||||
autoSsoEnabled: configCache.autoSsoEnabled,
|
||||
allowCustomJmapEndpoint: configCache.allowCustomJmapEndpoint,
|
||||
@@ -192,6 +198,8 @@ export function useConfig(): AppConfig {
|
||||
loginLogoMaxWidth: data.loginLogoMaxWidth,
|
||||
loginShowHeading: data.loginShowHeading,
|
||||
loginShowSubtitle: data.loginShowSubtitle,
|
||||
loginShowTotp: data.loginShowTotp,
|
||||
loginShowVersion: data.loginShowVersion,
|
||||
demoMode: data.demoMode,
|
||||
autoSsoEnabled: data.autoSsoEnabled,
|
||||
allowCustomJmapEndpoint: data.allowCustomJmapEndpoint,
|
||||
|
||||
@@ -178,6 +178,14 @@ export const CONFIG_ENV_MAP: Record<string, { envVar: string; fileEnvVar?: strin
|
||||
loginLogoMaxWidth: { envVar: 'LOGIN_LOGO_MAX_WIDTH', type: 'string', defaultValue: '' },
|
||||
loginShowHeading: { envVar: 'LOGIN_SHOW_HEADING', type: 'boolean', defaultValue: true },
|
||||
loginShowSubtitle: { envVar: 'LOGIN_SHOW_SUBTITLE', type: 'boolean', defaultValue: true },
|
||||
// Hide the manual "I have a 2FA code" toggle on the login form. Deployments
|
||||
// that delegate auth to an external directory (LDAP/OIDC) where 2FA lives in
|
||||
// the IdP have no server-side TOTP, so the toggle only leads to a failed
|
||||
// login. Server-required TOTP (totp_required) still shows regardless.
|
||||
loginShowTotp: { envVar: 'LOGIN_SHOW_TOTP', type: 'boolean', defaultValue: true },
|
||||
// Show the build version in the login footer. Off keeps the exact version
|
||||
// from being disclosed to unauthenticated visitors.
|
||||
loginShowVersion: { envVar: 'LOGIN_SHOW_VERSION', type: 'boolean', defaultValue: true },
|
||||
oauthEnabled: { envVar: 'OAUTH_ENABLED', type: 'boolean', defaultValue: false },
|
||||
oauthOnly: { envVar: 'OAUTH_ONLY', type: 'boolean', defaultValue: false },
|
||||
oauthClientId: { envVar: 'OAUTH_CLIENT_ID', type: 'string', defaultValue: '' },
|
||||
|
||||
Reference in New Issue
Block a user