From 56d72eeec23aae6291d31da23d7ffccbbf5b0fed Mon Sep 17 00:00:00 2001 From: Yvv Date: Sat, 25 Apr 2026 00:34:49 +0200 Subject: [PATCH] Auth : mode prototype factice en prod + fix test DB manquante MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Login : panneau proto-mode en avant quand DEMO_MODE actif (profils API) masque le formulaire extension-required ; note trustWallet à venir - auth.ts : TODO trustWallet avec protocole postMessage prévu - routers/auth.py : TODO trustWallet au point de vérification signature - test_middleware : fixture _create_tables (autouse) — ASGITransport ne déclenche pas le lifespan, init_db() ne tournait pas → duniter_identities introuvable au verify ; 224/224 passent Co-Authored-By: Claude Sonnet 4.6 --- backend/app/routers/auth.py | 6 +- backend/app/tests/test_middleware.py | 13 ++++ frontend/app/pages/login.vue | 103 +++++++++++++++------------ frontend/app/stores/auth.ts | 3 + 4 files changed, 80 insertions(+), 45 deletions(-) diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index 2175626..02e7f24 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -132,7 +132,11 @@ async def verify_challenge( detail="Challenge invalide", ) - # 4. Verify signature (bypass for demo profiles in dev/demo mode) + # 4. Verify signature + # TODO: trustWallet — déléguer la vérification au protocole trustWallet (librodrome) + # Quand trustWallet sera disponible : remplacer le bloc ci-dessous par une vérification + # du token signé fourni par trustWallet (JWT ou preuve Ed25519 via iframe postMessage). + # Le bypass DEMO_MODE sera alors supprimé. _demo_addresses = {p["address"] for p in DEV_PROFILES} is_demo_bypass = (settings.DEMO_MODE or settings.ENVIRONMENT == "development") and payload.address in _demo_addresses diff --git a/backend/app/tests/test_middleware.py b/backend/app/tests/test_middleware.py index eab2912..5f0b79f 100644 --- a/backend/app/tests/test_middleware.py +++ b/backend/app/tests/test_middleware.py @@ -14,8 +14,21 @@ from __future__ import annotations import pytest from httpx import ASGITransport, AsyncClient +import app.models # noqa: F401 — registers all models with Base.metadata before create_all +from app.database import init_db from app.main import app + +@pytest.fixture(scope="module", autouse=True) +async def _create_tables(): + """Create DB tables once for this module. + + ASGITransport does not trigger the FastAPI lifespan, so init_db() would + never run. Tests that hit endpoints backed by the DB need the tables to + exist beforehand. + """ + await init_db() + ORIGIN = "http://localhost:3002" CHALLENGE_URL = "/api/v1/auth/challenge" VERIFY_URL = "/api/v1/auth/verify" diff --git a/frontend/app/pages/login.vue b/frontend/app/pages/login.vue index 6ba7d2a..1f37039 100644 --- a/frontend/app/pages/login.vue +++ b/frontend/app/pages/login.vue @@ -100,6 +100,8 @@ const activeStepIndex = computed(() => { } }) +const isProtoMode = computed(() => devProfiles.value.length > 0) + onMounted(() => { if (auth.isAuthenticated) { router.push('/') @@ -166,45 +168,50 @@ onMounted(() => { Connecte. Redirection... - - - - -
-
- - Mode Dev — Connexion rapide + + - - + +
@@ -453,32 +460,40 @@ onMounted(() => { cursor: not-allowed; } -/* Dev panel */ -.dev-panel { - border: 2px dashed var(--mood-warning, #f59e0b); +/* Proto panel */ +.proto-panel { border-radius: 16px; padding: 1rem; - background: rgba(245, 158, 11, 0.04); + background: var(--mood-accent-soft); + box-shadow: 0 2px 12px var(--mood-shadow, rgba(0,0,0,0.06)); } -.dev-panel__header { +.proto-panel__header { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; font-weight: 700; - color: var(--mood-warning, #f59e0b); + color: var(--mood-accent); margin-bottom: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; } -.dev-panel__profiles { +.proto-panel__profiles { display: flex; flex-direction: column; gap: 0.5rem; } +.proto-panel__note { + margin-top: 0.75rem; + font-size: 0.75rem; + color: var(--mood-text-muted); + opacity: 0.7; + text-align: center; +} + .dev-profile { display: flex; align-items: center; diff --git a/frontend/app/stores/auth.ts b/frontend/app/stores/auth.ts index 171d6c4..202871c 100644 --- a/frontend/app/stores/auth.ts +++ b/frontend/app/stores/auth.ts @@ -11,6 +11,9 @@ * * The extension signs {challenge} to match the backend verifier. */ +// TODO: trustWallet — remplacer par postMessage vers l'iframe trustWallet (librodrome) +// Protocole prévu : window.postMessage({ type: 'LD_SIGN_REQUEST', address, challenge }) +// → trustWallet répond { type: 'LD_SIGN_RESPONSE', signature } async function _signWithExtension(address: string, challenge: string): Promise { const { web3Enable, web3FromAddress } = await import('@polkadot/extension-dapp') const { stringToHex } = await import('@polkadot/util')