source: Klonkt/src/config/google.js@ c73ac64

main
Last change on this file since c73ac64 was 834bcc3, checked in by Robin Genis <roboburr@…>, 3 months ago

i18n: translate Dutch code comments to English across src/

Comments in routes/services/views/config/middleware/assets translated to
English for the public repo. A few dev-facing throw/console message strings
were Englished too. No user-facing UI strings or i18n dictionary values changed
(src/services/i18n.js untouched). Logic unchanged.

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 2.8 KB
RevLine 
[834bcc3]1// Google OAuth2 for LISTENERS (commenting). Per-instance: each self-hoster sets
2// their OWN Google client. This way every site is tied to its own Google Cloud
3// project — no central dependency, no shared liability.
[32cc601]4//
[834bcc3]5// Config source (in this order): app_settings (set via Admin → Settings),
6// otherwise env vars. Not configured → no "Login with Google" button; the rest
7// of the site keeps working. Google login NEVER grants admin rights.
[32cc601]8//
[834bcc3]9// The redirect URI is derived from PUBLIC_BASE_URL (<base>/auth/google/callback),
10// or explicitly via GOOGLE_REDIRECT_URI. That exact URL must be listed in Google Cloud.
[32cc601]11
[2248cd2]12import { getSetting } from '../services/SettingsService.js';
[32cc601]13
[9e27d64]14const AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
15const TOKEN_URL = 'https://oauth2.googleapis.com/token';
16const USERINFO_URL = 'https://openidconnect.googleapis.com/v1/userinfo';
[32cc601]17
[834bcc3]18// Read dynamically (UI changes take effect without a restart). app_settings wins, env = fallback.
[2248cd2]19function clientId() {
20 return getSetting('google_client_id', '') || process.env.GOOGLE_CLIENT_ID || '';
21}
22function clientSecret() {
23 return getSetting('google_client_secret', '') || process.env.GOOGLE_CLIENT_SECRET || '';
24}
25export function redirectUri() {
26 if (process.env.GOOGLE_REDIRECT_URI) return process.env.GOOGLE_REDIRECT_URI;
27 const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
28 return base ? `${base}/auth/google/callback` : '';
29}
30
[834bcc3]31export function currentClientId() { return clientId(); } // not secret, used for the settings form
[2248cd2]32export function clientSecretSet() { return !!clientSecret(); }
[9e27d64]33export function googleConfigured() {
[2248cd2]34 return !!(clientId() && clientSecret() && redirectUri());
[c80e78b]35}
36
[9e27d64]37export function authorizeUrl(state) {
38 const p = new URLSearchParams({
[2248cd2]39 client_id: clientId(),
40 redirect_uri: redirectUri(),
[9e27d64]41 response_type: 'code',
42 scope: 'openid email profile',
43 state,
44 access_type: 'online',
45 prompt: 'select_account',
46 });
47 return `${AUTH_URL}?${p.toString()}`;
[32cc601]48}
49
[9e27d64]50export async function exchangeCode(code) {
51 const body = new URLSearchParams({
52 code,
[2248cd2]53 client_id: clientId(),
54 client_secret: clientSecret(),
55 redirect_uri: redirectUri(),
[9e27d64]56 grant_type: 'authorization_code',
57 });
58 const r = await fetch(TOKEN_URL, {
59 method: 'POST',
60 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
61 body,
[c80e78b]62 });
[834bcc3]63 if (!r.ok) throw new Error(`Google token exchange failed: ${r.status}`);
[9e27d64]64 return r.json(); // { access_token, id_token, ... }
[c80e78b]65}
66
[9e27d64]67// Returns { sub, email, email_verified, name, picture }.
68export async function fetchUserinfo(accessToken) {
69 const r = await fetch(USERINFO_URL, { headers: { Authorization: `Bearer ${accessToken}` } });
[834bcc3]70 if (!r.ok) throw new Error(`Google userinfo failed: ${r.status}`);
[9e27d64]71 return r.json();
[c80e78b]72}
Note: See TracBrowser for help on using the repository browser.