GOG Login: Nahtloser Auth-Flow wie Steam (kein Code-Paste noetig)

- Electron: Fängt GOG Redirect automatisch ab (will-redirect Interceptor)
- Code-Exchange passiert im Hintergrund, User sieht nur Erfolgs-Popup
- GOG Auth-URLs (auth.gog.com, login.gog.com, embed.gog.com) in Popup erlaubt
- Server: GET /gog/login Redirect + POST /gog/exchange Endpoint
- Browser-Fallback: Code-Paste Dialog falls nicht in Electron
- gog.ts: Feste redirect_uri (embed.gog.com/on_login_success)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-08 14:41:08 +01:00
parent af2448a5bd
commit 3e8febb851
5 changed files with 281 additions and 34 deletions

View file

@ -222,6 +222,53 @@ document.getElementById('cancelBtn').addEventListener('click', () => {
return { action: 'allow' };
});
// ── GOG OAuth: intercept the redirect in child windows ──
mainWindow.webContents.on('did-create-window', (childWindow) => {
childWindow.webContents.on('will-redirect', async (event, url) => {
// GOG redirects to embed.gog.com/on_login_success?code=XXX after auth
if (url.includes('on_login_success') && url.includes('code=')) {
event.preventDefault();
try {
const parsed = new URL(url);
const code = parsed.searchParams.get('code') || '';
const state = parsed.searchParams.get('state') || '';
if (code) {
// Exchange the code via our server
const resp = await fetch(`${HUB_URL}/api/game-library/gog/exchange`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code, linkTo: state }),
});
const result = await resp.json();
if (resp.ok && result.ok) {
childWindow.loadURL(`data:text/html,${encodeURIComponent(`<!DOCTYPE html><html><head><style>body{background:#1a1a2e;color:#fff;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}div{text-align:center}h2{color:#a855f7}</style></head><body><div><h2>GOG verbunden!</h2><p>${result.profileName}: ${result.gameCount} Spiele geladen.</p></div></body></html>`)}`);
// Notify renderer to refresh profiles
mainWindow.webContents.executeJavaScript('window.dispatchEvent(new Event("gog-connected"))');
setTimeout(() => { try { childWindow.close(); } catch {} }, 2500);
} else {
childWindow.loadURL(`data:text/html,${encodeURIComponent(`<!DOCTYPE html><html><head><style>body{background:#1a1a2e;color:#fff;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}div{text-align:center}h2{color:#e74c3c}</style></head><body><div><h2>Fehler</h2><p>${result.error || 'Unbekannter Fehler'}</p></div></body></html>`)}`);
}
}
} catch (err) {
console.error('[GOG] Exchange error:', err);
childWindow.loadURL(`data:text/html,${encodeURIComponent('<!DOCTYPE html><html><head><style>body{background:#1a1a2e;color:#fff;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}div{text-align:center}h2{color:#e74c3c}</style></head><body><div><h2>Fehler</h2><p>GOG-Verbindung fehlgeschlagen.</p></div></body></html>')}`);
}
}
});
// Allow child windows to navigate to GOG auth (don't open in external browser)
childWindow.webContents.on('will-navigate', (event, url) => {
if (url.startsWith('https://auth.gog.com') || url.startsWith('https://login.gog.com') ||
url.startsWith('https://embed.gog.com') || url.startsWith(HUB_URL)) {
// Allow navigation within popup for GOG auth flow
return;
}
});
});
// Handle navigation to external URLs
mainWindow.webContents.on('will-navigate', (event, url) => {
if (!url.startsWith(HUB_URL)) {