diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts index 8d827690..d148af7b 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts @@ -114,9 +114,14 @@ describe('syncVisitToOneIdentityHandler', () => { describe('VISIT_CREATED', () => { it('should create site access and system access in One Identity for science users and connect to proposal', async () => { // Mock the current time to a fixed value for testing - const mockNowDate = new Date('2022-12-15T00:00:00.000Z'); + const mockNowDate = new Date('2022-12-15T12:30:00.000Z'); const originalDateNow = Date.now; Date.now = jest.fn(() => mockNowDate.getTime()); + const visitMessageWithTimes = { + ...visitMessage, + startAt: '2023-01-01T10:30:00.000Z', + endAt: '2023-01-10T14:45:00.000Z', + }; // Mock person that is a science user const mockPerson = { @@ -141,14 +146,17 @@ describe('syncVisitToOneIdentityHandler', () => { .mockResolvedValueOnce([mockSiteAccess]) .mockResolvedValueOnce([mockSystemAccess]); - await syncVisitToOneIdentityHandler(visitMessage, Event.VISIT_CREATED); + await syncVisitToOneIdentityHandler( + visitMessageWithTimes, + Event.VISIT_CREATED + ); expect(mockOneIdentity.login).toHaveBeenCalled(); expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( 'visitor-oidc-sub' ); expect(mockOneIdentity.getProposal).toHaveBeenCalledWith( - visitMessage.proposal + visitMessageWithTimes.proposal ); expect(mockOneIdentity.getProposalPersonConnections).toHaveBeenCalledWith( mockUidESet @@ -159,29 +167,31 @@ describe('syncVisitToOneIdentityHandler', () => { expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 1, PersonWantsOrgRole.SITE_ACCESS, - visitMessage.visitorId, - visitMessage.startAt, - visitMessage.endAt, - visitMessage.id + visitMessageWithTimes.visitorId, + '2023-01-01T00:00:00.000Z', + '2023-01-11T00:00:00.000Z', + visitMessageWithTimes.id ); // Calculate expected system access dates // validFrom should be the current mock date - const expectedValidFrom = mockNowDate.toISOString(); - const expectedEndDate = new Date(visitMessage.endAt); - expectedEndDate.setDate( - expectedEndDate.getDate() + - parseInt(ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) + const expectedValidFrom = '2022-12-15T00:00:00.000Z'; + const expectedEndDate = new Date(visitMessageWithTimes.endAt); + expectedEndDate.setUTCDate( + expectedEndDate.getUTCDate() + + parseInt(ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) + + 1 ); + expectedEndDate.setUTCHours(0, 0, 0, 0); // Verify system access creation expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 2, PersonWantsOrgRole.SYSTEM_ACCESS, - visitMessage.visitorId, + visitMessageWithTimes.visitorId, expectedValidFrom, expectedEndDate.toISOString(), - visitMessage.id + visitMessageWithTimes.id ); expect(logger.logInfo).toHaveBeenCalledWith( @@ -754,7 +764,7 @@ describe('syncVisitToOneIdentityHandler', () => { PersonWantsOrgRole.SITE_ACCESS, 'visitor-oidc-sub', '2023-02-01T00:00:00.000Z', - '2023-02-15T00:00:00.000Z', + '2023-02-16T00:00:00.000Z', '1', 'site-access-uid' ); @@ -769,15 +779,19 @@ describe('syncVisitToOneIdentityHandler', () => { const expectedSystemAccessValidUntil = new Date( '2023-02-15T00:00:00.000Z' ); - expectedSystemAccessValidUntil.setDate( - expectedSystemAccessValidUntil.getDate() + - parseInt(ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) + expectedSystemAccessValidUntil.setUTCDate( + expectedSystemAccessValidUntil.getUTCDate() + + parseInt(ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) + + 1 ); + expectedSystemAccessValidUntil.setUTCHours(0, 0, 0, 0); + const expectedSystemAccessValidFrom = new Date(mockNowDate); + expectedSystemAccessValidFrom.setUTCHours(0, 0, 0, 0); expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 2, PersonWantsOrgRole.SYSTEM_ACCESS, 'visitor-oidc-sub', - mockNowDate.toISOString(), + expectedSystemAccessValidFrom.toISOString(), expectedSystemAccessValidUntil.toISOString(), '1', 'system-access-uid' @@ -807,7 +821,7 @@ describe('syncVisitToOneIdentityHandler', () => { UID_PersonOrdered: 'visitor-uid', DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, ValidFrom: visitMessage.startAt, - ValidUntil: visitMessage.endAt, + ValidUntil: '2023-01-11T00:00:00.000Z', CustomProperty04: '1', OrderState: OrderState.GRANTED, } as PersonWantsOrg; diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index add0ad9a..3806722f 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -114,8 +114,8 @@ async function createAccessInOneIdentity( const [pwoSite] = await oneIdentity.upsertPersonWantsOrg( PersonWantsOrgRole.SITE_ACCESS, centralAccount, - toIsoString(startAt), - toIsoString(endAt), + toStartOfDayIsoString(startAt), + toStartOfNextDayIsoString(endAt), visitId // CustomProperty04 - We store the visit ID for the site access to be able to find it later ); @@ -125,16 +125,16 @@ async function createAccessInOneIdentity( // validFrom in One Identity should be in the future so that the access is not immediately available const validFrom = Date.now(); - const validUntil = new Date(endAt).setDate( - new Date(endAt).getDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS + const validUntil = new Date(endAt).setUTCDate( + new Date(endAt).getUTCDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS ); // Create system access const [pwoSystem] = await oneIdentity.upsertPersonWantsOrg( PersonWantsOrgRole.SYSTEM_ACCESS, centralAccount, - toIsoString(validFrom), - toIsoString(validUntil), + toStartOfDayIsoString(validFrom), + toStartOfNextDayIsoString(validUntil), visitId // CustomProperty04 - We store the visit ID for the system access to be able to find it later ); @@ -180,8 +180,8 @@ async function updateAccessInOneIdentity( return; } - const validFrom = toIsoString(startAt); - const validUntil = toIsoString(endAt); + const validFrom = toStartOfDayIsoString(startAt); + const validUntil = toStartOfNextDayIsoString(endAt); // Find system access for the site access (CustomProperty04 is the visit ID) const systemAccess = personWantsOrgs.find( @@ -225,10 +225,10 @@ async function updateAccessInOneIdentity( UID_PersonWantsOrg: siteAccess.UID_PersonWantsOrg, }); - const systemAccessValidFrom = toIsoString(Date.now()); - const systemAccessValidUntil = toIsoString( - new Date(endAt).setDate( - new Date(endAt).getDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS + const systemAccessValidFrom = toStartOfDayIsoString(Date.now()); + const systemAccessValidUntil = toStartOfNextDayIsoString( + new Date(endAt).setUTCDate( + new Date(endAt).getUTCDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS ) ); @@ -361,6 +361,21 @@ function toIsoString(date: string | number) { return parsedDate.toISOString(); } +function toStartOfDayIsoString(date: string | number) { + const parsedDate = new Date(toIsoString(date)); + parsedDate.setUTCHours(0, 0, 0, 0); + + return parsedDate.toISOString(); +} + +function toStartOfNextDayIsoString(date: string | number) { + const parsedDate = new Date(toIsoString(date)); + parsedDate.setUTCHours(0, 0, 0, 0); + parsedDate.setUTCDate(parsedDate.getUTCDate() + 1); + + return parsedDate.toISOString(); +} + function isSameDateTime(left: string, right: string) { const leftTime = new Date(left).getTime(); const rightTime = new Date(right).getTime();