mirror of
https://github.com/fosrl/pangolin.git
synced 2026-04-25 15:35:17 +00:00
163 lines
4.8 KiB
TypeScript
163 lines
4.8 KiB
TypeScript
import {
|
|
AuthWithAccessTokenResponse,
|
|
GetResourceAuthInfoResponse,
|
|
GetResourceResponse
|
|
} from "@server/routers/resource";
|
|
import ResourceAuthPortal from "./ResourceAuthPortal";
|
|
import { internal, priv } from "@app/lib/api";
|
|
import { AxiosResponse } from "axios";
|
|
import { authCookieHeader } from "@app/lib/api/cookies";
|
|
import { cache } from "react";
|
|
import { verifySession } from "@app/lib/auth/verifySession";
|
|
import { redirect } from "next/navigation";
|
|
import ResourceNotFound from "./ResourceNotFound";
|
|
import ResourceAccessDenied from "./ResourceAccessDenied";
|
|
import { cookies } from "next/headers";
|
|
import { CheckResourceSessionResponse } from "@server/routers/auth";
|
|
import AccessTokenInvalid from "./AccessToken";
|
|
import AccessToken from "./AccessToken";
|
|
import { pullEnv } from "@app/lib/pullEnv";
|
|
|
|
export default async function ResourceAuthPage(props: {
|
|
params: Promise<{ resourceId: number }>;
|
|
searchParams: Promise<{
|
|
redirect: string | undefined;
|
|
token: string | undefined;
|
|
}>;
|
|
}) {
|
|
const params = await props.params;
|
|
const searchParams = await props.searchParams;
|
|
|
|
const env = pullEnv();
|
|
|
|
let authInfo: GetResourceAuthInfoResponse | undefined;
|
|
try {
|
|
const res = await internal.get<
|
|
AxiosResponse<GetResourceAuthInfoResponse>
|
|
>(`/resource/${params.resourceId}/auth`, await authCookieHeader());
|
|
|
|
if (res && res.status === 200) {
|
|
authInfo = res.data.data;
|
|
}
|
|
} catch (e) {}
|
|
|
|
const getUser = cache(verifySession);
|
|
const user = await getUser({ skipCheckVerifyEmail: true });
|
|
|
|
if (!authInfo) {
|
|
{
|
|
/* @ts-ignore */
|
|
} // TODO: fix this
|
|
return (
|
|
<div className="w-full max-w-md">
|
|
<ResourceNotFound />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const redirectUrl = searchParams.redirect || authInfo.url;
|
|
|
|
const hasAuth =
|
|
authInfo.password ||
|
|
authInfo.pincode ||
|
|
authInfo.sso ||
|
|
authInfo.whitelist;
|
|
const isSSOOnly =
|
|
authInfo.sso &&
|
|
!authInfo.password &&
|
|
!authInfo.pincode &&
|
|
!authInfo.whitelist;
|
|
|
|
if (user && !user.emailVerified && env.flags.emailVerificationRequired) {
|
|
redirect(
|
|
`/auth/verify-email?redirect=/auth/resource/${authInfo.resourceId}`
|
|
);
|
|
}
|
|
|
|
const allCookies = await cookies();
|
|
const cookieName =
|
|
env.server.resourceSessionCookieName + `_${params.resourceId}`;
|
|
const sessionId = allCookies.get(cookieName)?.value ?? null;
|
|
|
|
if (sessionId) {
|
|
let doRedirect = false;
|
|
try {
|
|
const res = await priv.get<
|
|
AxiosResponse<CheckResourceSessionResponse>
|
|
>(`/resource-session/${params.resourceId}/${sessionId}`);
|
|
|
|
if (res && res.data.data.valid) {
|
|
doRedirect = true;
|
|
}
|
|
} catch (e) {}
|
|
|
|
if (doRedirect) {
|
|
redirect(redirectUrl);
|
|
}
|
|
}
|
|
|
|
if (!hasAuth) {
|
|
// no authentication so always go straight to the resource
|
|
redirect(redirectUrl);
|
|
}
|
|
|
|
let userIsUnauthorized = false;
|
|
if (user && authInfo.sso) {
|
|
let doRedirect = false;
|
|
try {
|
|
const res = await internal.get<AxiosResponse<GetResourceResponse>>(
|
|
`/resource/${params.resourceId}`,
|
|
await authCookieHeader()
|
|
);
|
|
|
|
doRedirect = true;
|
|
} catch (e) {
|
|
userIsUnauthorized = true;
|
|
}
|
|
|
|
if (doRedirect) {
|
|
redirect(redirectUrl);
|
|
}
|
|
}
|
|
|
|
if (searchParams.token) {
|
|
const [accessTokenId, accessToken] = searchParams.token.split(".");
|
|
return (
|
|
<div className="w-full max-w-md">
|
|
<AccessToken
|
|
accessToken={accessToken}
|
|
accessTokenId={accessTokenId}
|
|
resourceId={params.resourceId}
|
|
redirectUrl={redirectUrl}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{userIsUnauthorized && isSSOOnly ? (
|
|
<div className="w-full max-w-md">
|
|
<ResourceAccessDenied />
|
|
</div>
|
|
) : (
|
|
<div className="w-full max-w-md">
|
|
<ResourceAuthPortal
|
|
methods={{
|
|
password: authInfo.password,
|
|
pincode: authInfo.pincode,
|
|
sso: authInfo.sso && !userIsUnauthorized,
|
|
whitelist: authInfo.whitelist
|
|
}}
|
|
resource={{
|
|
name: authInfo.resourceName,
|
|
id: authInfo.resourceId
|
|
}}
|
|
redirect={redirectUrl}
|
|
/>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|