Files
TimeTracker/env.example
Dries Peeters 04ed5ef8ae fix(oidc): only perform RP-Initiated Logout when OIDC_POST_LOGOUT_REDIRECT_URI is set
ixes #88

When OIDC_POST_LOGOUT_REDIRECT_URI was unset, the application was still
attempting RP-Initiated Logout by falling back to a generated redirect URL.
This caused issues with OIDC providers like Authelia that don't support
RP-Initiated Logout, resulting in failed redirects to unsupported endpoints.

Changes:
- Modified logout logic in app/routes/auth.py to only attempt provider
  logout when OIDC_POST_LOGOUT_REDIRECT_URI is explicitly configured
- If unset, users are now logged out locally and redirected to the
  TimeTracker login page (expected behavior)
- If set, RP-Initiated Logout proceeds as before (backward compatible)

Documentation:
- Updated docs/OIDC_SETUP.md with guidance on when to set the config
- Added clear comments in env.example explaining optional behavior
- Documented troubleshooting steps for providers without RP-Initiated
  Logout support (e.g., Authelia)

Tests:
- Added comprehensive test suite (tests/test_oidc_logout.py) with 9 tests
  covering different logout scenarios and edge cases
- All existing tests continue to pass (no regressions)

This change is fully backward compatible. Users with providers supporting
RP-Initiated Logout can continue using OIDC_POST_LOGOUT_REDIRECT_URI as
before. Users with providers like Authelia should leave it unset for
local-only logout.
2025-10-17 12:51:43 +02:00

98 lines
3.4 KiB
Plaintext

# Flask settings
# CRITICAL: Change SECRET_KEY in production! Used for sessions, cookies, and CSRF tokens.
# Generate a secure key with: python -c "import secrets; print(secrets.token_hex(32))"
# The same key must be used across restarts and all app replicas.
SECRET_KEY=your-secret-key-here
FLASK_ENV=production
FLASK_DEBUG=false
# Database settings
DATABASE_URL=postgresql+psycopg2://timetracker:timetracker@db:5432/timetracker
POSTGRES_DB=timetracker
POSTGRES_USER=timetracker
POSTGRES_PASSWORD=timetracker
POSTGRES_HOST=db
# Session settings
SESSION_COOKIE_SECURE=false
SESSION_COOKIE_HTTPONLY=true
PERMANENT_SESSION_LIFETIME=86400
# Application settings
TZ=Europe/Rome
CURRENCY=EUR
ROUNDING_MINUTES=1
SINGLE_ACTIVE_TIMER=true
IDLE_TIMEOUT_MINUTES=30
# User management
ALLOW_SELF_REGISTER=true
ADMIN_USERNAMES=admin
# Authentication
# Options: local | oidc | both
AUTH_METHOD=local
# OIDC (used when AUTH_METHOD=oidc or both)
# OIDC_ISSUER=https://login.microsoftonline.com/<tenant>/v2.0
# OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET=
# OIDC_REDIRECT_URI=https://yourapp.example.com/auth/oidc/callback
# OIDC_SCOPES=openid profile email
# OIDC_USERNAME_CLAIM=preferred_username
# OIDC_FULL_NAME_CLAIM=name
# OIDC_EMAIL_CLAIM=email
# OIDC_GROUPS_CLAIM=groups
# OIDC_ADMIN_GROUP=
# OIDC_ADMIN_EMAILS=
# Optional: RP-Initiated Logout. Only set if your provider supports end_session_endpoint.
# If unset, logout will be local only (recommended for providers like Authelia).
# If set, TimeTracker will redirect to the provider's logout endpoint.
# OIDC_POST_LOGOUT_REDIRECT_URI=https://yourapp.example.com/
# Backup settings
BACKUP_RETENTION_DAYS=30
BACKUP_TIME=02:00
# File upload settings
MAX_CONTENT_LENGTH=16777216
UPLOAD_FOLDER=/data/uploads
# CSRF protection
# IMPORTANT: Keep CSRF enabled in production for security
# Only disable for development/testing if needed
WTF_CSRF_ENABLED=true
WTF_CSRF_TIME_LIMIT=3600
# CSRF SSL Strict Mode
# Set to false if accessing via HTTP (localhost or IP address)
# Set to true only when using HTTPS in production
WTF_CSRF_SSL_STRICT=false
# CSRF Cookie Settings
# Only set these if you need to access the app via IP address or have cookie issues
# CSRF_COOKIE_SECURE=false # Set to false for HTTP access
# CSRF_COOKIE_SAMESITE=Lax # Options: Strict, Lax, None
# CSRF_COOKIE_DOMAIN= # Leave empty for single domain, set for subdomains
# Session Cookie Settings for IP Address Access
# If accessing via IP address (e.g., 192.168.1.100), use these settings:
# SESSION_COOKIE_SAMESITE=Lax # Change to 'None' only if needed for cross-site
# SESSION_COOKIE_SECURE=false # Must be false for HTTP
# TROUBLESHOOTING CSRF issues ("CSRF token missing or invalid" errors):
# 1. SECRET_KEY changed? All CSRF tokens become invalid when SECRET_KEY changes
# 2. Cookies blocked? Check browser settings and allow cookies from your domain
# 3. Behind a proxy? Ensure proxy forwards cookies and doesn't strip them
# 4. Token expired? Increase WTF_CSRF_TIME_LIMIT (in seconds)
# 5. Multiple app instances? All must use the SAME SECRET_KEY
# 6. Clock skew? Ensure server time is synchronized (use NTP)
# 7. Accessing via IP? Set WTF_CSRF_SSL_STRICT=false and SESSION_COOKIE_SECURE=false
# 8. Still broken? Try: docker-compose restart app
# 9. For testing only: Set WTF_CSRF_ENABLED=false (NOT for production!)
# See docs/CSRF_CONFIGURATION.md for detailed troubleshooting
# Logging
LOG_LEVEL=INFO
LOG_FILE=/data/logs/timetracker.log