preserve Tower Authentik operator login WIP
This commit is contained in:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
from datetime import UTC, datetime
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Request, Response, status
|
from fastapi import APIRouter, Depends, Request, Response, status
|
||||||
|
from fastapi.responses import RedirectResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.core.config import get_settings
|
from app.core.config import get_settings
|
||||||
@@ -10,6 +11,7 @@ from app.core.errors import AppError
|
|||||||
from app.db.session import get_db
|
from app.db.session import get_db
|
||||||
from app.schemas.auth import AuthLoginRequest, AuthSession, AuthSessionEnvelope
|
from app.schemas.auth import AuthLoginRequest, AuthSession, AuthSessionEnvelope
|
||||||
from app.services.auth_service import AuthPrincipal, AuthService
|
from app.services.auth_service import AuthPrincipal, AuthService
|
||||||
|
from app.services.authentik_oidc_service import AuthentikOidcService
|
||||||
from app.services.demo_workflow_service import DemoWorkflowService
|
from app.services.demo_workflow_service import DemoWorkflowService
|
||||||
|
|
||||||
|
|
||||||
@@ -18,6 +20,7 @@ COOKIE_NAME = "geointel_session"
|
|||||||
|
|
||||||
|
|
||||||
def _session_from_principal(principal: AuthPrincipal, *, guest_access_enabled: bool) -> AuthSession:
|
def _session_from_principal(principal: AuthPrincipal, *, guest_access_enabled: bool) -> AuthSession:
|
||||||
|
settings = get_settings()
|
||||||
return AuthSession(
|
return AuthSession(
|
||||||
authentication_required=True,
|
authentication_required=True,
|
||||||
authenticated=True,
|
authenticated=True,
|
||||||
@@ -25,6 +28,7 @@ def _session_from_principal(principal: AuthPrincipal, *, guest_access_enabled: b
|
|||||||
expires_at=datetime.fromtimestamp(principal.expires_at, tz=UTC),
|
expires_at=datetime.fromtimestamp(principal.expires_at, tz=UTC),
|
||||||
role=principal.role,
|
role=principal.role,
|
||||||
guest_access_enabled=guest_access_enabled,
|
guest_access_enabled=guest_access_enabled,
|
||||||
|
authentik_enabled=AuthentikOidcService(settings).enabled,
|
||||||
guest_project_id=principal.project_id,
|
guest_project_id=principal.project_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,11 +36,13 @@ def _session_from_principal(principal: AuthPrincipal, *, guest_access_enabled: b
|
|||||||
def _session_payload(request: Request) -> AuthSession:
|
def _session_payload(request: Request) -> AuthSession:
|
||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
guest_access_enabled = settings.auth_enabled and settings.guest_access_enabled
|
guest_access_enabled = settings.auth_enabled and settings.guest_access_enabled
|
||||||
|
authentik_enabled = AuthentikOidcService(settings).enabled
|
||||||
if not settings.auth_enabled:
|
if not settings.auth_enabled:
|
||||||
return AuthSession(
|
return AuthSession(
|
||||||
authentication_required=False,
|
authentication_required=False,
|
||||||
authenticated=True,
|
authenticated=True,
|
||||||
guest_access_enabled=False,
|
guest_access_enabled=False,
|
||||||
|
authentik_enabled=False,
|
||||||
)
|
)
|
||||||
principal = AuthService.verify_session_token(request.cookies.get(COOKIE_NAME), settings)
|
principal = AuthService.verify_session_token(request.cookies.get(COOKIE_NAME), settings)
|
||||||
if principal is None:
|
if principal is None:
|
||||||
@@ -44,6 +50,7 @@ def _session_payload(request: Request) -> AuthSession:
|
|||||||
authentication_required=True,
|
authentication_required=True,
|
||||||
authenticated=False,
|
authenticated=False,
|
||||||
guest_access_enabled=guest_access_enabled,
|
guest_access_enabled=guest_access_enabled,
|
||||||
|
authentik_enabled=authentik_enabled,
|
||||||
)
|
)
|
||||||
return _session_from_principal(
|
return _session_from_principal(
|
||||||
principal,
|
principal,
|
||||||
@@ -124,6 +131,35 @@ def login(payload: AuthLoginRequest, request: Request, response: Response) -> Au
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/authentik/start")
|
||||||
|
def authentik_start(request: Request) -> RedirectResponse:
|
||||||
|
settings = get_settings()
|
||||||
|
service = AuthentikOidcService(settings)
|
||||||
|
try:
|
||||||
|
location, flow = service.start()
|
||||||
|
except Exception as exc:
|
||||||
|
raise AppError(code="AUTHENTIK_UNAVAILABLE", message="Authentik is momenteel niet beschikbaar.", status_code=status.HTTP_503_SERVICE_UNAVAILABLE) from exc
|
||||||
|
response = RedirectResponse(location, status_code=status.HTTP_302_FOUND)
|
||||||
|
forwarded_proto = request.headers.get("x-forwarded-proto", "").split(",", 1)[0].strip().lower()
|
||||||
|
response.set_cookie("geointel_oidc_flow", flow, max_age=600, httponly=True, secure=forwarded_proto == "https" or request.url.scheme == "https", samesite="lax", path=f"{settings.api_prefix}/auth/authentik")
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/authentik/callback")
|
||||||
|
def authentik_callback(request: Request, code: str = "", state: str = "") -> RedirectResponse:
|
||||||
|
settings = get_settings()
|
||||||
|
service = AuthentikOidcService(settings)
|
||||||
|
try:
|
||||||
|
service.finish(code=code, state=state, flow_cookie=request.cookies.get("geointel_oidc_flow", ""))
|
||||||
|
token = AuthService.create_session_token(settings.auth_username or "operator", settings)
|
||||||
|
except Exception:
|
||||||
|
return RedirectResponse(f"{settings.public_base_url.rstrip('/')}?authentik=error", status_code=status.HTTP_302_FOUND)
|
||||||
|
response = RedirectResponse(settings.public_base_url.rstrip("/") + "/", status_code=status.HTTP_302_FOUND)
|
||||||
|
_set_session_cookie(request=request, response=response, token=token, max_age=settings.auth_session_ttl_seconds)
|
||||||
|
response.delete_cookie("geointel_oidc_flow", path=f"{settings.api_prefix}/auth/authentik")
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
@router.post("/guest", response_model=AuthSessionEnvelope)
|
@router.post("/guest", response_model=AuthSessionEnvelope)
|
||||||
def guest_login(
|
def guest_login(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ class Settings(BaseSettings):
|
|||||||
auth_username: str | None = Field(default=None, validation_alias="GEOINTEL_AUTH_USERNAME")
|
auth_username: str | None = Field(default=None, validation_alias="GEOINTEL_AUTH_USERNAME")
|
||||||
auth_password_hash: str | None = Field(default=None, validation_alias="GEOINTEL_AUTH_PASSWORD_HASH")
|
auth_password_hash: str | None = Field(default=None, validation_alias="GEOINTEL_AUTH_PASSWORD_HASH")
|
||||||
auth_session_secret: str | None = Field(default=None, validation_alias="GEOINTEL_AUTH_SESSION_SECRET")
|
auth_session_secret: str | None = Field(default=None, validation_alias="GEOINTEL_AUTH_SESSION_SECRET")
|
||||||
|
authentik_issuer: str | None = Field(default=None, validation_alias="GEOINTEL_AUTHENTIK_ISSUER")
|
||||||
|
authentik_client_id: str | None = Field(default=None, validation_alias="GEOINTEL_AUTHENTIK_CLIENT_ID")
|
||||||
|
authentik_client_secret: str | None = Field(default=None, validation_alias="GEOINTEL_AUTHENTIK_CLIENT_SECRET")
|
||||||
|
authentik_allowed_email: str | None = Field(default=None, validation_alias="GEOINTEL_AUTHENTIK_ALLOWED_EMAIL")
|
||||||
|
public_base_url: str = Field(default="http://localhost:8000", validation_alias="GEOINTEL_PUBLIC_BASE_URL")
|
||||||
auth_session_ttl_seconds: int = Field(
|
auth_session_ttl_seconds: int = Field(
|
||||||
default=43_200,
|
default=43_200,
|
||||||
ge=900,
|
ge=900,
|
||||||
@@ -470,6 +475,21 @@ class Settings(BaseSettings):
|
|||||||
self.guest_display_name = self.guest_display_name.strip()
|
self.guest_display_name = self.guest_display_name.strip()
|
||||||
if not self.guest_display_name:
|
if not self.guest_display_name:
|
||||||
raise ValueError("GEOINTEL_GUEST_DISPLAY_NAME must not be blank")
|
raise ValueError("GEOINTEL_GUEST_DISPLAY_NAME must not be blank")
|
||||||
|
authentik_values = (
|
||||||
|
self.authentik_issuer,
|
||||||
|
self.authentik_client_id,
|
||||||
|
self.authentik_client_secret,
|
||||||
|
self.authentik_allowed_email,
|
||||||
|
)
|
||||||
|
if any(authentik_values) and not all(authentik_values):
|
||||||
|
raise ValueError("All GEOINTEL_AUTHENTIK_* values must be configured together")
|
||||||
|
if all(authentik_values):
|
||||||
|
if not self.auth_enabled:
|
||||||
|
raise ValueError("GEOINTEL_AUTH_ENABLED must be true when Authentik is configured")
|
||||||
|
if not str(self.authentik_issuer).startswith("https://"):
|
||||||
|
raise ValueError("GEOINTEL_AUTHENTIK_ISSUER must use HTTPS")
|
||||||
|
if not self.public_base_url.startswith("https://"):
|
||||||
|
raise ValueError("GEOINTEL_PUBLIC_BASE_URL must use HTTPS for Authentik")
|
||||||
if not self.auth_enabled:
|
if not self.auth_enabled:
|
||||||
return self
|
return self
|
||||||
if not (self.auth_username or "").strip():
|
if not (self.auth_username or "").strip():
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ def create_app() -> FastAPI:
|
|||||||
f"{settings.api_prefix}/auth/login",
|
f"{settings.api_prefix}/auth/login",
|
||||||
f"{settings.api_prefix}/auth/guest",
|
f"{settings.api_prefix}/auth/guest",
|
||||||
f"{settings.api_prefix}/auth/logout",
|
f"{settings.api_prefix}/auth/logout",
|
||||||
|
f"{settings.api_prefix}/auth/authentik/start",
|
||||||
|
f"{settings.api_prefix}/auth/authentik/callback",
|
||||||
}
|
}
|
||||||
direct_loopback_request = (
|
direct_loopback_request = (
|
||||||
request.client is not None
|
request.client is not None
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class AuthSession(BaseModel):
|
|||||||
expires_at: datetime | None = None
|
expires_at: datetime | None = None
|
||||||
role: Literal["operator", "guest"] | None = None
|
role: Literal["operator", "guest"] | None = None
|
||||||
guest_access_enabled: bool = False
|
guest_access_enabled: bool = False
|
||||||
|
authentik_enabled: bool = False
|
||||||
guest_project_id: UUID | None = None
|
guest_project_id: UUID | None = None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import secrets
|
||||||
|
from urllib.parse import urlencode, urlparse
|
||||||
|
from urllib.request import Request, urlopen
|
||||||
|
|
||||||
|
import jwt
|
||||||
|
from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer
|
||||||
|
|
||||||
|
from app.core.config import Settings
|
||||||
|
|
||||||
|
|
||||||
|
class AuthentikOidcService:
|
||||||
|
def __init__(self, settings: Settings):
|
||||||
|
self.settings = settings
|
||||||
|
self.issuer = (settings.authentik_issuer or "").rstrip("/")
|
||||||
|
self.serializer = URLSafeTimedSerializer(settings.auth_session_secret or "", salt="geointel-authentik-v1")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enabled(self) -> bool:
|
||||||
|
return bool(self.issuer and self.settings.authentik_client_id and self.settings.authentik_client_secret and self.settings.authentik_allowed_email)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def redirect_uri(self) -> str:
|
||||||
|
return f"{self.settings.public_base_url.rstrip('/')}{self.settings.api_prefix}/auth/authentik/callback"
|
||||||
|
|
||||||
|
def _discovery(self) -> dict:
|
||||||
|
document = self._fetch_json(f"{self.issuer}/.well-known/openid-configuration")
|
||||||
|
if document.get("issuer", "").rstrip("/") != self.issuer:
|
||||||
|
raise ValueError("OIDC issuer mismatch")
|
||||||
|
issuer_origin = urlparse(self.issuer)
|
||||||
|
for key in ("authorization_endpoint", "token_endpoint", "jwks_uri"):
|
||||||
|
endpoint = urlparse(document[key])
|
||||||
|
if endpoint.scheme != "https" or (endpoint.hostname, endpoint.port) != (issuer_origin.hostname, issuer_origin.port):
|
||||||
|
raise ValueError("Untrusted OIDC endpoint")
|
||||||
|
return document
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _fetch_json(url: str, data: dict[str, str] | None = None) -> dict:
|
||||||
|
encoded = urlencode(data).encode("utf-8") if data is not None else None
|
||||||
|
request = Request(url, data=encoded, headers={"Accept": "application/json"})
|
||||||
|
with urlopen(request, timeout=10) as response: # noqa: S310 - URL is validated against the configured HTTPS issuer.
|
||||||
|
return json.loads(response.read())
|
||||||
|
|
||||||
|
def start(self) -> tuple[str, str]:
|
||||||
|
if not self.enabled:
|
||||||
|
raise ValueError("Authentik is not configured")
|
||||||
|
state, nonce, verifier = secrets.token_urlsafe(32), secrets.token_urlsafe(32), secrets.token_urlsafe(48)
|
||||||
|
flow = self.serializer.dumps({"state": state, "nonce": nonce, "verifier": verifier})
|
||||||
|
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()
|
||||||
|
discovery = self._discovery()
|
||||||
|
query = urlencode({"client_id": self.settings.authentik_client_id, "redirect_uri": self.redirect_uri, "response_type": "code", "scope": "openid email profile", "state": state, "nonce": nonce, "code_challenge": challenge, "code_challenge_method": "S256"})
|
||||||
|
return f"{discovery['authorization_endpoint']}?{query}", flow
|
||||||
|
|
||||||
|
def finish(self, *, code: str, state: str, flow_cookie: str) -> dict:
|
||||||
|
try:
|
||||||
|
flow = self.serializer.loads(flow_cookie, max_age=600)
|
||||||
|
except (BadSignature, SignatureExpired) as exc:
|
||||||
|
raise ValueError("Invalid OIDC flow") from exc
|
||||||
|
if not state or not secrets.compare_digest(state, str(flow.get("state", ""))):
|
||||||
|
raise ValueError("OIDC state mismatch")
|
||||||
|
discovery = self._discovery()
|
||||||
|
token = self._fetch_json(discovery["token_endpoint"], {"grant_type": "authorization_code", "code": code, "redirect_uri": self.redirect_uri, "client_id": self.settings.authentik_client_id or "", "client_secret": self.settings.authentik_client_secret or "", "code_verifier": flow["verifier"]}).get("id_token", "")
|
||||||
|
claims = jwt.decode(token, jwt.PyJWKClient(discovery["jwks_uri"]).get_signing_key_from_jwt(token).key, algorithms=["RS256"], audience=self.settings.authentik_client_id, issuer=discovery["issuer"], options={"require": ["exp", "iat", "iss", "aud", "sub", "nonce"]})
|
||||||
|
if claims.get("nonce") != flow["nonce"]:
|
||||||
|
raise ValueError("OIDC nonce mismatch")
|
||||||
|
email = str(claims.get("email", "")).strip().lower()
|
||||||
|
allowed = str(self.settings.authentik_allowed_email or "").strip().lower()
|
||||||
|
if claims.get("email_verified") is not True or not secrets.compare_digest(email, allowed):
|
||||||
|
raise ValueError("OIDC identity is not authorized")
|
||||||
|
return claims
|
||||||
@@ -16,6 +16,8 @@ dependencies = [
|
|||||||
"shapely>=2.0.4",
|
"shapely>=2.0.4",
|
||||||
"pyproj>=3.6.1",
|
"pyproj>=3.6.1",
|
||||||
"python-multipart>=0.0.9",
|
"python-multipart>=0.0.9",
|
||||||
|
"itsdangerous>=2.2.0",
|
||||||
|
"PyJWT[crypto]>=2.10.1",
|
||||||
"rdflib>=7.1,<8",
|
"rdflib>=7.1,<8",
|
||||||
"alembic>=1.13.2",
|
"alembic>=1.13.2",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# pip-compile --extra=dev --extra=gis --generate-hashes --output-file=requirements-ci.lock --strip-extras pyproject.toml
|
# pip-compile --extra=dev --extra=gis --generate-hashes --output-file=requirements-ci.lock --strip-extras pyproject.toml
|
||||||
#
|
#
|
||||||
# geointel-input-sha256: 03c20efedd96474cbe62591b7b70cdad2681688b618bdd76731bd4cfaf85b3d4
|
# geointel-input-sha256: 84583c5d59b9d8e24665361fc3624e0eb32ed32aac053966cf9bb1f1318b5c1f
|
||||||
affine==2.4.0 \
|
affine==2.4.0 \
|
||||||
--hash=sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92 \
|
--hash=sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92 \
|
||||||
--hash=sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea
|
--hash=sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea
|
||||||
@@ -41,6 +41,108 @@ certifi==2026.6.17 \
|
|||||||
# pyogrio
|
# pyogrio
|
||||||
# pyproj
|
# pyproj
|
||||||
# rasterio
|
# rasterio
|
||||||
|
cffi==2.1.1 \
|
||||||
|
--hash=sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e \
|
||||||
|
--hash=sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66 \
|
||||||
|
--hash=sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2 \
|
||||||
|
--hash=sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0 \
|
||||||
|
--hash=sha256:194cffa889098ced9976c3fc6340305e43f6303657d298da55366907c05c22d6 \
|
||||||
|
--hash=sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971 \
|
||||||
|
--hash=sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c \
|
||||||
|
--hash=sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d \
|
||||||
|
--hash=sha256:1dea0e4d7d4f11f619fe8c1d76caf49e24405b4b5743c0e3be16a500ecd930c9 \
|
||||||
|
--hash=sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517 \
|
||||||
|
--hash=sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735 \
|
||||||
|
--hash=sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80 \
|
||||||
|
--hash=sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f \
|
||||||
|
--hash=sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1 \
|
||||||
|
--hash=sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29 \
|
||||||
|
--hash=sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8 \
|
||||||
|
--hash=sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c \
|
||||||
|
--hash=sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e \
|
||||||
|
--hash=sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48 \
|
||||||
|
--hash=sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813 \
|
||||||
|
--hash=sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac \
|
||||||
|
--hash=sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632 \
|
||||||
|
--hash=sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6 \
|
||||||
|
--hash=sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1 \
|
||||||
|
--hash=sha256:3d22a20b1fb1632cc72c22f95f7b0d2961c3e1c235f245ba4c606c4771035659 \
|
||||||
|
--hash=sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688 \
|
||||||
|
--hash=sha256:42e2f76b9455f5a9a844f770bf3e200ed3da0e15f5df3db9c31fe80b04b3d004 \
|
||||||
|
--hash=sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0 \
|
||||||
|
--hash=sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062 \
|
||||||
|
--hash=sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779 \
|
||||||
|
--hash=sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94 \
|
||||||
|
--hash=sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50 \
|
||||||
|
--hash=sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab \
|
||||||
|
--hash=sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac \
|
||||||
|
--hash=sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6 \
|
||||||
|
--hash=sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676 \
|
||||||
|
--hash=sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1 \
|
||||||
|
--hash=sha256:5a59cc1c4442bc3d5c703bf720b51138d0bfc173618807c9ee2490a7541dd3d9 \
|
||||||
|
--hash=sha256:5bb4e7ea95dcd6a014a6fef62e62467d67d8e582326443f3d68e71d6320a9fcf \
|
||||||
|
--hash=sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13 \
|
||||||
|
--hash=sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e \
|
||||||
|
--hash=sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e \
|
||||||
|
--hash=sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973 \
|
||||||
|
--hash=sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527 \
|
||||||
|
--hash=sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72 \
|
||||||
|
--hash=sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890 \
|
||||||
|
--hash=sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c \
|
||||||
|
--hash=sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990 \
|
||||||
|
--hash=sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd \
|
||||||
|
--hash=sha256:75f80557d1389eddbd0de2681f6a390a0c5338c31ddaa821381c203fc3fd50d9 \
|
||||||
|
--hash=sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94 \
|
||||||
|
--hash=sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3 \
|
||||||
|
--hash=sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80 \
|
||||||
|
--hash=sha256:7ce713ace7c0e4520535b42b77eaa742c16dab813978064913e5a3cf82973b41 \
|
||||||
|
--hash=sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5 \
|
||||||
|
--hash=sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c \
|
||||||
|
--hash=sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a \
|
||||||
|
--hash=sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4 \
|
||||||
|
--hash=sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e \
|
||||||
|
--hash=sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6 \
|
||||||
|
--hash=sha256:9f8d177621de5cb38ee3e731eda45d421db093ec0739f46a5594babda7987a98 \
|
||||||
|
--hash=sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b \
|
||||||
|
--hash=sha256:a48d62ab9d6f4f98c983223a547af44be6ca3691074c31cecced6facd3ba2dc1 \
|
||||||
|
--hash=sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03 \
|
||||||
|
--hash=sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af \
|
||||||
|
--hash=sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231 \
|
||||||
|
--hash=sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2 \
|
||||||
|
--hash=sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3 \
|
||||||
|
--hash=sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836 \
|
||||||
|
--hash=sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5 \
|
||||||
|
--hash=sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399 \
|
||||||
|
--hash=sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96 \
|
||||||
|
--hash=sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e \
|
||||||
|
--hash=sha256:baed1e86cc735622097354b9d1281406caf42ff42a886d29faa8e8d1630333be \
|
||||||
|
--hash=sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf \
|
||||||
|
--hash=sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc \
|
||||||
|
--hash=sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455 \
|
||||||
|
--hash=sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0 \
|
||||||
|
--hash=sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12 \
|
||||||
|
--hash=sha256:ca82be1a1d406ecfe1d25dc16cb33488e5a16bf4438c9fb590484ea29d92478b \
|
||||||
|
--hash=sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7 \
|
||||||
|
--hash=sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692 \
|
||||||
|
--hash=sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54 \
|
||||||
|
--hash=sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3 \
|
||||||
|
--hash=sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b \
|
||||||
|
--hash=sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be \
|
||||||
|
--hash=sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d \
|
||||||
|
--hash=sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358 \
|
||||||
|
--hash=sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a \
|
||||||
|
--hash=sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7 \
|
||||||
|
--hash=sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc \
|
||||||
|
--hash=sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960 \
|
||||||
|
--hash=sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125 \
|
||||||
|
--hash=sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb \
|
||||||
|
--hash=sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a \
|
||||||
|
--hash=sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa \
|
||||||
|
--hash=sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf \
|
||||||
|
--hash=sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3 \
|
||||||
|
--hash=sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4 \
|
||||||
|
--hash=sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264
|
||||||
|
# via cryptography
|
||||||
click==8.4.2 \
|
click==8.4.2 \
|
||||||
--hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \
|
--hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \
|
||||||
--hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76
|
--hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76
|
||||||
@@ -57,6 +159,54 @@ cligj==0.7.2 \
|
|||||||
--hash=sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27 \
|
--hash=sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27 \
|
||||||
--hash=sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df
|
--hash=sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df
|
||||||
# via rasterio
|
# via rasterio
|
||||||
|
cryptography==50.0.1 \
|
||||||
|
--hash=sha256:01f41478cf33fc605a6a089cd56d28b45c6c0b45a1928b61797f2621a04bac71 \
|
||||||
|
--hash=sha256:05ba322c4da95b262a212c345af888ef2c37c88c0509756ea00a0e6d68850f23 \
|
||||||
|
--hash=sha256:16c5ecd954b3330ebfb6605eca4fd952da8bef376551d5cc264534e3770a9ee6 \
|
||||||
|
--hash=sha256:2a93d05e34d5f67fba6f891fe85d929999baa7195e853923ea6d7576c9e68c5e \
|
||||||
|
--hash=sha256:2b34d76a652ea2b6faf777c35df230c5637842cd904e04f16230c3f9f03e4361 \
|
||||||
|
--hash=sha256:2ebbfb0f1fed745e91796e3e1080a1440423fdae8ece1b995a1d80883a409054 \
|
||||||
|
--hash=sha256:30a125032e5642a21ff816e021152bd4e7e94f03eff3f4b7fca41cd22bc3110f \
|
||||||
|
--hash=sha256:330fbb252391c596f1ae42c5754449dc924e6ad012dca8efe0d703f9f2d12ec6 \
|
||||||
|
--hash=sha256:359e62deae718bce96170e223fdcb6357e4fbd3bb7a3a75f4430763532560e49 \
|
||||||
|
--hash=sha256:407fe2b6db00939c05c0e945e9914238f2f0a430974839429dafc82b1ee6bee5 \
|
||||||
|
--hash=sha256:42be3bb70596b3abe4ac097b75be223e8b3ab614a0e5de068e3dcc54d71d6149 \
|
||||||
|
--hash=sha256:4c4188f7c0cf655be5c06342b817ed0f9595b69ffa2b12026e5353eed29dea88 \
|
||||||
|
--hash=sha256:51593d180cf6d179bde5c5d065bed81386b1f381656ae7d042b7ffc87a9895ad \
|
||||||
|
--hash=sha256:51afcfceb15597cf2635068e4ac9a56b2abde622edde17f37d85fd7b5306497a \
|
||||||
|
--hash=sha256:53e279950892dc102c6b4e52af03ae5ea92fac572a1ddab78ca73a997f62b69f \
|
||||||
|
--hash=sha256:55d16b1ef3ee0958d893a977b19777887e546c9954ea81b200c3301a864013f2 \
|
||||||
|
--hash=sha256:5dd9bda1c12b4162f6ff568eeb5e0ff956c28d14406e875cfe8a63a2d414ff20 \
|
||||||
|
--hash=sha256:5fe002589592ed749ce77fe0695fcbd3500dd61d7d6db5858a7544c612fa8e45 \
|
||||||
|
--hash=sha256:5fe939deeb161024a6be98229c953b6591fef1f41214497a78fe793a244c017f \
|
||||||
|
--hash=sha256:693c99b49bd37d0d096e4334c10232c77248c415b98d35236094cdf96d57258b \
|
||||||
|
--hash=sha256:76de83fbd91ac49c0feaaa983d0748fd7a53176afac5fb3bf7478d244f0eb527 \
|
||||||
|
--hash=sha256:79bf008d1f9af6071c797ad133e39915dfee7614f18f18f4db9072eb715064a3 \
|
||||||
|
--hash=sha256:804728ce710890870f3aaa344b2e161172d258d768ac139d02cfd9092d0d94e6 \
|
||||||
|
--hash=sha256:8921d58f426793c5f1b47f0b59575780de9a095214958d0eb37d909593db8367 \
|
||||||
|
--hash=sha256:8df2de9102026855887e4587084f6eabd80ed0f345b8ad8a7ac27ab9bf4723e0 \
|
||||||
|
--hash=sha256:9cb3cb952cf5a8abd50c782a98a89d71699715e802fe349704b47f2425b42a94 \
|
||||||
|
--hash=sha256:9dde0a357190eb3b1da1bb9ab750e9c85cba82ca5977aa0836cbb94e92611239 \
|
||||||
|
--hash=sha256:9ebcdd5519be9b652a46f507817a74591774fc3d6923ac364e4dfa64e36b291b \
|
||||||
|
--hash=sha256:a0b1a59e3a089064a0ec309e9428c8e3ae4e161419d20ac33600767e83fc658a \
|
||||||
|
--hash=sha256:a255449073358275b64b67d3f595f268bbef70e72b6edb65e0c70c735bf739c9 \
|
||||||
|
--hash=sha256:a8f40ea47330e71b594a7e246898f93177c259490c63183dbaf9e571d71ed9a5 \
|
||||||
|
--hash=sha256:ac02b07824d4d1001bd4367599f839c19cb171924c796e52c23508ac14c2c0cc \
|
||||||
|
--hash=sha256:aed8db4f6d71c51efb89530e12d9464e7bf2923d46c3205dc794a2a93f8c0648 \
|
||||||
|
--hash=sha256:b8f852c65863251b9e3a1b8c150ce21e59b522dbb6a7d4bc80e680d38388e986 \
|
||||||
|
--hash=sha256:be224a65493ec5b74a158ff22a5522ce4a5ca1e543c647a3a4730d4a09e5f959 \
|
||||||
|
--hash=sha256:ca83d00d9e69cd5eb63f2e69c3a5a59e0cecae5ae14c6ae0b35830fe3b37bad0 \
|
||||||
|
--hash=sha256:cbf74a81765ee67413503ca6e26dcc4f6f5a519822436cc0a1b97aab6c1b8a17 \
|
||||||
|
--hash=sha256:d63ae8f6481fec907ac0f588eee8a90aefde112c633131fe540e5711ddbb5a4e \
|
||||||
|
--hash=sha256:e22dfed744bd4002e909464cb23d2f0b05c6f3113a79ef2e9864a53db737c733 \
|
||||||
|
--hash=sha256:e2ca8fd1b6b4b82a1c4cb02841d0837e3c12336c2e24b520ab8ab3b969733d8f \
|
||||||
|
--hash=sha256:e74591e283fe6eb956416c929eb58262a719fe0311fd9054c62c3350ed8760d8 \
|
||||||
|
--hash=sha256:f74455bb086a85d5e81246412602aaa97ed095e504cd40dd261ef50be42205bf \
|
||||||
|
--hash=sha256:fb4b9672d389c738b175c4166e78310f8a70358886aacd9173ee03a85ffdc671 \
|
||||||
|
--hash=sha256:fc3ed7ebd2a8c96f5b166de0ab9b624996bef3b07bbeb19364dfb78222c22c80 \
|
||||||
|
--hash=sha256:fd3718b960d0b5dd213cdf03f3bcb7000e69dda0de8b956061947ff6bcff5558 \
|
||||||
|
--hash=sha256:ff838d62ec1bfce4f9ba7fa16f4a7b554cd8d0c299e6be37502161a660c84eef
|
||||||
|
# via pyjwt
|
||||||
fastapi==0.139.2 \
|
fastapi==0.139.2 \
|
||||||
--hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \
|
--hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \
|
||||||
--hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c
|
--hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c
|
||||||
@@ -226,6 +376,10 @@ iniconfig==2.3.0 \
|
|||||||
--hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \
|
--hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \
|
||||||
--hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12
|
--hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12
|
||||||
# via pytest
|
# via pytest
|
||||||
|
itsdangerous==2.2.0 \
|
||||||
|
--hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \
|
||||||
|
--hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173
|
||||||
|
# via geointel-backend (pyproject.toml)
|
||||||
mako==1.3.12 \
|
mako==1.3.12 \
|
||||||
--hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \
|
--hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \
|
||||||
--hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a
|
--hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a
|
||||||
@@ -613,6 +767,10 @@ psycopg-binary==3.3.4 \
|
|||||||
--hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \
|
--hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \
|
||||||
--hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7
|
--hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7
|
||||||
# via psycopg
|
# via psycopg
|
||||||
|
pycparser==3.0 \
|
||||||
|
--hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \
|
||||||
|
--hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992
|
||||||
|
# via cffi
|
||||||
pydantic==2.13.4 \
|
pydantic==2.13.4 \
|
||||||
--hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \
|
--hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \
|
||||||
--hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6
|
--hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6
|
||||||
@@ -750,6 +908,12 @@ pygments==2.20.0 \
|
|||||||
--hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \
|
--hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \
|
||||||
--hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
|
--hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
|
||||||
# via pytest
|
# via pytest
|
||||||
|
pyjwt==2.13.0 \
|
||||||
|
--hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \
|
||||||
|
--hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728
|
||||||
|
# via
|
||||||
|
# geointel-backend (pyproject.toml)
|
||||||
|
# pyjwt
|
||||||
pyogrio==0.13.0 \
|
pyogrio==0.13.0 \
|
||||||
--hash=sha256:1b91f6d6e6757a6ea84b9459d24f479dcb52bbf4ebcdb16baf39e49d2836a1cf \
|
--hash=sha256:1b91f6d6e6757a6ea84b9459d24f479dcb52bbf4ebcdb16baf39e49d2836a1cf \
|
||||||
--hash=sha256:220a988ce2a26591d6db5c775b07289d4f54cabdf274cc048f0e17a0b9d5be14 \
|
--hash=sha256:220a988ce2a26591d6db5c775b07289d4f54cabdf274cc048f0e17a0b9d5be14 \
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# pip-compile --extra=gis --generate-hashes --output-file=requirements-runtime.lock --strip-extras pyproject.toml
|
# pip-compile --extra=gis --generate-hashes --output-file=requirements-runtime.lock --strip-extras pyproject.toml
|
||||||
#
|
#
|
||||||
# geointel-input-sha256: 0d0d2cdceb01da58354610f03b5ce244523130cf9fd29e3f8988dbe684838e8b
|
# geointel-input-sha256: 33fe220cd418bc4cdb2ecbb3abf9b9ff50bb9c90d9fed88846fae6d640caa2f0
|
||||||
affine==2.4.0 \
|
affine==2.4.0 \
|
||||||
--hash=sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92 \
|
--hash=sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92 \
|
||||||
--hash=sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea
|
--hash=sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea
|
||||||
@@ -38,6 +38,108 @@ certifi==2026.6.17 \
|
|||||||
# pyogrio
|
# pyogrio
|
||||||
# pyproj
|
# pyproj
|
||||||
# rasterio
|
# rasterio
|
||||||
|
cffi==2.1.1 \
|
||||||
|
--hash=sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e \
|
||||||
|
--hash=sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66 \
|
||||||
|
--hash=sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2 \
|
||||||
|
--hash=sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0 \
|
||||||
|
--hash=sha256:194cffa889098ced9976c3fc6340305e43f6303657d298da55366907c05c22d6 \
|
||||||
|
--hash=sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971 \
|
||||||
|
--hash=sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c \
|
||||||
|
--hash=sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d \
|
||||||
|
--hash=sha256:1dea0e4d7d4f11f619fe8c1d76caf49e24405b4b5743c0e3be16a500ecd930c9 \
|
||||||
|
--hash=sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517 \
|
||||||
|
--hash=sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735 \
|
||||||
|
--hash=sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80 \
|
||||||
|
--hash=sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f \
|
||||||
|
--hash=sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1 \
|
||||||
|
--hash=sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29 \
|
||||||
|
--hash=sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8 \
|
||||||
|
--hash=sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c \
|
||||||
|
--hash=sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e \
|
||||||
|
--hash=sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48 \
|
||||||
|
--hash=sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813 \
|
||||||
|
--hash=sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac \
|
||||||
|
--hash=sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632 \
|
||||||
|
--hash=sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6 \
|
||||||
|
--hash=sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1 \
|
||||||
|
--hash=sha256:3d22a20b1fb1632cc72c22f95f7b0d2961c3e1c235f245ba4c606c4771035659 \
|
||||||
|
--hash=sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688 \
|
||||||
|
--hash=sha256:42e2f76b9455f5a9a844f770bf3e200ed3da0e15f5df3db9c31fe80b04b3d004 \
|
||||||
|
--hash=sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0 \
|
||||||
|
--hash=sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062 \
|
||||||
|
--hash=sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779 \
|
||||||
|
--hash=sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94 \
|
||||||
|
--hash=sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50 \
|
||||||
|
--hash=sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab \
|
||||||
|
--hash=sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac \
|
||||||
|
--hash=sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6 \
|
||||||
|
--hash=sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676 \
|
||||||
|
--hash=sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1 \
|
||||||
|
--hash=sha256:5a59cc1c4442bc3d5c703bf720b51138d0bfc173618807c9ee2490a7541dd3d9 \
|
||||||
|
--hash=sha256:5bb4e7ea95dcd6a014a6fef62e62467d67d8e582326443f3d68e71d6320a9fcf \
|
||||||
|
--hash=sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13 \
|
||||||
|
--hash=sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e \
|
||||||
|
--hash=sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e \
|
||||||
|
--hash=sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973 \
|
||||||
|
--hash=sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527 \
|
||||||
|
--hash=sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72 \
|
||||||
|
--hash=sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890 \
|
||||||
|
--hash=sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c \
|
||||||
|
--hash=sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990 \
|
||||||
|
--hash=sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd \
|
||||||
|
--hash=sha256:75f80557d1389eddbd0de2681f6a390a0c5338c31ddaa821381c203fc3fd50d9 \
|
||||||
|
--hash=sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94 \
|
||||||
|
--hash=sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3 \
|
||||||
|
--hash=sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80 \
|
||||||
|
--hash=sha256:7ce713ace7c0e4520535b42b77eaa742c16dab813978064913e5a3cf82973b41 \
|
||||||
|
--hash=sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5 \
|
||||||
|
--hash=sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c \
|
||||||
|
--hash=sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a \
|
||||||
|
--hash=sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4 \
|
||||||
|
--hash=sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e \
|
||||||
|
--hash=sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6 \
|
||||||
|
--hash=sha256:9f8d177621de5cb38ee3e731eda45d421db093ec0739f46a5594babda7987a98 \
|
||||||
|
--hash=sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b \
|
||||||
|
--hash=sha256:a48d62ab9d6f4f98c983223a547af44be6ca3691074c31cecced6facd3ba2dc1 \
|
||||||
|
--hash=sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03 \
|
||||||
|
--hash=sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af \
|
||||||
|
--hash=sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231 \
|
||||||
|
--hash=sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2 \
|
||||||
|
--hash=sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3 \
|
||||||
|
--hash=sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836 \
|
||||||
|
--hash=sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5 \
|
||||||
|
--hash=sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399 \
|
||||||
|
--hash=sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96 \
|
||||||
|
--hash=sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e \
|
||||||
|
--hash=sha256:baed1e86cc735622097354b9d1281406caf42ff42a886d29faa8e8d1630333be \
|
||||||
|
--hash=sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf \
|
||||||
|
--hash=sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc \
|
||||||
|
--hash=sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455 \
|
||||||
|
--hash=sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0 \
|
||||||
|
--hash=sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12 \
|
||||||
|
--hash=sha256:ca82be1a1d406ecfe1d25dc16cb33488e5a16bf4438c9fb590484ea29d92478b \
|
||||||
|
--hash=sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7 \
|
||||||
|
--hash=sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692 \
|
||||||
|
--hash=sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54 \
|
||||||
|
--hash=sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3 \
|
||||||
|
--hash=sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b \
|
||||||
|
--hash=sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be \
|
||||||
|
--hash=sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d \
|
||||||
|
--hash=sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358 \
|
||||||
|
--hash=sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a \
|
||||||
|
--hash=sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7 \
|
||||||
|
--hash=sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc \
|
||||||
|
--hash=sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960 \
|
||||||
|
--hash=sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125 \
|
||||||
|
--hash=sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb \
|
||||||
|
--hash=sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a \
|
||||||
|
--hash=sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa \
|
||||||
|
--hash=sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf \
|
||||||
|
--hash=sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3 \
|
||||||
|
--hash=sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4 \
|
||||||
|
--hash=sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264
|
||||||
|
# via cryptography
|
||||||
click==8.4.2 \
|
click==8.4.2 \
|
||||||
--hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \
|
--hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \
|
||||||
--hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76
|
--hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76
|
||||||
@@ -54,6 +156,54 @@ cligj==0.7.2 \
|
|||||||
--hash=sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27 \
|
--hash=sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27 \
|
||||||
--hash=sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df
|
--hash=sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df
|
||||||
# via rasterio
|
# via rasterio
|
||||||
|
cryptography==50.0.1 \
|
||||||
|
--hash=sha256:01f41478cf33fc605a6a089cd56d28b45c6c0b45a1928b61797f2621a04bac71 \
|
||||||
|
--hash=sha256:05ba322c4da95b262a212c345af888ef2c37c88c0509756ea00a0e6d68850f23 \
|
||||||
|
--hash=sha256:16c5ecd954b3330ebfb6605eca4fd952da8bef376551d5cc264534e3770a9ee6 \
|
||||||
|
--hash=sha256:2a93d05e34d5f67fba6f891fe85d929999baa7195e853923ea6d7576c9e68c5e \
|
||||||
|
--hash=sha256:2b34d76a652ea2b6faf777c35df230c5637842cd904e04f16230c3f9f03e4361 \
|
||||||
|
--hash=sha256:2ebbfb0f1fed745e91796e3e1080a1440423fdae8ece1b995a1d80883a409054 \
|
||||||
|
--hash=sha256:30a125032e5642a21ff816e021152bd4e7e94f03eff3f4b7fca41cd22bc3110f \
|
||||||
|
--hash=sha256:330fbb252391c596f1ae42c5754449dc924e6ad012dca8efe0d703f9f2d12ec6 \
|
||||||
|
--hash=sha256:359e62deae718bce96170e223fdcb6357e4fbd3bb7a3a75f4430763532560e49 \
|
||||||
|
--hash=sha256:407fe2b6db00939c05c0e945e9914238f2f0a430974839429dafc82b1ee6bee5 \
|
||||||
|
--hash=sha256:42be3bb70596b3abe4ac097b75be223e8b3ab614a0e5de068e3dcc54d71d6149 \
|
||||||
|
--hash=sha256:4c4188f7c0cf655be5c06342b817ed0f9595b69ffa2b12026e5353eed29dea88 \
|
||||||
|
--hash=sha256:51593d180cf6d179bde5c5d065bed81386b1f381656ae7d042b7ffc87a9895ad \
|
||||||
|
--hash=sha256:51afcfceb15597cf2635068e4ac9a56b2abde622edde17f37d85fd7b5306497a \
|
||||||
|
--hash=sha256:53e279950892dc102c6b4e52af03ae5ea92fac572a1ddab78ca73a997f62b69f \
|
||||||
|
--hash=sha256:55d16b1ef3ee0958d893a977b19777887e546c9954ea81b200c3301a864013f2 \
|
||||||
|
--hash=sha256:5dd9bda1c12b4162f6ff568eeb5e0ff956c28d14406e875cfe8a63a2d414ff20 \
|
||||||
|
--hash=sha256:5fe002589592ed749ce77fe0695fcbd3500dd61d7d6db5858a7544c612fa8e45 \
|
||||||
|
--hash=sha256:5fe939deeb161024a6be98229c953b6591fef1f41214497a78fe793a244c017f \
|
||||||
|
--hash=sha256:693c99b49bd37d0d096e4334c10232c77248c415b98d35236094cdf96d57258b \
|
||||||
|
--hash=sha256:76de83fbd91ac49c0feaaa983d0748fd7a53176afac5fb3bf7478d244f0eb527 \
|
||||||
|
--hash=sha256:79bf008d1f9af6071c797ad133e39915dfee7614f18f18f4db9072eb715064a3 \
|
||||||
|
--hash=sha256:804728ce710890870f3aaa344b2e161172d258d768ac139d02cfd9092d0d94e6 \
|
||||||
|
--hash=sha256:8921d58f426793c5f1b47f0b59575780de9a095214958d0eb37d909593db8367 \
|
||||||
|
--hash=sha256:8df2de9102026855887e4587084f6eabd80ed0f345b8ad8a7ac27ab9bf4723e0 \
|
||||||
|
--hash=sha256:9cb3cb952cf5a8abd50c782a98a89d71699715e802fe349704b47f2425b42a94 \
|
||||||
|
--hash=sha256:9dde0a357190eb3b1da1bb9ab750e9c85cba82ca5977aa0836cbb94e92611239 \
|
||||||
|
--hash=sha256:9ebcdd5519be9b652a46f507817a74591774fc3d6923ac364e4dfa64e36b291b \
|
||||||
|
--hash=sha256:a0b1a59e3a089064a0ec309e9428c8e3ae4e161419d20ac33600767e83fc658a \
|
||||||
|
--hash=sha256:a255449073358275b64b67d3f595f268bbef70e72b6edb65e0c70c735bf739c9 \
|
||||||
|
--hash=sha256:a8f40ea47330e71b594a7e246898f93177c259490c63183dbaf9e571d71ed9a5 \
|
||||||
|
--hash=sha256:ac02b07824d4d1001bd4367599f839c19cb171924c796e52c23508ac14c2c0cc \
|
||||||
|
--hash=sha256:aed8db4f6d71c51efb89530e12d9464e7bf2923d46c3205dc794a2a93f8c0648 \
|
||||||
|
--hash=sha256:b8f852c65863251b9e3a1b8c150ce21e59b522dbb6a7d4bc80e680d38388e986 \
|
||||||
|
--hash=sha256:be224a65493ec5b74a158ff22a5522ce4a5ca1e543c647a3a4730d4a09e5f959 \
|
||||||
|
--hash=sha256:ca83d00d9e69cd5eb63f2e69c3a5a59e0cecae5ae14c6ae0b35830fe3b37bad0 \
|
||||||
|
--hash=sha256:cbf74a81765ee67413503ca6e26dcc4f6f5a519822436cc0a1b97aab6c1b8a17 \
|
||||||
|
--hash=sha256:d63ae8f6481fec907ac0f588eee8a90aefde112c633131fe540e5711ddbb5a4e \
|
||||||
|
--hash=sha256:e22dfed744bd4002e909464cb23d2f0b05c6f3113a79ef2e9864a53db737c733 \
|
||||||
|
--hash=sha256:e2ca8fd1b6b4b82a1c4cb02841d0837e3c12336c2e24b520ab8ab3b969733d8f \
|
||||||
|
--hash=sha256:e74591e283fe6eb956416c929eb58262a719fe0311fd9054c62c3350ed8760d8 \
|
||||||
|
--hash=sha256:f74455bb086a85d5e81246412602aaa97ed095e504cd40dd261ef50be42205bf \
|
||||||
|
--hash=sha256:fb4b9672d389c738b175c4166e78310f8a70358886aacd9173ee03a85ffdc671 \
|
||||||
|
--hash=sha256:fc3ed7ebd2a8c96f5b166de0ab9b624996bef3b07bbeb19364dfb78222c22c80 \
|
||||||
|
--hash=sha256:fd3718b960d0b5dd213cdf03f3bcb7000e69dda0de8b956061947ff6bcff5558 \
|
||||||
|
--hash=sha256:ff838d62ec1bfce4f9ba7fa16f4a7b554cd8d0c299e6be37502161a660c84eef
|
||||||
|
# via pyjwt
|
||||||
fastapi==0.139.2 \
|
fastapi==0.139.2 \
|
||||||
--hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \
|
--hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \
|
||||||
--hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c
|
--hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c
|
||||||
@@ -207,6 +357,10 @@ idna==3.18 \
|
|||||||
--hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \
|
--hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \
|
||||||
--hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848
|
--hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848
|
||||||
# via anyio
|
# via anyio
|
||||||
|
itsdangerous==2.2.0 \
|
||||||
|
--hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \
|
||||||
|
--hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173
|
||||||
|
# via geointel-backend (pyproject.toml)
|
||||||
mako==1.3.12 \
|
mako==1.3.12 \
|
||||||
--hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \
|
--hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \
|
||||||
--hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a
|
--hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a
|
||||||
@@ -589,6 +743,10 @@ psycopg-binary==3.3.4 \
|
|||||||
--hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \
|
--hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \
|
||||||
--hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7
|
--hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7
|
||||||
# via psycopg
|
# via psycopg
|
||||||
|
pycparser==3.0 \
|
||||||
|
--hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \
|
||||||
|
--hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992
|
||||||
|
# via cffi
|
||||||
pydantic==2.13.4 \
|
pydantic==2.13.4 \
|
||||||
--hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \
|
--hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \
|
||||||
--hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6
|
--hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6
|
||||||
@@ -722,6 +880,12 @@ pydantic-settings==2.14.2 \
|
|||||||
--hash=sha256:a20c97b37910b6550d5ea50fbcc2d4187defe58cd57070b73863d069419c9440 \
|
--hash=sha256:a20c97b37910b6550d5ea50fbcc2d4187defe58cd57070b73863d069419c9440 \
|
||||||
--hash=sha256:c19dd64b19097f1de80184f0cc7b0272a13ae6e170cbf240a3e27e381ed14a5f
|
--hash=sha256:c19dd64b19097f1de80184f0cc7b0272a13ae6e170cbf240a3e27e381ed14a5f
|
||||||
# via geointel-backend (pyproject.toml)
|
# via geointel-backend (pyproject.toml)
|
||||||
|
pyjwt==2.13.0 \
|
||||||
|
--hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \
|
||||||
|
--hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728
|
||||||
|
# via
|
||||||
|
# geointel-backend (pyproject.toml)
|
||||||
|
# pyjwt
|
||||||
pyogrio==0.13.0 \
|
pyogrio==0.13.0 \
|
||||||
--hash=sha256:1b91f6d6e6757a6ea84b9459d24f479dcb52bbf4ebcdb16baf39e49d2836a1cf \
|
--hash=sha256:1b91f6d6e6757a6ea84b9459d24f479dcb52bbf4ebcdb16baf39e49d2836a1cf \
|
||||||
--hash=sha256:220a988ce2a26591d6db5c775b07289d4f54cabdf274cc048f0e17a0b9d5be14 \
|
--hash=sha256:220a988ce2a26591d6db5c775b07289d4f54cabdf274cc048f0e17a0b9d5be14 \
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ def test_auth_session_and_health_are_public_but_api_is_protected(monkeypatch) ->
|
|||||||
"expires_at": None,
|
"expires_at": None,
|
||||||
"role": None,
|
"role": None,
|
||||||
"guest_access_enabled": False,
|
"guest_access_enabled": False,
|
||||||
|
"authentik_enabled": False,
|
||||||
"guest_project_id": None,
|
"guest_project_id": None,
|
||||||
}
|
}
|
||||||
assert protected.status_code == 401
|
assert protected.status_code == 401
|
||||||
@@ -113,6 +114,7 @@ def test_login_uses_http_only_session_cookie_and_logout_revokes_browser_access(m
|
|||||||
"expires_at": login.json()["data"]["expires_at"],
|
"expires_at": login.json()["data"]["expires_at"],
|
||||||
"role": "operator",
|
"role": "operator",
|
||||||
"guest_access_enabled": True,
|
"guest_access_enabled": True,
|
||||||
|
"authentik_enabled": False,
|
||||||
"guest_project_id": None,
|
"guest_project_id": None,
|
||||||
}
|
}
|
||||||
cookie = login.headers["set-cookie"].lower()
|
cookie = login.headers["set-cookie"].lower()
|
||||||
@@ -223,6 +225,7 @@ def test_unraid_runtime_carries_only_hashed_operator_credentials() -> None:
|
|||||||
browser_smoke = (root / "scripts/verify_browser_runtime.sh").read_text(encoding="utf-8")
|
browser_smoke = (root / "scripts/verify_browser_runtime.sh").read_text(encoding="utf-8")
|
||||||
|
|
||||||
assert '-e GEOINTEL_AUTH_PASSWORD_HASH="$GEOINTEL_AUTH_PASSWORD_HASH"' in runner
|
assert '-e GEOINTEL_AUTH_PASSWORD_HASH="$GEOINTEL_AUTH_PASSWORD_HASH"' in runner
|
||||||
|
assert '-e GEOINTEL_AUTHENTIK_CLIENT_SECRET="$GEOINTEL_AUTHENTIK_CLIENT_SECRET"' in runner
|
||||||
assert "GEOINTEL_AUTH_PASSWORD_HASH=" in example
|
assert "GEOINTEL_AUTH_PASSWORD_HASH=" in example
|
||||||
assert "GEOINTEL_AUTH_PASSWORD=" not in runner
|
assert "GEOINTEL_AUTH_PASSWORD=" not in runner
|
||||||
assert "GEOINTEL_GUEST_ACCESS_ENABLED=true" in example
|
assert "GEOINTEL_GUEST_ACCESS_ENABLED=true" in example
|
||||||
|
|||||||
+206
-199
@@ -1,201 +1,208 @@
|
|||||||
# GeoIntel Unraid all-in-one environment template.
|
# GeoIntel Unraid all-in-one environment template.
|
||||||
# Copy this file to /mnt/user/appdata/geointel/.env and edit values there.
|
# Copy this file to /mnt/user/appdata/geointel/.env and edit values there.
|
||||||
|
|
||||||
# GeoIntel runs as ONE container. This makes a bare `docker compose ...` in this
|
# GeoIntel runs as ONE container. This makes a bare `docker compose ...` in this
|
||||||
# directory use the single-container file instead of the multi-container
|
# directory use the single-container file instead of the multi-container
|
||||||
# development stack in docker-compose.yml.
|
# development stack in docker-compose.yml.
|
||||||
COMPOSE_FILE=docker-compose.unraid.yml
|
COMPOSE_FILE=docker-compose.unraid.yml
|
||||||
|
|
||||||
# Browser URL: http://<unraid-ip>:<GEOINTEL_FRONTEND_PORT>
|
# Browser URL: http://<unraid-ip>:<GEOINTEL_FRONTEND_PORT>
|
||||||
GEOINTEL_FRONTEND_PORT=1202
|
GEOINTEL_FRONTEND_PORT=1202
|
||||||
|
|
||||||
# Persisted application artifacts: uploads, tiles, masks, reports and exports.
|
# Persisted application artifacts: uploads, tiles, masks, reports and exports.
|
||||||
GEOINTEL_STORAGE_PATH=/mnt/user/appdata/geointel/storage
|
GEOINTEL_STORAGE_PATH=/mnt/user/appdata/geointel/storage
|
||||||
|
|
||||||
# Local AI model files mounted into the container as /app/models.
|
# Local AI model files mounted into the container as /app/models.
|
||||||
GEOINTEL_MODELS_PATH=/mnt/user/appdata/geointel/models
|
GEOINTEL_MODELS_PATH=/mnt/user/appdata/geointel/models
|
||||||
|
|
||||||
# Checksum-verified release backups mounted read-only for cleanup guards.
|
# Checksum-verified release backups mounted read-only for cleanup guards.
|
||||||
GEOINTEL_BACKUPS_PATH=/mnt/user/appdata/geointel/backups
|
GEOINTEL_BACKUPS_PATH=/mnt/user/appdata/geointel/backups
|
||||||
|
|
||||||
# Embedded PostGIS data directory for the all-in-one container.
|
# Embedded PostGIS data directory for the all-in-one container.
|
||||||
GEOINTEL_POSTGIS_DATA_PATH=/mnt/user/appdata/geointel/postgres-data
|
GEOINTEL_POSTGIS_DATA_PATH=/mnt/user/appdata/geointel/postgres-data
|
||||||
|
|
||||||
# Internal embedded PostGIS settings. The database is not published to the LAN.
|
# Internal embedded PostGIS settings. The database is not published to the LAN.
|
||||||
# Replace the placeholder with a unique secret before the first start. Production
|
# Replace the placeholder with a unique secret before the first start. Production
|
||||||
# startup rejects empty and known-default passwords.
|
# startup rejects empty and known-default passwords.
|
||||||
GEOINTEL_POSTGRES_DB=geointel
|
GEOINTEL_POSTGRES_DB=geointel
|
||||||
GEOINTEL_POSTGRES_USER=geointel
|
GEOINTEL_POSTGRES_USER=geointel
|
||||||
GEOINTEL_POSTGRES_PASSWORD=change-me-before-shared-use
|
GEOINTEL_POSTGRES_PASSWORD=change-me-before-shared-use
|
||||||
|
|
||||||
# Browser origins allowed when directly calling the backend API.
|
# Browser origins allowed when directly calling the backend API.
|
||||||
# Neem hier ook de publieke hostname op zodra Nginx Proxy Manager ervoor staat.
|
# Neem hier ook de publieke hostname op zodra Nginx Proxy Manager ervoor staat.
|
||||||
GEOINTEL_CORS_ORIGINS=https://geointel.itworx.tech,http://geointel.itworx.tech,http://localhost:1202,http://127.0.0.1:1202,http://192.168.10.150:1202
|
GEOINTEL_CORS_ORIGINS=https://geointel.itworx.tech,http://geointel.itworx.tech,http://localhost:1202,http://127.0.0.1:1202,http://192.168.10.150:1202
|
||||||
|
|
||||||
# Upload guard in MiB. The same 1-2048 limit is applied by nginx and FastAPI.
|
# Upload guard in MiB. The same 1-2048 limit is applied by nginx and FastAPI.
|
||||||
GEOINTEL_MAX_UPLOAD_MB=500
|
GEOINTEL_MAX_UPLOAD_MB=500
|
||||||
GEOINTEL_AOI_WORKER_ENABLED=true
|
GEOINTEL_AOI_WORKER_ENABLED=true
|
||||||
GEOINTEL_AOI_WORKER_POLL_SECONDS=2
|
GEOINTEL_AOI_WORKER_POLL_SECONDS=2
|
||||||
|
|
||||||
# Optional single-operator access gate. Never store a plaintext password here.
|
# Optional single-operator access gate. Never store a plaintext password here.
|
||||||
# Generate the password hash with AuthService.hash_password and use a unique,
|
# Generate the password hash with AuthService.hash_password and use a unique,
|
||||||
# random session secret of at least 32 characters.
|
# random session secret of at least 32 characters.
|
||||||
GEOINTEL_AUTH_ENABLED=false
|
GEOINTEL_AUTH_ENABLED=false
|
||||||
GEOINTEL_AUTH_USERNAME=
|
GEOINTEL_AUTH_USERNAME=
|
||||||
GEOINTEL_AUTH_PASSWORD_HASH=
|
GEOINTEL_AUTH_PASSWORD_HASH=
|
||||||
GEOINTEL_AUTH_SESSION_SECRET=
|
GEOINTEL_AUTH_SESSION_SECRET=
|
||||||
GEOINTEL_AUTH_SESSION_TTL_SECONDS=43200
|
GEOINTEL_AUTH_SESSION_TTL_SECONDS=43200
|
||||||
|
|
||||||
# Guest access is enabled by default whenever operator authentication is active.
|
# Optionele Authentik OIDC-login naast de lokale operatorlogin.
|
||||||
# It opens the seeded GeoIntel demo in a temporary, API-enforced restricted
|
GEOINTEL_PUBLIC_BASE_URL=https://geointel.itworx.tech
|
||||||
# session. Set this to false on installations containing private project data.
|
GEOINTEL_AUTHENTIK_ISSUER=https://auth.example.com/application/o/geointel/
|
||||||
# LET OP: scripts/configure_operator_login.sh zet dit op false tenzij je
|
GEOINTEL_AUTHENTIK_CLIENT_ID=
|
||||||
# expliciet --guest-access true meegeeft.
|
GEOINTEL_AUTHENTIK_CLIENT_SECRET=
|
||||||
GEOINTEL_GUEST_ACCESS_ENABLED=true
|
GEOINTEL_AUTHENTIK_ALLOWED_EMAIL=
|
||||||
GEOINTEL_GUEST_DISPLAY_NAME=Gast
|
|
||||||
GEOINTEL_GUEST_SESSION_TTL_SECONDS=7200
|
# Guest access is enabled by default whenever operator authentication is active.
|
||||||
|
# It opens the seeded GeoIntel demo in a temporary, API-enforced restricted
|
||||||
# Explicit, bounded acquisition from the official Digitaal Vlaanderen WMS.
|
# session. Set this to false on installations containing private project data.
|
||||||
ORTHOPHOTO_ENABLED=true
|
# LET OP: scripts/configure_operator_login.sh zet dit op false tenzij je
|
||||||
ORTHOPHOTO_WMS_URL=https://geo.api.vlaanderen.be/OMWRGBMRVL/wms
|
# expliciet --guest-access true meegeeft.
|
||||||
SPW_ORTHOPHOTO_WMS_URL=https://geoservices.wallonie.be/arcgis/services/IMAGERIE/ORTHO_LAST/MapServer/WMSServer
|
GEOINTEL_GUEST_ACCESS_ENABLED=true
|
||||||
BRUSSELS_ORTHOPHOTO_WMS_URL=https://geoservices-grid.irisnet.be/geoserver/urbisgrid/ows
|
GEOINTEL_GUEST_DISPLAY_NAME=Gast
|
||||||
ORTHOPHOTO_WMS_LAYER=Ortho
|
GEOINTEL_GUEST_SESSION_TTL_SECONDS=7200
|
||||||
ORTHOPHOTO_RESOLUTION_M=1.0
|
|
||||||
ORTHOPHOTO_MIN_SIDE_M=128
|
# Explicit, bounded acquisition from the official Digitaal Vlaanderen WMS.
|
||||||
ORTHOPHOTO_MAX_SIDE_M=1024
|
ORTHOPHOTO_ENABLED=true
|
||||||
ORTHOPHOTO_CACHE_TTL_HOURS=24
|
ORTHOPHOTO_WMS_URL=https://geo.api.vlaanderen.be/OMWRGBMRVL/wms
|
||||||
|
SPW_ORTHOPHOTO_WMS_URL=https://geoservices.wallonie.be/arcgis/services/IMAGERIE/ORTHO_LAST/MapServer/WMSServer
|
||||||
# Explicit read-only edition checks for GRB, orthophoto, Statbel and ALZ publications.
|
BRUSSELS_ORTHOPHOTO_WMS_URL=https://geoservices-grid.irisnet.be/geoserver/urbisgrid/ows
|
||||||
# No feature, raster, Statbel distribution or ALZ archive is downloaded by these probes.
|
ORTHOPHOTO_WMS_LAYER=Ortho
|
||||||
SOURCE_CATALOG_PROBE_ENABLED=true
|
ORTHOPHOTO_RESOLUTION_M=1.0
|
||||||
SOURCE_CATALOG_GRB_WFS_URL=https://geo.api.vlaanderen.be/GRB/wfs
|
ORTHOPHOTO_MIN_SIDE_M=128
|
||||||
SOURCE_CATALOG_STATBEL_DCAT_URL=https://doc.statbel.be/publications/DCAT/DCAT_opendata_datasets.ttl
|
ORTHOPHOTO_MAX_SIDE_M=1024
|
||||||
SOURCE_CATALOG_STATBEL_MAX_RESPONSE_MB=5
|
ORTHOPHOTO_CACHE_TTL_HOURS=24
|
||||||
SOURCE_CATALOG_ALZ_RELEASE_URL=https://landbouwcijfers.vlaanderen.be/open-geodata-landbouwgebruikspercelen
|
|
||||||
SOURCE_CATALOG_PROBE_TIMEOUT_SECONDS=10
|
# Explicit read-only edition checks for GRB, orthophoto, Statbel and ALZ publications.
|
||||||
SOURCE_CATALOG_PROBE_MAX_RESPONSE_MB=2
|
# No feature, raster, Statbel distribution or ALZ archive is downloaded by these probes.
|
||||||
SOURCE_CATALOG_PROBE_CACHE_TTL_SECONDS=900
|
SOURCE_CATALOG_PROBE_ENABLED=true
|
||||||
|
SOURCE_CATALOG_GRB_WFS_URL=https://geo.api.vlaanderen.be/GRB/wfs
|
||||||
# Bounded official Flemish, Walloon and Brussels vectors, loaded only after a map selection.
|
SOURCE_CATALOG_STATBEL_DCAT_URL=https://doc.statbel.be/publications/DCAT/DCAT_opendata_datasets.ttl
|
||||||
OFFICIAL_VECTOR_ENABLED=true
|
SOURCE_CATALOG_STATBEL_MAX_RESPONSE_MB=5
|
||||||
BWK_WFS_URL=https://geo.api.vlaanderen.be/BWK/wfs
|
SOURCE_CATALOG_ALZ_RELEASE_URL=https://landbouwcijfers.vlaanderen.be/open-geodata-landbouwgebruikspercelen
|
||||||
DOV_SOIL_WFS_URL=https://www.dov.vlaanderen.be/geoserver/wfs
|
SOURCE_CATALOG_PROBE_TIMEOUT_SECONDS=10
|
||||||
SPW_PICC_ENABLED=true
|
SOURCE_CATALOG_PROBE_MAX_RESPONSE_MB=2
|
||||||
SPW_PICC_MAPSERVER_URL=https://geoservices.wallonie.be/arcgis/rest/services/TOPOGRAPHIE/PICC_VDIFF/MapServer
|
SOURCE_CATALOG_PROBE_CACHE_TTL_SECONDS=900
|
||||||
SPW_FLOOD_HAZARD_ENABLED=true
|
|
||||||
SPW_FLOOD_HAZARD_MAPSERVER_URL=https://geoservices.wallonie.be/arcgis/rest/services/EAU/ALEA_INOND/MapServer
|
# Bounded official Flemish, Walloon and Brussels vectors, loaded only after a map selection.
|
||||||
URBIS_ENABLED=true
|
OFFICIAL_VECTOR_ENABLED=true
|
||||||
URBIS_WFS_URL=https://geoservices-vector.irisnet.be/geoserver/urbisvector/ows
|
BWK_WFS_URL=https://geo.api.vlaanderen.be/BWK/wfs
|
||||||
OFFICIAL_VECTOR_MIN_SIDE_M=10
|
DOV_SOIL_WFS_URL=https://www.dov.vlaanderen.be/geoserver/wfs
|
||||||
OFFICIAL_VECTOR_MAX_SIDE_M=20000
|
SPW_PICC_ENABLED=true
|
||||||
OFFICIAL_VECTOR_PAGE_SIZE=1000
|
SPW_PICC_MAPSERVER_URL=https://geoservices.wallonie.be/arcgis/rest/services/TOPOGRAPHIE/PICC_VDIFF/MapServer
|
||||||
OFFICIAL_VECTOR_MAX_PAGES=200
|
SPW_FLOOD_HAZARD_ENABLED=true
|
||||||
OFFICIAL_VECTOR_MAX_FEATURES=100000
|
SPW_FLOOD_HAZARD_MAPSERVER_URL=https://geoservices.wallonie.be/arcgis/rest/services/EAU/ALEA_INOND/MapServer
|
||||||
OFFICIAL_VECTOR_TIMEOUT_SECONDS=180
|
URBIS_ENABLED=true
|
||||||
OFFICIAL_VECTOR_MAX_RESPONSE_MB=20
|
URBIS_WFS_URL=https://geoservices-vector.irisnet.be/geoserver/urbisvector/ows
|
||||||
OFFICIAL_VECTOR_MAX_TOTAL_RESPONSE_MB=256
|
OFFICIAL_VECTOR_MIN_SIDE_M=10
|
||||||
OFFICIAL_VECTOR_CACHE_TTL_HOURS=24
|
OFFICIAL_VECTOR_MAX_SIDE_M=20000
|
||||||
DHMV_ENABLED=true
|
OFFICIAL_VECTOR_PAGE_SIZE=1000
|
||||||
DHMV_WCS_URL=https://geo.api.vlaanderen.be/DHMV/wcs
|
OFFICIAL_VECTOR_MAX_PAGES=200
|
||||||
DHMV_RESOLUTION_M=5.0
|
OFFICIAL_VECTOR_MAX_FEATURES=100000
|
||||||
DHMV_MIN_SIDE_M=10
|
OFFICIAL_VECTOR_TIMEOUT_SECONDS=180
|
||||||
DHMV_MAX_SIDE_M=20000
|
OFFICIAL_VECTOR_MAX_RESPONSE_MB=20
|
||||||
DHMV_MAX_PIXELS=12000000
|
OFFICIAL_VECTOR_MAX_TOTAL_RESPONSE_MB=256
|
||||||
DHMV_TIMEOUT_SECONDS=300
|
OFFICIAL_VECTOR_CACHE_TTL_HOURS=24
|
||||||
DHMV_MAX_RESPONSE_MB=160
|
DHMV_ENABLED=true
|
||||||
FLOOD_HAZARD_ENABLED=true
|
DHMV_WCS_URL=https://geo.api.vlaanderen.be/DHMV/wcs
|
||||||
FLOOD_HAZARD_WCS_URL=https://geoservice.waterinfo.be/OGRK/wcs
|
DHMV_RESOLUTION_M=5.0
|
||||||
FLOOD_HAZARD_RESOLUTION_M=5.0
|
DHMV_MIN_SIDE_M=10
|
||||||
FLOOD_HAZARD_MIN_SIDE_M=10
|
DHMV_MAX_SIDE_M=20000
|
||||||
FLOOD_HAZARD_MAX_SIDE_M=20000
|
DHMV_MAX_PIXELS=12000000
|
||||||
FLOOD_HAZARD_MAX_PIXELS=12000000
|
DHMV_TIMEOUT_SECONDS=300
|
||||||
FLOOD_HAZARD_TIMEOUT_SECONDS=300
|
DHMV_MAX_RESPONSE_MB=160
|
||||||
FLOOD_HAZARD_MAX_RESPONSE_MB=160
|
FLOOD_HAZARD_ENABLED=true
|
||||||
BATHYMETRY_PROFILES_ENABLED=true
|
FLOOD_HAZARD_WCS_URL=https://geoservice.waterinfo.be/OGRK/wcs
|
||||||
BATHYMETRY_PROFILES_LAYER_URL=https://vha.waterinfo.be/arcgis/rest/services/digitale_atlas/MapServer/0
|
FLOOD_HAZARD_RESOLUTION_M=5.0
|
||||||
BATHYMETRY_WATERCOURSE_LAYER_URL=https://vha.waterinfo.be/arcgis/rest/services/digitale_atlas/MapServer/1
|
FLOOD_HAZARD_MIN_SIDE_M=10
|
||||||
BATHYMETRY_PROFILES_PAGE_SIZE=1000
|
FLOOD_HAZARD_MAX_SIDE_M=20000
|
||||||
BATHYMETRY_PROFILES_MAX_FEATURES=50000
|
FLOOD_HAZARD_MAX_PIXELS=12000000
|
||||||
BATHYMETRY_PROFILES_TIMEOUT_SECONDS=120
|
FLOOD_HAZARD_TIMEOUT_SECONDS=300
|
||||||
BATHYMETRY_PROFILES_MAX_RESPONSE_MB=32
|
FLOOD_HAZARD_MAX_RESPONSE_MB=160
|
||||||
MDK_BATHYMETRY_PROBE_ENABLED=true
|
BATHYMETRY_PROFILES_ENABLED=true
|
||||||
MDK_BATHYMETRY_WCS_URL=https://bathy.agentschapmdk.be/spatialfusionserver/services/ows/wcs/EL_wcs
|
BATHYMETRY_PROFILES_LAYER_URL=https://vha.waterinfo.be/arcgis/rest/services/digitale_atlas/MapServer/0
|
||||||
MDK_BATHYMETRY_PROBE_TIMEOUT_SECONDS=20
|
BATHYMETRY_WATERCOURSE_LAYER_URL=https://vha.waterinfo.be/arcgis/rest/services/digitale_atlas/MapServer/1
|
||||||
MDK_BATHYMETRY_PROBE_MAX_RESPONSE_MB=4
|
BATHYMETRY_PROFILES_PAGE_SIZE=1000
|
||||||
|
BATHYMETRY_PROFILES_MAX_FEATURES=50000
|
||||||
# Bounded MDK acquisition stays fail-closed until the readiness probe reports
|
BATHYMETRY_PROFILES_TIMEOUT_SECONDS=120
|
||||||
# "reachable" and an advertised coverage id is configured explicitly.
|
BATHYMETRY_PROFILES_MAX_RESPONSE_MB=32
|
||||||
MDK_BATHYMETRY_ACQUISITION_ENABLED=false
|
MDK_BATHYMETRY_PROBE_ENABLED=true
|
||||||
MDK_BATHYMETRY_COVERAGE_ID=
|
MDK_BATHYMETRY_WCS_URL=https://bathy.agentschapmdk.be/spatialfusionserver/services/ows/wcs/EL_wcs
|
||||||
MDK_BATHYMETRY_REQUEST_CRS=EPSG:4326
|
MDK_BATHYMETRY_PROBE_TIMEOUT_SECONDS=20
|
||||||
MDK_BATHYMETRY_MAX_BBOX_DEG2=0.25
|
MDK_BATHYMETRY_PROBE_MAX_RESPONSE_MB=4
|
||||||
MDK_BATHYMETRY_ACQUISITION_TIMEOUT_SECONDS=120
|
|
||||||
MDK_BATHYMETRY_ACQUISITION_MAX_RESPONSE_MB=160
|
# Bounded MDK acquisition stays fail-closed until the readiness probe reports
|
||||||
|
# "reachable" and an advertised coverage id is configured explicitly.
|
||||||
# Allowlisted Departement Omgeving policy rasters. Regional requests are
|
MDK_BATHYMETRY_ACQUISITION_ENABLED=false
|
||||||
# transferred as fixed 10 km WCS tiles before exact Area clipping.
|
MDK_BATHYMETRY_COVERAGE_ID=
|
||||||
THEMATIC_RASTER_ENABLED=true
|
MDK_BATHYMETRY_REQUEST_CRS=EPSG:4326
|
||||||
THEMATIC_RASTER_WCS_URL=https://www.mercator.vlaanderen.be/raadpleegdienstenmercatorpubliek/wcs
|
MDK_BATHYMETRY_MAX_BBOX_DEG2=0.25
|
||||||
THEMATIC_RASTER_MIN_SIDE_M=100
|
MDK_BATHYMETRY_ACQUISITION_TIMEOUT_SECONDS=120
|
||||||
THEMATIC_RASTER_MAX_SIDE_M=60000
|
MDK_BATHYMETRY_ACQUISITION_MAX_RESPONSE_MB=160
|
||||||
THEMATIC_RASTER_MAX_PIXELS=30000000
|
|
||||||
THEMATIC_RASTER_TIMEOUT_SECONDS=300
|
# Allowlisted Departement Omgeving policy rasters. Regional requests are
|
||||||
THEMATIC_RASTER_MAX_RESPONSE_MB=160
|
# transferred as fixed 10 km WCS tiles before exact Area clipping.
|
||||||
WALOUS_ENABLED=true
|
THEMATIC_RASTER_ENABLED=true
|
||||||
WALOUS_SOURCE_DIR=/app/storage/source-cache/walous
|
THEMATIC_RASTER_WCS_URL=https://www.mercator.vlaanderen.be/raadpleegdienstenmercatorpubliek/wcs
|
||||||
WALOUS_ANALYSIS_RESOLUTION_M=10
|
THEMATIC_RASTER_MIN_SIDE_M=100
|
||||||
WALOUS_MAX_SIDE_M=60000
|
THEMATIC_RASTER_MAX_SIDE_M=60000
|
||||||
WALOUS_MAX_PIXELS=36000000
|
THEMATIC_RASTER_MAX_PIXELS=30000000
|
||||||
SPW_TERRAIN_ENABLED=true
|
THEMATIC_RASTER_TIMEOUT_SECONDS=300
|
||||||
SPW_TERRAIN_SOURCE_DIR=/app/storage/source-cache/spw-terrain
|
THEMATIC_RASTER_MAX_RESPONSE_MB=160
|
||||||
SPW_TERRAIN_ANALYSIS_RESOLUTION_M=5
|
WALOUS_ENABLED=true
|
||||||
SPW_TERRAIN_MAX_SIDE_M=20000
|
WALOUS_SOURCE_DIR=/app/storage/source-cache/walous
|
||||||
SPW_TERRAIN_MAX_PIXELS=12000000
|
WALOUS_ANALYSIS_RESOLUTION_M=10
|
||||||
|
WALOUS_MAX_SIDE_M=60000
|
||||||
# Optional configured-YOLO runtime. Keep disabled unless a local model is mounted.
|
WALOUS_MAX_PIXELS=36000000
|
||||||
GEOINTEL_INSTALL_AI=false
|
SPW_TERRAIN_ENABLED=true
|
||||||
YOLO_ENABLED=false
|
SPW_TERRAIN_SOURCE_DIR=/app/storage/source-cache/spw-terrain
|
||||||
YOLO_MODELS_DIR=/app/models
|
SPW_TERRAIN_ANALYSIS_RESOLUTION_M=5
|
||||||
YOLO_MODEL_PATH=
|
SPW_TERRAIN_MAX_SIDE_M=20000
|
||||||
YOLO_MODEL_ID=yolo-configured
|
SPW_TERRAIN_MAX_PIXELS=12000000
|
||||||
YOLO_MODEL_DISPLAY_NAME=Configured YOLO detector
|
|
||||||
YOLO_MODEL_VERSION=
|
# Optional configured-YOLO runtime. Keep disabled unless a local model is mounted.
|
||||||
YOLO_CONFIG_DIR=/app/storage/ultralytics
|
GEOINTEL_INSTALL_AI=false
|
||||||
YOLO_DEVICE=cuda:0
|
YOLO_ENABLED=false
|
||||||
YOLO_REQUIRE_CUDA=true
|
YOLO_MODELS_DIR=/app/models
|
||||||
YOLO_MODEL_CLASSES=building
|
YOLO_MODEL_PATH=
|
||||||
YOLO_ENFORCE_VALIDATION_SCOPE=true
|
YOLO_MODEL_ID=yolo-configured
|
||||||
YOLO_VALIDATION_SCOPE_MANIFEST_PATH=/app/storage/operator-data/model-validation-scopes/active-building-model.json
|
YOLO_MODEL_DISPLAY_NAME=Configured YOLO detector
|
||||||
YOLO_VALIDATION_SCOPE_MANIFEST_SHA256=
|
YOLO_MODEL_VERSION=
|
||||||
# Deprecated display metadata; never used as an inference authorization gate.
|
YOLO_CONFIG_DIR=/app/storage/ultralytics
|
||||||
YOLO_VALIDATED_AREA_NAMES=Mol,Kempen
|
YOLO_DEVICE=cuda:0
|
||||||
YOLO_IMAGE_SIZE=640
|
YOLO_REQUIRE_CUDA=true
|
||||||
YOLO_MAX_TILES=100
|
YOLO_MODEL_CLASSES=building
|
||||||
YOLO_MAX_DETECTIONS=1000
|
YOLO_ENFORCE_VALIDATION_SCOPE=true
|
||||||
YOLO_DUPLICATE_IOU_THRESHOLD=0.5
|
YOLO_VALIDATION_SCOPE_MANIFEST_PATH=/app/storage/operator-data/model-validation-scopes/active-building-model.json
|
||||||
YOLO_BATCH_SIZE=1
|
YOLO_VALIDATION_SCOPE_MANIFEST_SHA256=
|
||||||
|
# Deprecated display metadata; never used as an inference authorization gate.
|
||||||
# Local segmentation models. GeoIntel never downloads model weights
|
YOLO_VALIDATED_AREA_NAMES=Mol,Kempen
|
||||||
# automatically; point these to existing local files to enable inference.
|
YOLO_IMAGE_SIZE=640
|
||||||
YOLO_SEG_ENABLED=false
|
YOLO_MAX_TILES=100
|
||||||
YOLO_SEG_MODEL_PATH=
|
YOLO_MAX_DETECTIONS=1000
|
||||||
YOLO_SEG_MODEL_ID=yolo-seg-configured
|
YOLO_DUPLICATE_IOU_THRESHOLD=0.5
|
||||||
YOLO_SEG_MODEL_DISPLAY_NAME=Configured YOLO segmentation
|
YOLO_BATCH_SIZE=1
|
||||||
YOLO_SEG_MODEL_VERSION=
|
|
||||||
SAM_ENABLED=false
|
# Local segmentation models. GeoIntel never downloads model weights
|
||||||
SAM_MODEL_PATH=
|
# automatically; point these to existing local files to enable inference.
|
||||||
SAM_MODEL_ID=sam-configured
|
YOLO_SEG_ENABLED=false
|
||||||
SAM_MODEL_DISPLAY_NAME=Configured SAM segmentation
|
YOLO_SEG_MODEL_PATH=
|
||||||
SAM_MODEL_VERSION=
|
YOLO_SEG_MODEL_ID=yolo-seg-configured
|
||||||
SEGMENTATION_MAX_MASKS_PER_TILE=300
|
YOLO_SEG_MODEL_DISPLAY_NAME=Configured YOLO segmentation
|
||||||
SEGMENTATION_DUPLICATE_IOU_THRESHOLD=0.5
|
YOLO_SEG_MODEL_VERSION=
|
||||||
|
SAM_ENABLED=false
|
||||||
# Local Ollama assistant. The all-in-one container reaches the Unraid host
|
SAM_MODEL_PATH=
|
||||||
# through Docker's host-gateway mapping; no Ollama port is exposed by GeoIntel.
|
SAM_MODEL_ID=sam-configured
|
||||||
OLLAMA_ENABLED=true
|
SAM_MODEL_DISPLAY_NAME=Configured SAM segmentation
|
||||||
OLLAMA_BASE_URL=http://host.docker.internal:11434
|
SAM_MODEL_VERSION=
|
||||||
OLLAMA_DEFAULT_MODEL=qwen3.5:9b
|
SEGMENTATION_MAX_MASKS_PER_TILE=300
|
||||||
OLLAMA_TIMEOUT_SECONDS=120
|
SEGMENTATION_DUPLICATE_IOU_THRESHOLD=0.5
|
||||||
OLLAMA_MAX_OUTPUT_TOKENS=1200
|
|
||||||
OLLAMA_CONTEXT_TOKENS=16384
|
# Local Ollama assistant. The all-in-one container reaches the Unraid host
|
||||||
|
# through Docker's host-gateway mapping; no Ollama port is exposed by GeoIntel.
|
||||||
|
OLLAMA_ENABLED=true
|
||||||
|
OLLAMA_BASE_URL=http://host.docker.internal:11434
|
||||||
|
OLLAMA_DEFAULT_MODEL=qwen3.5:9b
|
||||||
|
OLLAMA_TIMEOUT_SECONDS=120
|
||||||
|
OLLAMA_MAX_OUTPUT_TOKENS=1200
|
||||||
|
OLLAMA_CONTEXT_TOKENS=16384
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ GEOINTEL_AUTH_USERNAME="${GEOINTEL_AUTH_USERNAME:-}"
|
|||||||
GEOINTEL_AUTH_PASSWORD_HASH="${GEOINTEL_AUTH_PASSWORD_HASH:-}"
|
GEOINTEL_AUTH_PASSWORD_HASH="${GEOINTEL_AUTH_PASSWORD_HASH:-}"
|
||||||
GEOINTEL_AUTH_SESSION_SECRET="${GEOINTEL_AUTH_SESSION_SECRET:-}"
|
GEOINTEL_AUTH_SESSION_SECRET="${GEOINTEL_AUTH_SESSION_SECRET:-}"
|
||||||
GEOINTEL_AUTH_SESSION_TTL_SECONDS="${GEOINTEL_AUTH_SESSION_TTL_SECONDS:-43200}"
|
GEOINTEL_AUTH_SESSION_TTL_SECONDS="${GEOINTEL_AUTH_SESSION_TTL_SECONDS:-43200}"
|
||||||
|
GEOINTEL_PUBLIC_BASE_URL="${GEOINTEL_PUBLIC_BASE_URL:-}"
|
||||||
|
GEOINTEL_AUTHENTIK_ISSUER="${GEOINTEL_AUTHENTIK_ISSUER:-}"
|
||||||
|
GEOINTEL_AUTHENTIK_CLIENT_ID="${GEOINTEL_AUTHENTIK_CLIENT_ID:-}"
|
||||||
|
GEOINTEL_AUTHENTIK_CLIENT_SECRET="${GEOINTEL_AUTHENTIK_CLIENT_SECRET:-}"
|
||||||
|
GEOINTEL_AUTHENTIK_ALLOWED_EMAIL="${GEOINTEL_AUTHENTIK_ALLOWED_EMAIL:-}"
|
||||||
GEOINTEL_GUEST_ACCESS_ENABLED="${GEOINTEL_GUEST_ACCESS_ENABLED:-true}"
|
GEOINTEL_GUEST_ACCESS_ENABLED="${GEOINTEL_GUEST_ACCESS_ENABLED:-true}"
|
||||||
GEOINTEL_GUEST_DISPLAY_NAME="${GEOINTEL_GUEST_DISPLAY_NAME:-Gast}"
|
GEOINTEL_GUEST_DISPLAY_NAME="${GEOINTEL_GUEST_DISPLAY_NAME:-Gast}"
|
||||||
GEOINTEL_GUEST_SESSION_TTL_SECONDS="${GEOINTEL_GUEST_SESSION_TTL_SECONDS:-7200}"
|
GEOINTEL_GUEST_SESSION_TTL_SECONDS="${GEOINTEL_GUEST_SESSION_TTL_SECONDS:-7200}"
|
||||||
@@ -212,6 +217,19 @@ validate_runtime_config() {
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local authentik_count=0
|
||||||
|
for value in "$GEOINTEL_AUTHENTIK_ISSUER" "$GEOINTEL_AUTHENTIK_CLIENT_ID" "$GEOINTEL_AUTHENTIK_CLIENT_SECRET" "$GEOINTEL_AUTHENTIK_ALLOWED_EMAIL"; do
|
||||||
|
if [ -n "$value" ]; then authentik_count=$((authentik_count + 1)); fi
|
||||||
|
done
|
||||||
|
if [ "$authentik_count" -ne 0 ] && [ "$authentik_count" -ne 4 ]; then
|
||||||
|
echo "All GEOINTEL_AUTHENTIK_* values must be configured together." >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
if [ "$authentik_count" -eq 4 ]; then
|
||||||
|
case "$GEOINTEL_AUTHENTIK_ISSUER" in https://*) ;; *) echo "GEOINTEL_AUTHENTIK_ISSUER must use HTTPS." >&2; return 2 ;; esac
|
||||||
|
case "$GEOINTEL_PUBLIC_BASE_URL" in https://*) ;; *) echo "GEOINTEL_PUBLIC_BASE_URL must use HTTPS for Authentik." >&2; return 2 ;; esac
|
||||||
|
fi
|
||||||
|
|
||||||
case "$GEOINTEL_GUEST_ACCESS_ENABLED" in
|
case "$GEOINTEL_GUEST_ACCESS_ENABLED" in
|
||||||
true|false) ;;
|
true|false) ;;
|
||||||
*)
|
*)
|
||||||
@@ -319,6 +337,11 @@ docker run -d \
|
|||||||
-e GEOINTEL_AUTH_PASSWORD_HASH="$GEOINTEL_AUTH_PASSWORD_HASH" \
|
-e GEOINTEL_AUTH_PASSWORD_HASH="$GEOINTEL_AUTH_PASSWORD_HASH" \
|
||||||
-e GEOINTEL_AUTH_SESSION_SECRET="$GEOINTEL_AUTH_SESSION_SECRET" \
|
-e GEOINTEL_AUTH_SESSION_SECRET="$GEOINTEL_AUTH_SESSION_SECRET" \
|
||||||
-e GEOINTEL_AUTH_SESSION_TTL_SECONDS="$GEOINTEL_AUTH_SESSION_TTL_SECONDS" \
|
-e GEOINTEL_AUTH_SESSION_TTL_SECONDS="$GEOINTEL_AUTH_SESSION_TTL_SECONDS" \
|
||||||
|
-e GEOINTEL_PUBLIC_BASE_URL="$GEOINTEL_PUBLIC_BASE_URL" \
|
||||||
|
-e GEOINTEL_AUTHENTIK_ISSUER="$GEOINTEL_AUTHENTIK_ISSUER" \
|
||||||
|
-e GEOINTEL_AUTHENTIK_CLIENT_ID="$GEOINTEL_AUTHENTIK_CLIENT_ID" \
|
||||||
|
-e GEOINTEL_AUTHENTIK_CLIENT_SECRET="$GEOINTEL_AUTHENTIK_CLIENT_SECRET" \
|
||||||
|
-e GEOINTEL_AUTHENTIK_ALLOWED_EMAIL="$GEOINTEL_AUTHENTIK_ALLOWED_EMAIL" \
|
||||||
-e GEOINTEL_GUEST_ACCESS_ENABLED="$GEOINTEL_GUEST_ACCESS_ENABLED" \
|
-e GEOINTEL_GUEST_ACCESS_ENABLED="$GEOINTEL_GUEST_ACCESS_ENABLED" \
|
||||||
-e GEOINTEL_GUEST_DISPLAY_NAME="$GEOINTEL_GUEST_DISPLAY_NAME" \
|
-e GEOINTEL_GUEST_DISPLAY_NAME="$GEOINTEL_GUEST_DISPLAY_NAME" \
|
||||||
-e GEOINTEL_GUEST_SESSION_TTL_SECONDS="$GEOINTEL_GUEST_SESSION_TTL_SECONDS" \
|
-e GEOINTEL_GUEST_SESSION_TTL_SECONDS="$GEOINTEL_GUEST_SESSION_TTL_SECONDS" \
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ Authenticated operator sessions return `role: "operator"`. Guest sessions
|
|||||||
return `role: "guest"` and the UUID of their bound demo project in
|
return `role: "guest"` and the UUID of their bound demo project in
|
||||||
`guest_project_id`.
|
`guest_project_id`.
|
||||||
|
|
||||||
|
`authentik_enabled` in the session payload indicates whether the landing page
|
||||||
|
may offer the additive Authentik operator login. Existing local and guest
|
||||||
|
access remain unchanged.
|
||||||
|
|
||||||
### POST `/api/v1/auth/login`
|
### POST `/api/v1/auth/login`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -136,6 +140,14 @@ the request body against the guest-session scope.
|
|||||||
Clears the browser cookie and returns an unauthenticated session. Logout is
|
Clears the browser cookie and returns an unauthenticated session. Logout is
|
||||||
idempotent and remains callable when the current cookie is missing or expired.
|
idempotent and remains callable when the current cookie is missing or expired.
|
||||||
|
|
||||||
|
### GET `/api/v1/auth/authentik/start`
|
||||||
|
|
||||||
|
Starts authorization-code OIDC with PKCE, state and nonce for the configured
|
||||||
|
single operator. The exact callback is `/api/v1/auth/authentik/callback`.
|
||||||
|
Only the configured, verified operator e-mail is accepted; success creates the
|
||||||
|
same operator session as local login. These redirect endpoints are the only
|
||||||
|
additional non-envelope authentication responses.
|
||||||
|
|
||||||
## Health
|
## Health
|
||||||
|
|
||||||
### GET `/health/live`
|
### GET `/health/live`
|
||||||
|
|||||||
@@ -12947,3 +12947,8 @@ Open:
|
|||||||
- Kept the historical evidence boundary explicit: this runtime receipt does not
|
- Kept the historical evidence boundary explicit: this runtime receipt does not
|
||||||
invent human review, a historical training commit/container, protected-test
|
invent human review, a historical training commit/container, protected-test
|
||||||
independence, national validity or a new promotion decision.
|
independence, national validity or a new promotion decision.
|
||||||
|
# 2026-08-26 — Additive Authentik operator login
|
||||||
|
|
||||||
|
- Added authorization-code OIDC with PKCE, signed state, nonce, strict issuer/audience validation and a verified e-mail allowlist.
|
||||||
|
- Kept the existing local single-operator login and API-enforced project-scoped guest demo unchanged.
|
||||||
|
- Added the Authentik action to the existing landing access card and documented the callback/environment contract.
|
||||||
|
|||||||
@@ -1244,3 +1244,4 @@ This file now starts with the current implementation status. Older preparation/b
|
|||||||
through a bottom rail and remove clipped result metrics.
|
through a bottom rail and remove clipped result metrics.
|
||||||
- [ ] Repeat the responsive audit with a physical touch device and screen
|
- [ ] Repeat the responsive audit with a physical touch device and screen
|
||||||
reader before claiming full mobile accessibility certification.
|
reader before claiming full mobile accessibility certification.
|
||||||
|
- [x] Offer Authentik as an additive single-operator login while retaining local recovery and the scoped guest demo.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ function App(): JSX.Element {
|
|||||||
<LandingPage
|
<LandingPage
|
||||||
serviceError={sessionError}
|
serviceError={sessionError}
|
||||||
guestAccessEnabled={session.guest_access_enabled}
|
guestAccessEnabled={session.guest_access_enabled}
|
||||||
|
authentikEnabled={session.authentik_enabled}
|
||||||
onAuthenticated={handleAuthenticated}
|
onAuthenticated={handleAuthenticated}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ interface LandingPageProps {
|
|||||||
onAuthenticated: (session: AuthSession) => void
|
onAuthenticated: (session: AuthSession) => void
|
||||||
serviceError?: string | null
|
serviceError?: string | null
|
||||||
guestAccessEnabled?: boolean
|
guestAccessEnabled?: boolean
|
||||||
|
authentikEnabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const capabilityItems = [
|
const capabilityItems = [
|
||||||
@@ -62,6 +63,7 @@ export function LandingPage({
|
|||||||
onAuthenticated,
|
onAuthenticated,
|
||||||
serviceError = null,
|
serviceError = null,
|
||||||
guestAccessEnabled = false,
|
guestAccessEnabled = false,
|
||||||
|
authentikEnabled = false,
|
||||||
}: LandingPageProps): JSX.Element {
|
}: LandingPageProps): JSX.Element {
|
||||||
const [username, setUsername] = useState('')
|
const [username, setUsername] = useState('')
|
||||||
const [password, setPassword] = useState('')
|
const [password, setPassword] = useState('')
|
||||||
@@ -247,6 +249,13 @@ export function LandingPage({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form onSubmit={submitLogin} aria-busy={pendingAction === 'operator'}>
|
<form onSubmit={submitLogin} aria-busy={pendingAction === 'operator'}>
|
||||||
|
{authentikEnabled ? (
|
||||||
|
<a className="landing-authentik-submit" href="/api/v1/auth/authentik/start">
|
||||||
|
<ShieldCheck aria-hidden="true" />
|
||||||
|
Aanmelden met Authentik
|
||||||
|
</a>
|
||||||
|
) : null}
|
||||||
|
{authentikEnabled ? <div className="landing-access-divider"><span>of met lokale operatorgegevens</span></div> : null}
|
||||||
<label htmlFor="login-username">Gebruikersnaam</label>
|
<label htmlFor="login-username">Gebruikersnaam</label>
|
||||||
<input
|
<input
|
||||||
ref={usernameRef}
|
ref={usernameRef}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export interface AuthSession {
|
|||||||
expires_at: string | null
|
expires_at: string | null
|
||||||
role: 'operator' | 'guest' | null
|
role: 'operator' | 'guest' | null
|
||||||
guest_access_enabled: boolean
|
guest_access_enabled: boolean
|
||||||
|
authentik_enabled?: boolean
|
||||||
guest_project_id: string | null
|
guest_project_id: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -793,6 +793,24 @@ body.landing-body {
|
|||||||
box-shadow: var(--gi-shadow-md);
|
box-shadow: var(--gi-shadow-md);
|
||||||
transition: background 160ms ease, transform 160ms ease, box-shadow 160ms ease;
|
transition: background 160ms ease, transform 160ms ease, box-shadow 160ms ease;
|
||||||
}
|
}
|
||||||
|
.landing-authentik-submit {
|
||||||
|
display: inline-flex;
|
||||||
|
min-height: 3rem;
|
||||||
|
gap: 0.55rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 1px solid var(--landing-primary);
|
||||||
|
border-radius: var(--gi-radius-md);
|
||||||
|
padding: 0.72rem 1rem;
|
||||||
|
background: var(--landing-primary);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.77rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: var(--gi-shadow-md);
|
||||||
|
}
|
||||||
|
.landing-authentik-submit:hover { background: var(--landing-primary-strong); color: #fff; }
|
||||||
|
.landing-authentik-submit svg { width: 1rem; height: 1rem; }
|
||||||
|
|
||||||
.landing-operator-submit:hover:not(:disabled) {
|
.landing-operator-submit:hover:not(:disabled) {
|
||||||
background: var(--landing-primary-strong);
|
background: var(--landing-primary-strong);
|
||||||
|
|||||||
Reference in New Issue
Block a user