Index: src/config/google.js
===================================================================
--- src/config/google.js	(revision 221a2097e364410e12aa34d7c668aab224bd16b4)
+++ src/config/google.js	(revision e2a8e313c3e2ab4e6c0b46dee342bf6b30e677c4)
@@ -1,17 +1,14 @@
 // Google OAuth2 voor LUISTERAARS (reageren). Per-instance: de self-hoster zet
-// z'n EIGEN Google-client in .env. Zo hangt elke site aan z'n eigen Google Cloud
-// project — geen centrale afhankelijkheid, geen gedeelde aansprakelijkheid.
+// z'n EIGEN Google-client. Zo hangt elke site aan z'n eigen Google Cloud project
+// — geen centrale afhankelijkheid, geen gedeelde aansprakelijkheid.
 //
-// Optioneel: staat dit niet ingesteld, dan is er simpelweg geen "Login met
-// Google"-knop en blijft de rest van de site werken. Google-login geeft NOOIT
-// beheerrechten — beheer gaat via het wachtwoord-account.
+// Config-bron (in deze volgorde): app_settings (ingesteld via Beheer → Instellingen),
+// anders de env-vars. Niet ingesteld → geen "Login met Google"-knop; de rest van
+// de site werkt door. Google-login geeft NOOIT beheerrechten.
 //
-// Config via env:
-//   GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
-//   GOOGLE_REDIRECT_URI = https://<dit-domein>/auth/google/callback
+// De redirect-URI wordt afgeleid van PUBLIC_BASE_URL (<base>/auth/google/callback),
+// of expliciet via GOOGLE_REDIRECT_URI. Die exacte URL moet in Google Cloud staan.
 
-const CLIENT_ID = process.env.GOOGLE_CLIENT_ID || '';
-const CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET || '';
-const REDIRECT_URI = process.env.GOOGLE_REDIRECT_URI || '';
+import { getSetting } from '../services/SettingsService.js';
 
 const AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
@@ -19,12 +16,27 @@
 const USERINFO_URL = 'https://openidconnect.googleapis.com/v1/userinfo';
 
+// Dynamisch lezen (UI-wijziging werkt zonder herstart). app_settings wint, env = fallback.
+function clientId() {
+  return getSetting('google_client_id', '') || process.env.GOOGLE_CLIENT_ID || '';
+}
+function clientSecret() {
+  return getSetting('google_client_secret', '') || process.env.GOOGLE_CLIENT_SECRET || '';
+}
+export function redirectUri() {
+  if (process.env.GOOGLE_REDIRECT_URI) return process.env.GOOGLE_REDIRECT_URI;
+  const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
+  return base ? `${base}/auth/google/callback` : '';
+}
+
+export function currentClientId() { return clientId(); } // niet-geheim, voor het formulier
+export function clientSecretSet() { return !!clientSecret(); }
 export function googleConfigured() {
-  return !!(CLIENT_ID && CLIENT_SECRET && REDIRECT_URI);
+  return !!(clientId() && clientSecret() && redirectUri());
 }
 
 export function authorizeUrl(state) {
   const p = new URLSearchParams({
-    client_id: CLIENT_ID,
-    redirect_uri: REDIRECT_URI,
+    client_id: clientId(),
+    redirect_uri: redirectUri(),
     response_type: 'code',
     scope: 'openid email profile',
@@ -39,7 +51,7 @@
   const body = new URLSearchParams({
     code,
-    client_id: CLIENT_ID,
-    client_secret: CLIENT_SECRET,
-    redirect_uri: REDIRECT_URI,
+    client_id: clientId(),
+    client_secret: clientSecret(),
+    redirect_uri: redirectUri(),
     grant_type: 'authorization_code',
   });
