UNPKG

gmail-to-exchange365

Version:

Complete Gmail to Exchange 365 migration tool with UI - Migrate emails, attachments, and folders seamlessly

153 lines (131 loc) 4.56 kB
import { Router, Request, Response } from "express"; import { generateGoogleAuthUrl, exchangeGoogleCode } from "./googleAuth"; import { getMSAuthUrl, exchangeMSCode } from "./msAuth"; import { migrateUser } from "./migrator"; import { UserSession } from "./types"; const router = Router(); // Extend Express Request to include session interface SessionRequest extends Request { session: any; } // Home page router.get("/", (req: Request, res: Response) => { res.sendFile("index.html", { root: __dirname + "/../ui" }); }); // Google OAuth router.get("/google/auth", (req: Request, res: Response) => { const authUrl = generateGoogleAuthUrl(); res.redirect(authUrl); }); router.get("/google/callback", async (req: SessionRequest, res: Response) => { try { const code = req.query.code as string; if (!code) { return res.redirect("/?error=no_code"); } const tokens = await exchangeGoogleCode(code); req.session.google = tokens; req.session.save(() => { res.redirect("/?google=connected"); }); } catch (error: any) { console.error("Google OAuth error:", error); res.redirect("/?error=google_auth_failed"); } }); // Microsoft OAuth router.get("/ms/auth", (req: Request, res: Response) => { const authUrl = getMSAuthUrl(); res.redirect(authUrl); }); router.get("/ms/callback", async (req: SessionRequest, res: Response) => { try { const code = req.query.code as string; if (!code) { return res.redirect("/?error=no_code"); } const tokens = await exchangeMSCode(code); req.session.ms = tokens; req.session.save(() => { res.redirect("/?ms=connected"); }); } catch (error: any) { console.error("Microsoft OAuth error:", error); res.redirect("/?error=ms_auth_failed"); } }); // Check auth status router.get("/api/status", (req: SessionRequest, res: Response) => { res.json({ google: !!req.session.google, ms: !!req.session.ms }); }); // Start migration router.post("/api/migrate", async (req: SessionRequest, res: Response) => { try { if (!req.session.google || !req.session.ms) { return res.status(400).json({ error: "Both Google and Microsoft accounts must be connected" }); } // Set up Server-Sent Events for progress updates res.setHeader("Content-Type", "text/event-stream"); res.setHeader("Cache-Control", "no-cache"); res.setHeader("Connection", "keep-alive"); const options = { batchSize: req.body.batchSize || 10, delayBetweenBatches: req.body.delayBetweenBatches || 1000, retryAttempts: req.body.retryAttempts || 3, retryDelay: req.body.retryDelay || 5000 }; await migrateUser( req.session.google, req.session.ms, (current, total, message) => { const progress = { current, total, percentage: total > 0 ? Math.round((current / total) * 100) : 0, message: message || `Migrated ${current}/${total} emails` }; res.write(`data: ${JSON.stringify(progress)}\n\n`); }, options ); res.write(`data: ${JSON.stringify({ completed: true })}\n\n`); res.end(); } catch (error: any) { console.error("Migration error:", error); res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`); res.end(); } }); // Pause migration (would need to store migrator instance in production) router.post("/api/migrate/pause", (req: SessionRequest, res: Response) => { // In a real implementation, you'd store the migrator instance // and call pause() on it res.json({ message: "Migration paused" }); }); // Resume migration router.post("/api/migrate/resume", (req: SessionRequest, res: Response) => { // In a real implementation, you'd store the migrator instance // and call resume() on it res.json({ message: "Migration resumed" }); }); // Stop migration router.post("/api/migrate/stop", (req: SessionRequest, res: Response) => { // In a real implementation, you'd store the migrator instance // and call stop() on it res.json({ message: "Migration stopped" }); }); // Logout router.post("/api/logout", (req: SessionRequest, res: Response) => { req.session.destroy((err: any) => { if (err) { return res.status(500).json({ error: "Failed to logout" }); } res.json({ message: "Logged out successfully" }); }); }); export default router;