mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: logins
This commit is contained in:
1 parent
9ad3fb220f
commit
1e64cb9e7d
5 files changed
+114
-3
No files matched your search
@@ -73,7 +73,7 @@ export function fetchBlitz<Data extends object>(
|
||||
queue.push({
|
||||
url: `https://api.wotblitz.${region}/wotb/${path}/?${Object.entries({
|
||||
application_id: assertSecret(
|
||||
process.env.PUBLIC_WARGAMING_APPLICATION_ID,
|
||||
import.meta.env.PUBLIC_WARGAMING_APPLICATION_ID,
|
||||
),
|
||||
...params,
|
||||
})
|
||||
|
||||
@@ -11,6 +11,7 @@ type PageWrapperProps = FlexProps & {
|
||||
containerProps?: ComponentProps<typeof Theme>;
|
||||
noFlex1?: boolean;
|
||||
padding?: RadixSize;
|
||||
noMinHeight?: boolean;
|
||||
};
|
||||
|
||||
export function PageWrapper({
|
||||
@@ -21,6 +22,7 @@ export function PageWrapper({
|
||||
noMaxWidth = false,
|
||||
noFlex1 = false,
|
||||
containerProps,
|
||||
noMinHeight = false,
|
||||
padding = '4',
|
||||
...props
|
||||
}: PageWrapperProps) {
|
||||
@@ -30,7 +32,7 @@ export function PageWrapper({
|
||||
style={{
|
||||
flex: noFlex1 ? undefined : 1,
|
||||
display: 'flex',
|
||||
minHeight: `calc(100dvh - ${NAVBAR_HEIGHT}px)`,
|
||||
minHeight: noMinHeight ? 'unset' : `calc(100dvh - ${NAVBAR_HEIGHT}px)`,
|
||||
flexDirection: 'column',
|
||||
...containerProps?.style,
|
||||
}}
|
||||
|
||||
@@ -8,7 +8,7 @@ export function HistorySection() {
|
||||
if (!tank.description) return null;
|
||||
|
||||
return (
|
||||
<PageWrapper noFlex1 align="center">
|
||||
<PageWrapper noFlex1 align="center" noMinHeight>
|
||||
<Heading>History of the {tank.name}</Heading>
|
||||
<Text>{tank.description}</Text>
|
||||
</PageWrapper>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { useEffect } from 'react';
|
||||
import { $patreonLogin } from '../../../stores/patreonLogin';
|
||||
import { $wargamingLogin } from '../../../stores/wargamingLogin';
|
||||
|
||||
export const AUTH_PROVIDERS = ['wargaming', 'patreon'] as const;
|
||||
|
||||
type AuthProvider = (typeof AUTH_PROVIDERS)[number];
|
||||
|
||||
export const AUTH_PROVIDER_NAMES: Record<AuthProvider, string> = {
|
||||
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;
|
||||
}
|
||||
|
||||
export function Authorize({ provider }: AuthorizeProps) {
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
switch (provider) {
|
||||
case 'wargaming': {
|
||||
if (
|
||||
!searchParams.has('expires_at') ||
|
||||
!searchParams.has('access_token') ||
|
||||
!searchParams.has('account_id')
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
$wargamingLogin.set({
|
||||
expires: `${Number(searchParams.get('expires_at')) * 1000}`,
|
||||
token: searchParams.get('access_token')!,
|
||||
id: searchParams.get('account_id')!,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'patreon': {
|
||||
if (!searchParams.get('code')) break;
|
||||
|
||||
const response = await fetch(
|
||||
`/api/patreon/auth/${searchParams.get('code')}`,
|
||||
);
|
||||
const data = (await response.json()) as PatreonAuthResponse;
|
||||
|
||||
$patreonLogin.set({
|
||||
token: data.access_token,
|
||||
refreshToken: data.refresh_token,
|
||||
expires: `${Date.now() + data.expires_in * 1000}`,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown provider: ${provider}`);
|
||||
}
|
||||
|
||||
window.location.href = searchParams.get('return') ?? '/';
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
import { Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import type { GetStaticPaths } from 'astro';
|
||||
import { PageWrapper } from '../../../components/PageWrapper';
|
||||
import RootLayout from '../../../layouts/RootLayout.astro';
|
||||
import { AUTH_PROVIDERS, AUTH_PROVIDER_NAMES, Authorize } from './_index';
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return AUTH_PROVIDERS.map((provider) => ({ params: { provider } }));
|
||||
}) satisfies GetStaticPaths;
|
||||
|
||||
const { provider } = Astro.params;
|
||||
---
|
||||
|
||||
<RootLayout>
|
||||
<PageWrapper>
|
||||
<Flex
|
||||
style={{ flex: 1 }}
|
||||
align="center"
|
||||
justify="center"
|
||||
direction="column"
|
||||
gap="2"
|
||||
>
|
||||
<Heading align="center"
|
||||
>Authorizing you with {AUTH_PROVIDER_NAMES[provider]}...</Heading
|
||||
>
|
||||
<Text color="gray" align="center">You'll be on your way shortly.</Text>
|
||||
</Flex>
|
||||
</PageWrapper>
|
||||
|
||||
<Authorize client:only {provider} />
|
||||
</RootLayout>
|
||||
Reference in new issue
Block a user