73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import { URLSearchParams } from "url";
|
|
import {
|
|
discordRedirectUri,
|
|
DiscordAccessTokenResponse,
|
|
makeTicket,
|
|
getDiscordID
|
|
} from "../oauth";
|
|
import { cookies } from "next/dist/client/components/headers";
|
|
import prisma from "@/prisma";
|
|
|
|
export async function GET(request: Request) {
|
|
let url = new URL(request.url);
|
|
let code = url.searchParams.get("code");
|
|
let state = url.searchParams.get("state");
|
|
|
|
if (code === null || state === null)
|
|
return new Response("missing code/state", { status: 400 });
|
|
console.log(`code: ${code}, state: ${state}`);
|
|
|
|
const cookieStore = cookies();
|
|
let cookieState = cookieStore.get("state");
|
|
// prevent forgery
|
|
console.log(`state: ${state}, cookieState: ${cookieState?.value}`);
|
|
if (cookieState?.value !== state)
|
|
return new Response("state is invalid", { status: 400 });
|
|
|
|
let form = new URLSearchParams();
|
|
form.append("client_id", process.env.DISCORD_CLIENT_ID);
|
|
form.append("client_secret", process.env.DISCORD_CLIENT_SECRET);
|
|
form.append("grant_type", "authorization_code");
|
|
form.append("code", code);
|
|
form.append("redirect_uri", discordRedirectUri());
|
|
|
|
let tokenResponse = await fetch("https://discord.com/api/oauth2/token", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
},
|
|
body: form.toString()
|
|
});
|
|
if (!tokenResponse.ok) throw "baby";
|
|
let tokenBody: DiscordAccessTokenResponse = await tokenResponse.json();
|
|
const id = await getDiscordID(tokenBody.access_token);
|
|
|
|
const user = await prisma.authTicket.create({
|
|
data: {
|
|
username: null,
|
|
ticket: makeTicket(),
|
|
discordAuth: {
|
|
connectOrCreate: {
|
|
where: {
|
|
id
|
|
},
|
|
create: {
|
|
id,
|
|
accessToken: tokenBody.access_token,
|
|
refreshToken: tokenBody.refresh_token,
|
|
refreshAt: new Date(Date.now() + tokenBody.expires_in * 1000)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return new Response(null, {
|
|
status: 302,
|
|
headers: {
|
|
"Set-Cookie": `ticket=${user.ticket}; Path=/;`,
|
|
Location: "/register"
|
|
}
|
|
});
|
|
}
|