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
+12 -12
View File
@@ -14,35 +14,35 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
.nav a { color: #6c757d; 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: #0066cc; border-bottom-color: #0066cc; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #fff; border-radius: 12px; padding: 32px; margin-bottom: 32px; border-left: 4px solid #0066cc; }
.philosophy { background: #fff; border-radius: var(--radius-md); padding: 32px; margin-bottom: 32px; border-left: 4px solid #0066cc; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 16px; color: #1a1a1a; }
.philosophy p { color: #495057; margin-bottom: 12px; }
.philosophy ul { margin-left: 20px; color: #495057; }
.philosophy li { margin-bottom: 8px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-bottom: 32px; }
.stat-card { background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.stat-card { background: #fff; border-radius: var(--radius-md); padding: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.stat-card h3 { font-size: 0.75rem; color: #6c757d; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #1a1a1a; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #28a745; }
.section { background: #fff; border-radius: 12px; padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.section { background: #fff; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.section h2 { font-size: 1.1rem; margin-bottom: 16px; color: #1a1a1a; }
.project-card { border: 1px solid #e9ecef; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.project-card { border: 1px solid #e9ecef; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.project-card h3 { font-size: 1rem; margin-bottom: 8px; }
.project-card .meta { font-size: 0.8rem; color: #6c757d; margin-bottom: 8px; }
.project-card .findings { font-size: 0.85rem; color: #495057; }
.project-card .findings li { margin-bottom: 4px; }
.score { display: inline-block; padding: 4px 12px; border-radius: 4px; font-size: 0.75rem; font-weight: 600; }
.score { display: inline-block; padding: 4px 12px; border-radius: var(--radius-sm); font-size: 0.75rem; font-weight: 600; }
.score.high { background: #d4edda; color: #155724; }
.score.medium { background: #fff3cd; color: #856404; }
.score.low { background: #f8d7da; color: #721c24; }
.discrepancy { background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.discrepancy { background: #fff3cd; border: 1px solid #ffeaa7; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.discrepancy h4 { color: #856404; margin-bottom: 8px; }
.discrepancy p { font-size: 0.85rem; color: #495057; }
.positive { background: #d4edda; border: 1px solid #c3e6cb; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.positive { background: #d4edda; border: 1px solid #c3e6cb; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.positive h4 { color: #155724; margin-bottom: 8px; }
.framework-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.framework-card { border: 1px solid #e9ecef; border-radius: 8px; padding: 16px; }
.framework-card { border: 1px solid #e9ecef; border-radius: var(--radius-md); padding: 16px; }
.framework-card h4 { font-size: 0.95rem; margin-bottom: 8px; }
.framework-card p { font-size: 0.8rem; color: #6c757d; }
</style>
@@ -157,7 +157,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
<p style="color: #6c757d; margin-bottom: 16px;">These findings indicate areas where additional verification may be valuable. They are not conclusions of wrongdoing.</p>
<div class="discrepancy">
<h4>⚠️ Schedule Variance - Mogadishu Primary School</h4>
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Schedule Variance - Mogadishu Primary School</h4>
<p><strong>Reported:</strong> 95% complete (June 2026)<br>
<strong>Observed:</strong> 85% complete (July 2026)<br>
<strong>Evidence:</strong> Field observation, Satellite, AI analysis<br>
@@ -166,7 +166,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
</div>
<div class="discrepancy">
<h4>⚠️ Activity Gap - Lagos Road Rehabilitation</h4>
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Activity Gap - Lagos Road Rehabilitation</h4>
<p><strong>Reported:</strong> Active construction<br>
<strong>Observed:</strong> No activity for 90 days, equipment removed<br>
<strong>Evidence:</strong> Field observation, Satellite time-series<br>
@@ -180,14 +180,14 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; back
<p style="color: #6c757d; margin-bottom: 16px;">Projects demonstrating strong implementation and sustained operation. These enable benchmarking and dissemination of successful practices.</p>
<div class="positive">
<h4> Accra Solar Microgrid - Ghana</h4>
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Accra Solar Microgrid - Ghana</h4>
<p><strong>SII Score:</strong> 89/100 | <strong>Confidence:</strong> 92%<br>
<strong>Strengths:</strong> Strong implementation, Sustained operation (24+ months), High community utilization, Long-term maintenance observed, Positive environmental outcomes<br>
<strong>Benchmark Category:</strong> Energy Infrastructure</p>
</div>
<div class="positive">
<h4> Nairobi Digital Health Records - Kenya</h4>
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Nairobi Digital Health Records - Kenya</h4>
<p><strong>SII Score:</strong> 84/100 | <strong>Confidence:</strong> 86%<br>
<strong>Strengths:</strong> Operational continuity, Staff training evident, Patient utilization increasing, Data transparency<br>
<strong>Benchmark Category:</strong> Digital Health</p>