diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts index c391fda353e41..6e1749b2d8459 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts @@ -32,8 +32,8 @@ describe( describe('Renders and saves protection updates', () => { let indexedPolicy: IndexedFleetEndpointPolicyResponse; let policy: PolicyData; - const today = moment.utc(); - const formattedToday = today.format('MMMM DD, YYYY'); + const defaultDate = moment.utc().subtract(1, 'days'); + const formattedDefaultDate = defaultDate.format('MMMM DD, YYYY'); beforeEach(() => { login(); @@ -66,7 +66,7 @@ describe( cy.getByTestSubj('protection-updates-deployed-version').contains('latest'); cy.getByTestSubj('protection-updates-manifest-name-version-to-deploy-title'); cy.getByTestSubj('protection-updates-version-to-deploy-picker').within(() => { - cy.get('input').should('have.value', formattedToday); + cy.get('input').should('have.value', formattedDefaultDate); }); cy.getByTestSubj('protection-updates-manifest-name-note-title'); cy.getByTestSubj('protection-updates-manifest-note'); @@ -84,7 +84,7 @@ describe( cy.getByTestSubj('protectionUpdatesSaveButton').click(); cy.wait('@policy').then(({ request, response }) => { expect(request.body.inputs[0].config.policy.value.global_manifest_version).to.equal( - today.format('YYYY-MM-DD') + defaultDate.format('YYYY-MM-DD') ); expect(response?.statusCode).to.equal(200); }); @@ -95,7 +95,7 @@ describe( }); cy.getByTestSubj('protectionUpdatesSuccessfulMessage'); - cy.getByTestSubj('protection-updates-deployed-version').contains(formattedToday); + cy.getByTestSubj('protection-updates-deployed-version').contains(formattedDefaultDate); cy.getByTestSubj('protection-updates-manifest-note').contains(testNote); cy.getByTestSubj('protectionUpdatesSaveButton').should('be.disabled'); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/protection_updates/protection_updates_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/protection_updates/protection_updates_layout.tsx index cf7012f901974..dc260fdb6449d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/protection_updates/protection_updates_layout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/protection_updates/protection_updates_layout.tsx @@ -73,7 +73,9 @@ export const ProtectionUpdatesLayout = React.memo( const [manifestVersion, setManifestVersion] = useState(deployedVersion); const today = moment.utc(); - const [selectedDate, setSelectedDate] = useState(today); + const defaultDate = today.clone().subtract(1, 'days'); + + const [selectedDate, setSelectedDate] = useState(defaultDate); const { data: fetchedNote, isLoading: getNoteInProgress } = useGetProtectionUpdatesNote({ packagePolicyId: _policy.id, @@ -181,24 +183,24 @@ export const ProtectionUpdatesLayout = React.memo( if (checked && !automaticUpdatesEnabled) { setManifestVersion('latest'); // Clear selected date on user enabling automatic updates - if (selectedDate !== today) { - setSelectedDate(today); + if (selectedDate !== defaultDate) { + setSelectedDate(defaultDate); } } else { setManifestVersion(selectedDate.format(internalDateFormat)); } }, - [automaticUpdatesEnabled, selectedDate, today] + [automaticUpdatesEnabled, selectedDate, defaultDate] ); const updateDatepickerSelectedDate = useCallback( (date: Moment | null) => { - if (date?.isAfter(cutoffDate) && date?.isSameOrBefore(today)) { - setSelectedDate(date || today); + if (date?.isAfter(cutoffDate) && date?.isSameOrBefore(defaultDate)) { + setSelectedDate(date || defaultDate); setManifestVersion(date?.format(internalDateFormat) || 'latest'); } }, - [cutoffDate, today] + [cutoffDate, defaultDate] ); const renderVersionToDeployPicker = () => { @@ -224,7 +226,7 @@ export const ProtectionUpdatesLayout = React.memo( popoverPlacement={'downCenter'} dateFormat={displayDateFormat} selected={selectedDate} - maxDate={today} + maxDate={defaultDate} minDate={cutoffDate} onChange={updateDatepickerSelectedDate} /> diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 3d586d1dfab1a..7c861bf87f18f 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -441,6 +441,8 @@ describe('ingest_integration tests ', () => { licenseEmitter.next(Enterprise); // set license level to enterprise }); + const validDateYesterday = moment.utc().subtract(1, 'day'); + it.each([ { date: 'invalid', @@ -457,13 +459,21 @@ describe('ingest_integration tests ', () => { }, { date: '2100-10-01', - message: 'Global manifest version cannot be in the future. UTC time.', + message: `Global manifest version cannot be in the future. Latest selectable date is ${validDateYesterday.format( + 'MMMM DD, YYYY' + )} UTC time.`, + }, + { + date: validDateYesterday.clone().add(1, 'day').format('YYYY-MM-DD'), + message: `Global manifest version cannot be in the future. Latest selectable date is ${validDateYesterday.format( + 'MMMM DD, YYYY' + )} UTC time.`, }, { date: 'latest', }, { - date: moment.utc().subtract(1, 'day').format('YYYY-MM-DD'), // Correct date + date: validDateYesterday.format('YYYY-MM-DD'), // Correct date }, ])( 'should return bad request for invalid endpoint package policy global manifest values', diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_endpoint_package_policy.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_endpoint_package_policy.ts index d8f1a8afecd79..f63d07d890c2d 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_endpoint_package_policy.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_endpoint_package_policy.ts @@ -29,9 +29,12 @@ export const validateEndpointPackagePolicy = (inputs: NewPackagePolicyInput[]) = 'Global manifest version is too far in the past. Please use either "latest" or a date within the last 18 months. The earliest valid date is October 1, 2023, in UTC time.' ); } - if (parsedDate.isAfter(moment.utc())) { + const minAllowedDate = moment.utc().subtract(1, 'day'); + if (parsedDate.isAfter(minAllowedDate)) { throw createManifestVersionError( - 'Global manifest version cannot be in the future. UTC time.' + `Global manifest version cannot be in the future. Latest selectable date is ${minAllowedDate.format( + 'MMMM DD, YYYY' + )} UTC time.` ); } }