diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3b32597..b551f10 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,14 @@ repos: # Versioning: Commit messages & changelog - repo: https://github.com/commitizen-tools/commitizen - rev: v4.13.10 + rev: v4.17.0 hooks: - id: commitizen stages: [commit-msg] # Lint / autoformat: Python code - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.12" + rev: "v0.16.1" hooks: - id: ruff files: ^(?:backend|auth-libs/python)/.*\.py$ @@ -18,7 +18,7 @@ repos: # Deps: ensure Python uv lockfile is up to date - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.11.7 + rev: 0.12.1 hooks: - id: uv-lock files: ^backend/pyproject\.toml$ @@ -37,7 +37,7 @@ repos: # Lint: code cognitive complexity - repo: https://github.com/rohaquinlop/complexipy-pre-commit - rev: v5.1.0 + rev: v6.2.0 hooks: - id: complexipy files: ^(?:backend|auth-libs/python)/.*\.py$ @@ -84,7 +84,7 @@ repos: # Lint: Markdown - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.48.0 + rev: v0.49.1 hooks: - id: markdownlint args: diff --git a/docs/src/admin.md b/docs/src/admin.md index 7c8be6c..388c5f8 100644 --- a/docs/src/admin.md +++ b/docs/src/admin.md @@ -54,7 +54,7 @@ app.include_router(admin_router, prefix="/api") This creates: | Method | Path | Description | -|--------|------|-------------| +| -------- | ------ | ------------- | | `GET` | `/api/admin/mappings` | List mappings (paginated) | | `POST` | `/api/admin/mappings` | Create a mapping | | `GET` | `/api/admin/mappings/{hanko_user_id}` | Get one mapping | @@ -157,7 +157,7 @@ These map to the app keys used in the proxy: `drone-tm`, `fair`, `umap`. ## Proxy Endpoints (Login Backend) | Method | Path | Description | -|--------|------|-------------| +| -------- | ------ | ------------- | | `GET` | `/api/admin/check` | Check if current user is admin | | `GET` | `/api/admin/apps` | List configured apps | | `GET` | `/api/admin/{app}/mappings` | List mappings for an app (enriched with Hanko emails) | diff --git a/docs/src/index.md b/docs/src/index.md index a72ed48..5814606 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -119,7 +119,7 @@ app = Litestar(route_handlers=[*route_handlers, me], dependencies=deps) ## Reference | Document | Description | -|----------|-------------| +| ---------- | ------------- | | [**Overview**](overview.md) | Auth flow, JWT validation, user mapping, env vars | | [**Python Libraries**](python-libs.md) | `hotosm_auth`, `hotosm_auth_fastapi`, `hotosm_auth_django` | | [**Web Component**](web-component.md) | `` Lit element — attributes, events, modes | @@ -138,7 +138,7 @@ app = Litestar(route_handlers=[*route_handlers, me], dependencies=deps) ## Implementations | Project | Stack | Documentation | -|---------|-------|---------------| +| --------- | ------- | --------------- | | Portal | FastAPI + React | [Implementation](projects/portal.md) | | ChatMap | FastAPI + React | [Implementation](projects/chatmap.md) | | Drone-TM | FastAPI + React | [Implementation](projects/drone-tm.md) | diff --git a/docs/src/integration-guide.md b/docs/src/integration-guide.md index 12a6d16..704337c 100644 --- a/docs/src/integration-guide.md +++ b/docs/src/integration-guide.md @@ -5,7 +5,7 @@ Step by step guide to integrate `hotosm-auth` in your project. ## Quick Links | Framework | Without Legacy Auth | With Legacy Auth | -|-----------|---------------------|------------------| +| ----------- | --------------------- | ------------------ | | **FastAPI** | [Simple](#fastapi-simple-integration) | [With Mapping](#fastapi-integration-with-mapping) | | **Django** | [Simple](#django-simple-integration) | [With Mapping](#django-integration-with-mapping) | | **Litestar** | [Simple](#litestar-simple-integration) | [With Mapping](#litestar-integration-with-mapping) | @@ -434,7 +434,7 @@ VITE_HANKO_URL=https://login.hotosm.org ## Checklist | Step | FastAPI Simple | FastAPI+Mapping | Django Simple | Django+Mapping | Litestar Simple | Litestar+Mapping | -|------|----------------|-----------------|---------------|----------------|-----------------|------------------| +| ------ | ---------------- | ----------------- | --------------- | ---------------- | ----------------- | ------------------ | | Dependency | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Init | init_auth | init_auth | middleware | middleware | setup_auth() | setup_auth() | | Protect routes | CurrentUser | Override login_required | request.hotosm | BaseAuthentication | AuthContext | Custom dep | diff --git a/docs/src/overview.md b/docs/src/overview.md index fd1f506..a4fcc3a 100644 --- a/docs/src/overview.md +++ b/docs/src/overview.md @@ -9,7 +9,7 @@ - **User Mapping**: Maps Hanko users to app-specific user IDs | Component | Purpose | -|-----------|---------| +| ----------- | --------- | | `hotosm_auth` | Core Python package (JWT, config, crypto) | | `hotosm_auth_fastapi` | FastAPI integration (dependencies, routes) | | `hotosm_auth_django` | Django integration (middleware, decorators) | @@ -155,7 +155,7 @@ VITE_AUTH_PROVIDER=hanko # "legacy" or "hanko" ### Variables by Project | Variable | Portal | ChatMap | Drone-TM | fAIr | uMap | Login | -|----------|--------|---------|----------|------|------|-------| +| ---------- | -------- | --------- | ---------- | ------ | ------ | ------- | | **Backend** | | `HANKO_API_URL` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | `COOKIE_SECRET` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | diff --git a/docs/src/projects/chatmap.md b/docs/src/projects/chatmap.md index a938efc..307754e 100644 --- a/docs/src/projects/chatmap.md +++ b/docs/src/projects/chatmap.md @@ -5,7 +5,7 @@ ## Overview | Aspect | Detail | -|--------|--------| +| -------- | -------- | | Framework | FastAPI | | Type | Simple (no mapping) | | OSM | Not used | diff --git a/docs/src/projects/drone-tm.md b/docs/src/projects/drone-tm.md index 6c06d31..666825f 100644 --- a/docs/src/projects/drone-tm.md +++ b/docs/src/projects/drone-tm.md @@ -5,7 +5,7 @@ ## Overview | Aspect | Detail | -|--------|--------| +| -------- | -------- | | Framework | FastAPI | | Frontend | React SPA (Vite) | | Legacy Auth | Google OAuth | @@ -298,7 +298,7 @@ VITE_FRONTEND_URL=https://drone.hotosm.org ## Auth Flow | Step | What happens | -|------|-------------| +| ------ | ------------- | | 1. Sign In | User clicks role button (Project Creator / Drone Pilot) | | 2. Redirect | `window.location.href` to `{HANKO_URL}/app?return_to={returnUrl}` | | 3. Login service | User authenticates at login.hotosm.org, gets JWT cookie | diff --git a/docs/src/projects/fair.md b/docs/src/projects/fair.md index f5ed220..0cce74d 100644 --- a/docs/src/projects/fair.md +++ b/docs/src/projects/fair.md @@ -5,7 +5,7 @@ ## Overview | Aspect | Detail | -|--------|--------| +| -------- | -------- | | Framework | Django (DRF) | | Frontend | React SPA (Vite) | | Legacy Auth | OSM OAuth (`osm-login-python`) | @@ -290,7 +290,7 @@ VITE_BASE_API_URL=https://fair.hotosm.org/api/v1/ ## Auth Flow | Step | What happens | -|------|-------------| +| ------ | ------------- | | 1. Login | Web component redirects to login service | | 2. Auth | User authenticates, gets session cookie | | 3. Return | Web component fires `hanko-login` event | diff --git a/docs/src/projects/portal.md b/docs/src/projects/portal.md index a8a1ee1..0601a84 100644 --- a/docs/src/projects/portal.md +++ b/docs/src/projects/portal.md @@ -5,7 +5,7 @@ ## Overview | Aspect | Detail | -|--------|--------| +| -------- | -------- | | Framework | FastAPI | | Type | Simple (no mapping) | | OSM Required | Optional | @@ -137,7 +137,7 @@ VITE_HANKO_URL=https://login.hotosm.org ### Available Dependencies (FastAPI) | Dependency | Type | Error if missing | -|------------|------|------------------| +| ------------ | ------ | ------------------ | | `CurrentUser` | `HankoUser` | 401 Unauthorized | | `CurrentUserOptional` | `Optional[HankoUser]` | None (no error) | | `OSMConnectionRequired` | `OSMConnection` | 403 Forbidden | diff --git a/docs/src/projects/umap.md b/docs/src/projects/umap.md index 80a5ac6..17e4a24 100644 --- a/docs/src/projects/umap.md +++ b/docs/src/projects/umap.md @@ -5,7 +5,7 @@ ## Overview | Aspect | Detail | -|--------|--------| +| -------- | -------- | | Framework | Django (umap-project) | | Frontend | Django templates (no SPA) + web component via CDN | | Legacy Auth | OSM OAuth via `django-social-auth` | @@ -327,7 +327,7 @@ No frontend-specific env vars — everything comes from Django context processor ## Auth Flow | Step | What happens | -|------|-------------| +| ------ | ------------- | | 1. Login | Web component redirects to login service (`HANKO_PUBLIC_URL`) | | 2. Auth | User authenticates at login.hotosm.org, gets JWT cookie | | 3. Return | Login service redirects to `SITE_URL` | diff --git a/docs/src/python-libs.md b/docs/src/python-libs.md index 4f5e3e8..a63cdbf 100644 --- a/docs/src/python-libs.md +++ b/docs/src/python-libs.md @@ -215,7 +215,7 @@ async def edit(osm: OSMConnectionRequired): ### Dependencies | Dependency | Type | Raises | -|------------|------|--------| +| ------------ | ------ | -------- | | `CurrentUser` | `HankoUser` | 401 | | `CurrentUserOptional` | `Optional[HankoUser]` | - | | `OSMConnectionDep` | `Optional[OSMConnection]` | - | @@ -403,7 +403,7 @@ async def public(optional_auth: OptionalAuthContext) -> dict: ### Dependencies | Dependency | Type | Raises | -|------------|------|--------| +| ------------ | ------ | -------- | | `AuthContext` | `AuthContext` (`.user`, `.osm`) | 401 | | `OptionalAuthContext` | `OptionalAuthContext` | - | | `AdminUser` | `HankoUser` | 403 | diff --git a/docs/src/web-component.md b/docs/src/web-component.md index 9a271fd..de7496d 100644 --- a/docs/src/web-component.md +++ b/docs/src/web-component.md @@ -72,7 +72,7 @@ export function AuthButton({ hankoUrl, onLogin }) { ### Core | Attribute | Type | Default | Description | -|-----------|------|---------|-------------| +| ----------- | ------ | --------- | ------------- | | `hanko-url` | string | `window.location.origin` | Login service URL (login.hotosm.org) for Hanko authentication | | `base-path` | string | `""` | Base URL for OSM OAuth endpoints. Usually same as `hanko-url` since login service hosts both Hanko and OSM auth | | `auth-path` | string | `/api/auth/osm` | OSM auth endpoints path (appended to `base-path`) | @@ -80,7 +80,7 @@ export function AuthButton({ hankoUrl, onLogin }) { ### Behavior | Attribute | Type | Default | Description | -|-----------|------|---------|-------------| +| ----------- | ------ | --------- | ------------- | | `osm-required` | boolean | `false` | Require OSM connection | | `osm-scopes` | string | `"read_prefs"` | Space-separated OSM scopes | | `auto-connect` | boolean | `false` | Auto-redirect to OSM OAuth | @@ -112,7 +112,7 @@ export function AuthButton({ hankoUrl, onLogin }) { ## Events | Event | Detail | When | -|-------|--------|------| +| ------- | -------- | ------ | | `hanko-login` | `{ user: HankoUser }` | User logged in | | `osm-connected` | `{ osmData: OSMData }` | OSM account linked | | `osm-skipped` | `{}` | User skipped OSM connection |