diff --git a/src/app/api/dashboard/stats/route.ts b/src/app/api/dashboard/stats/route.ts index 84c997d..0352c3e 100644 --- a/src/app/api/dashboard/stats/route.ts +++ b/src/app/api/dashboard/stats/route.ts @@ -1,31 +1,25 @@ import { NextRequest, NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; +import { getAuthenticatedUser, handleErrorResponse } from "@/lib/apiUtils"; -import { authOptions } from "@/lib/auth"; -import { fetchViewerLogin } from "@/lib/githubViewer"; import { fetchCommitActivityHeatmap } from "@/lib/githubYearInReview"; export async function GET(request: NextRequest) { - const session = await getServerSession(authOptions); - const token = session?.accessToken; + try { + const user = await getAuthenticatedUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } - if (!session || !token) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } + const yearParam = request.nextUrl.searchParams.get("year"); + const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); - const yearParam = request.nextUrl.searchParams.get("year"); - const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); + if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { + return NextResponse.json({ error: "Invalid year" }, { status: 400 }); + } - if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { - return NextResponse.json({ error: "Invalid year" }, { status: 400 }); - } - - try { - const username = session.user?.login ?? (await fetchViewerLogin(token)); - const heatmap = await fetchCommitActivityHeatmap(username, year, token); + const heatmap = await fetchCommitActivityHeatmap(user.username, year, user.token); return NextResponse.json({ year, heatmap }); } catch (error) { - const message = error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json({ error: message }, { status: 500 }); + return handleErrorResponse(error); } } diff --git a/src/app/api/dashboard/summary/route.ts b/src/app/api/dashboard/summary/route.ts index b99930c..7292c8e 100644 --- a/src/app/api/dashboard/summary/route.ts +++ b/src/app/api/dashboard/summary/route.ts @@ -1,24 +1,18 @@ import { NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; +import { getAuthenticatedUser, handleErrorResponse } from "@/lib/apiUtils"; -import { authOptions } from "@/lib/auth"; import { fetchUserSummary } from "@/lib/github"; -import { fetchViewerLogin } from "@/lib/githubViewer"; export async function GET() { - const session = await getServerSession(authOptions); - const token = session?.accessToken; - - if (!session || !token) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } - try { - const username = session.user?.login ?? (await fetchViewerLogin(token)); - const summary = await fetchUserSummary(username, token); - return NextResponse.json({ username, summary }); + const user = await getAuthenticatedUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const summary = await fetchUserSummary(user.username, user.token); + return NextResponse.json({ username: user.username, summary }); } catch (error) { - const message = error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json({ error: message }, { status: 500 }); + return handleErrorResponse(error); } } diff --git a/src/app/api/dashboard/year/route.ts b/src/app/api/dashboard/year/route.ts index 10e757f..b858132 100644 --- a/src/app/api/dashboard/year/route.ts +++ b/src/app/api/dashboard/year/route.ts @@ -1,31 +1,25 @@ import { NextRequest, NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; +import { getAuthenticatedUser, handleErrorResponse } from "@/lib/apiUtils"; -import { authOptions } from "@/lib/auth"; -import { fetchViewerLogin } from "@/lib/githubViewer"; import { fetchYearInReviewData } from "@/lib/githubYearInReview"; export async function GET(request: NextRequest) { - const session = await getServerSession(authOptions); - const token = session?.accessToken; + try { + const user = await getAuthenticatedUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } - if (!session || !token) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } + const yearParam = request.nextUrl.searchParams.get("year"); + const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); - const yearParam = request.nextUrl.searchParams.get("year"); - const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); + if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { + return NextResponse.json({ error: "Invalid year" }, { status: 400 }); + } - if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { - return NextResponse.json({ error: "Invalid year" }, { status: 400 }); - } - - try { - const username = session.user?.login ?? (await fetchViewerLogin(token)); - const data = await fetchYearInReviewData(username, year, token); + const data = await fetchYearInReviewData(user.username, year, user.token); return NextResponse.json(data); } catch (error) { - const message = error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json({ error: message }, { status: 500 }); + return handleErrorResponse(error); } } diff --git a/src/lib/apiUtils.ts b/src/lib/apiUtils.ts new file mode 100644 index 0000000..42258ca --- /dev/null +++ b/src/lib/apiUtils.ts @@ -0,0 +1,21 @@ +import { NextResponse } from "next/server"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/lib/auth"; +import { fetchViewerLogin } from "@/lib/githubViewer"; + +export async function getAuthenticatedUser() { + const session = await getServerSession(authOptions); + const token = session?.accessToken; + + if (!session || !token) { + return null; + } + + const username = session.user?.login ?? (await fetchViewerLogin(token)); + return { username, token }; +} + +export function handleErrorResponse(error: unknown) { + const message = error instanceof Error ? error.message : "Unknown error"; + return NextResponse.json({ error: message }, { status: 500 }); +}