mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 11:39:50 +02:00
feat: patreon login
This commit is contained in:
1 parent
03aa690247
commit
a7e89c2147
14 files changed
+260
-191
No files matched your search
@@ -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);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user