diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/DeniedHttpHeaders.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/DeniedHttpHeaders.java new file mode 100644 index 0000000000..b66bc05866 --- /dev/null +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/DeniedHttpHeaders.java @@ -0,0 +1,77 @@ +/* + * Copyright 2021 Adobe. All rights reserved. + * + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package com.adobe.cq.commerce.core.components.client; + +import java.util.Set; + +import com.google.common.collect.ImmutableSet; + +public interface DeniedHttpHeaders { + /** + * A list of HTTP headers that cannot be overriden when configuring a list of custom HTTP headers + */ + final Set DENYLIST = ImmutableSet.of(org.apache.http.HttpHeaders.ACCEPT, + org.apache.http.HttpHeaders.ACCEPT_CHARSET, + org.apache.http.HttpHeaders.ACCEPT_ENCODING, + org.apache.http.HttpHeaders.ACCEPT_LANGUAGE, + org.apache.http.HttpHeaders.ACCEPT_RANGES, + org.apache.http.HttpHeaders.AGE, + org.apache.http.HttpHeaders.ALLOW, + org.apache.http.HttpHeaders.AUTHORIZATION, + org.apache.http.HttpHeaders.CACHE_CONTROL, + org.apache.http.HttpHeaders.CONNECTION, + org.apache.http.HttpHeaders.CONTENT_ENCODING, + org.apache.http.HttpHeaders.CONTENT_LANGUAGE, + org.apache.http.HttpHeaders.CONTENT_LENGTH, + org.apache.http.HttpHeaders.CONTENT_LOCATION, + org.apache.http.HttpHeaders.CONTENT_MD5, + org.apache.http.HttpHeaders.CONTENT_RANGE, + org.apache.http.HttpHeaders.CONTENT_TYPE, + org.apache.http.HttpHeaders.DATE, + org.apache.http.HttpHeaders.DAV, + org.apache.http.HttpHeaders.DEPTH, + org.apache.http.HttpHeaders.DESTINATION, + org.apache.http.HttpHeaders.ETAG, + org.apache.http.HttpHeaders.EXPECT, + org.apache.http.HttpHeaders.EXPIRES, + org.apache.http.HttpHeaders.FROM, + org.apache.http.HttpHeaders.HOST, + org.apache.http.HttpHeaders.IF, + org.apache.http.HttpHeaders.IF_MATCH, + org.apache.http.HttpHeaders.IF_MODIFIED_SINCE, + org.apache.http.HttpHeaders.IF_NONE_MATCH, + org.apache.http.HttpHeaders.IF_RANGE, + org.apache.http.HttpHeaders.IF_UNMODIFIED_SINCE, + org.apache.http.HttpHeaders.LAST_MODIFIED, + org.apache.http.HttpHeaders.LOCATION, + org.apache.http.HttpHeaders.LOCK_TOKEN, + org.apache.http.HttpHeaders.MAX_FORWARDS, + org.apache.http.HttpHeaders.OVERWRITE, + org.apache.http.HttpHeaders.PRAGMA, + org.apache.http.HttpHeaders.PROXY_AUTHENTICATE, + org.apache.http.HttpHeaders.PROXY_AUTHORIZATION, + org.apache.http.HttpHeaders.RANGE, + org.apache.http.HttpHeaders.REFERER, + org.apache.http.HttpHeaders.RETRY_AFTER, + org.apache.http.HttpHeaders.SERVER, + org.apache.http.HttpHeaders.STATUS_URI, + org.apache.http.HttpHeaders.TE, + org.apache.http.HttpHeaders.TIMEOUT, + org.apache.http.HttpHeaders.TRAILER, + org.apache.http.HttpHeaders.TRANSFER_ENCODING, + org.apache.http.HttpHeaders.UPGRADE, + org.apache.http.HttpHeaders.USER_AGENT, + org.apache.http.HttpHeaders.VARY, + org.apache.http.HttpHeaders.VIA, + org.apache.http.HttpHeaders.WARNING, + org.apache.http.HttpHeaders.WWW_AUTHENTICATE, + "Store", + "Preview-Version"); +} diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClient.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClient.java index 37ed74fad0..32e00b8152 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClient.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClient.java @@ -16,9 +16,13 @@ import java.time.OffsetDateTime; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.TimeZone; +import java.util.stream.Collectors; import javax.servlet.http.Cookie; @@ -69,6 +73,8 @@ public class MagentoGraphqlClient { private RequestOptions requestOptions; + private List
httpHeaders; + /** * Instantiates and returns a new MagentoGraphqlClient. * This method returns null if the client cannot be instantiated.
@@ -150,6 +156,7 @@ private MagentoGraphqlClient(Resource resource, Page page, SlingHttpServletReque graphqlClient = configurationResource.adaptTo(GraphqlClient.class); } else { LOGGER.debug("Crafting a configuration resource and attempting to get a GraphQL client from it..."); + // The Context-Aware Configuration API does return a ValueMap with all the collected properties from /conf and /libs, // but if you ask it for a resource via ConfigurationResourceResolver#getConfigurationResource() you get the resource that // resolves first (e.g. /conf/.../settings/cloudonfigs/commerce). This resource might not contain the properties @@ -171,7 +178,7 @@ private MagentoGraphqlClient(Resource resource, Page page, SlingHttpServletReque .withDataFetchingPolicy(DataFetchingPolicy.CACHE_FIRST); requestOptions.withCachingStrategy(cachingStrategy); - List
headers = new ArrayList<>(); + List
headers = configuration.size() > 0 ? getCustomHttpHeaders(configuration) : new ArrayList<>(); String storeCode; if (configuration.size() > 0) { @@ -215,6 +222,30 @@ private MagentoGraphqlClient(Resource resource, Page page, SlingHttpServletReque if (!headers.isEmpty()) { requestOptions.withHeaders(headers); } + + this.httpHeaders = headers; + } + + private List
getCustomHttpHeaders(ComponentsConfiguration configuration) { + List
headers = new ArrayList<>(); + + String[] customHeaders = configuration.get("httpHeaders", String[].class); + + if (customHeaders != null) { + headers = Arrays.stream(customHeaders) + .map(headerConfig -> { + String name = headerConfig.substring(0, headerConfig.indexOf('=')); + if (DeniedHttpHeaders.DENYLIST.stream().noneMatch(name::equalsIgnoreCase)) { + String value = headerConfig.substring(headerConfig.indexOf('=') + 1, headerConfig.length()); + return new BasicHeader(name, value); + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + return headers; } private Long getTimeWarpEpoch(SlingHttpServletRequest request) { @@ -272,6 +303,15 @@ public GraphqlClientConfiguration getConfiguration() { return graphqlClient.getConfiguration(); } + /** + * Returns the list of custom HTTP headers used by the GraphQL client. + * + * @return a {@link Map} with header names as keys and header values as values + */ + public Map getHttpHeaders() { + return httpHeaders.stream().collect(Collectors.toMap(Header::getName, Header::getValue)); + } + private String readFallBackConfiguration(Resource resource, String propertyName) { InheritanceValueMap properties; diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/package-info.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/package-info.java index 563e6799dc..bcc507bc40 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/package-info.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/client/package-info.java @@ -12,7 +12,7 @@ * ******************************************************************************/ -@Version("1.6.0") +@Version("1.7.0") package com.adobe.cq.commerce.core.components.client; import org.osgi.annotation.versioning.Version; \ No newline at end of file diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterImpl.java index 3f4ff3f8ed..c04a8ac3a3 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterImpl.java @@ -14,6 +14,8 @@ package com.adobe.cq.commerce.core.components.internal.models.v1.storeconfigexporter; +import java.util.Map; + import javax.annotation.PostConstruct; import javax.inject.Inject; @@ -31,6 +33,9 @@ import com.adobe.cq.commerce.graphql.client.GraphqlClientConfiguration; import com.adobe.cq.commerce.graphql.client.HttpMethod; import com.day.cq.wcm.api.Page; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; @Model( adaptables = SlingHttpServletRequest.class, @@ -56,6 +61,7 @@ public class StoreConfigExporterImpl implements StoreConfigExporter { private String graphqlEndpoint = "/magento/graphql"; private HttpMethod method = HttpMethod.POST; private Page storeRootPage; + private Map httpHeaders; @PostConstruct void initModel() { @@ -70,6 +76,7 @@ void initModel() { if (magentoGraphqlClient != null) { GraphqlClientConfiguration graphqlClientConfiguration = magentoGraphqlClient.getConfiguration(); method = graphqlClientConfiguration.httpMethod(); + httpHeaders = magentoGraphqlClient.getHttpHeaders(); } } @@ -88,6 +95,19 @@ public String getMethod() { return method.toString(); } + @Override + public String getHttpHeaders() { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode objectNode = mapper.createObjectNode(); + httpHeaders.entrySet().stream().forEach(entry -> objectNode.put(entry.getKey(), entry.getValue())); + try { + return mapper.writeValueAsString(objectNode); + } catch (JsonProcessingException e) { + LOGGER.error(e.getMessage(), e); + return "{}"; + } + } + @Override public String getStoreRootUrl() { if (storeRootPage == null) { diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/StoreConfigExporter.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/StoreConfigExporter.java index 3e4231a4ee..2956be6f1f 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/StoreConfigExporter.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/StoreConfigExporter.java @@ -35,4 +35,9 @@ public interface StoreConfigExporter { * @return The URL of the storefront homepage */ String getStoreRootUrl(); + + /** + * @return the list of custom HTTP headers configured in addition to the standard ones. This list is in JSON format. + */ + String getHttpHeaders(); } diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/package-info.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/package-info.java index 538fa7c066..553f8578c6 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/package-info.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/models/storeconfigexporter/package-info.java @@ -12,7 +12,7 @@ * ******************************************************************************/ -@Version("2.0.0") +@Version("3.0.0") package com.adobe.cq.commerce.core.components.models.storeconfigexporter; import org.osgi.annotation.versioning.Version; \ No newline at end of file diff --git a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClientTest.java b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClientTest.java index 479514f89a..4111d77180 100644 --- a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClientTest.java +++ b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/client/MagentoGraphqlClientTest.java @@ -105,6 +105,34 @@ private void executeAndCheck(boolean withStoreHeader, MagentoGraphqlClient clien Mockito.verify(graphqlClient).execute(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.argThat(matcher)); } + @Test + public void testCustomHeaders() { + + List
expectedHeaders = new ArrayList<>(); + expectedHeaders.add(new BasicHeader("Store", "my-store")); + expectedHeaders.add(new BasicHeader("customHeader-1", "value1")); + expectedHeaders.add(new BasicHeader("customHeader-2", "value2")); + expectedHeaders.add(new BasicHeader("customHeader-3", "=value3=3=3=3=3")); + + ValueMap MOCK_CONFIGURATION_CUSTOM_HEADERS = new ValueMapDecorator(ImmutableMap.of("cq:graphqlClient", "default", "magentoStore", + "my-store", "httpHeaders", new String[] { "customHeader-1=value1", "customHeader-2=value2", "customHeader-3==value3=3=3=3=3", + "Authorization=099sx8x7v1" })); + ComponentsConfiguration MOCK_CONFIGURATION_OBJECT = new ComponentsConfiguration(MOCK_CONFIGURATION_CUSTOM_HEADERS); + + Page pageWithConfig = Mockito.spy(context.pageManager().getPage(PAGE_A)); + Resource pageResource = Mockito.spy(pageWithConfig.adaptTo(Resource.class)); + when(pageWithConfig.adaptTo(Resource.class)).thenReturn(pageResource); + when(pageResource.adaptTo(GraphqlClient.class)).thenReturn(graphqlClient); + when(pageResource.adaptTo(ComponentsConfiguration.class)).thenReturn(MOCK_CONFIGURATION_OBJECT); + + RequestOptionsMatcher matcher = new RequestOptionsMatcher(expectedHeaders, HttpMethod.GET); + MagentoGraphqlClient client = MagentoGraphqlClient.create(pageWithConfig.adaptTo(Resource.class), pageWithConfig); + client.execute("{dummy}", HttpMethod.GET); + graphqlClient.getConfiguration(); + + Mockito.verify(graphqlClient).execute(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.argThat(matcher)); + } + @Test public void testMagentoStorePropertyWithConfigBuilder() { Page pageWithConfig = Mockito.spy(context.pageManager().getPage(PAGE_A)); @@ -318,10 +346,16 @@ public boolean matches(Object obj) { return false; } + List
actualHeaders = requestOptions.getHeaders(); + + if (headers.size() != actualHeaders.size()) { + return false; + } + for (Header header : headers) { - if (!requestOptions.getHeaders() + if (actualHeaders .stream() - .anyMatch(h -> h.getName() + .noneMatch(h -> h.getName() .equals(header.getName()) && h.getValue() .equals(header.getValue()))) { return false; diff --git a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterTest.java b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterTest.java index f69b1a0fe1..2e3a358d8a 100644 --- a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterTest.java +++ b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/storeconfigexporter/StoreConfigExporterTest.java @@ -14,6 +14,8 @@ package com.adobe.cq.commerce.core.components.internal.models.v1.storeconfigexporter; +import java.io.IOException; + import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.scripting.SlingBindings; @@ -31,6 +33,8 @@ import com.adobe.cq.launches.api.Launch; import com.day.cq.wcm.api.Page; import com.day.cq.wcm.scripting.WCMBindingsConstants; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import io.wcm.testing.mock.aem.junit.AemContext; @@ -43,7 +47,7 @@ public class StoreConfigExporterTest { private static final ValueMap MOCK_CONFIGURATION = new ValueMapDecorator( ImmutableMap.of("magentoGraphqlEndpoint", "/my/magento/graphql", "magentoStore", "my-magento-store", "cq:graphqlClient", - "my-graphql-client")); + "my-graphql-client", "httpHeaders", new String[] { "customHeader-1=value1", "customHeader-2=value2" })); private static final ComponentsConfiguration MOCK_CONFIGURATION_OBJECT = new ComponentsConfiguration(MOCK_CONFIGURATION); @Rule @@ -122,6 +126,19 @@ public void testGetStoreRootUrl() { Assert.assertEquals("/content/pageB.html", storeConfigExporter.getStoreRootUrl()); } + @Test + public void testCustomHttpHeaders() throws IOException { + setupWithPage("/content/pageH", HttpMethod.POST); + StoreConfigExporterImpl storeConfigExporter = context.request().adaptTo(StoreConfigExporterImpl.class); + String expectedHeaders = "{\"Store\":\"my-magento-store\",\"customHeader-1\":\"value1\",\"customHeader-2\":\"value2\"}"; + + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualNode = mapper.readTree(storeConfigExporter.getHttpHeaders()); + JsonNode expectedNode = mapper.readTree(expectedHeaders); + + Assert.assertEquals("The custom HTTP headers are correctly parsed", expectedNode, actualNode); + } + private void setupWithPage(String pagePath, HttpMethod method) { Page page = context.pageManager().getPage(pagePath); SlingBindings slingBindings = (SlingBindings) context.request().getAttribute(SlingBindings.class.getName()); diff --git a/react-components/src/components/App/app.js b/react-components/src/components/App/app.js index f154681032..7a0b0fda7c 100644 --- a/react-components/src/components/App/app.js +++ b/react-components/src/components/App/app.js @@ -25,7 +25,7 @@ import useReferrerEvent from '../../utils/useReferrerEvent'; import usePageEvent from '../../utils/usePageEvent'; const App = props => { - const { graphqlEndpoint, storeView = 'default', graphqlMethod = 'POST' } = useConfigContext(); + const { graphqlEndpoint, storeView = 'default', graphqlMethod = 'POST', headers = {} } = useConfigContext(); useCustomUrlEvent(); useReferrerEvent(); usePageEvent(); @@ -35,7 +35,7 @@ const App = props => { graphqlAuthLink, new HttpLink({ uri: graphqlEndpoint, - headers: { Store: storeView }, + headers: { ...headers, Store: storeView }, useGETForQueries: graphqlMethod === 'GET', fetch: compressQueryFetch }) diff --git a/react-components/src/context/ConfigContext.js b/react-components/src/context/ConfigContext.js index abbfbd0b91..6aa7cf874e 100644 --- a/react-components/src/context/ConfigContext.js +++ b/react-components/src/context/ConfigContext.js @@ -25,6 +25,7 @@ const ConfigContextProvider = props => { ConfigContextProvider.propTypes = { config: PropTypes.shape({ storeView: PropTypes.string.isRequired, + headers: PropTypes.object, graphqlEndpoint: PropTypes.string.isRequired, graphqlMethod: PropTypes.oneOf(['GET', 'POST']).isRequired, mountingPoints: PropTypes.shape({ diff --git a/ui.apps/package-lock.json b/ui.apps/package-lock.json index 628c716a54..690b70cb39 100644 --- a/ui.apps/package-lock.json +++ b/ui.apps/package-lock.json @@ -1787,7 +1787,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -2162,7 +2162,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -2278,7 +2278,7 @@ }, "component-emitter": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, @@ -2329,7 +2329,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -2770,7 +2770,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -2806,7 +2806,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -3018,7 +3018,7 @@ }, "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -3027,7 +3027,7 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -3036,7 +3036,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -3059,7 +3059,7 @@ }, "extend-shallow": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { @@ -3105,7 +3105,7 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -3203,7 +3203,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -3537,7 +3537,7 @@ }, "is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { @@ -3546,7 +3546,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -3821,7 +3821,7 @@ }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -3898,7 +3898,7 @@ }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -4580,7 +4580,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -4591,7 +4591,7 @@ }, "fill-range": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { @@ -4603,7 +4603,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -4620,7 +4620,7 @@ }, "is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { @@ -4629,7 +4629,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -4640,7 +4640,7 @@ }, "to-regex-range": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { @@ -5104,7 +5104,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -5119,7 +5119,7 @@ }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -5959,7 +5959,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -6056,7 +6056,7 @@ }, "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -6065,7 +6065,7 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -6074,7 +6074,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -6148,7 +6148,7 @@ }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -6182,7 +6182,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -6227,7 +6227,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -6255,7 +6255,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } @@ -6378,7 +6378,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -6589,7 +6589,7 @@ }, "is-wsl": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/is-wsl/-/is-wsl-1.1.0.tgz", "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true }, @@ -6743,7 +6743,7 @@ }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-release/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/clientlibs/common/js/CommerceGraphqlApi.js b/ui.apps/src/main/content/jcr_root/apps/core/cif/clientlibs/common/js/CommerceGraphqlApi.js index 5089b39590..5f8647e5f7 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/clientlibs/common/js/CommerceGraphqlApi.js +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/clientlibs/common/js/CommerceGraphqlApi.js @@ -25,6 +25,7 @@ class CommerceGraphqlApi { this.endpoint = props.endpoint; this.storeView = props.storeView; this.method = props.graphqlMethod; + this.headers = props.headers; } async _fetch(url, params) { @@ -47,6 +48,7 @@ class CommerceGraphqlApi { let params = { method: this.method === 'GET' && !ignoreCache ? 'GET' : 'POST', headers: { + ...this.headers, 'Content-Type': 'application/json', Store: this.storeView } @@ -164,8 +166,13 @@ class CommerceGraphqlApi { (function() { function onDocumentReady() { - const { storeView, graphqlEndpoint, graphqlMethod } = document.querySelector('body').dataset; - window.CIF.CommerceGraphqlApi = new CommerceGraphqlApi({ endpoint: graphqlEndpoint, storeView, graphqlMethod }); + const { storeView, graphqlEndpoint, graphqlMethod, httpHeaders } = document.querySelector('body').dataset; + window.CIF.CommerceGraphqlApi = new CommerceGraphqlApi({ + endpoint: graphqlEndpoint, + storeView, + graphqlMethod, + headers: JSON.parse(httpHeaders) + }); } if (document.readyState !== 'loading') { diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/page/v1/page/page.html b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/page/v1/page/page.html index 2e8667a9aa..0088d0186d 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/page/v1/page/page.html +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/page/v1/page/page.html @@ -1,15 +1,15 @@ - + data-graphql-method="${storeView.method}" + data-http-headers="${storeView.httpHeaders}">