fix: switch to service account auth for Google Calendar
Some checks failed
Deploy to VM / deploy (push) Failing after 1s

This commit is contained in:
Cosmo
2026-04-22 13:10:06 +00:00
parent 38a64ff9c8
commit 444239a5e5
2 changed files with 51 additions and 14 deletions

View File

@@ -1,41 +1,61 @@
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
import { NextResponse } from 'next/server' import { NextResponse } from 'next/server'
import { google } from 'googleapis' import { google } from 'googleapis'
import * as fs from 'fs'
import * as path from 'path'
function getAuth() {
// Service account JSON (inline or from file)
const saJson = process.env.GOOGLE_SA_JSON
if (saJson) {
const sa = JSON.parse(saJson)
return new google.auth.GoogleAuth({
credentials: sa,
scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
})
}
// Fallback: file
const saPath = path.join(process.cwd(), 'google-sa.json')
if (fs.existsSync(saPath)) {
return new google.auth.GoogleAuth({
keyFile: saPath,
scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
})
}
return null
}
export async function GET(req: Request) { export async function GET(req: Request) {
const { searchParams } = new URL(req.url) const { searchParams } = new URL(req.url)
const range = searchParams.get('range') || 'today' const range = searchParams.get('range') || 'today'
const clientId = process.env.GOOGLE_CLIENT_ID const auth = getAuth()
const clientSecret = process.env.GOOGLE_CLIENT_SECRET if (!auth) {
const refreshToken = process.env.GOOGLE_REFRESH_TOKEN
const svetaCalendarId = process.env.SVETA_CALENDAR_ID
if (!clientId || !clientSecret || !refreshToken) {
return NextResponse.json({ events: [], error: 'not_configured' }) return NextResponse.json({ events: [], error: 'not_configured' })
} }
const auth = new google.auth.OAuth2(clientId, clientSecret) const daniilCalendarId = process.env.DANIIL_CALENDAR_ID || 'daniilklimov25@gmail.com'
auth.setCredentials({ refresh_token: refreshToken }) const svetaCalendarId = process.env.SVETA_CALENDAR_ID || ''
const now = new Date() const now = new Date()
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()) let timeMin: string
let timeMin = todayStart.toISOString()
let timeMax: string let timeMax: string
if (range === 'today') { if (range === 'today') {
timeMin = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString()
timeMax = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString() timeMax = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString()
} else if (range === 'week') { } else if (range === 'week') {
timeMin = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString()
timeMax = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7).toISOString() timeMax = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7).toISOString()
} else { } else {
timeMax = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59).toISOString()
timeMin = new Date(now.getFullYear(), now.getMonth(), 1).toISOString() timeMin = new Date(now.getFullYear(), now.getMonth(), 1).toISOString()
timeMax = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59).toISOString()
} }
const calendarClient = google.calendar({ version: 'v3', auth }) const calendarClient = google.calendar({ version: 'v3', auth: auth as any })
const calendars = [ const calendars = [
{ id: 'daniilklimov25@gmail.com', owner: 'daniil', color: '#6366f1', name: 'Даниил' }, { id: daniilCalendarId, owner: 'daniil', color: '#6366f1', name: 'Даниил' },
...(svetaCalendarId ? [{ id: svetaCalendarId, owner: 'sveta', color: '#ec4899', name: 'Света' }] : []) ...(svetaCalendarId ? [{ id: svetaCalendarId, owner: 'sveta', color: '#ec4899', name: 'Света' }] : [])
] ]
@@ -71,5 +91,9 @@ export async function GET(req: Request) {
}) })
.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()) .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())
return NextResponse.json({ events: allEvents, fetchedAt: new Date().toISOString() }) const errors = results
.filter(r => r.status === 'rejected')
.map(r => (r as PromiseRejectedResult).reason?.message || 'unknown')
return NextResponse.json({ events: allEvents, errors: errors.length ? errors : undefined, fetchedAt: new Date().toISOString() })
} }

13
google-sa.json Normal file
View File

