From 00bc6b838efc9ae1429c34459661f204e1fe4fa6 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 22 Mar 2024 13:21:44 -0400 Subject: [PATCH 1/6] first commit --- .gitignore | 2 +- .../apple-pay/apple-pay.service.ts | 59 ++++++++------- .../opf-quick-buy/opf-quick-buy.service.ts | 8 ++ .../base/root/model/opf-quick-buy.model.ts | 2 + projects/storefrontapp/project.json | 3 +- ...eveloper-merchantid-domain-association.txt | 75 +++++++++++++++++++ 6 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt diff --git a/.gitignore b/.gitignore index 93674d1220e..880ebeb2d75 100644 --- a/.gitignore +++ b/.gitignore @@ -57,7 +57,7 @@ scripts/install/config.sh /libpeerconnection.log /typings /.nx -.well-known/ +# .well-known/ # Logs npm-debug.log diff --git a/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts b/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts index 89b1b955466..a5c271722df 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts @@ -32,6 +32,7 @@ import { OpfQuickBuyLocation, PaymentMethod, QuickBuyTransactionDetails, + defaultMerchantName, } from '@spartacus/opf/base/root'; import { Cart, DeliveryMode } from '@spartacus/cart/base/root'; @@ -61,7 +62,7 @@ export class ApplePayService { quantity: 0, addressIds: [], total: { - label: '', + label: defaultMerchantName, amount: '', currency: '', }, @@ -184,33 +185,37 @@ export class ApplePayService { countryCode, }; - return this.opfQuickBuyService - .getQuickBuyDeliveryInfo( - this.transactionDetails.context as OpfQuickBuyLocation - ) - .pipe( - switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => { - this.transactionDetails.deliveryInfo = deliveryInfo; - if (deliveryInfo.type === OpfQuickBuyDeliveryType.PICKUP) { - // Don't display shipping contact form on payment sheet - initialRequest.requiredShippingContactFields = []; - initialRequest.shippingType = ApplePayShippingType.STORE_PICKUP; - - return this.transactionDetails.context === - OpfQuickBuyLocation.PRODUCT - ? this.opfPickupInStoreHandlerService.getSingleProductDeliveryInfo() - : of(undefined); - } - return of(undefined); - }), - map((opfQuickBuyDeliveryInfo) => { - if (!opfQuickBuyDeliveryInfo) { - return initialRequest; - } - this.transactionDetails.deliveryInfo = opfQuickBuyDeliveryInfo; + return this.opfQuickBuyService.getMerchantName().pipe( + switchMap((merchantName) => { + if (merchantName) { + this.transactionDetails.total.label = merchantName; + initialRequest.total.label = merchantName; + } + return this.opfQuickBuyService.getQuickBuyDeliveryInfo( + this.transactionDetails.context as OpfQuickBuyLocation + ); + }), + switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => { + this.transactionDetails.deliveryInfo = deliveryInfo; + if (deliveryInfo.type === OpfQuickBuyDeliveryType.PICKUP) { + // Don't display shipping contact form on payment sheet + initialRequest.requiredShippingContactFields = []; + initialRequest.shippingType = ApplePayShippingType.STORE_PICKUP; + + return this.transactionDetails.context === OpfQuickBuyLocation.PRODUCT + ? this.opfPickupInStoreHandlerService.getSingleProductDeliveryInfo() + : of(undefined); + } + return of(undefined); + }), + map((opfQuickBuyDeliveryInfo) => { + if (!opfQuickBuyDeliveryInfo) { return initialRequest; - }) - ); + } + this.transactionDetails.deliveryInfo = opfQuickBuyDeliveryInfo; + return initialRequest; + }) + ); } protected handleSingleProductTransaction( diff --git a/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.ts b/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.ts index 764c6897df9..3c9b3ea57fb 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.ts @@ -16,6 +16,7 @@ import { OpfProviderType, OpfQuickBuyDeliveryInfo, OpfQuickBuyLocation, + defaultMerchantName, } from '@spartacus/opf/base/root'; import { Observable, of } from 'rxjs'; import { map, switchMap, take } from 'rxjs/operators'; @@ -116,4 +117,11 @@ export class OpfQuickBuyService { return deliveryTypeObservable.pipe(take(1)); } + + getMerchantName(): Observable { + return this.baseSiteService.get().pipe( + take(1), + map((baseSite) => baseSite?.name ?? defaultMerchantName) + ); + } } diff --git a/integration-libs/opf/base/root/model/opf-quick-buy.model.ts b/integration-libs/opf/base/root/model/opf-quick-buy.model.ts index 2d46636dc9d..5f9d4e894a5 100644 --- a/integration-libs/opf/base/root/model/opf-quick-buy.model.ts +++ b/integration-libs/opf/base/root/model/opf-quick-buy.model.ts @@ -158,3 +158,5 @@ export enum ApplePayShippingType { STORE_PICKUP = 'storePickup', SERVICE_PICKUP = 'servicePickup', } + +export const defaultMerchantName: string = ''; \ No newline at end of file diff --git a/projects/storefrontapp/project.json b/projects/storefrontapp/project.json index 7fa15f719bf..ae77920488a 100644 --- a/projects/storefrontapp/project.json +++ b/projects/storefrontapp/project.json @@ -153,7 +153,8 @@ "serve": { "executor": "@angular-builders/custom-webpack:dev-server", "options": { - "buildTarget": "storefrontapp:build" + "buildTarget": "storefrontapp:build", + "disableHostCheck": true }, "configurations": { "production": { diff --git a/projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt b/projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt new file mode 100644 index 00000000000..bf893ab2c8d --- /dev/null +++ b/projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt @@ -0,0 +1,75 @@ +MIIQgQYJKoZIhvcNAQcCoIIQcjCCEG4CAQExCzAJBgUrDgMCGgUAMIGPBgkqhkiG9w0BBwGggYEE +f3sidGVhbUlkIjoiRFdGTEVRN0VaNSIsImRvbWFpbiI6InNwYXJ0YWN1cy1kZXYtYXN4MS5lYXN0 +dXMuY2xvdWRhcHAuYXp1cmUuY29tIiwiZGF0ZUNyZWF0ZWQiOiIyMDI0LTAzLTExLDE0OjEwOjQz +IiwidmVyc2lvbiI6MX2ggg0_MIIENDCCAxygAwIBAgIIRzxMYfKZiNQwDQYJKoZIhvcNAQELBQAw +czEtMCsGA1UEAwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQL +DBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMC +VVMwHhcNMjMwNDExMjIyMzU5WhcNMjgwNDA5MjIyMzU4WjBZMTUwMwYDVQQDDCxBcHBsZSBpUGhv +bmUgT1MgUHJvdmlzaW9uaW5nIFByb2ZpbGUgU2lnbmluZzETMBEGA1UECgwKQXBwbGUgSW5jLjEL +MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqQ-T801OftoAP_MZt +borJ1sPSjvvdm_fAS-H7SOnN8ywYMsbuLNMxMBfRqETC-alko-KO66ung4IsLcGGAq8EV1OZTQw3 +kEN2dntunBtrFbHkAf2dnBWbd3_A9CPRrqCyRPohS9JNiLxqmAPRUaV08l_u-75ZgUfjT2J7uWOl +T9KOyhBOMVWN7VyRR7b2N9PfNt8sW88XTk3DBVE9_BlwnwD4tYnX18swFeu51u1Ne5LMXYDLDDsr +Rw3IW3F7tMHbxtdn0NdThpCXAd7_Br0dmYWk18_u6kHkXv4KZ3AgFR2U7jRm7kJqz9-j9RBKxJiy +1VxoSO37mqdw_haZsxf1AgMBAAGjgeUwgeIwDAYDVR0TAQH_BAIwADAfBgNVHSMEGDAWgBRv8ZUY +YlzgyPHF7WwYyeDTZFKYIDBABggrBgEFBQcBAQQ0MDIwMAYIKwYBBQUHMAGGJGh0dHA6Ly9vY3Nw +LmFwcGxlLmNvbS9vY3NwMDMtYWlwY2EwNzAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmFw +cGxlLmNvbS9haXBjYS5jcmwwHQYDVR0OBBYEFE-zO0h9RI1qIItA5UMxgvmGu4fiMA4GA1UdDwEB +_wQEAwIHgDAPBgkqhkiG92NkBjoEAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQA_jhwU4vCy9v91URbG +HQMZjB234-ewkxiLvqlyxQSEbg7ZexxfIzojL6v8gudymdsjoHXDYk6EZ8uOwCxOxuKXD-HQB19c +2Iz3e5DtHdAA3rNnAhdtWz7zabLH08lXZNGuAkbMC3ojQtBy_XUPp1kL_tVUZkW7oeW9xT0LQBDL +X36J8A3fYT6nc0F4ZVZ5lYZlG2b1DE4Krm5f7UdSsPJndgGkoi-Fc1YVIBGpVxIFa7yw9xtGOF01 +__-YxmkJE2UfTcW7K627rOC0gC7eAbO-EifxKZGHLKblYZU_rn41C1wuDk3yNk-xgQjLr9liXq3v +Omkgm6B4u54ffEqBbnolMIIERDCCAyygAwIBAgIIXGPK5Eo3U8kwDQYJKoZIhvcNAQELBQAwYjEL +MAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTE3MDUxMDIxMjczMFoX +DTMwMTIzMTAwMDAwMFowczEtMCsGA1UEAwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUg +SW5jLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJRWoBDz6D +BIbH_L_cXvAege4XMHNjJi7ePXokzZM-TzlHunW-88DS8Vmiqx_-CoY82S2aB_IOa7kpkRpfIgqL +8XJYBa5MS0TFeaeAPLCI4IwMJ4RdGeWHGTbL48V2t7D0QXJR9AVcg0uibaZRuPEm33terWUMxrKY +UYy7fRtMwU7ICMfS7WQLtN0bjU9AfRuPSJaSW_PQmH7ZvKQZDplhu0FdAcxbd3p9JNDc01P_w9zF +lCy2Wk2OGCM5vdnGUj7R8vQliqEqh_3YDEYpUf_tF2yJJWuHv4ppFJ93n8MVt2iziEW9hOYGAkFk +D60qKLgVyeCsp4q6cgQ0sniM-LKFAgMBAAGjgewwgekwDwYDVR0TAQH_BAUwAwEB_zAfBgNVHSME +GDAWgBQr0GlHlHYJ_vRrjS5ApvdHTX8IXjBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0 +dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYXBwbGVyb290Y2EwLgYDVR0fBCcwJTAjoCGgH4Yd +aHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5jcmwwHQYDVR0OBBYEFG_xlRhiXODI8cXtbBjJ4NNk +UpggMA4GA1UdDwEB_wQEAwIBBjAQBgoqhkiG92NkBgISBAIFADANBgkqhkiG9w0BAQsFAAOCAQEA +Os-smI2-kiAhCa2V87FcIfo2LVcgRHRzZJIIs5as922X-ls0OCfPEkbTPBHwB8mZkLHR6BEJpeOl +a2xjCD-eJfrVmZxM5uXOjrJNaOyLq6OiT4oRFT7cFCscxkS2b2fFW0-VKS2HXD_cgx53T-3aVKct +5xOBwWPEVAsbSwpqKCII1DeSfH9nKF-vPT-3rFkdODRkWu4zShlCRCnEyhhr4cFTLS30TcIV9jMy +GHjxJm-KTeuUTKPo_w-zA4tl2usu2GVQn9yfit8xqIRU3FJSQdKyEx0xRkeIXz7uw_KMIwSV66yK +PoJsBp8u44tDmmJbNA30mc8s7rpyhhkjpfyOtTCCBLswggOjoAMCAQICAQIwDQYJKoZIhvcNAQEF +BQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTA2MDQyNTIx +NDAzNloXDTM1MDIwOTIxNDAzNlowYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4x +JjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBS +b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5JGpCR-R2x5HUOsF7V55hC3r +NqJXTFXsixmJ3vlLbPUHqyIwAugYPvhQCdN_QaiY-dHKZpwkaxHQo7vkGyrDH5WeegykR4tb1BY3 +M8vED03OFGnRyRly9V0O1X9fm_IlA7pVj01dDfFkNSMVSxVZHbOU9_acns9QusFYUGePCLQg98us +LCBvcLY_ATCMt0PPD5098ytJKBrI_s61uQ7ZXhzWyz21Oq30Dw4AkguxIRYudNU8DdtiFqujcZJH +U1XBry9Bs_j743DN5qNMRX4fTGtQlkGJxHRiCxCDQYczioGxMFjsWgQyjGizjx3eZXP_Z15lvEnY +dp8zFGWhd5TJLQIDAQABo4IBejCCAXYwDgYDVR0PAQH_BAQDAgEGMA8GA1UdEwEB_wQFMAMBAf8w +HQYDVR0OBBYEFCvQaUeUdgn-9GuNLkCm90dNfwheMB8GA1UdIwQYMBaAFCvQaUeUdgn-9GuNLkCm +90dNfwheMIIBEQYDVR0gBIIBCDCCAQQwggEABgkqhkiG92NkBQEwgfIwKgYIKwYBBQUHAgEWHmh0 +dHBzOi8vd3d3LmFwcGxlLmNvbS9hcHBsZWNhLzCBwwYIKwYBBQUHAgIwgbYagbNSZWxpYW5jZSBv +biB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhl +IHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNl +cnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjAN +BgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14t-2Mm9zzd5vydtJ3ME_BH4WDhRuZPUc38qmbQI4s1LGQ +Eti-9HOb7tJkD8t5TzTYoj75eP9ryAfsfTmDi1Mg0zjEsb-aTwpr_yv8WacFCXwXQFYRHnTTt4sj +O0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UXF6jcfiI1yiXV2Q_Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4 +REjwYDieFfU9JmcgijNq9w2Cz97roy_5U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU-12TZ_wYdV2aeZ +uTJC-9jVcZ5-oVK3G72TQiQSKscPHbZNnF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAoUwggKBAgEB +MH8wczEtMCsGA1UEAwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYD +VQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UE +BhMCVVMCCEc8TGHymYjUMAkGBSsOAwIaBQCggdwwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc +BgkqhkiG9w0BCQUxDxcNMjQwMzExMTQxMDQzWjAjBgkqhkiG9w0BCQQxFgQUBY6mjB2KcxgJq_rC +XD12rRNoMYYwKQYJKoZIhvcNAQk0MRwwGjAJBgUrDgMCGgUAoQ0GCSqGSIb3DQEBAQUAMFIGCSqG +SIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcG +BSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIIBAERONkrymDkkBVURVpO4Ltzh +xE1ATBTt3s6Cs1SDei7cvOQIIFg4L4PSwZCl0kPVkfEN9I2pooD_zlsWefHr4seEY912eq62jwpN +XIbSx_HKfAFm9lO9HXdMgmUVa9c2Ws7_tQVreq7rLPW5I9b1mTlLKsuJ4FG31YKwxQ6VHjcgtrEU +GXuqLUh-LXGnm9a7nf0DFs-XF547SMZcNZTElCjUothfCHpX1UpSn4kJR_5hrBFaJKTwGmPrQ3Z3 +qinRhdRvcZWMOHXkoyQAFPlwry1LUw9SgfY3wKb6BD__mMtRP2HYLi-GaEsCeyrhMpfg5_6qchHI +tI9XSY1jHDDwYso From 4ba4fd02b54fdce0594af177c97c1238ded9a945 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 22 Mar 2024 15:09:24 -0400 Subject: [PATCH 2/6] add unit tests --- .../apple-pay/apple-pay.service.spec.ts | 14 +++++++++++-- .../opf-quick-buy.service.spec.ts | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.spec.ts b/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.spec.ts index fe0eb6a9d4c..a61187007e4 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.spec.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.spec.ts @@ -125,6 +125,7 @@ describe('ApplePayService', () => { 'getQuickBuyLocationContext', 'getQuickBuyProviderConfig', 'getQuickBuyDeliveryInfo', + 'getMerchantName', ]); applePaySessionFactoryMock = jasmine.createSpyObj( @@ -197,6 +198,7 @@ describe('ApplePayService', () => { describe('observable callbacks', () => { let config: ApplePayObservableConfig; + const merchantNameMock = 'Nakano'; beforeEach(() => { ( applePayObservableFactoryMock.initApplePayEventsHandler as jasmine.Spy @@ -209,6 +211,9 @@ describe('ApplePayService', () => { type: OpfQuickBuyDeliveryType.SHIPPING, }) ); + opfQuickBuyServiceMock.getMerchantName.and.returnValue( + of(merchantNameMock) + ); }); it('should handle validateMerchant change', () => { @@ -309,7 +314,7 @@ describe('ApplePayService', () => { expect(paymentMethodChangeResult.newTotal).toEqual({ amount: mockProduct.price?.value?.toString(), - label: mockProduct.name, + label: merchantNameMock, }); }); @@ -345,7 +350,7 @@ describe('ApplePayService', () => { .subscribe((actural) => (shippingMethodChangeResult = actural)); expect(shippingMethodChangeResult.newTotal).toEqual({ amount: mockCart.totalPrice?.value?.toString(), - label: mockProduct.name, + label: merchantNameMock, }); }); @@ -665,6 +670,7 @@ describe('ApplePayService', () => { it('should handle errors during Apple Pay session start', () => { service = TestBed.inject(ApplePayService); + const merchantNameMock = 'Nakano'; opfQuickBuyServiceMock.getQuickBuyDeliveryInfo.and.returnValue( of({ type: OpfQuickBuyDeliveryType.SHIPPING, @@ -680,6 +686,10 @@ describe('ApplePayService', () => { throwError('Error') ); + opfQuickBuyServiceMock.getMerchantName.and.returnValue( + of(merchantNameMock) + ); + service .start({ product: mockProduct, quantity: 1, countryCode: 'us' }) .subscribe({ diff --git a/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts b/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts index b409c1ad3c3..575be9f2fb1 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts @@ -14,6 +14,7 @@ import { OpfPaymentProviderType, OpfProviderType, OpfQuickBuyLocation, + defaultMerchantName, } from '../../root/model'; import { OpfQuickBuyService } from './opf-quick-buy.service'; @@ -268,5 +269,24 @@ describe('OpfQuickBuyService', () => { ); expect(result).toBe(config); }); + + describe('getMerchantName', () => { + it('should return baseSite name', (done) => { + const mockName = 'Electronics store'; + baseSiteServiceMock.get.and.returnValue(of({ name: mockName })); + service.getMerchantName().subscribe((merchantName) => { + expect(merchantName).toBe(mockName); + done(); + }); + }); + it('should return default MerchantName name when empty', (done) => { + const mockName = undefined; + baseSiteServiceMock.get.and.returnValue(of({ name: mockName })); + service.getMerchantName().subscribe((merchantName) => { + expect(merchantName).toBe(defaultMerchantName); + done(); + }); + }); + }); }); }); From e40e1cfa624bb05256ecee607a3bd240df6d8551 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 22 Mar 2024 15:19:17 -0400 Subject: [PATCH 3/6] use forkjoin --- .../apple-pay/apple-pay.service.ts | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts b/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts index a5c271722df..cb63dfb1505 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/apple-pay/apple-pay.service.ts @@ -7,7 +7,7 @@ /// import { Injectable, inject } from '@angular/core'; import { Address, Product, WindowRef } from '@spartacus/core'; -import { Observable, of, throwError } from 'rxjs'; +import { Observable, forkJoin, of, throwError } from 'rxjs'; import { catchError, finalize, @@ -27,7 +27,6 @@ import { ApplePayShippingType, ApplePayTransactionInput, OpfPaymentFacade, - OpfQuickBuyDeliveryInfo, OpfQuickBuyDeliveryType, OpfQuickBuyLocation, PaymentMethod, @@ -185,17 +184,15 @@ export class ApplePayService { countryCode, }; - return this.opfQuickBuyService.getMerchantName().pipe( - switchMap((merchantName) => { - if (merchantName) { - this.transactionDetails.total.label = merchantName; - initialRequest.total.label = merchantName; - } - return this.opfQuickBuyService.getQuickBuyDeliveryInfo( - this.transactionDetails.context as OpfQuickBuyLocation - ); - }), - switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => { + return forkJoin({ + deliveryInfo: this.opfQuickBuyService.getQuickBuyDeliveryInfo( + this.transactionDetails.context as OpfQuickBuyLocation + ), + merchantName: this.opfQuickBuyService.getMerchantName(), + }).pipe( + switchMap(({ deliveryInfo, merchantName }) => { + this.transactionDetails.total.label = merchantName; + initialRequest.total.label = merchantName; this.transactionDetails.deliveryInfo = deliveryInfo; if (deliveryInfo.type === OpfQuickBuyDeliveryType.PICKUP) { // Don't display shipping contact form on payment sheet From f92bbb0b104dced65371bde9194f97762d74be0a Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 22 Mar 2024 15:38:46 -0400 Subject: [PATCH 4/6] add googlepay --- .../google-pay/google-pay.service.spec.ts | 6 + .../google-pay/google-pay.service.ts | 142 +++++++++--------- .../base/root/model/opf-quick-buy.model.ts | 2 +- 3 files changed, 80 insertions(+), 70 deletions(-) diff --git a/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.spec.ts b/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.spec.ts index 0aa7ee9f563..3bab112149a 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.spec.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.spec.ts @@ -23,6 +23,7 @@ import { OpfQuickBuyService } from '../opf-quick-buy.service'; import { OpfGooglePayService } from './google-pay.service'; describe('OpfGooglePayService', () => { + const mockMerchantName = 'mockMerchantName'; let service: OpfGooglePayService; let mockResourceLoaderService: jasmine.SpyObj; let mockItemCounterService: jasmine.SpyObj; @@ -69,6 +70,7 @@ describe('OpfGooglePayService', () => { 'getQuickBuyLocationContext', 'getQuickBuyProviderConfig', 'getQuickBuyDeliveryInfo', + 'getMerchantName', ]); const googlePayApiMock = { @@ -495,6 +497,8 @@ describe('OpfGooglePayService', () => { of(OpfQuickBuyLocation.PRODUCT) ); + mockQuickBuyService.getMerchantName.and.returnValue(of(mockMerchantName)); + service.initTransaction(); expect(service['transactionDetails'].context).toBe( @@ -518,6 +522,8 @@ describe('OpfGooglePayService', () => { of(OpfQuickBuyLocation.CART) ); + mockQuickBuyService.getMerchantName.and.returnValue(of(mockMerchantName)); + service.initTransaction(); expect(service['transactionDetails'].context).toBe( diff --git a/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.ts b/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.ts index 54813256729..7684e8e07a2 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/google-pay/google-pay.service.ts @@ -14,12 +14,12 @@ import { ActiveConfiguration, OpfPaymentFacade, OpfProviderType, - OpfQuickBuyDeliveryInfo, OpfQuickBuyDeliveryType, OpfQuickBuyLocation, OpfResourceLoaderService, PaymentMethod, QuickBuyTransactionDetails, + defaultMerchantName, } from '@spartacus/opf/base/root'; import { CurrentProductService, @@ -72,7 +72,7 @@ export class OpfGooglePayService { // @ts-ignore merchantInfo: { // merchantId: 'spartacusStorefront', - merchantName: 'Spartacus Storefront', + merchantName: defaultMerchantName, }, shippingOptionRequired: true, shippingAddressRequired: true, @@ -116,7 +116,8 @@ export class OpfGooglePayService { } protected setGooglePaymentRequestConfig( - deliveryType: OpfQuickBuyDeliveryType + deliveryType: OpfQuickBuyDeliveryType, + merchantName: string ) { if (deliveryType === OpfQuickBuyDeliveryType.PICKUP) { this.googlePaymentClientOptions = { @@ -139,7 +140,7 @@ export class OpfGooglePayService { }; this.googlePaymentRequest = this.initialGooglePaymentRequest; } - + this.googlePaymentRequest.merchantInfo.merchantName = merchantName; this.updateGooglePaymentClient(); } @@ -261,79 +262,82 @@ export class OpfGooglePayService { handleSingleProductTransaction(): Observable { this.transactionDetails.context = OpfQuickBuyLocation.PRODUCT; - return this.opfQuickBuyService - .getQuickBuyDeliveryInfo(this.transactionDetails.context) - .pipe( - switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => { - this.transactionDetails.deliveryInfo = deliveryInfo; - this.setGooglePaymentRequestConfig(deliveryInfo.type); - - return this.currentProductService.getProduct().pipe( - take(1), - switchMap((product: Product | null) => { - const count = this.itemCounterService.getCounter(); - this.transactionDetails.product = product as Product; - this.transactionDetails.quantity = count; - return this.opfCartHandlerService - .addProductToCart( - product?.code || '', - count, - this.transactionDetails.deliveryInfo?.pickupDetails?.name - ) - .pipe( - tap(() => { - this.setDeliveryMode( - undefined, - this.transactionDetails.deliveryInfo?.type - ); - this.updateTransactionInfo({ - totalPrice: this.estimateTotalPrice( - product?.price?.value - ), - currencyCode: - product?.price?.currencyIso || - this.initialTransactionInfo.currencyCode, - totalPriceStatus: - this.initialTransactionInfo.totalPriceStatus, - }); - }) - ); - }) - ); - }) - ); - } - - handleActiveCartTransaction(): Observable { - this.transactionDetails.context = OpfQuickBuyLocation.CART; - - return this.opfQuickBuyService - .getQuickBuyDeliveryInfo(this.transactionDetails.context) - .pipe( - switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => { - this.transactionDetails.deliveryInfo = deliveryInfo; - this.setGooglePaymentRequestConfig(deliveryInfo.type); - - return this.setDeliveryMode(undefined, deliveryInfo.type).pipe( - switchMap(() => - this.opfCartHandlerService.getCurrentCart().pipe( - take(1), - tap((cart: Cart) => { - this.transactionDetails.cart = cart; + return forkJoin({ + deliveryInfo: this.opfQuickBuyService.getQuickBuyDeliveryInfo( + this.transactionDetails.context as OpfQuickBuyLocation + ), + merchantName: this.opfQuickBuyService.getMerchantName(), + }).pipe( + switchMap(({ deliveryInfo, merchantName }) => { + this.transactionDetails.deliveryInfo = deliveryInfo; + this.setGooglePaymentRequestConfig(deliveryInfo.type, merchantName); + return this.currentProductService.getProduct().pipe( + take(1), + switchMap((product: Product | null) => { + const count = this.itemCounterService.getCounter(); + this.transactionDetails.product = product as Product; + this.transactionDetails.quantity = count; + return this.opfCartHandlerService + .addProductToCart( + product?.code || '', + count, + this.transactionDetails.deliveryInfo?.pickupDetails?.name + ) + .pipe( + tap(() => { + this.setDeliveryMode( + undefined, + this.transactionDetails.deliveryInfo?.type + ); this.updateTransactionInfo({ - totalPrice: `${cart.totalPrice?.value}`, + totalPrice: this.estimateTotalPrice(product?.price?.value), currencyCode: - cart.totalPrice?.currencyIso || + product?.price?.currencyIso || this.initialTransactionInfo.currencyCode, totalPriceStatus: this.initialTransactionInfo.totalPriceStatus, }); }) - ) + ); + }) + ); + }) + ); + } + + handleActiveCartTransaction(): Observable { + this.transactionDetails.context = OpfQuickBuyLocation.CART; + + return forkJoin({ + deliveryInfo: this.opfQuickBuyService.getQuickBuyDeliveryInfo( + this.transactionDetails.context as OpfQuickBuyLocation + ), + merchantName: this.opfQuickBuyService.getMerchantName(), + }).pipe( + switchMap(({ deliveryInfo, merchantName }) => { + this.transactionDetails.deliveryInfo = deliveryInfo; + this.setGooglePaymentRequestConfig(deliveryInfo.type, merchantName); + + return this.setDeliveryMode(undefined, deliveryInfo.type).pipe( + switchMap(() => + this.opfCartHandlerService.getCurrentCart().pipe( + take(1), + tap((cart: Cart) => { + this.transactionDetails.cart = cart; + this.updateTransactionInfo({ + totalPrice: `${cart.totalPrice?.value}`, + currencyCode: + cart.totalPrice?.currencyIso || + this.initialTransactionInfo.currencyCode, + totalPriceStatus: + this.initialTransactionInfo.totalPriceStatus, + }); + }) ) - ); - }) - ); + ) + ); + }) + ); } initTransaction(): void { diff --git a/integration-libs/opf/base/root/model/opf-quick-buy.model.ts b/integration-libs/opf/base/root/model/opf-quick-buy.model.ts index 5f9d4e894a5..ceba5cb1d08 100644 --- a/integration-libs/opf/base/root/model/opf-quick-buy.model.ts +++ b/integration-libs/opf/base/root/model/opf-quick-buy.model.ts @@ -159,4 +159,4 @@ export enum ApplePayShippingType { SERVICE_PICKUP = 'servicePickup', } -export const defaultMerchantName: string = ''; \ No newline at end of file +export const defaultMerchantName: string = 'Store'; From 1ea33545b1d24670e817969498603aece614a2a3 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 22 Mar 2024 15:45:45 -0400 Subject: [PATCH 5/6] fix unit test --- .../opf-quick-buy.service.spec.ts | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts b/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts index 575be9f2fb1..c0c66522ebd 100644 --- a/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts +++ b/integration-libs/opf/base/components/opf-quick-buy/opf-quick-buy.service.spec.ts @@ -269,23 +269,22 @@ describe('OpfQuickBuyService', () => { ); expect(result).toBe(config); }); - - describe('getMerchantName', () => { - it('should return baseSite name', (done) => { - const mockName = 'Electronics store'; - baseSiteServiceMock.get.and.returnValue(of({ name: mockName })); - service.getMerchantName().subscribe((merchantName) => { - expect(merchantName).toBe(mockName); - done(); - }); + }); + describe('getMerchantName', () => { + it('should return baseSite name', (done) => { + const mockName = 'Electronics store'; + baseSiteServiceMock.get.and.returnValue(of({ name: mockName })); + service.getMerchantName().subscribe((merchantName) => { + expect(merchantName).toBe(mockName); + done(); }); - it('should return default MerchantName name when empty', (done) => { - const mockName = undefined; - baseSiteServiceMock.get.and.returnValue(of({ name: mockName })); - service.getMerchantName().subscribe((merchantName) => { - expect(merchantName).toBe(defaultMerchantName); - done(); - }); + }); + it('should return default MerchantName name when empty', (done) => { + const mockName = undefined; + baseSiteServiceMock.get.and.returnValue(of({ name: mockName })); + service.getMerchantName().subscribe((merchantName) => { + expect(merchantName).toBe(defaultMerchantName); + done(); }); }); }); From 739367611fd8125cdcc293b98d71af9b5bdbd87b Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Sun, 24 Mar 2024 21:40:21 -0400 Subject: [PATCH 6/6] remove certificate --- .gitignore | 2 +- projects/storefrontapp/project.json | 3 +- ...eveloper-merchantid-domain-association.txt | 75 ------------------- 3 files changed, 2 insertions(+), 78 deletions(-) delete mode 100644 projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt diff --git a/.gitignore b/.gitignore index 880ebeb2d75..93674d1220e 100644 --- a/.gitignore +++ b/.gitignore @@ -57,7 +57,7 @@ scripts/install/config.sh /libpeerconnection.log /typings /.nx -# .well-known/ +.well-known/ # Logs npm-debug.log diff --git a/projects/storefrontapp/project.json b/projects/storefrontapp/project.json index ae77920488a..7fa15f719bf 100644 --- a/projects/storefrontapp/project.json +++ b/projects/storefrontapp/project.json @@ -153,8 +153,7 @@ "serve": { "executor": "@angular-builders/custom-webpack:dev-server", "options": { - "buildTarget": "storefrontapp:build", - "disableHostCheck": true + "buildTarget": "storefrontapp:build" }, "configurations": { "production": { diff --git a/projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt b/projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt deleted file mode 100644 index bf893ab2c8d..00000000000 --- a/projects/storefrontapp/src/.well-known/apple-developer-merchantid-domain-association.txt +++ /dev/null @@ -1,75 +0,0 @@ -MIIQgQYJKoZIhvcNAQcCoIIQcjCCEG4CAQExCzAJBgUrDgMCGgUAMIGPBgkqhkiG9w0BBwGggYEE -f3sidGVhbUlkIjoiRFdGTEVRN0VaNSIsImRvbWFpbiI6InNwYXJ0YWN1cy1kZXYtYXN4MS5lYXN0 -dXMuY2xvdWRhcHAuYXp1cmUuY29tIiwiZGF0ZUNyZWF0ZWQiOiIyMDI0LTAzLTExLDE0OjEwOjQz -IiwidmVyc2lvbiI6MX2ggg0_MIIENDCCAxygAwIBAgIIRzxMYfKZiNQwDQYJKoZIhvcNAQELBQAw -czEtMCsGA1UEAwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQL -DBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMC -VVMwHhcNMjMwNDExMjIyMzU5WhcNMjgwNDA5MjIyMzU4WjBZMTUwMwYDVQQDDCxBcHBsZSBpUGhv -bmUgT1MgUHJvdmlzaW9uaW5nIFByb2ZpbGUgU2lnbmluZzETMBEGA1UECgwKQXBwbGUgSW5jLjEL -MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqQ-T801OftoAP_MZt -borJ1sPSjvvdm_fAS-H7SOnN8ywYMsbuLNMxMBfRqETC-alko-KO66ung4IsLcGGAq8EV1OZTQw3 -kEN2dntunBtrFbHkAf2dnBWbd3_A9CPRrqCyRPohS9JNiLxqmAPRUaV08l_u-75ZgUfjT2J7uWOl -T9KOyhBOMVWN7VyRR7b2N9PfNt8sW88XTk3DBVE9_BlwnwD4tYnX18swFeu51u1Ne5LMXYDLDDsr -Rw3IW3F7tMHbxtdn0NdThpCXAd7_Br0dmYWk18_u6kHkXv4KZ3AgFR2U7jRm7kJqz9-j9RBKxJiy -1VxoSO37mqdw_haZsxf1AgMBAAGjgeUwgeIwDAYDVR0TAQH_BAIwADAfBgNVHSMEGDAWgBRv8ZUY -YlzgyPHF7WwYyeDTZFKYIDBABggrBgEFBQcBAQQ0MDIwMAYIKwYBBQUHMAGGJGh0dHA6Ly9vY3Nw -LmFwcGxlLmNvbS9vY3NwMDMtYWlwY2EwNzAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmFw -cGxlLmNvbS9haXBjYS5jcmwwHQYDVR0OBBYEFE-zO0h9RI1qIItA5UMxgvmGu4fiMA4GA1UdDwEB -_wQEAwIHgDAPBgkqhkiG92NkBjoEAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQA_jhwU4vCy9v91URbG -HQMZjB234-ewkxiLvqlyxQSEbg7ZexxfIzojL6v8gudymdsjoHXDYk6EZ8uOwCxOxuKXD-HQB19c -2Iz3e5DtHdAA3rNnAhdtWz7zabLH08lXZNGuAkbMC3ojQtBy_XUPp1kL_tVUZkW7oeW9xT0LQBDL -X36J8A3fYT6nc0F4ZVZ5lYZlG2b1DE4Krm5f7UdSsPJndgGkoi-Fc1YVIBGpVxIFa7yw9xtGOF01 -__-YxmkJE2UfTcW7K627rOC0gC7eAbO-EifxKZGHLKblYZU_rn41C1wuDk3yNk-xgQjLr9liXq3v -Omkgm6B4u54ffEqBbnolMIIERDCCAyygAwIBAgIIXGPK5Eo3U8kwDQYJKoZIhvcNAQELBQAwYjEL -MAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTE3MDUxMDIxMjczMFoX -DTMwMTIzMTAwMDAwMFowczEtMCsGA1UEAwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUg -SW5jLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJRWoBDz6D -BIbH_L_cXvAege4XMHNjJi7ePXokzZM-TzlHunW-88DS8Vmiqx_-CoY82S2aB_IOa7kpkRpfIgqL -8XJYBa5MS0TFeaeAPLCI4IwMJ4RdGeWHGTbL48V2t7D0QXJR9AVcg0uibaZRuPEm33terWUMxrKY -UYy7fRtMwU7ICMfS7WQLtN0bjU9AfRuPSJaSW_PQmH7ZvKQZDplhu0FdAcxbd3p9JNDc01P_w9zF -lCy2Wk2OGCM5vdnGUj7R8vQliqEqh_3YDEYpUf_tF2yJJWuHv4ppFJ93n8MVt2iziEW9hOYGAkFk -D60qKLgVyeCsp4q6cgQ0sniM-LKFAgMBAAGjgewwgekwDwYDVR0TAQH_BAUwAwEB_zAfBgNVHSME -GDAWgBQr0GlHlHYJ_vRrjS5ApvdHTX8IXjBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0 -dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYXBwbGVyb290Y2EwLgYDVR0fBCcwJTAjoCGgH4Yd -aHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5jcmwwHQYDVR0OBBYEFG_xlRhiXODI8cXtbBjJ4NNk -UpggMA4GA1UdDwEB_wQEAwIBBjAQBgoqhkiG92NkBgISBAIFADANBgkqhkiG9w0BAQsFAAOCAQEA -Os-smI2-kiAhCa2V87FcIfo2LVcgRHRzZJIIs5as922X-ls0OCfPEkbTPBHwB8mZkLHR6BEJpeOl -a2xjCD-eJfrVmZxM5uXOjrJNaOyLq6OiT4oRFT7cFCscxkS2b2fFW0-VKS2HXD_cgx53T-3aVKct -5xOBwWPEVAsbSwpqKCII1DeSfH9nKF-vPT-3rFkdODRkWu4zShlCRCnEyhhr4cFTLS30TcIV9jMy -GHjxJm-KTeuUTKPo_w-zA4tl2usu2GVQn9yfit8xqIRU3FJSQdKyEx0xRkeIXz7uw_KMIwSV66yK -PoJsBp8u44tDmmJbNA30mc8s7rpyhhkjpfyOtTCCBLswggOjoAMCAQICAQIwDQYJKoZIhvcNAQEF -BQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTA2MDQyNTIx -NDAzNloXDTM1MDIwOTIxNDAzNlowYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4x -JjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBS -b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5JGpCR-R2x5HUOsF7V55hC3r -NqJXTFXsixmJ3vlLbPUHqyIwAugYPvhQCdN_QaiY-dHKZpwkaxHQo7vkGyrDH5WeegykR4tb1BY3 -M8vED03OFGnRyRly9V0O1X9fm_IlA7pVj01dDfFkNSMVSxVZHbOU9_acns9QusFYUGePCLQg98us -LCBvcLY_ATCMt0PPD5098ytJKBrI_s61uQ7ZXhzWyz21Oq30Dw4AkguxIRYudNU8DdtiFqujcZJH -U1XBry9Bs_j743DN5qNMRX4fTGtQlkGJxHRiCxCDQYczioGxMFjsWgQyjGizjx3eZXP_Z15lvEnY -dp8zFGWhd5TJLQIDAQABo4IBejCCAXYwDgYDVR0PAQH_BAQDAgEGMA8GA1UdEwEB_wQFMAMBAf8w -HQYDVR0OBBYEFCvQaUeUdgn-9GuNLkCm90dNfwheMB8GA1UdIwQYMBaAFCvQaUeUdgn-9GuNLkCm -90dNfwheMIIBEQYDVR0gBIIBCDCCAQQwggEABgkqhkiG92NkBQEwgfIwKgYIKwYBBQUHAgEWHmh0 -dHBzOi8vd3d3LmFwcGxlLmNvbS9hcHBsZWNhLzCBwwYIKwYBBQUHAgIwgbYagbNSZWxpYW5jZSBv -biB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhl -IHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNl -cnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjAN -BgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14t-2Mm9zzd5vydtJ3ME_BH4WDhRuZPUc38qmbQI4s1LGQ -Eti-9HOb7tJkD8t5TzTYoj75eP9ryAfsfTmDi1Mg0zjEsb-aTwpr_yv8WacFCXwXQFYRHnTTt4sj -O0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UXF6jcfiI1yiXV2Q_Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4 -REjwYDieFfU9JmcgijNq9w2Cz97roy_5U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU-12TZ_wYdV2aeZ -uTJC-9jVcZ5-oVK3G72TQiQSKscPHbZNnF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAoUwggKBAgEB -MH8wczEtMCsGA1UEAwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYD -VQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UE -BhMCVVMCCEc8TGHymYjUMAkGBSsOAwIaBQCggdwwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc -BgkqhkiG9w0BCQUxDxcNMjQwMzExMTQxMDQzWjAjBgkqhkiG9w0BCQQxFgQUBY6mjB2KcxgJq_rC -XD12rRNoMYYwKQYJKoZIhvcNAQk0MRwwGjAJBgUrDgMCGgUAoQ0GCSqGSIb3DQEBAQUAMFIGCSqG -SIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcG -BSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIIBAERONkrymDkkBVURVpO4Ltzh -xE1ATBTt3s6Cs1SDei7cvOQIIFg4L4PSwZCl0kPVkfEN9I2pooD_zlsWefHr4seEY912eq62jwpN -XIbSx_HKfAFm9lO9HXdMgmUVa9c2Ws7_tQVreq7rLPW5I9b1mTlLKsuJ4FG31YKwxQ6VHjcgtrEU -GXuqLUh-LXGnm9a7nf0DFs-XF547SMZcNZTElCjUothfCHpX1UpSn4kJR_5hrBFaJKTwGmPrQ3Z3 -qinRhdRvcZWMOHXkoyQAFPlwry1LUw9SgfY3wKb6BD__mMtRP2HYLi-GaEsCeyrhMpfg5_6qchHI -tI9XSY1jHDDwYso