feat: patreon login

This commit is contained in:
TrèsAbhi committed 2024-06-13 14:52:43 -05:00
1 parent 03aa690247
commit a7e89c2147
14 files changed
+260 -191

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
import { NextResponse } from 'next/server';
export async function GET(
request: Request,
{ params }: { params: { code: string } },
) {
const response = await fetch(
`https://www.patreon.com/api/oauth2/token?code=${params.code}&grant_type=authorization_code&client_id=${process.env.NEXT_PUBLIC_PATREON_CLIENT_ID}&client_secret=${process.env.PATREON_CLIENT_SECRET}&redirect_uri=${process.env.NEXT_PUBLIC_PATREON_REDIRECT_URI}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
},
);
const json = await response.json();
return NextResponse.json(json);
}
@@ -0,0 +1,14 @@
import { NextResponse } from 'next/server';
export async function GET(
request: Request,
{ params }: { params: { token: string } },
) {
const response = await fetch(
`https://www.patreon.com/api/oauth2/token?grant_type=refresh_token&refresh_token=${params.token}&client_id=${process.env.NEXT_PUBLIC_PATREON_CLIENT_ID}&client_secret=${process.env.PATREON_CLIENT_SECRET}`,
{ method: 'POST' },
);
const json = await response.json();
return NextResponse.json(json);
}
+91
View File
@@ -0,0 +1,91 @@
'use client';
import { Flex, Heading, Text } from '@radix-ui/themes';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import PageWrapper from '../../../components/PageWrapper';
import { mutateApp } from '../../../stores/app';
export interface PatreonAuthResponse {
access_token: string;
expires_in: number;
token_type: 'Bearer';
scope: string;
refresh_token: string;
version: string;
}
export default function Page({
params,
searchParams,
}: {
params: { provider: string };
searchParams: { [key: string]: string };
}) {
const router = useRouter();
useEffect(() => {
(async () => {
switch (params.provider) {
case 'wargaming': {
if (
!searchParams.expires_at ||
!searchParams.access_token ||
!searchParams.account_id
) {
break;
}
mutateApp((draft) => {
draft.logins.wargaming = {
id: Number(searchParams.account_id),
token: searchParams.access_token,
expires: Number(searchParams.expires_at) * 1000,
};
});
break;
}
case 'patreon': {
if (!searchParams.code) break;
const data = (await fetch(
`/api/auth/patreon/${searchParams.code}`,
).then((response) => 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: {
console.error(`Unknown provider: ${params.provider}`);
}
}
router.push(searchParams.return ?? '/');
})();
});
return (
<PageWrapper>
<Flex
style={{ flex: 1 }}
align="center"
justify="center"
direction="column"
gap="2"
>
<Heading>Verifying you...</Heading>
<Text color="gray">You'll be on your way shortly.</Text>
</Flex>
</PageWrapper>
);
}
-62
View File
@@ -1,62 +0,0 @@
'use client';
import { Flex, Heading, Text } from '@radix-ui/themes';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import PageWrapper from '../../../components/PageWrapper';
import { mutateApp } from '../../../stores/app';
export default function Page({
params,
searchParams,
}: {
params: { provider: string };
searchParams: { [key: string]: string };
}) {
const router = useRouter();
useEffect(() => {
switch (params.provider) {
case 'wargaming': {
if (
!searchParams.expires_at ||
!searchParams.access_token ||
!searchParams.account_id
) {
break;
}
mutateApp((draft) => {
draft.login = {
expiresAt: Number(searchParams.expires_at),
id: Number(searchParams.account_id),
token: searchParams.access_token,
};
});
break;
}
default: {
console.error(`Unknown provider: ${params.provider}`);
}
}
router.push(searchParams.return ? searchParams.return : '/');
});
return (
<PageWrapper>
<Flex
style={{ flex: 1 }}
align="center"
justify="center"
direction="column"
gap="2"
>
<Heading>Verifying you...</Heading>
<Text color="gray">You'll be on your way shortly.</Text>
</Flex>
</PageWrapper>
);
}
+28 -10
View File
@@ -10,17 +10,24 @@ import {
} from '@radix-ui/themes';
import { usePathname } from 'next/navigation';
import { useEffect, useState } from 'react';
import { extendAuth } from '../../core/blitz/extendAuth';
import { logout } from '../../core/blitz/logout';
import { extendAuthPatreon } from '../../core/blitz/extendAuthPatreon';
import { extendAuthWargaming } from '../../core/blitz/extendAuthWargaming';
import { logoutPatreon } from '../../core/blitz/logoutPatreon';
import { logoutWargaming } from '../../core/blitz/logoutWargaming';
import isDev from '../../core/blitzkit/isDev';
import { isLocalhost } from '../../core/blitzkit/isLocalhost';
import { CURRENT_POLICIES_AGREEMENT_INDEX, useApp } from '../../stores/app';
const DEV_BUILD_AGREEMENT_COOLDOWN = 8 * 24 * 60 * 60 * 1000;
/**
* Wargaming: 14 (refresh: 7)
* Patreon: 31 (refresh: 15)
*/
export function Checks() {
const [showDevBuildAlert, setShowDevBuildAlert] = useState(false);
const login = useApp((state) => state.login);
const logins = useApp((state) => state.logins);
const policiesAgreementIndex = useApp(
(state) => state.policiesAgreementIndex,
);
@@ -43,15 +50,26 @@ export function Checks() {
}, [policiesAgreementIndex, isLegal]);
useEffect(() => {
if (!login) return;
if (logins.wargaming) {
const expiresIn = logins.wargaming.expires - Date.now();
const expiresInDays = expiresIn / 1000 / 60 / 60 / 24;
const expiresIn = login.expiresAt - Date.now() / 1000;
const expiresInDays = expiresIn / 60 / 60 / 24;
if (expiresInDays < 0) {
logoutWargaming();
} else if (expiresInDays < 7) {
extendAuthWargaming();
}
}
if (expiresInDays < 0) {
logout();
} else if (expiresInDays < 7) {
extendAuth();
if (logins.patreon) {
const expiresIn = logins.patreon.expires - Date.now();
const expiresInDays = expiresIn / 1000 / 60 / 60 / 24;
if (expiresInDays < 0) {
logoutPatreon();
} else if (expiresInDays < 15) {
extendAuthPatreon();
}
}
});