Commit Graph

123 Commits

Author SHA1 Message Date
Fusion 753f1506b6 fix: wrap /auth/me response in user object to match frontend types
Frontend expects {user: {id, email, name, avatar_url}} but backend
was returning flat object. This caused auth state to fail parsing.
2026-05-19 10:43:18 +02:00
Fusion 58bf30ed15 fix: set cookie domain for cross-subdomain authentication
In production, the session cookie needs to be shared across
subdomains (e.g., api.example.com and app.example.com).

- Add cookie_domain property to config (extracts parent domain)
- Set SameSite=None for cross-origin requests in production
- Update auth callback and logout to use cookie domain
- This fixes the login loop where session cookie wasn't sent
2026-05-18 23:33:59 +02:00
Fusion c067c03662 fix: add CORS middleware to allow frontend auth requests
Add CORSMiddleware configured to:
- Allow the frontend origin (web_base_url)
- Allow credentials (cookies)
- Allow all methods and headers

This fixes cross-origin requests between frontend and API
when they're on different subdomains.
2026-05-18 23:27:11 +02:00
Fusion d273535950 fix: redirect to frontend after OAuth callback instead of returning JSON
- /auth/callback now redirects to frontend URL with session cookie
- /auth/login stores 'next' path in cookie for post-login redirect
- User is redirected to their original destination after authentication
2026-05-18 23:22:25 +02:00
Fusion caf73e39ba fix: use subprocess for alembic migrations to avoid async/sync issues
SQLAlchemy 2.0 async engines conflict with alembic's sync context manager.
Instead of trying to bridge async/sync, use subprocess to run
'alembic upgrade head' directly. This is simpler and more reliable.

- Remove psycopg2-binary dependency (no longer needed)
- Simplify init_database to use subprocess.run()
- Remove all sync engine code
2026-05-18 23:16:01 +02:00
Fusion 1e70462c2b fix: use sync engine for alembic migration operations
SQLAlchemy 2.0 async engines don't support the sync context manager
protocol needed by alembic. Create a separate sync engine (using
psycopg2) for migration operations while keeping async engine for
application queries.

- Add psycopg2-binary dependency
- Rename async connection variable to avoid mypy confusion
- Use sync engine for MigrationContext and alembic commands
2026-05-18 23:09:44 +02:00
Fusion b9684b0107 fix: fail fast on startup if database migrations fail
- Exit with error code 1 if init_database() returns False
- Update health check to verify database connectivity
- Prevents confusing 'table does not exist' errors later
2026-05-18 23:05:30 +02:00
Fusion 2ce7862058 feat: simplify auth flow - replace JWT with session cookies
Replace complex JWT + refresh token authentication with simple
session-based auth using signed cookies.

**Removed:**
- JWT token service (jwt_service.py)
- Refresh token store (refresh_store.py)
- Refresh token model and database table
- JWKS fetching and OIDC token verification
- python-jose dependency

**Added:**
- Session service (session.py) with HMAC-SHA256 signed cookies
- Auth dependencies module for shared auth logic
- Session-based auth endpoints

**Updated:**
- All API endpoints to use session-based auth
- Config: removed JWT settings, added SESSION_SECRET/SESSION_TTL_HOURS
- Tests: rewritten for session-based flow
- Frontend: no changes needed (already uses cookies)

Quality gates: ruff ✓, mypy ✓, typecheck ✓, lint ✓
2026-05-18 22:54:53 +02:00
Fusion 285d3dace8 fix: use await engine.connect() instead of async with
SQLAlchemy 2.0 async engine.connect() doesn't support context manager.
Use explicit connect/close instead.
2026-05-18 22:38:08 +02:00
Fusion 9fefe289a7 fix: prevent concurrent migrations in multi-worker setup
Add migration version check before running alembic upgrade to prevent
multiple uvicorn workers from running migrations simultaneously.

- Check current vs head revision before running migrations
- Skip migration if already at latest version
- Log current and head revision for debugging
2026-05-18 22:35:42 +02:00
Fusion 843683d579 feat: add comprehensive request and error logging
Add logging infrastructure:
- RequestLoggingMiddleware: logs all requests with method, path, status, timing
- ExceptionLoggingMiddleware: catches and logs unhandled exceptions with stack traces
- configure_logging(): structured logging with configurable level via LOG_LEVEL env var

Add detailed auth flow logging:
- Login initiation
- Token exchange success/failure
- JWKS fetch success/failure
- Token verification
- User lookup/creation
- Database errors
- Final response

This enables tracing Internal Server Errors through the logs.
2026-05-18 22:22:56 +02:00
Fusion ea6c466c6c feat: add automatic database initialization and recovery
- Add init_database() with alembic programmatic API and retry logic
- Add connection retry with exponential backoff (5 attempts)
- Improve error messages for connection/auth failures
- Add table existence check before seeding data
- Update startup event to run migrations before seeding
- Add wait-for-db.sh script for Docker containers
- Update Docker and docker-compose configurations

