From 797e26a7f56733f5edb1e1106d9ab617dcf334ed Mon Sep 17 00:00:00 2001 From: Chris Dymond Date: Sat, 18 Jan 2025 11:42:31 +0800 Subject: [PATCH 1/4] warning on active > 2 --- components/app-registrations/CredentialStatusGrid.columns.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/app-registrations/CredentialStatusGrid.columns.tsx b/components/app-registrations/CredentialStatusGrid.columns.tsx index 0764acc..8ca6aa9 100644 --- a/components/app-registrations/CredentialStatusGrid.columns.tsx +++ b/components/app-registrations/CredentialStatusGrid.columns.tsx @@ -105,7 +105,7 @@ export const credentialStatusColumns = ( ); } - if (activeCount === 1) { + if (activeCount === 1 || activeCount === 2) { return ( } From 3aabb76dc43f67d6f6ef8bb433037f6fd1c42f6a Mon Sep 17 00:00:00 2001 From: Chris Dymond Date: Sat, 18 Jan 2025 12:10:22 +0800 Subject: [PATCH 2/4] present long lived secrets --- .../CredentialStatusGrid.columns.tsx | 67 +++++++++++-------- .../CredentialStatusGrid.data-model.ts | 4 +- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/components/app-registrations/CredentialStatusGrid.columns.tsx b/components/app-registrations/CredentialStatusGrid.columns.tsx index 8ca6aa9..931376f 100644 --- a/components/app-registrations/CredentialStatusGrid.columns.tsx +++ b/components/app-registrations/CredentialStatusGrid.columns.tsx @@ -66,6 +66,26 @@ function getEarliestWarningDate(item: GridItem): Date | null { return dates.length > 0 ? dates[0] : null; } +function getLongLivedDates(item: GridItem): Date[] { + const allLongLivedDates = [ + ...item.longLivedPasswordCredentials.map((x) => + new Date(x.endDateTime).getTime() + ), + ...item.longLivedKeyCredentials.map((x) => + new Date(x.endDateTime).getTime() + ), + ].filter((time) => !isNaN(time)); // Filter out invalid dates + + return allLongLivedDates + .map((t) => new Date(t)) + .sort((a, b) => a.getTime() - b.getTime()); +} + +function getLatestLongLivedDate(item: GridItem): Date | null { + const dates = getLongLivedDates(item); + return dates.length > 0 ? dates[dates.length - 1] : null; +} + export const credentialStatusColumns = ( isAuthenticated: boolean ): TableColumnDefinition[] => [ @@ -132,13 +152,7 @@ export const credentialStatusColumns = ( const expiredCount = getExpiredCredentialsCount(item); if (expiredCount === 0) { - return ( - - - - - ); + return -; } return ( @@ -151,25 +165,29 @@ export const credentialStatusColumns = ( createTableColumn({ columnId: "longLived", - compare: (a, b) => - getLongLivedCredentialsCount(a) - getLongLivedCredentialsCount(b), + compare: (a, b) => { + const latestA = getLatestLongLivedDate(a); + const latestB = getLatestLongLivedDate(b); + + // Handle null values (no valid dates) + if (!latestA && !latestB) return 0; + if (!latestA) return 1; // Put nulls at the "bottom" + if (!latestB) return -1; + + return latestA.getTime() - latestB.getTime(); + }, renderHeaderCell: () => "Long-lived", renderCell: (item) => { - const count = getLongLivedCredentialsCount(item); + const longLivedDates = getLongLivedDates(item); + const longLivedCount = getLongLivedDates.length; - if (count === 0) { - return ( - - - - - ); + if (longLivedDates.length === 0) { + return -; } return ( }> - {count} + ); }, @@ -194,18 +212,13 @@ export const credentialStatusColumns = ( const expiringCount = warningDates.length; if (expiringCount === 0) { - return ( - - - - - ); + return -; } return ( }> - - + + ); }, }), diff --git a/components/app-registrations/CredentialStatusGrid.data-model.ts b/components/app-registrations/CredentialStatusGrid.data-model.ts index 10f6f2b..5f1949c 100644 --- a/components/app-registrations/CredentialStatusGrid.data-model.ts +++ b/components/app-registrations/CredentialStatusGrid.data-model.ts @@ -44,6 +44,8 @@ export function generateApplications(): Application[] { const twoYearsFromNow = new Date(); twoYearsFromNow.setFullYear(now.getFullYear() + 2); + const fourYearsFromNow = new Date(); + fourYearsFromNow.setFullYear(now.getFullYear() + 4); const twoMonthsFromNow = new Date(); twoMonthsFromNow.setMonth(now.getMonth() + 2); @@ -70,7 +72,7 @@ export function generateApplications(): Application[] { secretText: null, customKeyIdentifier: null, keyId: "password-id-long-lived", - endDateTime: twoYearsFromNow.toISOString(), + endDateTime: fourYearsFromNow.toISOString(), hint: "LLP", displayName: "Long Lived Password", }, From ebb9e5603685efbe28e1c3e940c5f2d714a4031d Mon Sep 17 00:00:00 2001 From: Chris Dymond Date: Sat, 18 Jan 2025 12:13:54 +0800 Subject: [PATCH 3/4] default sort --- .../SamlStatusGrid.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/components/enterprise-applications/SamlStatusGrid.tsx b/components/enterprise-applications/SamlStatusGrid.tsx index 71ddc2c..5faf105 100644 --- a/components/enterprise-applications/SamlStatusGrid.tsx +++ b/components/enterprise-applications/SamlStatusGrid.tsx @@ -109,16 +109,16 @@ export default function SamlStatusGrid() { ); } - // type SortDirection = "ascending" | "descending"; - // interface SortState { - // sortColumn?: string; - // sortDirection: SortDirection; - // } + type SortDirection = "ascending" | "descending"; + interface SortState { + sortColumn: string | undefined; + sortDirection: SortDirection; + } - // const defaultSortState: SortState = { - // sortColumn: "warnCredential", - // sortDirection: "ascending", - // }; + const newSortState: SortState = { + sortColumn: "expiry", + sortDirection: "ascending", + }; return (
@@ -153,7 +153,7 @@ export default function SamlStatusGrid() { columns={columns} sortable getRowId={(item) => item.displayName} - // defaultSortState={defaultSortState} + defaultSortState={newSortState} style={{ marginBottom: "10px" }} > From de90eed56f100f5c13128f9f36b758fa4e233a43 Mon Sep 17 00:00:00 2001 From: Chris Dymond Date: Sat, 18 Jan 2025 12:21:55 +0800 Subject: [PATCH 4/4] sort order for longlived credentials correction --- .../CredentialStatusGrid.columns.tsx | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/components/app-registrations/CredentialStatusGrid.columns.tsx b/components/app-registrations/CredentialStatusGrid.columns.tsx index 931376f..72a27a0 100644 --- a/components/app-registrations/CredentialStatusGrid.columns.tsx +++ b/components/app-registrations/CredentialStatusGrid.columns.tsx @@ -41,13 +41,6 @@ function getExpiredCredentialsCount(item: GridItem): number { ); } -function getLongLivedCredentialsCount(item: GridItem): number { - return ( - item.longLivedKeyCredentials.length + - item.longLivedPasswordCredentials.length - ); -} - function getWarningDates(item: GridItem): Date[] { const allWarningTimes = [ ...item.warningPasswordCredentials.map((x) => @@ -68,22 +61,20 @@ function getEarliestWarningDate(item: GridItem): Date | null { function getLongLivedDates(item: GridItem): Date[] { const allLongLivedDates = [ - ...item.longLivedPasswordCredentials.map((x) => - new Date(x.endDateTime).getTime() - ), - ...item.longLivedKeyCredentials.map((x) => - new Date(x.endDateTime).getTime() + ...(item.longLivedPasswordCredentials || []).map( + (x) => new Date(x.endDateTime) ), - ].filter((time) => !isNaN(time)); // Filter out invalid dates + ...(item.longLivedKeyCredentials || []).map((x) => new Date(x.endDateTime)), + ]; - return allLongLivedDates - .map((t) => new Date(t)) - .sort((a, b) => a.getTime() - b.getTime()); + const validDates = allLongLivedDates.filter((date) => !isNaN(date.getTime())); + + return validDates.sort((a, b) => b.getTime() - a.getTime()); } function getLatestLongLivedDate(item: GridItem): Date | null { const dates = getLongLivedDates(item); - return dates.length > 0 ? dates[dates.length - 1] : null; + return dates.length > 0 ? dates[0] : null; } export const credentialStatusColumns = ( @@ -179,7 +170,6 @@ export const credentialStatusColumns = ( renderHeaderCell: () => "Long-lived", renderCell: (item) => { const longLivedDates = getLongLivedDates(item); - const longLivedCount = getLongLivedDates.length; if (longLivedDates.length === 0) { return -;