feat: prepare for dynamic rendering

This commit is contained in:
Jozef Steinhübl 2024-08-03 10:46:56 +02:00
parent b7dd3bf3ef
commit 92d0c39db2
No known key found for this signature in database
GPG key ID: E6BC90C91973B08F
6 changed files with 121 additions and 14 deletions

View file

@ -1,5 +1,6 @@
import Discord from "@auth/core/providers/discord";
import { defineConfig } from "auth-astro";
import type { User } from "~/env";
export default defineConfig({
providers: [
@ -15,6 +16,9 @@ export default defineConfig({
if (account && profile) {
token.accessToken = account.access_token;
token.id = profile.id;
token.name = profile.username as string;
token.global_name = profile.global_name;
}
return token;
@ -22,15 +26,20 @@ export default defineConfig({
async session({ session, token }) {
if (session.user) {
session.user.id = token.id as string;
(session.user as unknown as User).global_name =
token.global_name as string;
const guilds = await fetch("https://discord.com/api/users/@me/guilds", {
headers: {
Authorization: `Bearer ${token.accessToken as string}`,
"Cache-Control": "max-age=300",
},
});
const guilds = await fetch(
"https://discord.com/api/v10/users/@me/guilds",
{
headers: {
Authorization: `Bearer ${token.accessToken as string}`,
"Cache-Control": "max-age=300",
},
}
);
session.user.guilds = await guilds.json();
(session.user as unknown as User).guilds = await guilds.json();
}
return session;

View file

@ -3,9 +3,14 @@
import type { User as AuthCoreUser } from "@auth/core/types";
export type User = AuthCoreUser & {
guilds: {
id: string;
name: string;
icon: string;
}[];
global_name: string;
guilds: Guild[];
};
export interface Guild {
id: string;
name: string;
icon: string;
permissions: string;
owner: boolean;
}

View file

@ -0,0 +1,43 @@
import type { Guild } from "~/env";
// Checks if user has AMDINISTRATOR permissions in the guild
export async function filterUserGuilds(guilds: Guild[]): Promise<
{
mutual: boolean;
guild: Guild;
}[]
> {
const filtered = guilds
.filter((g) => (BigInt(g.permissions) & 0x8n) == 0x8n)
.sort((a, b) => Number(b.owner) - Number(a.owner));
const result: {
mutual: boolean;
guild: Guild;
}[] = [];
for (const guild of filtered) {
const mutual = await isMutualGuild(guild);
result.push({ mutual, guild });
}
result.sort((a, b) => Number(b.mutual) - Number(a.mutual));
return result;
}
export async function isMutualGuild(guild: Guild): Promise<boolean> {
const res = await fetch(
`https://discord.com/api/v10/guilds/${guild.id}/members/${
import.meta.env.DISCORD_CLIENT_ID
}`,
{
headers: {
Authorization: `Bot ${import.meta.env.DISCORD_BOT_TOKEN}`,
},
}
);
return res.ok;
}

View file

@ -0,0 +1,23 @@
import type { APIRoute } from "astro";
import { getSession } from "auth-astro/server";
import type { User } from "~/env";
export const GET: APIRoute = async ({ request }) => {
const session = await getSession(request);
if (!session || !session.user) {
return new Response(null, {
status: 401,
});
}
const user = session.user as User;
return Response.json(
user.guilds.map((g) => ({
id: g.id,
name: g.name,
owner: g.owner,
permissions: g.permissions,
}))
);
};

View file

@ -0,0 +1,21 @@
import type { APIRoute } from "astro";
import { getSession } from "auth-astro/server";
import type { User } from "~/env";
export const GET: APIRoute = async ({ request }) => {
const session = await getSession(request);
if (!session || !session.user) {
return new Response(null, {
status: 401,
});
}
const user = session.user as User;
return Response.json({
id: user.id,
username: user.name,
global_name: user.global_name,
avatar_url: user.image,
});
};

View file

@ -1,5 +1,6 @@
---
import type { User } from "~/env";
import { filterUserGuilds } from "~/lib/guilds";
import { getSession } from "auth-astro/server";
import Layout from "~/layouts/Layout.astro";
import Container from "~/components/Container.astro";
@ -11,6 +12,7 @@ if (!session || !session.user) {
}
const user = session.user as User;
const guilds = await filterUserGuilds(user.guilds);
---
<Layout>
@ -33,8 +35,12 @@ const user = session.user as User;
class="flex flex-wrap items-center justify-center gap-12 pb-4 text-white"
>
{
user.guilds.map((guild) => (
<section class="flex min-h-max w-80 justify-between rounded-md border-[1px] border-neutral-800 bg-dark-100 p-6 md:w-96">
guilds.map(({ guild, mutual }) => (
<section
class={`flex min-h-max w-80 justify-between rounded-md border-[1px] border-neutral-800 bg-dark-100 p-6 md:w-96 ${
!mutual && "brightness-50"
}`}
>
<div class="flex flex-row items-center">
<Image
src={`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp`}