44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
export const runtime = "nodejs";
|
|
|
|
import { NextResponse } from "next/server";
|
|
import { cookies } from "next/headers";
|
|
import { requireAdminSession } from "@/lib/auth/require";
|
|
import { connectGoogleCalendar } from "@/lib/google/calendar";
|
|
|
|
const STATE_COOKIE = "google_oauth_state";
|
|
|
|
function redirectToSettings(request: Request, params: Record<string, string>) {
|
|
const url = new URL("/settings/google", request.url);
|
|
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
|
|
return NextResponse.redirect(url);
|
|
}
|
|
|
|
export async function GET(request: Request) {
|
|
const { session, response } = await requireAdminSession();
|
|
if (!session) return response;
|
|
|
|
const url = new URL(request.url);
|
|
const code = url.searchParams.get("code");
|
|
const state = url.searchParams.get("state");
|
|
const error = url.searchParams.get("error");
|
|
|
|
const cookieStore = await cookies();
|
|
const expectedState = cookieStore.get(STATE_COOKIE)?.value;
|
|
cookieStore.delete(STATE_COOKIE);
|
|
|
|
if (error) {
|
|
return redirectToSettings(request, { error: "Доступ не предоставлен" });
|
|
}
|
|
if (!code || !state || !expectedState || state !== expectedState) {
|
|
return redirectToSettings(request, { error: "Некорректный ответ от Google — попробуйте подключить снова" });
|
|
}
|
|
|
|
try {
|
|
await connectGoogleCalendar(code, session.user.id);
|
|
} catch (err) {
|
|
return redirectToSettings(request, { error: err instanceof Error ? err.message : "Не удалось подключить Google Calendar" });
|
|
}
|
|
|
|
return redirectToSettings(request, { connected: "1" });
|
|
}
|