From ab6d8161eef87357b3e3584f0d0d6240c5d61f08 Mon Sep 17 00:00:00 2001 From: sravan Date: Fri, 18 Sep 2026 00:04:31 +0530 Subject: [PATCH] push: accept FCM_SERVICE_ACCOUNT_B64 (base64 service-account key) Base64 is a single env-safe token, so the FCM service-account key can live in .env without the quoting/interpolation hazards of inline JSON. Falls back to the existing FCM_SERVICE_ACCOUNT (inline JSON or file path). No behavior change when neither is set. Co-Authored-By: Claude Opus 4.8 --- server/push.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/push.js b/server/push.js index 33e5691..9cf0e3e 100644 --- a/server/push.js +++ b/server/push.js @@ -30,7 +30,14 @@ if (webpush && PUBLIC && PRIVATE) { // ---------------- FCM (Android), HTTP v1 ---------------- let fcmSA = null; // { client_email, private_key, project_id } (function loadFcm() { - const raw = process.env.FCM_SERVICE_ACCOUNT; + // FCM_SERVICE_ACCOUNT = inline JSON or a file path. FCM_SERVICE_ACCOUNT_B64 = base64 of the JSON — the + // preferred way to put the service-account key in .env, since it's a single env-safe token (no quotes, + // spaces, or newlines to break env_file/compose interpolation). + let raw = process.env.FCM_SERVICE_ACCOUNT || ''; + if (!raw && process.env.FCM_SERVICE_ACCOUNT_B64) { + try { raw = Buffer.from(process.env.FCM_SERVICE_ACCOUNT_B64, 'base64').toString('utf8'); } + catch (e) { console.warn('[push] FCM_SERVICE_ACCOUNT_B64 decode failed:', e.message); } + } if (!raw) return; try { fcmSA = JSON.parse(raw.trim().startsWith('{') ? raw : fs.readFileSync(raw, 'utf8')); } catch (e) { console.warn('[push] FCM service account unreadable:', e.message); }