Quality gates: ruff ✓, mypy ✓, unit tests (8 passed)
2026-05-18 22:10:15 +02:00
Fusion 0509b9eb4a fix: separate Authentik application slug from OAuth client ID
Authentik uses different values for:
- OAuth Client ID (UUID for authentication)
- Application Slug (URL-friendly identifier like 'headquarter-web')

Add AUTHENTIK_APPLICATION_SLUG config to build correct Authentik URLs
while keeping AUTHENTIK_CLIENT_ID for OAuth token exchange.
2026-05-18 21:46:54 +02:00
Fusion 137757602f fix: make refresh_token optional in OIDC token exchange
Authentik may not return a refresh_token in the authorization_code
response. Use .get() instead of direct dict access to prevent KeyError.
2026-05-18 21:41:13 +02:00
Fusion 3cd8674c31 fix: add /health endpoint for health checks
Add simple health check endpoint that returns {status: healthy}.
Needed for Traefik health checks and monitoring.
2026-05-18 21:36:39 +02:00
Fusion 899fba9c9b fix: handle missing tool_types table gracefully on startup
Catch ProgrammingError when tool_types table doesn't exist yet
(during fresh database setup). Log warning and skip seeding instead
of crashing.
2026-05-18 21:29:48 +02:00
Fusion 6b302b3279 feat: implement tool types definition system
- Add ToolType SQLAlchemy model with Docker Compose template support
- Create CRUD API endpoints for tool type management
- Implement YAML and template variable validation
- Add built-in tool types (code-server, jupyter-notebook) seeded on startup
- Create frontend page with list, create, edit, and delete functionality
- Add tool types navigation to app shell
- Update mypy config to ignore missing imports

Quality gates: ruff (passed), mypy (passed), pytest unit (8 passed),
typecheck (passed), lint (passed), build (passed)
2026-05-18 16:27:19 +02:00
Fusion 94254ee3fd feat: complete user config management
- Add theme support with dark/light/system modes
- Add useTheme hook for applying user config theme
- Update router to use SettingsPage
- Update app-shell to apply theme on load
- Add CSS variables for dark theme
- Fix mypy errors in user_config.py
- Quality gates pass: ruff, mypy, typecheck, lint, build
2026-05-18 15:58:01 +02:00
Fusion 4e2edb1d93 feat: implement git repository management
- Add backend API for git repository CRUD (create, list, delete)
- Support bare repository initialization and mirror cloning
- Add cascade delete for repositories when project is deleted
- Add frontend page for repository management per project
- Update project page with link to repositories
- Add repo_base_path to config
- Quality gates: ruff, mypy, typecheck, lint, build all pass
2026-05-18 15:47:42 +02:00
Fusion 4299c64922 refactor: remove duplicate fixtures and add SQLite support
Task 2.5: Remove duplicate fixtures from integration tests
- test_auth_api.py, test_auth_services.py, test_models.py
- test_projects_api.py, test_seed.py, test_users_api.py
- Fix npytest typos in all test files

Task 3.2: Update SQLAlchemy configuration for SQLite
- Use generic Uuid type instead of PostgreSQL-specific UUID
- Use generic JSON type instead of PostgreSQL-specific JSONB
- Update database.py to handle SQLite connection args

Unit tests now run without PostgreSQL (5/8 passing)
2026-05-18 15:14:46 +02:00
Fusion a441ea2fac feat: implement SSH key management
- Add backend API endpoints for SSH key CRUD (POST, GET, DELETE)
- Implement Ed25519 key generation with Fernet-encrypted private keys
- Add frontend SSH keys page with generate, list, and delete functionality
- Include copy-to-clipboard for public keys
- Add responsive CSS styles for key cards
- Register ssh_keys router in main.py
- Add basic auth tests for SSH key endpoints

Quality gates: ruff ✓, mypy ✓, typecheck ✓, lint ✓
2026-05-18 14:44:21 +02:00
Fusion 577b052c05 feat: implement user profile management and oauth/traefik integration
User Profile (US-004):
- Add authenticated profile endpoints (GET/PUT /users/me)
- Add avatar upload with file validation (PNG/JPEG, max 2MB)
- Create frontend profile page with edit form and avatar upload
- Update app shell to link to profile page

OAuth/Traefik Integration:
- Externalize all Authentik URLs to environment variables
- Add domain configuration (API_DOMAIN, WEB_DOMAIN, AUTHENTIK_DOMAIN)
- Create docker-compose.traefik.yml for reverse proxy deployment
- Update OAuth redirect/callback URLs to use configured domains
- Add VITE_APP_URL for frontend public URL configuration

Quality gates: pytest (50 passed), ruff, mypy, npm test (12 passed), typecheck, lint, build
2026-05-17 23:17:10 +02:00
alex 71d9fe6406 feat: implement auth, projects, and frontend foundation 2026-05-17 20:21:55 +00:00