mirror of
https://git.moonleay.net/Websites/liljudd-website.git
synced 2025-07-23 17:25:08 +02:00
132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
import { createId } from "@paralleldrive/cuid2";
|
|
import { APIEvent } from "@solidjs/start/server/types";
|
|
import { OAuth2RequestError } from "arctic";
|
|
import { eq } from "drizzle-orm";
|
|
import createClient from "openapi-fetch";
|
|
import { getCookie, setCookie } from "vinxi/http";
|
|
import db from "~/drizzle";
|
|
import { discordTokens, users } from "~/drizzle/schema";
|
|
import { discord, lucia } from "~/lib/auth";
|
|
import { paths } from "~/types/discord";
|
|
|
|
export async function GET(event: APIEvent): Promise<Response> {
|
|
const code = new URL(event.request.url).searchParams.get("code");
|
|
const state = new URL(event.request.url).searchParams.get("state");
|
|
const error = new URL(event.request.url).searchParams.get("error");
|
|
const error_description = new URL(event.request.url).searchParams.get(
|
|
"error_description",
|
|
);
|
|
if (error)
|
|
switch (error) {
|
|
case "access_denied":
|
|
return new Response(null, {
|
|
status: 302,
|
|
headers: { Location: "/" },
|
|
});
|
|
default:
|
|
console.log("Discord oauth error:", error_description);
|
|
return new Response(decodeURI(error_description ?? ""), {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const storedState = getCookie("discord_oauth_state") ?? null;
|
|
if (!code || !state || !storedState || state !== storedState) {
|
|
return new Response(null, {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
try {
|
|
const tokens = await discord.validateAuthorizationCode(code);
|
|
const { GET } = createClient<paths>({
|
|
baseUrl: "https://discord.com/api/v10",
|
|
});
|
|
const discordUserResponse = await GET("/users/@me", {
|
|
headers: { Authorization: `Bearer ${tokens.accessToken}` },
|
|
});
|
|
if (discordUserResponse.error) throw discordUserResponse.error;
|
|
const discordUser = discordUserResponse.data;
|
|
const existingUser = await db.query.users
|
|
.findFirst({
|
|
where: eq(users.discord_id, discordUser.id),
|
|
})
|
|
.execute();
|
|
|
|
if (existingUser) {
|
|
const session = await lucia.createSession(
|
|
existingUser.id,
|
|
{},
|
|
{ sessionId: createId() },
|
|
);
|
|
const sessionCookie = lucia.createSessionCookie(session.id);
|
|
console.log(sessionCookie);
|
|
setCookie(
|
|
sessionCookie.name,
|
|
sessionCookie.value,
|
|
sessionCookie.attributes,
|
|
);
|
|
await db
|
|
.update(users)
|
|
.set({
|
|
name: discordUser.global_name,
|
|
image: discordUser.avatar,
|
|
})
|
|
.where(eq(users.discord_id, discordUser.id))
|
|
.returning()
|
|
.execute();
|
|
|
|
return new Response(null, {
|
|
status: 302,
|
|
headers: { Location: "/config" },
|
|
});
|
|
}
|
|
|
|
const userId = createId();
|
|
await db.insert(users).values({
|
|
id: userId,
|
|
discord_id: discordUser.id,
|
|
name: discordUser.global_name,
|
|
image: discordUser.avatar,
|
|
});
|
|
await db
|
|
.insert(discordTokens)
|
|
.values({
|
|
userId,
|
|
accessToken: tokens.accessToken,
|
|
expiresAt: tokens.accessTokenExpiresAt,
|
|
refreshToken: tokens.refreshToken,
|
|
})
|
|
.returning()
|
|
.execute();
|
|
console.log(createId(), createId(), { warst: createId() });
|
|
const session = await lucia.createSession(
|
|
userId,
|
|
{},
|
|
{ sessionId: createId() },
|
|
);
|
|
const sessionCookie = lucia.createSessionCookie(session.id);
|
|
setCookie(
|
|
sessionCookie.name,
|
|
sessionCookie.value,
|
|
sessionCookie.attributes,
|
|
);
|
|
return new Response(null, {
|
|
status: 302,
|
|
headers: { Location: "/config" },
|
|
});
|
|
} catch (e) {
|
|
// the specific error message depends on the provider
|
|
if (e instanceof OAuth2RequestError) {
|
|
// invalid code
|
|
return new Response(null, {
|
|
status: 400,
|
|
});
|
|
}
|
|
console.error("Unknown error on callback.");
|
|
console.error(e);
|
|
return new Response(null, {
|
|
status: 500,
|
|
});
|
|
}
|
|
}
|