From 96fa78bd5c58ab67bdc85e0018298401fb73da89 Mon Sep 17 00:00:00 2001 From: Cosmo Date: Mon, 27 Apr 2026 12:59:17 +0000 Subject: [PATCH] =?UTF-8?q?fix(calendar):=20GOOGLE=5FSA=5FJSON=5FB64=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20(env-f?= =?UTF-8?q?ile=20friendly)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docker --env-file не поддерживает многострочные значения и не парсит кавычки. Сырой JSON service-account ломается на newline'ах в private_key поле → docker пытается парсить '-----END PRIVATE KEY-----' как имя переменной и валится с 'contains whitespaces'. Решение: base64 GOOGLE_SA_JSON_B64 (одна строка ASCII, никаких кавычек). Старая GOOGLE_SA_JSON оставлена как fallback. Третий fallback на файл — для локальной разработки. --- app/api/calendar/route.ts | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/app/api/calendar/route.ts b/app/api/calendar/route.ts index 5f64bec..9fcbad4 100644 --- a/app/api/calendar/route.ts +++ b/app/api/calendar/route.ts @@ -15,20 +15,32 @@ function getAuth(readonly = true) { ? ['https://www.googleapis.com/auth/calendar.readonly'] : ['https://www.googleapis.com/auth/calendar'] + // 1) Предпочтительно — base64. docker --env-file не парсит кавычки и не + // поддерживает многострочные значения, а private_key в JSON ломается + // на переводах строк → base64 это решает (одна строка ASCII). + const saB64 = process.env.GOOGLE_SA_JSON_B64 + if (saB64) { + try { + const sa = JSON.parse(Buffer.from(saB64, 'base64').toString('utf-8')) + return new google.auth.GoogleAuth({ credentials: sa, scopes }) + } catch (e) { + console.error('[calendar] GOOGLE_SA_JSON_B64 decode failed:', e) + } + } + // 2) Сырая JSON-строка (legacy). const saJson = process.env.GOOGLE_SA_JSON if (saJson) { - const sa = JSON.parse(saJson) - return new google.auth.GoogleAuth({ - credentials: sa, - scopes, - }) + try { + const sa = JSON.parse(saJson) + return new google.auth.GoogleAuth({ credentials: sa, scopes }) + } catch (e) { + console.error('[calendar] GOOGLE_SA_JSON parse failed:', e) + } } + // 3) Fallback на файл (для локальной разработки). const saPath = path.join(process.cwd(), 'google-sa.json') if (fs.existsSync(saPath)) { - return new google.auth.GoogleAuth({ - keyFile: saPath, - scopes, - }) + return new google.auth.GoogleAuth({ keyFile: saPath, scopes }) } return null }