feat: Schritte 14–15 — Google Calendar OAuth + Apple CalDAV Sync + Settings-Seite
- server/services/google-calendar.js: OAuth 2.0, bidirektionaler Sync via Google Calendar API v3, inkrementeller syncToken, 410-Fallback auf Vollsync - server/services/apple-calendar.js: CalDAV via tsdav (dynamic ESM import), minimaler ICS-Parser + ICS-Builder, bidirektionaler Sync - server/routes/calendar.js: 7 neue Sync-Routen (google/auth, google/callback, google/sync, google/status, google/disconnect, apple/status, apple/sync) - server/db.js: Migration 2 — sync_config Tabelle + idx_calendar_external_id - server/db-schema-test.js: MIGRATIONS_SQL[2] für Tests synchronisiert - server/auth.js: PATCH /me/password Endpoint - server/index.js: Auto-Sync-Scheduler (setInterval, SYNC_INTERVAL_MINUTES) - public/pages/settings.js: vollständige Settings-Seite (Konto, Passwort, Kalender-Sync-Status + Aktionen, Familienmitglieder-Verwaltung) - public/styles/settings.css: neue Stylesheet-Datei - public/index.html + public/sw.js: settings.css eingebunden und gecacht - .env.example: SYNC_INTERVAL_MINUTES ergänzt - README.md: vollständige Setup-Anleitung, Google/Apple-Sync-Dokumentation, modernes GitHub-Layout mit Badges und aufklappbaren Abschnitten Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+28
-1
@@ -11,9 +11,11 @@ const express = require('express');
|
||||
const helmet = require('helmet');
|
||||
const rateLimit = require('express-rate-limit');
|
||||
const path = require('path');
|
||||
const db = require('./db');
|
||||
const db = require('./db');
|
||||
const { router: authRouter, sessionMiddleware, requireAuth } = require('./auth');
|
||||
const { csrfMiddleware } = require('./middleware/csrf');
|
||||
const googleCalendar = require('./services/google-calendar');
|
||||
const appleCalendar = require('./services/apple-calendar');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
@@ -154,12 +156,37 @@ app.use((err, req, res, _next) => {
|
||||
res.status(500).json({ error: 'Interner Serverfehler.', code: 500 });
|
||||
});
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Auto-Sync Scheduler (Google + Apple Calendar)
|
||||
// --------------------------------------------------------
|
||||
|
||||
const SYNC_INTERVAL_MS = (parseInt(process.env.SYNC_INTERVAL_MINUTES, 10) || 15) * 60_000;
|
||||
|
||||
async function runSync() {
|
||||
const { connected: googleConnected } = googleCalendar.getStatus();
|
||||
if (googleConnected) {
|
||||
googleCalendar.sync().catch((e) => console.error('[Sync] Google Fehler:', e.message));
|
||||
}
|
||||
|
||||
const { configured: appleConfigured } = appleCalendar.getStatus();
|
||||
if (appleConfigured) {
|
||||
appleCalendar.sync().catch((e) => console.error('[Sync] Apple Fehler:', e.message));
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Server starten
|
||||
// --------------------------------------------------------
|
||||
app.listen(PORT, () => {
|
||||
console.log(`[Oikos] Server läuft auf Port ${PORT}`);
|
||||
console.log(`[Oikos] Umgebung: ${process.env.NODE_ENV || 'development'}`);
|
||||
|
||||
// Erster Sync nach 10 Sekunden (warten bis DB vollständig initialisiert)
|
||||
setTimeout(() => {
|
||||
runSync();
|
||||
setInterval(runSync, SYNC_INTERVAL_MS);
|
||||
console.log(`[Sync] Auto-Sync alle ${SYNC_INTERVAL_MS / 60_000} Minuten aktiv.`);
|
||||
}, 10_000);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
|
||||
Reference in New Issue
Block a user