From 09a4e9f06cc32fea1ceee079e215fbd593b21de5 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Wed, 23 Oct 2024 15:58:41 -0700 Subject: [PATCH 01/13] fix: hide other recipients --- api/src/services/email.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/src/services/email.service.ts b/api/src/services/email.service.ts index 2dab3f2604..99a3e04013 100644 --- a/api/src/services/email.service.ts +++ b/api/src/services/email.service.ts @@ -416,7 +416,7 @@ export class EmailService { void (await this.loadTranslations(jurisdiction)); await this.sendSES({ - to: emails, + bcc: emails, subject: this.polyglot.t('requestApproval.header'), html: this.template('request-approval')({ appOptions: { listingName: listingInfo.name }, @@ -438,7 +438,7 @@ export class EmailService { void (await this.loadTranslations(jurisdiction)); await this.sendSES({ - to: emails, + bcc: emails, subject: this.polyglot.t('changesRequested.header'), html: this.template('changes-requested')({ appOptions: { listingName: listingInfo.name }, @@ -458,7 +458,7 @@ export class EmailService { void (await this.loadTranslations(jurisdiction)); await this.sendSES({ - to: emails, + bcc: emails, subject: this.polyglot.t('listingApproved.header'), html: this.template('listing-approved')({ appOptions: { listingName: listingInfo.name }, @@ -617,7 +617,7 @@ export class EmailService { appUrl: string, ) { await this.sendSES({ - to: emails, + bcc: emails, subject: this.polyglot.t('lotteryReleased.header', { listingName: listingInfo.name, }), @@ -639,7 +639,7 @@ export class EmailService { ]); void (await this.loadTranslations(jurisdiction)); await this.sendSES({ - to: emails, + bcc: emails, subject: this.polyglot.t('lotteryPublished.header', { listingName: listingInfo.name, }), From d6330c3eca02c91240b409fed6d229e02a71a936 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Wed, 23 Oct 2024 16:07:09 -0700 Subject: [PATCH 02/13] fix: testing update --- api/test/unit/services/email.service.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/test/unit/services/email.service.spec.ts b/api/test/unit/services/email.service.spec.ts index 3caf02eec6..07ea3cef24 100644 --- a/api/test/unit/services/email.service.spec.ts +++ b/api/test/unit/services/email.service.spec.ts @@ -336,7 +336,7 @@ describe('Testing email service', () => { expect(sendMock).toHaveBeenCalled(); const emailMock = sendMock.mock.calls[0][0]; - expect(emailMock.to).toEqual(emailArr); + expect(emailMock.bcc).toEqual(emailArr); expect(emailMock.subject).toEqual('Listing approval requested'); expect(emailMock.html).toMatch( `Bloom Housing Portal`, @@ -378,7 +378,7 @@ describe('Testing email service', () => { expect(sendMock).toHaveBeenCalled(); const emailMock = sendMock.mock.calls[0][0]; - expect(emailMock.to).toEqual(emailArr); + expect(emailMock.bcc).toEqual(emailArr); expect(emailMock.subject).toEqual('Listing changes requested'); expect(emailMock.html).toMatch( `Bloom Housing Portal`, @@ -423,7 +423,7 @@ describe('Testing email service', () => { expect(sendMock).toHaveBeenCalled(); const emailMock = sendMock.mock.calls[0][0]; - expect(emailMock.to).toEqual(emailArr); + expect(emailMock.bcc).toEqual(emailArr); expect(emailMock.subject).toEqual('New published listing'); expect(emailMock.html).toMatch( `Bloom Housing Portal`, From 0c5b29b93d1606d11e8566eb3fd2c336e1dcd620 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Tue, 29 Oct 2024 12:27:52 -0700 Subject: [PATCH 03/13] fix: cover lottery publish case --- api/src/services/email.service.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/services/email.service.ts b/api/src/services/email.service.ts index 99a3e04013..7bca41382f 100644 --- a/api/src/services/email.service.ts +++ b/api/src/services/email.service.ts @@ -664,8 +664,7 @@ export class EmailService { for (const language in emails) { void (await this.loadTranslations(null, language as LanguagesEnum)); await this.sendSES({ - to: emails[language], - + bcc: emails[language], subject: this.polyglot.t('lotteryAvailable.header', { listingName: listingInfo.name, }), From fa6d1d0f54ce892f22c7137c879db13e40c62f69 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Thu, 31 Oct 2024 16:37:13 -0700 Subject: [PATCH 04/13] fix: fill out email from address --- api/src/services/email.service.ts | 11 +++++++++++ api/src/services/listing.service.ts | 27 ++++++++++++++++++++++----- api/src/services/lottery.service.ts | 6 ++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/api/src/services/email.service.ts b/api/src/services/email.service.ts index 7bca41382f..e1eab9692a 100644 --- a/api/src/services/email.service.ts +++ b/api/src/services/email.service.ts @@ -411,11 +411,13 @@ export class EmailService { listingInfo: IdDTO, emails: string[], appUrl: string, + jurisEmail: string, ) { const jurisdiction = await this.getJurisdiction([jurisdictionId]); void (await this.loadTranslations(jurisdiction)); await this.sendSES({ + to: jurisEmail, bcc: emails, subject: this.polyglot.t('requestApproval.header'), html: this.template('request-approval')({ @@ -431,6 +433,7 @@ export class EmailService { listingInfo: listingInfo, emails: string[], appUrl: string, + jurisEmail: string, ) { const jurisdiction = listingInfo.juris ? await this.getJurisdiction([{ id: listingInfo.juris }]) @@ -438,6 +441,7 @@ export class EmailService { void (await this.loadTranslations(jurisdiction)); await this.sendSES({ + to: jurisEmail, bcc: emails, subject: this.polyglot.t('changesRequested.header'), html: this.template('changes-requested')({ @@ -453,11 +457,13 @@ export class EmailService { listingInfo: IdDTO, emails: string[], publicUrl: string, + jurisEmail: string, ) { const jurisdiction = await this.getJurisdiction([jurisdictionId]); void (await this.loadTranslations(jurisdiction)); await this.sendSES({ + to: jurisEmail, bcc: emails, subject: this.polyglot.t('listingApproved.header'), html: this.template('listing-approved')({ @@ -615,8 +621,10 @@ export class EmailService { listingInfo: listingInfo, emails: string[], appUrl: string, + jurisEmail: string, ) { await this.sendSES({ + to: jurisEmail, bcc: emails, subject: this.polyglot.t('lotteryReleased.header', { listingName: listingInfo.name, @@ -633,12 +641,14 @@ export class EmailService { listingInfo: listingInfo, emails: string[], appUrl: string, + jurisEmail: string, ) { const jurisdiction = await this.getJurisdiction([ { id: listingInfo.juris }, ]); void (await this.loadTranslations(jurisdiction)); await this.sendSES({ + to: jurisEmail, bcc: emails, subject: this.polyglot.t('lotteryPublished.header', { listingName: listingInfo.name, @@ -664,6 +674,7 @@ export class EmailService { for (const language in emails) { void (await this.loadTranslations(null, language as LanguagesEnum)); await this.sendSES({ + to: jurisdiction.emailFromAddress, bcc: emails[language], subject: this.polyglot.t('lotteryAvailable.header', { listingName: listingInfo.name, diff --git a/api/src/services/listing.service.ts b/api/src/services/listing.service.ts index 3f1f2d8465..aa0e7562d3 100644 --- a/api/src/services/listing.service.ts +++ b/api/src/services/listing.service.ts @@ -364,7 +364,12 @@ export class ListingService implements OnModuleInit { listingId?: string, jurisId?: string, getPublicUrl = false, - ): Promise<{ emails: string[]; publicUrl?: string | null }> { + getEmailFromAddress = false, + ): Promise<{ + emails: string[]; + publicUrl?: string | null; + emailFromAddress?: string | null; + }> { // determine where clause(s) const userRolesWhere: Prisma.UserAccountsWhereInput[] = []; if (userRoles.includes(UserRoleEnum.admin)) @@ -387,6 +392,7 @@ export class ListingService implements OnModuleInit { select: { id: true, publicUrl: getPublicUrl, + emailFromAddress: getEmailFromAddress, }, }, }, @@ -396,13 +402,16 @@ export class ListingService implements OnModuleInit { }); // account for users having access to multiple jurisdictions - const publicUrl = getPublicUrl - ? userResults[0]?.jurisdictions?.find((juris) => juris.id === jurisId) - ?.publicUrl + const jurisInfo = userResults[0]?.jurisdictions?.find( + (juris) => juris.id === jurisId, + ); + const publicUrl = getPublicUrl ? jurisInfo?.publicUrl : null; + const emailFromAddress = getEmailFromAddress + ? jurisInfo?.emailFromAddress : null; const userEmails: string[] = []; userResults?.forEach((user) => user?.email && userEmails.push(user.email)); - return { emails: userEmails, publicUrl }; + return { emails: userEmails, publicUrl, emailFromAddress }; } public async listingApprovalNotify(params: { @@ -424,12 +433,15 @@ export class ListingService implements OnModuleInit { params.approvingRoles, params.listingInfo.id, params.jurisId, + false, + true, ); await this.emailService.requestApproval( { id: params.jurisId }, { id: params.listingInfo.id, name: params.listingInfo.name }, userInfo.emails, this.configService.get('PARTNERS_PORTAL_URL'), + userInfo.emailFromAddress, ); } // admin updates status to changes requested when approval requires partner changes @@ -441,6 +453,8 @@ export class ListingService implements OnModuleInit { nonApprovingRoles, params.listingInfo.id, params.jurisId, + false, + true, ); await this.emailService.changesRequested( params.user, @@ -451,6 +465,7 @@ export class ListingService implements OnModuleInit { }, userInfo.emails, this.configService.get('PARTNERS_PORTAL_URL'), + userInfo.emailFromAddress, ); } // check if status of active requires notification @@ -466,12 +481,14 @@ export class ListingService implements OnModuleInit { params.listingInfo.id, params.jurisId, true, + true, ); await this.emailService.listingApproved( { id: params.jurisId }, { id: params.listingInfo.id, name: params.listingInfo.name }, userInfo.emails, userInfo.publicUrl, + userInfo.emailFromAddress, ); } } diff --git a/api/src/services/lottery.service.ts b/api/src/services/lottery.service.ts index 6414b64e13..8ee935c99d 100644 --- a/api/src/services/lottery.service.ts +++ b/api/src/services/lottery.service.ts @@ -406,6 +406,8 @@ export class LotteryService { ], listing.id, listing.jurisdictions?.id, + false, + true, ); const publicUserEmailInfo = await this.getPublicUserEmailInfo(listing.id); @@ -423,6 +425,7 @@ export class LotteryService { }, partnerUserEmailInfo.emails, this.configService.get('PARTNERS_PORTAL_URL'), + partnerUserEmailInfo.emailFromAddress, ); await this.emailService.lotteryPublishedApplicant( @@ -508,6 +511,8 @@ export class LotteryService { ], storedListing.id, storedListing.jurisdictionId, + false, + true, ); await this.emailService.lotteryReleased( @@ -518,6 +523,7 @@ export class LotteryService { }, partnerUserEmailInfo.emails, this.configService.get('PARTNERS_PORTAL_URL'), + partnerUserEmailInfo.emailFromAddress, ); break; } From d7cfcbf86ccb240e325b7f7687f4d2c026268614 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Mon, 4 Nov 2024 16:28:38 -0800 Subject: [PATCH 05/13] fix: unit testing fix --- api/test/unit/services/listing.service.spec.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/api/test/unit/services/listing.service.spec.ts b/api/test/unit/services/listing.service.spec.ts index 4dc1defbf0..f219671ab2 100644 --- a/api/test/unit/services/listing.service.spec.ts +++ b/api/test/unit/services/listing.service.spec.ts @@ -3131,9 +3131,10 @@ describe('Testing listing service', () => { describe('Test listingApprovalNotify endpoint', () => { it('listingApprovalNotify request approval email', async () => { - jest - .spyOn(service, 'getUserEmailInfo') - .mockResolvedValueOnce({ emails: ['admin@email.com'] }); + jest.spyOn(service, 'getUserEmailInfo').mockResolvedValueOnce({ + emails: ['admin@email.com'], + emailFromAddress: 'no-reply@housingbayarea.org', + }); await service.listingApprovalNotify({ user, listingInfo: { id: 'id', name: 'name' }, @@ -3146,18 +3147,22 @@ describe('Testing listing service', () => { ['admin'], 'id', 'jurisId', + false, + true, ); expect(requestApprovalMock).toBeCalledWith( { id: 'jurisId' }, { id: 'id', name: 'name' }, ['admin@email.com'], config.get('PARTNERS_PORTAL_URL'), + 'no-reply@housingbayarea.org', ); }); it('listingApprovalNotify changes requested email', async () => { jest.spyOn(service, 'getUserEmailInfo').mockResolvedValueOnce({ emails: ['jurisAdmin@email.com', 'partner@email.com'], + emailFromAddress: 'no-reply@housingbayarea.org', }); await service.listingApprovalNotify({ user, @@ -3171,12 +3176,15 @@ describe('Testing listing service', () => { ['partner', 'jurisdictionAdmin'], 'id', 'jurisId', + false, + true, ); expect(changesRequestedMock).toBeCalledWith( user, { id: 'id', name: 'name', juris: 'jurisId' }, ['jurisAdmin@email.com', 'partner@email.com'], config.get('PARTNERS_PORTAL_URL'), + 'no-reply@housingbayarea.org', ); }); @@ -3184,6 +3192,7 @@ describe('Testing listing service', () => { jest.spyOn(service, 'getUserEmailInfo').mockResolvedValueOnce({ emails: ['jurisAdmin@email.com', 'partner@email.com'], publicUrl: 'public.housing.gov', + emailFromAddress: 'no-reply@housingbayarea.org', }); await service.listingApprovalNotify({ user, @@ -3199,12 +3208,14 @@ describe('Testing listing service', () => { 'id', 'jurisId', true, + true, ); expect(listingApprovedMock).toBeCalledWith( expect.objectContaining({ id: 'jurisId' }), { id: 'id', name: 'name' }, ['jurisAdmin@email.com', 'partner@email.com'], 'public.housing.gov', + 'no-reply@housingbayarea.org', ); }); From 7d2f47c0ea95a741dc3c72876385ac1cbcde5aaa Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Mon, 4 Nov 2024 18:13:41 -0800 Subject: [PATCH 06/13] fix: lottery unit testing --- api/test/unit/services/lottery.service.spec.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/api/test/unit/services/lottery.service.spec.ts b/api/test/unit/services/lottery.service.spec.ts index 026231c996..7a959d5867 100644 --- a/api/test/unit/services/lottery.service.spec.ts +++ b/api/test/unit/services/lottery.service.spec.ts @@ -87,14 +87,6 @@ describe('Testing lottery service', () => { prisma = module.get(PrismaService); listingService = module.get(ListingService); config = module.get(ConfigService); - - jest.spyOn(listingService, 'getUserEmailInfo').mockResolvedValueOnce({ - emails: ['admin@email.com', 'partner@email.com'], - }); - - jest.spyOn(service, 'getPublicUserEmailInfo').mockResolvedValueOnce({ - en: ['applicant@email.com'], - }); }); describe('Testing lotteryRandomizerHelper()', () => { @@ -685,6 +677,7 @@ describe('Testing lottery service', () => { jest.spyOn(listingService, 'getUserEmailInfo').mockResolvedValueOnce({ emails: ['admin@email.com', 'partner@email.com'], + emailFromAddress: 'no-reply@housingbayarea.org', }); jest.spyOn(service, 'getPublicUserEmailInfo').mockResolvedValueOnce({ @@ -721,12 +714,15 @@ describe('Testing lottery service', () => { ['admin', 'jurisdictionAdmin', 'partner'], 'example id', 'jurisId', + false, + true, ); expect(lotteryReleasedMock).toBeCalledWith( { id: 'example id', juris: 'jurisId', name: 'example name' }, ['admin@email.com', 'partner@email.com'], config.get('PARTNERS_PORTAL_URL'), + 'no-reply@housingbayarea.org', ); }); From 908efebea7ab78d622933142200b85376f3ad23d Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Mon, 4 Nov 2024 18:30:52 -0800 Subject: [PATCH 07/13] fix: partial e2e fix --- api/test/integration/listing.e2e-spec.ts | 7 ++++++- api/test/integration/lottery.e2e-spec.ts | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/api/test/integration/listing.e2e-spec.ts b/api/test/integration/listing.e2e-spec.ts index b5a14bf62a..c7e9a5e6b5 100644 --- a/api/test/integration/listing.e2e-spec.ts +++ b/api/test/integration/listing.e2e-spec.ts @@ -51,6 +51,7 @@ describe('Listing Controller Tests', () => { let app: INestApplication; let prisma: PrismaService; let jurisdictionAId: string; + let jurisdictionAEmail: string; let adminAccessToken: string; const testEmailService = { @@ -87,6 +88,7 @@ describe('Listing Controller Tests', () => { data: jurisdictionFactory(), }); jurisdictionAId = jurisdiction.id; + jurisdictionAEmail = jurisdiction.emailFromAddress; await reservedCommunityTypeFactoryAll(jurisdictionAId, prisma); await unitAccessibilityPriorityTypeFactoryAll(prisma); const adminUser = await prisma.userAccounts.create({ @@ -906,7 +908,7 @@ describe('Listing Controller Tests', () => { ); }); - it('update status to pending approval and notify appropriate users', async () => { + it.only('update status to pending approval and notify appropriate users', async () => { const res = await request(app.getHttpServer()) .post('/auth/login') .set({ passkey: process.env.API_PASS_KEY || '' }) @@ -940,6 +942,7 @@ describe('Listing Controller Tests', () => { { id: listing.id, name: val.name }, expect.arrayContaining([adminUser.email, jurisAdmin.email]), process.env.PARTNERS_PORTAL_URL, + jurisdictionAEmail, ); //ensure juris admin is not included since don't have approver permissions in alameda seed expect(mockRequestApproval.mock.calls[0]['emails']).toEqual( @@ -980,6 +983,7 @@ describe('Listing Controller Tests', () => { { id: listing.id, name: val.name }, expect.arrayContaining([partnerUser.email]), jurisdictionA.publicUrl, + jurisdictionA.emailFromAddress, ); expect(mockListingOpportunity).toBeCalledWith( expect.objectContaining({ @@ -1022,6 +1026,7 @@ describe('Listing Controller Tests', () => { { id: listing.id, name: val.name, juris: expect.anything() }, expect.arrayContaining([partnerUser.email]), process.env.PARTNERS_PORTAL_URL, + jurisdictionAEmail, ); }); }); diff --git a/api/test/integration/lottery.e2e-spec.ts b/api/test/integration/lottery.e2e-spec.ts index acd005132d..d79e15d7a3 100644 --- a/api/test/integration/lottery.e2e-spec.ts +++ b/api/test/integration/lottery.e2e-spec.ts @@ -44,6 +44,7 @@ describe('Lottery Controller Tests', () => { let cookies = ''; let adminAccessToken: string; let jurisdictionAId: string; + let jurisdictionAEmail: string; let unitTypeA: UnitTypes; const testEmailService = { @@ -101,6 +102,7 @@ describe('Lottery Controller Tests', () => { data: jurisdictionFactory(), }); jurisdictionAId = jurisdiction.id; + jurisdictionAEmail = jurisdiction.emailFromAddress; await reservedCommunityTypeFactoryAll(jurisdictionAId, prisma); await unitTypeFactoryAll(prisma); unitTypeA = await unitTypeFactorySingle(prisma, UnitTypeEnum.oneBdrm); @@ -895,6 +897,7 @@ describe('Lottery Controller Tests', () => { }, expect.arrayContaining([partnerUser.email, adminUser.email]), process.env.PARTNERS_PORTAL_URL, + jurisdictionAEmail, ); const activityLogResult = await prisma.activityLog.findFirst({ @@ -1077,7 +1080,7 @@ describe('Lottery Controller Tests', () => { juris: expect.stringMatching(jurisdictionAId), }, expect.arrayContaining([partnerUser.email, adminUser.email]), - process.env.PARTNERS_PORTAL_URL, + jurisdictionAEmail, ); expect(mockLotteryPublishedApplicant).toBeCalledWith( From 4b56195623a293642120f96d83e161de7474a285 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Wed, 13 Nov 2024 14:01:07 -0500 Subject: [PATCH 08/13] fix: updated find juris approach --- api/src/services/listing.service.ts | 10 ++++++---- api/test/integration/listing.e2e-spec.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/api/src/services/listing.service.ts b/api/src/services/listing.service.ts index aa0e7562d3..3ffdc71bc9 100644 --- a/api/src/services/listing.service.ts +++ b/api/src/services/listing.service.ts @@ -400,14 +400,16 @@ export class ListingService implements OnModuleInit { OR: userRolesWhere, }, }); - // account for users having access to multiple jurisdictions - const jurisInfo = userResults[0]?.jurisdictions?.find( + const userWithJuris = userResults?.find( + (user) => user.jurisdictions.length, + ); + const matchingJurisInfo = userWithJuris?.jurisdictions?.find( (juris) => juris.id === jurisId, ); - const publicUrl = getPublicUrl ? jurisInfo?.publicUrl : null; + const publicUrl = getPublicUrl ? matchingJurisInfo?.publicUrl : null; const emailFromAddress = getEmailFromAddress - ? jurisInfo?.emailFromAddress + ? matchingJurisInfo?.emailFromAddress : null; const userEmails: string[] = []; userResults?.forEach((user) => user?.email && userEmails.push(user.email)); diff --git a/api/test/integration/listing.e2e-spec.ts b/api/test/integration/listing.e2e-spec.ts index c7e9a5e6b5..513c3f95fa 100644 --- a/api/test/integration/listing.e2e-spec.ts +++ b/api/test/integration/listing.e2e-spec.ts @@ -908,7 +908,7 @@ describe('Listing Controller Tests', () => { ); }); - it.only('update status to pending approval and notify appropriate users', async () => { + it('update status to pending approval and notify appropriate users', async () => { const res = await request(app.getHttpServer()) .post('/auth/login') .set({ passkey: process.env.API_PASS_KEY || '' }) From d63c61549f4786d541b440a3fd4964d6cf8460e3 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Wed, 13 Nov 2024 14:57:52 -0500 Subject: [PATCH 09/13] fix: add missing url check --- api/test/integration/lottery.e2e-spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/api/test/integration/lottery.e2e-spec.ts b/api/test/integration/lottery.e2e-spec.ts index d79e15d7a3..cca9da797d 100644 --- a/api/test/integration/lottery.e2e-spec.ts +++ b/api/test/integration/lottery.e2e-spec.ts @@ -1080,6 +1080,7 @@ describe('Lottery Controller Tests', () => { juris: expect.stringMatching(jurisdictionAId), }, expect.arrayContaining([partnerUser.email, adminUser.email]), + process.env.PARTNERS_PORTAL_URL, jurisdictionAEmail, ); From 74627799f2b7566319cee0fffb596bbe79cffbd5 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Fri, 15 Nov 2024 10:08:04 -0500 Subject: [PATCH 10/13] fix: juris matching logic adjustment --- api/src/services/listing.service.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/services/listing.service.ts b/api/src/services/listing.service.ts index 3ffdc71bc9..184e43cdaf 100644 --- a/api/src/services/listing.service.ts +++ b/api/src/services/listing.service.ts @@ -400,10 +400,12 @@ export class ListingService implements OnModuleInit { OR: userRolesWhere, }, }); + // account for users having access to multiple jurisdictions - const userWithJuris = userResults?.find( - (user) => user.jurisdictions.length, + const userWithJuris = userResults?.find((user) => + user.jurisdictions.some((juris) => juris.id === jurisId), ); + const matchingJurisInfo = userWithJuris?.jurisdictions?.find( (juris) => juris.id === jurisId, ); From 2042c586e99c5f9e8ee21088ca2abb83706acb44 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Mon, 18 Nov 2024 11:54:06 -0500 Subject: [PATCH 11/13] fix: update user and juris call --- api/src/services/listing.service.ts | 36 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/api/src/services/listing.service.ts b/api/src/services/listing.service.ts index 184e43cdaf..1b1633d24f 100644 --- a/api/src/services/listing.service.ts +++ b/api/src/services/listing.service.ts @@ -386,35 +386,33 @@ export class ListingService implements OnModuleInit { }); } - const userResults = await this.prisma.userAccounts.findMany({ - include: { - jurisdictions: { - select: { - id: true, - publicUrl: getPublicUrl, - emailFromAddress: getEmailFromAddress, - }, - }, + const rawUsers = await this.prisma.userAccounts.findMany({ + select: { + id: true, + email: true, }, where: { OR: userRolesWhere, }, }); - // account for users having access to multiple jurisdictions - const userWithJuris = userResults?.find((user) => - user.jurisdictions.some((juris) => juris.id === jurisId), - ); + const rawJuris = await this.prisma.jurisdictions.findFirst({ + select: { + id: true, + publicUrl: getPublicUrl, + emailFromAddress: getEmailFromAddress, + }, + where: { + id: jurisId, + }, + }); - const matchingJurisInfo = userWithJuris?.jurisdictions?.find( - (juris) => juris.id === jurisId, - ); - const publicUrl = getPublicUrl ? matchingJurisInfo?.publicUrl : null; + const publicUrl = getPublicUrl ? rawJuris?.publicUrl : null; const emailFromAddress = getEmailFromAddress - ? matchingJurisInfo?.emailFromAddress + ? rawJuris?.emailFromAddress : null; const userEmails: string[] = []; - userResults?.forEach((user) => user?.email && userEmails.push(user.email)); + rawUsers?.forEach((user) => user?.email && userEmails.push(user.email)); return { emails: userEmails, publicUrl, emailFromAddress }; } From bb3ca148d634edd6a70384500be890d02f81c551 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Mon, 18 Nov 2024 12:30:19 -0500 Subject: [PATCH 12/13] fix: yarn lock updates --- yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0e514ae6a4..67b4bb1305 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14631,13 +14631,6 @@ rfdc@^1.3.0: resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - rimraf@^2.6.3: version "2.7.1" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" @@ -14645,6 +14638,13 @@ rimraf@^2.6.3: dependencies: glob "^7.1.3" +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rollup@2.78.0: version "2.78.0" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.0.tgz#00995deae70c0f712ea79ad904d5f6b033209d9e" From d6a304e68492b02e7a9140bff483b8299725e520 Mon Sep 17 00:00:00 2001 From: ColinBuyck Date: Mon, 18 Nov 2024 17:34:40 -0500 Subject: [PATCH 13/13] fix: reduce approach --- api/src/services/listing.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/src/services/listing.service.ts b/api/src/services/listing.service.ts index 1b1633d24f..a6653bc38f 100644 --- a/api/src/services/listing.service.ts +++ b/api/src/services/listing.service.ts @@ -411,8 +411,11 @@ export class ListingService implements OnModuleInit { const emailFromAddress = getEmailFromAddress ? rawJuris?.emailFromAddress : null; - const userEmails: string[] = []; - rawUsers?.forEach((user) => user?.email && userEmails.push(user.email)); + + const userEmails: string[] = rawUsers?.reduce((userEmails, user) => { + if (user?.email) userEmails.push(user.email); + return userEmails; + }, []); return { emails: userEmails, publicUrl, emailFromAddress }; }