53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import { createFileRoute } from '@tanstack/react-router';
|
|
import { zodValidator } from '@tanstack/zod-adapter';
|
|
import { isNil } from 'lodash-es';
|
|
import { useEffect } from 'react';
|
|
import z from 'zod';
|
|
import { LoginForm } from '@/components/login-form';
|
|
import { useExchangeToken } from '@/hooks/data/useExchangeToken';
|
|
import { generateOAuthState } from '@/lib/random';
|
|
import { getAccessToken } from '@/lib/token';
|
|
|
|
const baseUrl = import.meta.env.VITE_APP_BASE_URL;
|
|
|
|
const authorizeSchema = z.object({
|
|
response_type: z.literal('code').default('code'),
|
|
client_id: z.literal('org_client').default('org_client'),
|
|
redirect_uri: z.string().default(`${new URL(baseUrl).toString()}token`),
|
|
state: z.string().default(generateOAuthState()),
|
|
});
|
|
|
|
export type AuthorizeSearchParams = z.infer<typeof authorizeSchema>;
|
|
|
|
export const Route = createFileRoute('/authorize')({
|
|
component: RouteComponent,
|
|
validateSearch: zodValidator(authorizeSchema),
|
|
});
|
|
|
|
function RouteComponent() {
|
|
const token = getAccessToken();
|
|
const oauthParams = Route.useSearch();
|
|
const mutation = useExchangeToken();
|
|
/**
|
|
* Auth by Token Flow
|
|
*/
|
|
useEffect(() => {
|
|
if (!isNil(token) && mutation.isIdle) {
|
|
mutation.mutate({
|
|
body: {
|
|
client_id: oauthParams.client_id,
|
|
redirect_uri: oauthParams.redirect_uri,
|
|
state: oauthParams.state,
|
|
},
|
|
});
|
|
}
|
|
}, [token, mutation.isIdle]);
|
|
return (
|
|
<div className="bg-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
|
|
<div className="w-full max-w-sm">
|
|
<LoginForm oauthParams={oauthParams} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|