feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+23 -23
View File
@@ -14,43 +14,43 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
.nav a { color: #94a3b8; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #38bdf8; border-bottom-color: #38bdf8; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #1e293b; border-radius: 12px; padding: 32px; margin-bottom: 32px; border-left: 4px solid #38bdf8; }
.philosophy { background: #1e293b; border-radius: var(--radius-md); padding: 32px; margin-bottom: 32px; border-left: 4px solid #38bdf8; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 16px; color: #f8fafc; }
.philosophy p { color: #cbd5e1; margin-bottom: 12px; }
.philosophy .process { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
.process-step { background: #334155; border-radius: 8px; padding: 16px; text-align: center; }
.process-step { background: #334155; border-radius: var(--radius-md); padding: 16px; text-align: center; }
.process-step .number { font-size: 1.5rem; font-weight: 700; color: #38bdf8; }
.process-step .name { font-size: 0.9rem; color: #f8fafc; margin-top: 8px; }
.process-step .desc { font-size: 0.75rem; color: #94a3b8; margin-top: 4px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-bottom: 32px; }
.stat-card { background: #1e293b; border-radius: 12px; padding: 24px; border: 1px solid #334155; }
.stat-card { background: #1e293b; border-radius: var(--radius-md); padding: 24px; border: 1px solid #334155; }
.stat-card h3 { font-size: 0.75rem; color: #94a3b8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #f8fafc; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #4ade80; }
.section { background: #1e293b; border-radius: 12px; padding: 24px; margin-bottom: 24px; border: 1px solid #334155; }
.section { background: #1e293b; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; border: 1px solid #334155; }
.section h2 { font-size: 1.1rem; margin-bottom: 16px; color: #f8fafc; }
.data-source { display: flex; align-items: center; gap: 12px; padding: 12px; background: #334155; border-radius: 8px; margin-bottom: 8px; }
.data-source .icon { width: 40px; height: 40px; background: #475569; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
.data-source { display: flex; align-items: center; gap: 12px; padding: 12px; background: #334155; border-radius: var(--radius-md); margin-bottom: 8px; }
.data-source .icon { width: 40px; height: 40px; background: #475569; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
.data-source .info { flex: 1; }
.data-source .info h4 { font-size: 0.9rem; color: #f8fafc; }
.data-source .info p { font-size: 0.75rem; color: #94a3b8; }
.data-source .status { font-size: 0.75rem; padding: 4px 8px; border-radius: 4px; }
.data-source .status { font-size: 0.75rem; padding: 4px 8px; border-radius: var(--radius-sm); }
.data-source .status.active { background: #166534; color: #4ade80; }
.event-card { background: #334155; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.event-card { background: #334155; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.event-card h4 { font-size: 0.95rem; margin-bottom: 8px; }
.event-card .meta { font-size: 0.8rem; color: #94a3b8; margin-bottom: 8px; }
.event-card .severity { display: inline-block; padding: 3px 10px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; }
.event-card .severity { display: inline-block; padding: 3px 10px; border-radius: var(--radius-sm); font-size: 0.7rem; font-weight: 600; }
.event-card .severity.high { background: #7f1d1d; color: #fca5a5; }
.event-card .severity.medium { background: #713f12; color: #fde047; }
.event-card .severity.low { background: #1e3a5f; color: #93c5fd; }
.confidence-bar { background: #334155; border-radius: 4px; height: 8px; overflow: hidden; margin-top: 8px; }
.confidence-bar .fill { height: 100%; border-radius: 4px; }
.confidence-bar { background: #334155; border-radius: var(--radius-sm); height: 8px; overflow: hidden; margin-top: 8px; }
.confidence-bar .fill { height: 100%; border-radius: var(--radius-sm); }
.confidence-bar .fill.high { background: #4ade80; }
.confidence-bar .fill.medium { background: #fbbf24; }
.confidence-bar .fill.low { background: #f87171; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.insight-card { background: #334155; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.insight-card { background: #334155; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.insight-card h4 { font-size: 0.9rem; margin-bottom: 8px; color: #38bdf8; }
.insight-card p { font-size: 0.85rem; color: #cbd5e1; }
</style>
@@ -142,7 +142,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
<h2>Continuous Data Acquisition</h2>
<div class="data-source">
<div class="icon">📊</div>
<div class="icon"></div>
<div class="info">
<h4>Official Project Information</h4>
<p>Development agency portals, government databases, procurement portals, evaluation reports</p>
@@ -151,7 +151,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="data-source">
<div class="icon">📰</div>
<div class="icon"></div>
<div class="info">
<h4>News Intelligence</h4>
<p>International, national, regional news, RSS feeds, development and humanitarian news</p>
@@ -160,7 +160,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="data-source">
<div class="icon">🌐</div>
<div class="icon"></div>
<div class="info">
<h4>Public Communications</h4>
<p>Press releases, official websites, social media, research publications</p>
@@ -169,7 +169,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="data-source">
<div class="icon">🛰️</div>
<div class="icon"></div>
<div class="info">
<h4>Geospatial Intelligence</h4>
<p>Satellite imagery, night lights, land cover, construction detection, environmental monitoring</p>
@@ -178,7 +178,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="data-source">
<div class="icon">📱</div>
<div class="icon"></div>
<div class="info">
<h4>QUIXZOOM Reality Network</h4>
<p>Field observations, photographic evidence, infrastructure inspections, community observations</p>
@@ -187,7 +187,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="data-source">
<div class="icon">📈</div>
<div class="icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div class="info">
<h4>Open Data</h4>
<p>Population, weather, climate, health indicators, economic data, conflict datasets</p>
@@ -201,7 +201,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
<h2>Recent Events Detected</h2>
<div class="event-card">
<h4>🌊 Severe flooding in Mogadishu region</h4>
<h4> Severe flooding in Mogadishu region</h4>
<div class="meta">Somalia • June 15, 2026 • Natural Disaster</div>
<p style="font-size: 0.85rem; color: #cbd5e1; margin-bottom: 8px;">Heavy rainfall caused flooding affecting infrastructure accessibility</p>
<div>
@@ -214,7 +214,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="event-card">
<h4>🏗️ Construction delay due to seasonal rainfall</h4>
<h4><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg> Construction delay due to seasonal rainfall</h4>
<div class="meta">Nigeria • May 20, 2026 • Construction Delay</div>
<p style="font-size: 0.85rem; color: #cbd5e1; margin-bottom: 8px;">Road rehabilitation delayed due to extended rainy season</p>
<div>
@@ -231,7 +231,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
<h2>Recent Fusion Insights</h2>
<div class="insight-card">
<h4>🔗 Mogadishu Primary School</h4>
<h4> Mogadishu Primary School</h4>
<p>Construction delay likely due to flooding + poor drainage</p>
<div style="margin-top: 8px;">
<span style="font-size: 0.75rem; color: #94a3b8;">Confidence: 78% • Sources fused: 5</span>
@@ -239,7 +239,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="insight-card">
<h4>🔗 Kampala Water Supply</h4>
<h4> Kampala Water Supply</h4>
<p>Operational sustainability high based on maintenance records + community feedback</p>
<div style="margin-top: 8px;">
<span style="font-size: 0.75rem; color: #94a3b8;">Confidence: 88% • Sources fused: 6</span>
@@ -247,7 +247,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="insight-card">
<h4>🔗 Accra Solar Microgrid</h4>
<h4> Accra Solar Microgrid</h4>
<p>24 months continuous operation verified across 4 independent sources</p>
<div style="margin-top: 8px;">
<span style="font-size: 0.75rem; color: #94a3b8;">Confidence: 92% • Sources fused: 4</span>