Enable demo mode features, auto-fill demo credentials, and enhance branding integration

- Added `DEMO_MODE` to backend configuration with relaxed security support for specific demo accounts.
- Updated password validators to allow predefined weak passwords in demo mode.
- Auto-fill login forms with demo credentials via query parameters for improved demo accessibility.
- Introduced demo user creation logic during database initialization if `DEMO_MODE` is enabled.
- Replaced `img` tags with `next/image` for consistent and optimized visuals in branding elements.
- Refined footer, header, and layout components to incorporate improved logo handling.
This commit is contained in:
Felipe Cardoso
2025-11-21 07:42:40 +01:00
parent 0e34cab921
commit a410586cfb
14 changed files with 138 additions and 24 deletions

View File

@@ -14,6 +14,10 @@ class Settings(BaseSettings):
default="development",
description="Environment: development, staging, or production",
)
DEMO_MODE: bool = Field(
default=False,
description="Enable demo mode (relaxed security, demo users)",
)
# Security: Content Security Policy
# Set to False to disable CSP entirely (not recommended)
@@ -110,11 +114,21 @@ class Settings(BaseSettings):
@field_validator("FIRST_SUPERUSER_PASSWORD")
@classmethod
def validate_superuser_password(cls, v: str | None) -> str | None:
def validate_superuser_password(cls, v: str | None, info) -> str | None:
"""Validate superuser password strength."""
if v is None:
return v
# Get environment from values if available
values_data = info.data if info.data else {}
demo_mode = values_data.get("DEMO_MODE", False)
if demo_mode:
# In demo mode, allow specific weak passwords for demo accounts
demo_passwords = {"Demo123!", "Admin123!"}
if v in demo_passwords:
return v
if len(v) < 12:
raise ValueError("FIRST_SUPERUSER_PASSWORD must be at least 12 characters")

View File

@@ -57,6 +57,27 @@ async def init_db() -> User | None:
await session.refresh(user)
logger.info(f"Created first superuser: {user.email}")
# Create demo user if in demo mode
if settings.DEMO_MODE:
demo_email = "demo@example.com"
demo_password = "Demo123!"
existing_demo_user = await user_crud.get_by_email(session, email=demo_email)
if not existing_demo_user:
demo_user_in = UserCreate(
email=demo_email,
password=demo_password,
first_name="Demo",
last_name="User",
is_superuser=False,
)
demo_user = await user_crud.create(session, obj_in=demo_user_in)
await session.commit()
logger.info(f"Created demo user: {demo_user.email}")
else:
logger.info(f"Demo user already exists: {existing_demo_user.email}")
return user
except Exception as e:

View File

@@ -60,6 +60,15 @@ def validate_password_strength(password: str) -> str:
>>> validate_password_strength("MySecureP@ss123") # Valid
>>> validate_password_strength("password1") # Invalid - too weak
"""
# Check if we are in demo mode
from app.core.config import settings
if settings.DEMO_MODE:
# In demo mode, allow specific weak passwords for demo accounts
demo_passwords = {"Demo123!", "Admin123!"}
if password in demo_passwords:
return password
# Check minimum length
if len(password) < 12:
raise ValueError("Password must be at least 12 characters long")