apps/api/src/routes/auth.ts (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
import type { Error, ProvisionalTokenResponse } from "@purrkit/types";
import { IS_PROD } from "@stealth-developers/config";
import db, { sessions, upsertUser } from "@stealth-developers/db";
import Elysia, { t } from "elysia";
import { createClient } 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 Error | ProvisionalTokenResponse;
if ("code" in tokenData) throw new Error(tokenData.message);
const client = createClient(`${tokenData.token_type} ${tokenData.access_token}`);
const userRes = await client.users.me.get();
if (!userRes.ok) throw new Error(userRes.data.message);
const userData = userRes.data;
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(),
}),
},
),
);
|