import { IS_PROD } from "@stealth-developers/config"; import db, { sessions, upsertUser } from "@stealth-developers/db"; import { RESTGetAPICurrentUserResult, RESTPostOAuth2AccessTokenResult, RouteBases, Routes, } from "discord.js"; import Elysia, { t } from "elysia"; import { OAuth2ErrorResponse, isError, isOAuth2Error, makeRequest } from "../discord"; import { CLIENT_ID, CLIENT_SECRET, FRONTEND_URL, REDIRECT_URI } from "../lib/constants"; export const authRoutes = new Elysia().group("/auth", (app) => app .get( "/login", ({ redirect }) => { const redirectUri = `https://discord.com/oauth2/authorize?client_id=${CLIENT_ID}&response_type=code&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&scope=identify+guilds`; return redirect(redirectUri, 302); }, { tags: ["auth"], }, ) .get( "/callback", async ({ query: { code }, cookie: { session_id }, redirect }) => { const params = new URLSearchParams({ code, client_id: CLIENT_ID, client_secret: CLIENT_SECRET, grant_type: "authorization_code", redirect_uri: REDIRECT_URI, }); const tokenResponse = await fetch("https://discord.com/api/oauth2/token", { method: "POST", body: params, headers: { "Content-Type": "application/x-www-form-urlencoded" }, }); const tokenData = (await tokenResponse.json()) as | OAuth2ErrorResponse | RESTPostOAuth2AccessTokenResult; if (isOAuth2Error(tokenData)) throw new Error(tokenData.error_description ?? tokenData.error); const userData = await makeRequest( `${RouteBases.api}${Routes.user()}`, tokenData.access_token, ); if (isError(userData)) throw new Error(userData.message); const upsertedUser = await upsertUser({ avatar: userData.avatar, username: userData.username, displayName: userData.global_name, id: userData.id, }); const sessionId = crypto.randomUUID(); const expiresAt = new Date().getTime() + tokenData.expires_in * 1_000; await db.insert(sessions).values({ id: sessionId, userId: upsertedUser.id, accessToken: tokenData.access_token, refreshToken: tokenData.refresh_token, scope: tokenData.scope, tokenType: tokenData.token_type, createdAt: new Date(), expiresAt: new Date(expiresAt), }); session_id.set({ value: sessionId, httpOnly: true, path: "/", secure: IS_PROD, sameSite: "lax", expires: new Date(expiresAt), }); return redirect(FRONTEND_URL); }, { tags: ["auth"], query: t.Object({ code: t.String(), }), }, ), );