Compare commits

..

4 Commits

Author SHA1 Message Date
miloschwartz
acca1b6a91 improve red alert colors 2026-01-18 22:10:34 -08:00
miloschwartz
355265cd1e show paid user alert on approvals 2026-01-18 21:49:15 -08:00
miloschwartz
6ec8d143fa hide pending approval filter in oss 2026-01-18 21:47:00 -08:00
miloschwartz
8ae327e8f5 fix org policy check 2026-01-18 21:24:17 -08:00
4 changed files with 60 additions and 42 deletions

View File

@@ -125,10 +125,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
return; return;
} }
if ( if (!policyCheck.policies?.passwordAge?.compliant === false) {
policyCheck?.policies?.passwordAge &&
!policyCheck.policies.passwordAge.compliant
) {
logger.warn( logger.warn(
`Olm user ${olm.userId} has non-compliant password age for org ${orgId}` `Olm user ${olm.userId} has non-compliant password age for org ${orgId}`
); );
@@ -138,8 +135,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
); );
return; return;
} else if ( } else if (
policyCheck?.policies?.maxSessionLength && !policyCheck.policies?.maxSessionLength?.compliant === false
!policyCheck.policies.maxSessionLength.compliant
) { ) {
logger.warn( logger.warn(
`Olm user ${olm.userId} has non-compliant session length for org ${orgId}` `Olm user ${olm.userId} has non-compliant session length for org ${orgId}`
@@ -149,10 +145,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
olm.olmId olm.olmId
); );
return; return;
} else if ( } else if (policyCheck.policies?.requiredTwoFactor === false) {
policyCheck?.policies &&
!policyCheck.policies.requiredTwoFactor
) {
logger.warn( logger.warn(
`Olm user ${olm.userId} does not have 2FA enabled for org ${orgId}` `Olm user ${olm.userId} does not have 2FA enabled for org ${orgId}`
); );

View File

@@ -1,4 +1,5 @@
import { ApprovalFeed } from "@app/components/ApprovalFeed"; import { ApprovalFeed } from "@app/components/ApprovalFeed";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle"; import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { internal } from "@app/lib/api"; import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies"; import { authCookieHeader } from "@app/lib/api/cookies";
@@ -42,6 +43,9 @@ export default async function ApprovalFeedPage(props: ApprovalFeedPageProps) {
title={t("accessApprovalsManage")} title={t("accessApprovalsManage")}
description={t("accessApprovalsDescription")} description={t("accessApprovalsDescription")}
/> />
<PaidFeaturesAlert />
<OrgProvider org={org}> <OrgProvider org={org}>
<div className="container mx-auto max-w-12xl"> <div className="container mx-auto max-w-12xl">
<ApprovalFeed orgId={params.orgId} /> <ApprovalFeed orgId={params.orgId} />

View File

@@ -82,12 +82,16 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
const router = useRouter(); const router = useRouter();
const t = useTranslations(); const t = useTranslations();
const formatFingerprintInfo = (fingerprint: ClientRow["fingerprint"]): string => { const formatFingerprintInfo = (
fingerprint: ClientRow["fingerprint"]
): string => {
if (!fingerprint) return ""; if (!fingerprint) return "";
const parts: string[] = []; const parts: string[] = [];
if (fingerprint.platform) { if (fingerprint.platform) {
parts.push(`${t("platform")}: ${formatPlatform(fingerprint.platform)}`); parts.push(
`${t("platform")}: ${formatPlatform(fingerprint.platform)}`
);
} }
if (fingerprint.deviceModel) { if (fingerprint.deviceModel) {
parts.push(`${t("deviceModel")}: ${fingerprint.deviceModel}`); parts.push(`${t("deviceModel")}: ${fingerprint.deviceModel}`);
@@ -562,6 +566,49 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
return baseColumns; return baseColumns;
}, [hasRowsWithoutUserId, t]); }, [hasRowsWithoutUserId, t]);
const statusFilterOptions = useMemo(() => {
const allOptions = [
{
id: "active",
label: t("active"),
value: "active"
},
{
id: "pending",
label: t("pendingApproval"),
value: "pending"
},
{
id: "denied",
label: t("deniedApproval"),
value: "denied"
},
{
id: "archived",
label: t("archived"),
value: "archived"
},
{
id: "blocked",
label: t("blocked"),
value: "blocked"
}
];
if (build === "oss") {
return allOptions.filter((option) => option.value !== "pending");
}
return allOptions;
}, [t]);
const statusFilterDefaultValues = useMemo(() => {
if (build === "oss") {
return ["active"];
}
return ["active", "pending"];
}, []);
return ( return (
<> <>
{selectedClient && !selectedClient.userId && ( {selectedClient && !selectedClient.userId && (
@@ -604,33 +651,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
label: t("status") || "Status", label: t("status") || "Status",
multiSelect: true, multiSelect: true,
displayMode: "calculated", displayMode: "calculated",
options: [ options: statusFilterOptions,
{
id: "active",
label: t("active"),
value: "active"
},
{
id: "pending",
label: t("pendingApproval"),
value: "pending"
},
{
id: "denied",
label: t("deniedApproval"),
value: "denied"
},
{
id: "archived",
label: t("archived"),
value: "archived"
},
{
id: "blocked",
label: t("blocked"),
value: "blocked"
}
],
filterFn: ( filterFn: (
row: ClientRow, row: ClientRow,
selectedValues: (string | number | boolean)[] selectedValues: (string | number | boolean)[]
@@ -639,7 +660,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
const rowArchived = row.archived; const rowArchived = row.archived;
const rowBlocked = row.blocked; const rowBlocked = row.blocked;
const approvalState = row.approvalState; const approvalState = row.approvalState;
const isActive = !rowArchived && !rowBlocked; const isActive = !rowArchived && !rowBlocked && approvalState !== "pending" && approvalState !== "denied";
if (selectedValues.includes("active") && isActive) if (selectedValues.includes("active") && isActive)
return true; return true;
@@ -665,7 +686,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
return true; return true;
return false; return false;
}, },
defaultValues: ["active", "pending"] // Default to showing active clients defaultValues: statusFilterDefaultValues
} }
]} ]}
/> />

View File

@@ -11,7 +11,7 @@ const alertVariants = cva(
default: "bg-card border text-foreground", default: "bg-card border text-foreground",
neutral: "bg-card bg-muted border text-foreground", neutral: "bg-card bg-muted border text-foreground",
destructive: destructive:
"border-destructive/50 border bg-destructive/8 text-destructive dark:border-destructive/50 [&>svg]:text-destructive", "border-destructive/50 border bg-destructive/8 dark:text-red-200 text-red-900 dark:border-destructive/50 [&>svg]:text-destructive",
success: success:
"border-green-500/50 border bg-green-500/10 text-green-500 dark:border-success [&>svg]:text-green-500", "border-green-500/50 border bg-green-500/10 text-green-500 dark:border-success [&>svg]:text-green-500",
info: "border-blue-500/50 border bg-blue-500/10 text-blue-800 dark:text-blue-400 dark:border-blue-400 [&>svg]:text-blue-500", info: "border-blue-500/50 border bg-blue-500/10 text-blue-800 dark:text-blue-400 dark:border-blue-400 [&>svg]:text-blue-500",