@@ -0,0 +1,13 @@
{
"type": "service_account",
"project_id": "cosmo-486412",
"private_key_id": "97159754f1652d3231d5cc9381760da69796b7f1",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCl6SmxATP8+lPG\ncAMg1FgchlSSx26ESpZXJMXpxtFGSKy7MVjLU43OJEa9MW/ZjLpn6fuHtsGTe12U\neDlltKdsrCuLq5InTvYCTfNKGUUm4RkquQa5sLmKTIWS0VObIyvCE2mtQz+q6vlE\nu9fs4rrJguquG7fOfLfodaJ4vEeR7daDdpohWG5NXNBgfc2wWVzoHMBsVMmj7lmY\n3CnUvzFiIfr1Nlp2x/x82eIb4zw3dpc89W5X+rCkseMV1Tup90XFAxzVEM+F7loQ\nAjnsaxaZJ3cqo/eo0kMOdmMJEyreXFIPkH4OZfjq7EyNrbtd0sMv19ghZh1j8wwy\nKf6CqnuDAgMBAAECggEABW5cePQ8xV4wKgQEQHwVTyyX+7pa2wXtwUE/1+TrCrkH\nmV39Y31npVKrZdv0XZhEP98CeRpZqbujCTv4R+TUQWGq4maFxcnJbbMrZ5kQmhdu\nuouD41hlTep3ycaETTK5ncRMNDwA+Qze0IDWieVHBjKztY86TA4y+rhQzuNrhcls\n8bmJrnT7jeCvMKQqbhnulG89JGh4r6pFfAKMCn3dJOu5ATaTY0xNLG2H9h41doKx\nwKBm/4T3HJTtIuAPdwKxzf96QuSIl1WfvomYIz4Lpb8DGqEMqMtvIH7G0LNj00dU\nn0us6yqevLGbVqF+0P0ndtJxvPzqoSkfhTebnM8Z6QKBgQDQr6Ty/Ej0/Y8pr7MS\nL4VqEa85W4nvAuSr9NPo+bSxTRNbZnXlhBsVeYedXrfBQrsSDuigeRG31kTmwxfD\nUaEFA7134J68OZGD/rhCzjBxzRpVi7YgOXz0PxkgXlZvqLf4YZmbAF73sRYCxcJj\nw938dSieDTCYWwAvr6a840HCqQKBgQDLhsuUEe5xxKXHd390MLUda1pkV0AOcYiS\n3oqjWOijQic43fEHMLYrs4A/lOBjWqdJ1fn2DQJHfRl7RvaAi2yUqWyMWtPVAhBs\nUvsckFOuepu6fO2RhxF4lUNqH9mFKw3sn/EmlDKsUAQ5tijLKdNyaQHam6cfV3qG\nCsLGoa9USwKBgQCxy7PhQYh3EkCS55rNd6dXQ1HisFbIR9LDnoedCoIkPOKtEJKJ\nxQ++MBiWv0gXY98193XCouOxmOCDKtxoEHf7acBXDgyvmOydZLtgT4N+sZwqHipB\nMjl/bvLdXQKPh1OWTrEsGhjPNxTlr896aDoNCVRdtCce5wk1l5WbgJNaYQKBgH54\n7Aa+QdL2pSHXcx8rqVB3xnr18PtIt9q0aahp9l6FHERtPnr+XSW47KgWBn4W9j+e\ntS6eFN2BspT1mvZ0LWwQAEETq/EA0F3QDvVIBog07pKrUSGOsl+hOXw4AH6NK6Dw\nHvWfQAHt00JdnOnquteswxcqhGaogJ3NEA5IqOATAoGBAMoXSmrSxn2YDmlYIxI7\nskML3wEHZWezTpwMiTTqCSgF2bJVHeXNYpupJjh6t95gMmqtdC7Ulg/UGbgYX7Fi\nicompJeZgBmcorcgcxWk9umBK8F8sMwHDEO70RiYHOv6MdEcwy0Ev5hTl1WG44g4\nyOcojdbhrK0Ji9lNa0BZjz1H\n-----END PRIVATE KEY-----\n",
"client_email": "homedashboard@cosmo-486412.iam.gserviceaccount.com",
"client_id": "115741671545733594404",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/homedashboard%40cosmo-486412.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}