From 0df58d2d2cab8f1eb34ca4345d62a052edf53a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:29:58 -0500 Subject: [PATCH] feat: remove patreon --- packages/website/src/components/Checks.tsx | 29 ------- packages/website/src/components/Footer.astro | 2 - packages/website/src/components/Navbar.astro | 10 --- .../src/components/NavbarAccount/index.tsx | 39 +-------- .../website/src/components/PatreonIcon.tsx | 13 --- packages/website/src/components/Plugs.tsx | 65 ++++----------- .../src/components/TankSearch/index.tsx | 2 - .../components/Characteristics/index.tsx | 2 - packages/website/src/hooks/useAdExempt.ts | 36 -------- .../src/pages/api/patreon/auth/index.ts | 34 -------- .../src/pages/api/patreon/membership/index.ts | 83 ------------------- .../src/pages/auth/[provider]/_index.tsx | 31 +------ packages/website/src/stores/app/index.ts | 1 - 13 files changed, 21 insertions(+), 326 deletions(-) delete mode 100644 packages/website/src/components/PatreonIcon.tsx delete mode 100644 packages/website/src/hooks/useAdExempt.ts delete mode 100644 packages/website/src/pages/api/patreon/auth/index.ts delete mode 100644 packages/website/src/pages/api/patreon/membership/index.ts diff --git a/packages/website/src/components/Checks.tsx b/packages/website/src/components/Checks.tsx index 65d782d97..00b1c9654 100644 --- a/packages/website/src/components/Checks.tsx +++ b/packages/website/src/components/Checks.tsx @@ -3,7 +3,6 @@ import { idToRegion } from '@blitzkit/core'; import { Button, Flex, Heading, Link, Text } from '@radix-ui/themes'; import { useEffect, useState } from 'react'; -import type { PatreonAuthResponse } from '../pages/auth/[provider]/_index'; import { App } from '../stores/app'; import { CURRENT_POLICIES_AGREEMENT_INDEX } from '../stores/app/constants'; @@ -30,7 +29,6 @@ export function Checks() { /** * Wargaming: 14 (refresh: 7) - * Patreon: 31 (refresh: 15) */ function Content() { const logins = App.use((state) => state.logins); @@ -103,33 +101,6 @@ function Content() { }); } } - - if (logins.patreon) { - const expiresIn = logins.patreon.expires - Date.now(); - const expiresInDays = expiresIn / 1000 / 60 / 60 / 24; - - if (expiresInDays < 0) { - mutateApp((draft) => { - draft.logins.patreon = undefined; - }); - } else if (expiresInDays < 15) { - const { patreon } = appStore.getState().logins; - - if (!patreon) return; - - fetch(`/api/patreon/refresh/${patreon.refreshToken}`) - .then((response) => response.json() as Promise) - .then((data) => { - mutateApp((draft) => { - draft.logins.patreon = { - token: data.access_token, - refreshToken: data.refresh_token, - expires: Date.now() + data.expires_in * 1000, - }; - }); - }); - } - } }); if (!showPoliciesAgreement) return null; diff --git a/packages/website/src/components/Footer.astro b/packages/website/src/components/Footer.astro index 18465fb7c..948488497 100644 --- a/packages/website/src/components/Footer.astro +++ b/packages/website/src/components/Footer.astro @@ -84,8 +84,6 @@ const gameDefinitions = await fetchGameDefinitions(); GitHub Patches - - {/* patreon supporters? */} diff --git a/packages/website/src/components/Navbar.astro b/packages/website/src/components/Navbar.astro index 1f4caeebf..050337195 100644 --- a/packages/website/src/components/Navbar.astro +++ b/packages/website/src/components/Navbar.astro @@ -19,7 +19,6 @@ import { } from '@radix-ui/themes'; import { resolveBranchName } from '../core/blitzkit/branches'; import { homeTool, TOOLS } from '../constants/tools'; -import { PatreonIcon } from './PatreonIcon'; import { NavbarAccount } from './NavbarAccount'; const toolsFiltered = TOOLS.filter((tool) => !('href' in tool)); @@ -176,15 +175,6 @@ const isBranchNamed = branchName !== undefined; > - - - event.preventDefault()} > - {(logins.patreon || logins.wargaming) && ( + {logins.wargaming && ( Logged in accounts - {logins.patreon && ( - - - Patreon - - - )} - {logins.wargaming && ( @@ -96,26 +73,18 @@ function Content() { )} - {!logins.patreon !== !logins.wargaming && ( + {/* {!logins. !== !logins.wargaming && ( - )} + )} */} - {(!logins.patreon || !logins.wargaming) && ( + {!logins.wargaming && ( Log in with... - {!logins.patreon && ( - - - - )} - {!logins.wargaming && } )} diff --git a/packages/website/src/components/PatreonIcon.tsx b/packages/website/src/components/PatreonIcon.tsx deleted file mode 100644 index 874cfa03d..000000000 --- a/packages/website/src/components/PatreonIcon.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import type { ComponentProps } from 'react'; - -export function PatreonIcon(props: ComponentProps<'svg'>) { - return ( - - - - ); -} diff --git a/packages/website/src/components/Plugs.tsx b/packages/website/src/components/Plugs.tsx index 0b37eee83..3a1a93f7e 100644 --- a/packages/website/src/components/Plugs.tsx +++ b/packages/website/src/components/Plugs.tsx @@ -1,9 +1,7 @@ -import { assertSecret, patreonLoginUrl } from '@blitzkit/core'; +import { assertSecret } from '@blitzkit/core'; import { ArrowRightIcon } from '@radix-ui/react-icons'; -import { Button, Code, Flex, Link, Separator, Text } from '@radix-ui/themes'; -import { useAdExempt } from '../hooks/useAdExempt'; +import { Button, Code, Flex, Link, Text } from '@radix-ui/themes'; import { App } from '../stores/app'; -import { PatreonIcon } from './PatreonIcon'; export function Plugs() { return ( @@ -14,9 +12,6 @@ export function Plugs() { } function Content() { - const exempt = useAdExempt(); - const hasPatreon = App.use((state) => state.logins.patreon !== undefined); - return ( {assertSecret(import.meta.env.PUBLIC_PROMOTE_OPENTEST) === 'true' && assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH) !== 'opentest' && ( - <> - - - BlitzKit{' '} - - opentest - {' '} - is available now{' '} - + + + BlitzKit{' '} + + opentest + {' '} + is available now{' '} + - - - - - - - - )} - - - - - {exempt - ? 'You are supporting BlitzKit, thank you!' - : 'Active Patreon supports go ad-free'} - - - - - - - - {!hasPatreon && !exempt && ( - - + + - )} - - + + )} ); } diff --git a/packages/website/src/components/TankSearch/index.tsx b/packages/website/src/components/TankSearch/index.tsx index caf8d2335..5db8a4806 100644 --- a/packages/website/src/components/TankSearch/index.tsx +++ b/packages/website/src/components/TankSearch/index.tsx @@ -16,7 +16,6 @@ import { times } from 'lodash-es'; import { memo, useEffect, useMemo, useState } from 'react'; import { filterTank } from '../../core/blitzkit/filterTank'; import { resolveReload } from '../../core/blitzkit/resolveReload'; -import { useAdExempt } from '../../hooks/useAdExempt'; import { $tankFilters } from '../../stores/tankFilters'; import { SORT_NAMES, @@ -49,7 +48,6 @@ const tankNames = await fetchTankNames(); export const TankSearch = memo( ({ compact, onSelect, onSelectAll, ...props }) => { const awaitedTanksDefinitionsArray = Object.values(tankDefinitions.tanks); - const exempt = useAdExempt(); const tankFilters = useStore($tankFilters); const tankopediaSort = useStore($tankopediaSort); diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx index 23205b2b6..4d3ac2e69 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -26,7 +26,6 @@ import { Fragment } from 'react/jsx-runtime'; import { lerp } from 'three/src/math/MathUtils.js'; import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits'; import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics'; -import { useAdExempt } from '../../../../../hooks/useAdExempt'; import { useEquipment } from '../../../../../hooks/useEquipment'; import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition'; import { Duel } from '../../../../../stores/duel'; @@ -39,7 +38,6 @@ const provisionDefinitions = await fetchProvisionDefinitions(); export function Characteristics() { const mutateDuel = Duel.useMutation(); - const exempt = useAdExempt(); const crewSkills = TankopediaEphemeral.use((state) => state.skills); const penetrationDistanceInput = useRef(null); const hasImprovedVentilation = useEquipment(102); diff --git a/packages/website/src/hooks/useAdExempt.ts b/packages/website/src/hooks/useAdExempt.ts deleted file mode 100644 index 088095b3a..000000000 --- a/packages/website/src/hooks/useAdExempt.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { useEffect, useState } from 'react'; -import { App } from '../stores/app'; - -let cache: Record> = {}; - -export function useAdExempt() { - const patreon = App.use((state) => state.logins.patreon); - const [exempt, setExempt] = useState(false); - - useEffect(() => { - (async () => { - if (!patreon) return setExempt(false); - - if (!(patreon.token in cache)) { - cache[patreon.token] = new Promise(async (resolve) => { - const response = await fetch(`/api/patreon/membership`, { - cache: 'default', - headers: { token: patreon.token }, - }); - - if (!response.ok) return resolve(false); - - const json = await response.json(); - const exempt = typeof json === 'boolean' && json; - - cache[patreon.token] = exempt; - resolve(exempt); - }); - } - - setExempt(await cache[patreon.token]); - })(); - }, []); - - return exempt; -} diff --git a/packages/website/src/pages/api/patreon/auth/index.ts b/packages/website/src/pages/api/patreon/auth/index.ts deleted file mode 100644 index 9612a0118..000000000 --- a/packages/website/src/pages/api/patreon/auth/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { assertSecret, type BlitzkitResponse } from '@blitzkit/core'; -import type { APIContext } from 'astro'; - -export const prerender = false; - -export async function GET({ request, params }: APIContext) { - const code = request.headers.get('code'); - - if (!code) { - return Response.json({ - status: 'error', - error: 'UNDEFINED_CODE', - } satisfies BlitzkitResponse); - } - - const response = await fetch( - `https://www.patreon.com/api/oauth2/token?code=${ - code - }&grant_type=authorization_code&client_id=${assertSecret( - import.meta.env.PUBLIC_PATREON_CLIENT_ID, - )}&client_secret=${assertSecret( - import.meta.env.PATREON_CLIENT_SECRET, - )}&redirect_uri=${assertSecret( - import.meta.env.PUBLIC_PATREON_REDIRECT_URI, - )}`, - { - method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - }, - ); - const json = await response.json(); - - return Response.json(json); -} diff --git a/packages/website/src/pages/api/patreon/membership/index.ts b/packages/website/src/pages/api/patreon/membership/index.ts deleted file mode 100644 index 5ec4391c3..000000000 --- a/packages/website/src/pages/api/patreon/membership/index.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { assertSecret } from '@blitzkit/core'; -import type { APIContext } from 'astro'; - -export const prerender = false; - -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); - - 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; -} diff --git a/packages/website/src/pages/auth/[provider]/_index.tsx b/packages/website/src/pages/auth/[provider]/_index.tsx index 6e53a1ed1..a9dd5444c 100644 --- a/packages/website/src/pages/auth/[provider]/_index.tsx +++ b/packages/website/src/pages/auth/[provider]/_index.tsx @@ -1,24 +1,14 @@ import { useEffect } from 'react'; import { App } from '../../../stores/app'; -export const AUTH_PROVIDERS = ['wargaming', 'patreon'] as const; +export const AUTH_PROVIDERS = ['wargaming'] as const; type AuthProvider = (typeof AUTH_PROVIDERS)[number]; export const AUTH_PROVIDER_NAMES: Record = { - patreon: 'Patreon', wargaming: 'Wargaming', }; -export interface PatreonAuthResponse { - access_token: string; - expires_in: number; - token_type: 'Bearer'; - scope: string; - refresh_token: string; - version: string; -} - interface AuthorizeProps { provider: AuthProvider; } @@ -59,25 +49,6 @@ function Content({ provider }: AuthorizeProps) { break; } - case 'patreon': { - if (!searchParams.get('code')) break; - - const response = await fetch('/api/patreon/auth', { - headers: { code: searchParams.get('code')! }, - }); - const data = (await response.json()) as PatreonAuthResponse; - - mutateApp((draft) => { - draft.logins.patreon = { - token: data.access_token, - refreshToken: data.refresh_token, - expires: Date.now() + data.expires_in * 1000, - }; - }); - - break; - } - default: throw new Error(`Unknown provider: ${provider}`); } diff --git a/packages/website/src/stores/app/index.ts b/packages/website/src/stores/app/index.ts index 3bed8ea58..bf61e2489 100644 --- a/packages/website/src/stores/app/index.ts +++ b/packages/website/src/stores/app/index.ts @@ -8,7 +8,6 @@ interface AppStore { policiesAgreementIndex: number; logins: { wargaming?: { token: string; id: number; expires: number }; - patreon?: { token: string; refreshToken: string; expires: number }; }; }