Files
top-reservation/src/app/api/google/callback/route.ts
T

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" });
}