tududi/backend/routes/calendar.js
Chris 03f38f05dc
Setup intelligence (#84)
* Add next suggestions and remove console logs

* Add pomodoro timer

* Add pomodoro switch in settings

* Fix pomodoro setting

* Add timezones to settings

* Fix an issue with password reset

* Cleanup

* Sort tags alphabetically

* Clean up today's view

* Add an indicator for repeatedly added to today

* Refactor tags

* Add due date today item

* Move recurrence to the subtitle area

* Fix today layout

* Add a badge to Inbox items

* Move inbox badge to sidebar

* Add quotes and progress bar

* Add translations for quotes

* Fix test issues

* Add helper script for docker local

* Set up overdue tasks

* Add  linux/arm/v7 build to deploy script

* Add  linux/arm/v7 build to deploy script pt2

* Fix an issue with helmet and SSL

* Add volume db persistence

* Fix cog icon issues
2025-06-27 14:02:18 +03:00

183 lines
No EOL
6.1 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { google } = require('googleapis');
const { requireAuth } = require('../middleware/auth');
// Google Calendar configuration
const SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'];
// OAuth2 client setup
const getOAuth2Client = () => {
return new google.auth.OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.GOOGLE_REDIRECT_URI || 'http://localhost:3002/api/calendar/oauth/callback'
);
};
// GET /api/calendar/auth - Start OAuth flow (Demo mode)
router.get('/auth', requireAuth, (req, res) => {
try {
// Check if Google credentials are configured
if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
// Demo mode - simulate successful connection
console.log('Demo mode: Simulating Google Calendar connection for user:', req.currentUser.id);
// Simulate the callback redirect with success
const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:8080';
return res.json({
authUrl: `${frontendUrl}/calendar?demo=true&connected=true`,
demo: true,
message: 'Demo mode: Google Calendar integration simulated'
});
}
// Production mode with real Google OAuth
const oauth2Client = getOAuth2Client();
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
state: JSON.stringify({ userId: req.currentUser.id })
});
res.json({ authUrl });
} catch (error) {
console.error('Error generating auth URL:', error);
res.status(500).json({ error: 'Failed to generate authorization URL' });
}
});
// GET /api/calendar/oauth/callback - Handle OAuth callback
router.get('/oauth/callback', async (req, res) => {
try {
const { code, state } = req.query;
if (!code) {
return res.status(400).json({ error: 'Authorization code not provided' });
}
const oauth2Client = getOAuth2Client();
const { tokens } = await oauth2Client.getToken(code);
// Parse state to get user ID
const { userId } = JSON.parse(state);
// Here you would typically save the tokens to the database
// For now, we'll just return them (in production, store securely)
console.log('Google Calendar tokens received for user:', userId);
console.log('Tokens:', tokens);
// TODO: Save tokens to database associated with user
// await saveGoogleTokensForUser(userId, tokens);
// Redirect to frontend with success
res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:8080'}/calendar?connected=true`);
} catch (error) {
console.error('Error handling OAuth callback:', error);
res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:8080'}/calendar?error=auth_failed`);
}
});
// GET /api/calendar/status - Check connection status
router.get('/status', requireAuth, async (req, res) => {
try {
// Check if we're in demo mode or have real Google integration
if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
// Demo mode - check if user has been "connected" in this session
// For demo purposes, we'll simulate connection status
res.json({
connected: false, // Will be set to true after demo connection
email: null,
demo: true
});
return;
}
// TODO: Check if user has valid Google Calendar tokens in database
// const tokens = await getGoogleTokensForUser(req.currentUser.id);
res.json({
connected: false, // Change to true when tokens exist and are valid
email: null // Return connected Google account email when available
});
} catch (error) {
console.error('Error checking calendar status:', error);
res.status(500).json({ error: 'Failed to check calendar status' });
}
});
// GET /api/calendar/events - Get events from Google Calendar
router.get('/events', requireAuth, async (req, res) => {
try {
const { start, end } = req.query;
// TODO: Get tokens from database
// const tokens = await getGoogleTokensForUser(req.currentUser.id);
// if (!tokens) {
// return res.status(401).json({ error: 'Google Calendar not connected' });
// }
// For now, return sample data
const sampleEvents = [
{
id: 'google-1',
title: 'Google Calendar Event',
start: new Date().toISOString(),
end: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
type: 'google',
color: '#ea4335'
}
];
res.json({ events: sampleEvents });
// TODO: Implement actual Google Calendar API call
/*
const oauth2Client = getOAuth2Client();
oauth2Client.setCredentials(tokens);
const calendar = google.calendar({ version: 'v3', auth: oauth2Client });
const response = await calendar.events.list({
calendarId: 'primary',
timeMin: start || new Date().toISOString(),
timeMax: end || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
maxResults: 100,
singleEvents: true,
orderBy: 'startTime',
});
const events = response.data.items.map(event => ({
id: event.id,
title: event.summary,
start: event.start.dateTime || event.start.date,
end: event.end.dateTime || event.end.date,
type: 'google',
color: '#ea4335',
description: event.description,
location: event.location
}));
res.json({ events });
*/
} catch (error) {
console.error('Error fetching calendar events:', error);
res.status(500).json({ error: 'Failed to fetch calendar events' });
}
});
// POST /api/calendar/disconnect - Disconnect Google Calendar
router.post('/disconnect', requireAuth, async (req, res) => {
try {
// TODO: Remove tokens from database
// await removeGoogleTokensForUser(req.currentUser.id);
res.json({ success: true, message: 'Google Calendar disconnected' });
} catch (error) {
console.error('Error disconnecting calendar:', error);
res.status(500).json({ error: 'Failed to disconnect calendar' });
}
});
module.exports = router;