Feature: Server-driven auth method discovery + OIDC-only enforcement

Backend:
- New AUTH_PASSWORD_ENABLED flag (default true). When false, email/password
  registration and login return 403; the server enforces OIDC-only login.
- New OIDC_GENERIC_DISPLAY_NAME so the app can show 'Authentik'/'Keycloak'
  instead of a generic 'OIDC' label.
- New public endpoint GET /api/config returns which auth methods the
  server offers (password_enabled + per-provider OIDC capabilities).
  No auth required, so the login screen can query it before logging in.
- .env.example and docker-compose.yml expose the new env vars.

App:
- DTOs + MitbringslApi.getServerConfig() for /api/config.
- AuthViewModel: new 'connect' flow. The user enters the server URL,
  taps 'Verbinden', and the app fetches /api/config. The returned
  ServerAuthConfig drives which login options are shown:
    * password-only -> email/password form
    * OIDC-only     -> OIDC token form
    * both          -> toggle between the two
  If the server offers no method, a clear error is shown.
- AuthScreen: split into ConnectView (server URL) and LoginView (the
  login form matching the server's capabilities). The mode toggle only
  appears when the server offers more than one method.
This commit is contained in:
Tronax 2026-08-06 10:28:12 +02:00
parent b44bc8c3af
commit 3f187f1ede
Signed by: Tronax
SSH key fingerprint: SHA256:2pKKXDZucWvaF/GzXNz0FY53EAO1YDLN80bqS+TTz/o
10 changed files with 577 additions and 244 deletions

View file

@ -35,6 +35,10 @@ type Config struct {
SessionTokenTTL time.Duration `env:"SESSION_TOKEN_TTL" envDefault:"720h"` // 30 days
SessionCookieName string `env:"SESSION_COOKIE_NAME" envDefault:"mitbringsl_session"`
// AuthPasswordEnabled controls whether email/password registration and
// login are offered. Set to false to enforce OIDC-only login.
AuthPasswordEnabled bool `env:"AUTH_PASSWORD_ENABLED" envDefault:"true"`
// OIDC providers. Both optional; enable per provider.
GoogleOIDC GoogleOIDCConfig
GenericOIDC GenericOIDCConfig
@ -52,9 +56,12 @@ type GoogleOIDCConfig struct {
// GenericOIDCConfig for any standards-compliant OIDC IdP (Keycloak, Authentik, ...).
type GenericOIDCConfig struct {
Enabled bool `env:"OIDC_GENERIC_ENABLED" envDefault:"false"`
Issuer string `env:"OIDC_GENERIC_ISSUER"`
ClientID string `env:"OIDC_GENERIC_CLIENT_ID"`
Enabled bool `env:"OIDC_GENERIC_ENABLED" envDefault:"false"`
Issuer string `env:"OIDC_GENERIC_ISSUER"`
ClientID string `env:"OIDC_GENERIC_CLIENT_ID"`
// DisplayName is shown to users in the app, e.g. "Authentik" or "Keycloak".
// Defaults to "OIDC" when empty.
DisplayName string `env:"OIDC_GENERIC_DISPLAY_NAME" envDefault:"OIDC"`
}
// Load reads configuration from environment variables and validates basic invariants.