Merge pull request #3200 from Adityakk9031/#3001

fix: redirect lost after Pangolin auth session timeout (#3001)
This commit is contained in:
Milo Schwartz
2026-07-08 12:30:39 -04:00
committed by GitHub
3 changed files with 64 additions and 4 deletions
+3
View File
@@ -2756,6 +2756,9 @@
"twoFactorSetupRequired": "Two-factor authentication setup is required. Please log in again via {dashboardUrl}/auth/login complete this step. Then, come back here.",
"additionalSecurityRequired": "Additional Security Required",
"organizationRequiresAdditionalSteps": "This organization requires additional security steps before you can access resources.",
"sessionExpired": "Session Expired",
"sessionExpiredReauthRequired": "Your session has expired per your organization's security policy. Please re-authenticate to continue.",
"reauthenticate": "Re-authenticate",
"completeTheseSteps": "Complete these steps",
"enableTwoFactorAuthentication": "Enable two-factor authentication",
"completeSecuritySteps": "Complete Security Steps",
@@ -166,11 +166,13 @@ export default async function ResourceAuthPage(props: {
// If user is not compliant with org policies, show policy requirements
if (orgPolicyCheck && !orgPolicyCheck.allowed && orgPolicyCheck.policies) {
const resourceAuthPageUrl = `/auth/resource/${authInfo.resourceGuid}${redirectUrl !== authInfo.url ? `?redirect=${encodeURIComponent(redirectUrl)}` : ""}`;
return (
<div className="w-full max-w-md">
<OrgPolicyRequired
orgId={authInfo.orgId}
policies={orgPolicyCheck.policies}
redirectAfterAuth={resourceAuthPageUrl}
/>
</div>
);
+59 -4
View File
@@ -11,24 +11,79 @@ import {
import { Shield, ArrowRight } from "lucide-react";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
type OrgPolicyRequiredProps = {
orgId: string;
policies: {
requiredTwoFactor?: boolean;
maxSessionLength?: {
compliant: boolean;
maxSessionLengthHours: number;
sessionAgeHours: number;
};
passwordAge?: {
compliant: boolean;
maxPasswordAgeDays: number;
passwordAgeDays: number;
};
};
redirectAfterAuth?: string;
};
export default function OrgPolicyRequired({
orgId,
policies
policies,
redirectAfterAuth
}: OrgPolicyRequiredProps) {
const t = useTranslations();
const router = useRouter();
const policySteps = [];
const api = createApiClient(useEnvContext());
if (policies?.requiredTwoFactor === false) {
policySteps.push(t("enableTwoFactorAuthentication"));
const sessionExpired =
policies?.maxSessionLength &&
policies.maxSessionLength.compliant === false;
function reauthenticate() {
api.post("/auth/logout")
.catch(() => {})
.then(() => {
const destination = redirectAfterAuth ?? `/${orgId}`;
router.push(destination);
router.refresh();
});
}
if (sessionExpired) {
return (
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-orange-100">
<Shield className="h-6 w-6 text-orange-600" />
</div>
<CardTitle className="text-xl font-semibold">
{t("sessionExpired")}
</CardTitle>
<CardDescription>
{t("sessionExpiredReauthRequired")}
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="pt-4">
<Button
className="w-full"
onClick={reauthenticate}
>
{t("reauthenticate")}
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
</div>
</CardContent>
</Card>
);
}
return (