mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: patreon exempt
This commit is contained in:
1 parent
9bc745bc0e
commit
4f5a8c9a37
5 files changed
+110
-12
No files matched your search
@@ -1,7 +1,85 @@
|
||||
import { assertSecret } from '@blitzkit/core';
|
||||
import type { APIContext } from 'astro';
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
export async function GET({}: APIContext) {
|
||||
return Response.json({ hello: Math.random() });
|
||||
interface PatreonMembershipResponse {
|
||||
data: {
|
||||
attributes: unknown;
|
||||
id: `${number}`;
|
||||
relationships: {
|
||||
memberships: {
|
||||
data: {
|
||||
id: string; // uuid
|
||||
type: 'member';
|
||||
}[];
|
||||
};
|
||||
};
|
||||
type: 'user';
|
||||
};
|
||||
included?: (
|
||||
| {
|
||||
attributes: {
|
||||
patron_status:
|
||||
| 'active_patron'
|
||||
| 'declined_patron'
|
||||
| 'former_patron'
|
||||
| null; // null = never a paid member
|
||||
};
|
||||
id: string; // uuid
|
||||
relationships: {
|
||||
campaign: {
|
||||
data: {
|
||||
id: `${number}`; // id of my campaign to check against
|
||||
type: 'campaign';
|
||||
};
|
||||
links: {
|
||||
related: string; // url
|
||||
};
|
||||
};
|
||||
};
|
||||
type: 'member';
|
||||
}
|
||||
| {
|
||||
attributes: {};
|
||||
id: `${number}`;
|
||||
type: 'campaign'; // ignore this discriminator
|
||||
}
|
||||
)[];
|
||||
links: {
|
||||
self: 'https://www.patreon.com/api/oauth2/v2/user/124201389';
|
||||
};
|
||||
}
|
||||
|
||||
export async function GET({ request }: APIContext) {
|
||||
const token = request.headers.get('token');
|
||||
|
||||
if (!token) return Response.json(false);
|
||||
|
||||
console.log('doing it');
|
||||
|
||||
const patreonResponse = await fetch(
|
||||
encodeURI(
|
||||
'https://www.patreon.com/api/oauth2/v2/identity?include=memberships.campaign&fields[member]=patron_status',
|
||||
),
|
||||
{ headers: { Authorization: `Bearer ${token}` } },
|
||||
);
|
||||
|
||||
if (!patreonResponse.ok) return Response.json(false);
|
||||
|
||||
const json = (await patreonResponse.json()) as PatreonMembershipResponse;
|
||||
|
||||
const response = Response.json(
|
||||
json.included?.some(
|
||||
(item) =>
|
||||
item.type === 'member' &&
|
||||
item.relationships.campaign.data.id ===
|
||||
assertSecret(process.env.PATREON_CAMPAIGN_ID) &&
|
||||
item.attributes.patron_status === 'active_patron',
|
||||
) ?? false,
|
||||
);
|
||||
|
||||
response.headers.set('Cache-Control', 'max-age=86400'); // a day
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
import { Box, Flex, Heading } from '@radix-ui/themes';
|
||||
import { Ad } from '../components/Ad';
|
||||
import { AdWithContext } from '../components/AdWithContext';
|
||||
import HomeHero from '../components/HomeHero.astro';
|
||||
import { Plugs } from '../components/Plugs.tsx';
|
||||
import ToolCard from '../components/ToolCard.astro';
|
||||
@@ -24,7 +24,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
<Flex maxWidth="64rem" flexGrow="1" gap="4" direction="column">
|
||||
<ToolCard tool={tankopediaTool} />
|
||||
|
||||
<Ad client:only="react" id="homepage-ad-1" />
|
||||
<AdWithContext client:only="react" id="homepage-ad-1" />
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
{/* <ToolCard tool={playerStatsTool} /> */}
|
||||
@@ -39,7 +39,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
<ToolCard tool={discordTool} />
|
||||
</Flex>
|
||||
|
||||
<Ad client:only="react" id="homepage-ad-2" />
|
||||
<AdWithContext client:only="react" id="homepage-ad-2" />
|
||||
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
<ToolCard tool={moreTool} />
|
||||
|
||||
Reference in new issue
Block a user