OSM-Verknüpfung (Modell A): OAuth2-Fundament für Nutzer-Beiträge
- Tabelle user_osm (access_token verschlüsselt at rest via Fernet, Schlüssel aus JWT_SECRET abgeleitet oder OSM_TOKEN_KEY). - Router /api/osm-auth: authorize (signierter state mit user_id+CSRF), callback (Code-Tausch + OSM-Name holen + speichern), status, unlink. - Profil-UI (Settings): "OSM-Konto verknüpfen" / verknüpft-als / trennen, hundehalter-spezifische Motivation. - cryptography in requirements. - Basis für dog=yes-Beiträge + Gamification/Pro (folgt). Staging-Branch. ENV nötig: OSM_CLIENT_ID, OSM_CLIENT_SECRET (Redirect-URI default staging).
This commit is contained in:
parent
4bc7454258
commit
46caa05020
5 changed files with 237 additions and 0 deletions
|
|
@ -672,6 +672,13 @@ window.Page_settings = (() => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="by-card-section-header">OpenStreetMap – die Karte mitverbessern</div>
|
||||
<div id="settings-osm-body" class="p-4">
|
||||
<div class="text-sm-muted">Lädt…</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body" style="padding:0">
|
||||
<div class="sidebar-item" data-page="dog-profile"
|
||||
|
|
@ -925,6 +932,54 @@ window.Page_settings = (() => {
|
|||
});
|
||||
}).catch(() => {});
|
||||
|
||||
// OSM-Account-Verknüpfung (Modell A) — Status laden + Buttons verdrahten
|
||||
(function _osmLink() {
|
||||
const el = document.getElementById('settings-osm-body');
|
||||
if (!el) return;
|
||||
API.get('/osm-auth/status').then(st => {
|
||||
if (st.linked) {
|
||||
el.innerHTML = `
|
||||
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap">
|
||||
<svg class="ph-icon" style="color:var(--c-success)" aria-hidden="true"><use href="/icons/phosphor.svg#check-circle"></use></svg>
|
||||
<span style="font-size:var(--text-sm)">Verknüpft als <strong>${UI.escape(st.osm_name)}</strong></span>
|
||||
</div>
|
||||
<button id="settings-osm-unlink"
|
||||
style="margin-top:var(--space-3);background:none;border:none;
|
||||
color:var(--c-text-muted);font-size:var(--text-xs);cursor:pointer">
|
||||
Verknüpfung trennen
|
||||
</button>`;
|
||||
el.querySelector('#settings-osm-unlink').addEventListener('click', async () => {
|
||||
try { await API.post('/osm-auth/unlink', {}); } catch (e) {}
|
||||
_osmLink();
|
||||
});
|
||||
} else {
|
||||
el.innerHTML = `
|
||||
<p class="text-sm-muted" style="margin:0 0 var(--space-3);line-height:1.45">
|
||||
Du kennst die hundefreundlichen Orte besser als jede Karte. Verknüpfe deinen
|
||||
kostenlosen OpenStreetMap-Account und trag mit einem Tap ein, wo dein Hund
|
||||
willkommen war – das hilft jedem Hundehalter nach dir. Kostenlos, gemeinnützig,
|
||||
keine Werbung.
|
||||
</p>
|
||||
<button id="settings-osm-link"
|
||||
style="display:flex;align-items:center;justify-content:center;gap:var(--space-2);
|
||||
padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);
|
||||
border:none;background:var(--c-primary);color:#fff;
|
||||
font-size:var(--text-sm);font-weight:600;cursor:pointer">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#map-trifold"></use></svg>
|
||||
OSM-Konto verknüpfen
|
||||
</button>`;
|
||||
el.querySelector('#settings-osm-link').addEventListener('click', async () => {
|
||||
try {
|
||||
const r = await API.get('/osm-auth/authorize');
|
||||
if (r.authorize_url) window.location.href = r.authorize_url;
|
||||
} catch (e) {
|
||||
UI.toast?.('OSM-Anbindung noch nicht konfiguriert.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => { el.innerHTML = '<div class="text-sm-muted">OSM-Status nicht verfügbar.</div>'; });
|
||||
})();
|
||||
|
||||
// Achievements laden (Streak + Stats + Badges)
|
||||
API.get('/achievements/me').then(a => {
|
||||
const statsEl = document.getElementById('settings-stats-body');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue