"use client"; import { useState } from "react"; import { CheckOrgUserAccessResponse } from "@server/routers/org"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { CheckCircle2, XCircle, Shield } from "lucide-react"; import Enable2FaDialog from "./Enable2FaDialog"; import ChangePasswordDialog from "./ChangePasswordDialog"; import { useTranslations } from "next-intl"; import { useUserContext } from "@app/hooks/useUserContext"; import { useRouter } from "next/navigation"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { createApiClient } from "@app/lib/api"; type OrgPolicyResultProps = { orgId: string; userId: string; accessRes: CheckOrgUserAccessResponse; }; type PolicyItem = { id: string; name: string; description: string; compliant: boolean; action?: () => void; actionText?: string; }; export default function OrgPolicyResult({ orgId, userId, accessRes }: OrgPolicyResultProps) { const [show2FaDialog, setShow2FaDialog] = useState(false); const [showChangePasswordDialog, setShowChangePasswordDialog] = useState(false); const t = useTranslations(); const { user } = useUserContext(); const router = useRouter(); let requireedSteps = 0; let completedSteps = 0; const { env } = useEnvContext(); const api = createApiClient({ env }); const policies: PolicyItem[] = []; if ( accessRes.policies?.requiredTwoFactor === false || accessRes.policies?.requiredTwoFactor === true ) { const isTwoFactorCompliant = accessRes.policies?.requiredTwoFactor === true; policies.push({ id: "two-factor", name: t("twoFactorAuthentication"), description: t("twoFactorDescription"), compliant: isTwoFactorCompliant, action: !isTwoFactorCompliant ? () => setShow2FaDialog(true) : undefined, actionText: !isTwoFactorCompliant ? t("enableTwoFactor") : undefined }); requireedSteps += 1; if (isTwoFactorCompliant) { completedSteps += 1; } } // Add max session length policy if the organization has it enforced if (accessRes.policies?.maxSessionLength) { const maxSessionPolicy = accessRes.policies?.maxSessionLength; const maxHours = maxSessionPolicy.maxSessionLengthHours; // Use hours if less than 24, otherwise convert to days const useHours = maxHours < 24; const maxTime = useHours ? maxHours : Math.round(maxHours / 24); const descriptionKey = useHours ? "reauthenticationDescriptionHours" : "reauthenticationDescription"; const description = useHours ? t(descriptionKey, { maxHours }) : t(descriptionKey, { maxDays: maxTime }); policies.push({ id: "max-session-length", name: t("reauthenticationRequired"), description, compliant: maxSessionPolicy.compliant, action: !maxSessionPolicy.compliant ? async () => { try { await api.post("/auth/logout", undefined); router.push(`/auth/login?orgId=${orgId}`); } catch (error) { console.error("Error during logout:", error); router.push(`/auth/login?orgId=${orgId}`); } } : undefined, actionText: !maxSessionPolicy.compliant ? t("reauthenticateNow") : undefined }); requireedSteps += 1; if (maxSessionPolicy.compliant) { completedSteps += 1; } } // Add password age policy if the organization has it enforced if (accessRes.policies?.passwordAge) { const passwordAgePolicy = accessRes.policies.passwordAge; const maxDays = passwordAgePolicy.maxPasswordAgeDays; const daysAgo = Math.round(passwordAgePolicy.passwordAgeDays); policies.push({ id: "password-age", name: t("passwordExpiryRequired"), description: t("passwordExpiryDescription", { maxDays, daysAgo }), compliant: passwordAgePolicy.compliant, action: !passwordAgePolicy.compliant ? () => setShowChangePasswordDialog(true) : undefined, actionText: !passwordAgePolicy.compliant ? t("changePasswordNow") : undefined }); requireedSteps += 1; if (passwordAgePolicy.compliant) { completedSteps += 1; } } const progressPercentage = requireedSteps === 0 ? 100 : (completedSteps / requireedSteps) * 100; const allCompliant = completedSteps === requireedSteps; return ( <> {t("securityRequirements")} {allCompliant ? t("allRequirementsMet") : t("completeRequirementsToContinue")}
{completedSteps} of {requireedSteps} steps completed {Math.round(progressPercentage)}%
{policies.map((policy) => (
{policy.compliant ? ( ) : ( )}

{policy.name}

{policy.description}

{policy.action && policy.actionText && (
)}
))}
{ setShow2FaDialog(val); router.refresh(); }} /> { setShowChangePasswordDialog(val); router.refresh(); }} /> ); }