godcrm/backend/routes/v3/calendar/connectionController.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

116 lines
3.7 KiB
JavaScript

// calendar/connectionController.js — Connection/auth and calendars listing
import { Router } from 'express';
import {
getAuthUrl,
handleCallback,
getConnectionStatus,
disconnectCalendar,
listCalendars,
} from '../../../services/GoogleCalendarService.js';
import { calLogger, respondSuccess, respondError } from './helpers.js';
const router = Router();
// =============================================================================
// CONNECTION / AUTH
// =============================================================================
/**
* GET /api/v3/calendar/status
* Check Google Calendar connection status for current user
*/
router.get('/status', async (req, res) => {
try {
const status = await getConnectionStatus(req.user.id);
return respondSuccess(res, status);
} catch (err) {
calLogger.error({ err }, 'Failed to get calendar status');
return respondError(res, 500, 'STATUS_FAILED', 'Failed to get calendar status', err.message);
}
});
/**
* GET /api/v3/calendar/connect
* Generate URL for connecting Google Calendar
* Query params: redirect_uri (optional)
*/
router.get('/connect', async (req, res) => {
try {
const url = getAuthUrl(req.user.id, req.query.redirect_uri);
return respondSuccess(res, { url });
} catch (err) {
calLogger.error({ err }, 'Failed to generate connect URL');
return respondError(res, 500, 'CONNECT_FAILED', 'Failed to generate connect URL', err.message);
}
});
/**
* POST /api/v3/calendar/callback
* OAuth callback — exchange code for tokens and store account
* Body: { code, redirect_uri? }
*/
router.post('/callback', async (req, res) => {
try {
const { code, redirect_uri } = req.body;
if (!code) {
return respondError(res, 400, 'NO_CODE', 'Authorization code is required');
}
const result = await handleCallback(code, redirect_uri, req.user.id);
calLogger.info({ userId: req.user.id }, 'Calendar account connected');
// Get email and calendars for response
let email = req.user.email;
let calendars = [];
try {
calendars = await listCalendars(req.user.id);
} catch (e) {
calLogger.warn({ err: e }, 'Could not list calendars after connect');
}
return respondSuccess(res, { ...result, email, calendars });
} catch (err) {
calLogger.error({ err }, 'Calendar callback failed');
return respondError(res, 500, 'CALLBACK_FAILED', 'Calendar callback failed', err.message);
}
});
/**
* POST /api/v3/calendar/disconnect
* Disconnect Google Calendar for current user
*/
router.post('/disconnect', async (req, res) => {
try {
const result = disconnectCalendar(req.user.id);
return respondSuccess(res, result);
} catch (err) {
calLogger.error({ err }, 'Failed to disconnect calendar');
return respondError(res, 500, 'DISCONNECT_FAILED', 'Failed to disconnect calendar', err.message);
}
});
// =============================================================================
// CALENDARS
// =============================================================================
/**
* GET /api/v3/calendar/calendars
* List all Google Calendars for current user
*/
router.get('/calendars', async (req, res) => {
try {
const status = await getConnectionStatus(req.user.id);
if (!status.connected) {
return respondError(res, 401, 'NOT_CONNECTED', 'Google Calendar is not connected. Please authorize first.');
}
const calendars = await listCalendars(req.user.id);
return respondSuccess(res, calendars);
} catch (err) {
calLogger.error({ err }, 'Failed to get calendar list');
return respondError(res, 500, 'FETCH_FAILED', 'Failed to get calendar list', err.message);
}
});
export default router;