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;
}
if (
policyCheck?.policies?.passwordAge &&
!policyCheck.policies.passwordAge.compliant
) {
if (!policyCheck.policies?.passwordAge?.compliant === false) {
logger.warn(
`Olm user ${olm.userId} has non-compliant password age for org ${orgId}`
);
@@ -138,8 +135,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
);
return;
} else if (
policyCheck?.policies?.maxSessionLength &&
!policyCheck.policies.maxSessionLength.compliant
!policyCheck.policies?.maxSessionLength?.compliant === false
) {
logger.warn(
`Olm user ${olm.userId} has non-compliant session length for org ${orgId}`
@@ -149,10 +145,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
olm.olmId
);
return;
} else if (
policyCheck?.policies &&
!policyCheck.policies.requiredTwoFactor
) {
} else if (policyCheck.policies?.requiredTwoFactor === false) {
logger.warn(
`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 { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
@@ -42,6 +43,9 @@ export default async function ApprovalFeedPage(props: ApprovalFeedPageProps) {
title={t("accessApprovalsManage")}
description={t("accessApprovalsDescription")}
/>
<PaidFeaturesAlert />
<OrgProvider org={org}>
<div className="container mx-auto max-w-12xl">
<ApprovalFeed orgId={params.orgId} />

View File

@@ -82,12 +82,16 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
const router = useRouter();
const t = useTranslations();
const formatFingerprintInfo = (fingerprint: ClientRow["fingerprint"]): string => {
const formatFingerprintInfo = (
fingerprint: ClientRow["fingerprint"]
): string => {
if (!fingerprint) return "";
const parts: string[] = [];
if (fingerprint.platform) {
parts.push(`${t("platform")}: ${formatPlatform(fingerprint.platform)}`);
parts.push(
`${t("platform")}: ${formatPlatform(fingerprint.platform)}`
);
}
if (fingerprint.deviceModel) {
parts.push(`${t("deviceModel")}: ${fingerprint.deviceModel}`);
@@ -562,6 +566,49 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
return baseColumns;
}, [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 (
<>
{selectedClient && !selectedClient.userId && (
@@ -604,33 +651,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
label: t("status") || "Status",
multiSelect: true,
displayMode: "calculated",
options: [
{
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"
}
],
options: statusFilterOptions,
filterFn: (
row: ClientRow,
selectedValues: (string | number | boolean)[]
@@ -639,7 +660,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
const rowArchived = row.archived;
const rowBlocked = row.blocked;
const approvalState = row.approvalState;
const isActive = !rowArchived && !rowBlocked;
const isActive = !rowArchived && !rowBlocked && approvalState !== "pending" && approvalState !== "denied";
if (selectedValues.includes("active") && isActive)
return true;
@@ -665,7 +686,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
return true;
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",
neutral: "bg-card bg-muted border text-foreground",
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:
"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",