diff --git a/packages/pwa-kit-runtime/CHANGELOG.md b/packages/pwa-kit-runtime/CHANGELOG.md index 5ad0585602..b570afbca1 100644 --- a/packages/pwa-kit-runtime/CHANGELOG.md +++ b/packages/pwa-kit-runtime/CHANGELOG.md @@ -1,33 +1,52 @@ +## v2.8.1 (Nov 08, 2023) + +- Revert mandatory enforcement of Content-Security-Policy headers. Provide middleware as an opt-in replacement. [#1530](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1530) + +```js +// your-project/app/ssr.js +import {defaultPwaKitSecurityHeaders} from '@salesforce/pwa-kit-runtime/utils/middleware' +const {handler} = runtime.createHandler(options, (app) => { + app.use(defaultPwaKitSecurityHeaders) + // ... +} +``` + ## v2.8.0 (Nov 03, 2023) -- Move Content-Security-Policy logic into pwa-kit-runtime [#1491](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1491) + +- Move Content-Security-Policy logic into pwa-kit-runtime [#1491](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1491) + ## v2.7.4 (Aug 28, 2023) + ## v2.7.3 (Jun 20, 2023) -- Support Node 18 and NPM 9. [#1265](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1265) + +- Support Node 18 and NPM 9. [#1265](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1265) + ## v2.7.2 (May 29, 2023) + ## v2.7.1 (May 11, 2023) -- Add optional parameter to override configuration folder used in `getConfig` [#1049](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1049) -- Moved the MRT reference app to the SDKs, so that we can verify eg. Node support [#966](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/966) +- Add optional parameter to override configuration folder used in `getConfig` [#1049](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1049) +- Moved the MRT reference app to the SDKs, so that we can verify eg. Node support [#966](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/966) ## v2.7.0 (Mar 03, 2023) -- Support Node 16 [#965](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/965) +- Support Node 16 [#965](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/965) ## v2.6.0 (Jan 25, 2023) -- Security package updates +- Security package updates ## v2.5.0 (Jan 05, 2023) -- Logging cid from res header isntead of req in local development [#821](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/821) -- Replace morgan stream to use console.log [#847](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/847) +- Logging cid from res header isntead of req in local development [#821](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/821) +- Replace morgan stream to use console.log [#847](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/847) ## v2.4.0 (Dec 01, 2022) ## v2.3.0 (Oct 27, 2022) -- Performance: Skip retries when flushing CloudWatch metrics, prioritize returning a response instead. [720](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/720) -- Add Correlation ID to SCAPI requests. [#728](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/728) +- Performance: Skip retries when flushing CloudWatch metrics, prioritize returning a response instead. [720](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/720) +- Add Correlation ID to SCAPI requests. [#728](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/728) ## v2.2.0 (Aug 25, 2022) @@ -35,9 +54,9 @@ ## v2.0.0 (May 16, 2022) -- Drop node 12 support for [#589](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/589) -- Improve test coverage [#550](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/550) -- Make the createApp API idiomatic for Express, fix service-worker loading. [#536](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/536) -- Add environment specific configuration support via `getConfig`. [#447](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/447) -- Remove legacy remote proxy, which allowed remote environments to use proxy configs in package.json [#425](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/425) -- Remove default `body-parser` middleware from express server. [#444](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/444) +- Drop node 12 support for [#589](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/589) +- Improve test coverage [#550](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/550) +- Make the createApp API idiomatic for Express, fix service-worker loading. [#536](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/536) +- Add environment specific configuration support via `getConfig`. [#447](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/447) +- Remove legacy remote proxy, which allowed remote environments to use proxy configs in package.json [#425](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/425) +- Remove default `body-parser` middleware from express server. [#444](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/444) diff --git a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js index 4d60ce9bdf..c9b3a87bbf 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js +++ b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js @@ -11,9 +11,7 @@ import { X_MOBIFY_QUERYSTRING, SET_COOKIE, CACHE_CONTROL, - NO_CACHE, - CONTENT_SECURITY_POLICY, - STRICT_TRANSPORT_SECURITY + NO_CACHE } from './constants' import { catchAndLog, @@ -598,7 +596,6 @@ export const RemoteServerFactory = { // Apply the SSR middleware to any subsequent routes that we expect users // to add in their projects, like in any regular Express app. - app.use(enforceSecurityHeaders) // Must be AFTER prepNonProxyRequest, as they both modify setHeader. app.use(ssrMiddleware) app.use(errorHandlerMiddleware) @@ -919,105 +916,6 @@ export const RemoteServerFactory = { } } -/** - * Patches `res.setHeader` to ensure that the Content-Security-Policy header always includes the - * directives required for PWA Kit to work. - * @param {express.Request} req Express request object - * @param {express.Response} res Express response object - * @param {express.NextFunction} next Express next callback - */ -export const enforceSecurityHeaders = (req, res, next) => { - /** CSP-compatible origin for Runtime Admin. */ - // localhost doesn't include a protocol because different browsers behave differently :\ - const runtimeAdmin = isRemote() ? 'https://runtime.commercecloud.com' : 'localhost:*' - /** - * Map of directive names/values that are required for PWA Kit to work. Array values will be - * merged with user-provided values; boolean values will replace user-provided values. - * @type Object. - */ - const directives = { - 'connect-src': ["'self'", runtimeAdmin], - 'frame-ancestors': [runtimeAdmin], - 'img-src': ["'self'", 'data:'], - 'script-src': ["'self'", "'unsafe-eval'", runtimeAdmin], - // Always upgrade insecure requests when deployed, never upgrade on local dev server - 'upgrade-insecure-requests': isRemote() - } - - const setHeader = res.setHeader - res.setHeader = (name, value) => { - let modifiedValue = value - switch (name?.toLowerCase()) { - case CONTENT_SECURITY_POLICY: { - // If multiple Content-Security-Policy headers are provided, then the most restrictive - // option is chosen for each directive. Therefore, we must modify *all* directives to - // ensure that our required directives will work as expected. - // Ref: https://w3c.github.io/webappsec-csp/#multiple-policies - modifiedValue = Array.isArray(value) - ? value.map((item) => modifyDirectives(item, directives)) - : modifyDirectives(value, directives) - break - } - case STRICT_TRANSPORT_SECURITY: { - // Block setting this header on local development server - it will break things! - if (!isRemote()) return - break - } - default: { - break - } - } - return setHeader.call(res, name, modifiedValue) - } - // Provide an initial CSP (or patch the existing header) - res.setHeader(CONTENT_SECURITY_POLICY, res.getHeader(CONTENT_SECURITY_POLICY) ?? '') - // Provide an initial value for HSTS, if not already set - use default from `helmet` - if (!res.hasHeader(STRICT_TRANSPORT_SECURITY)) { - res.setHeader(STRICT_TRANSPORT_SECURITY, 'max-age=15552000; includeSubDomains') - } - next() -} - -/** - * Updates the given Content-Security-Policy header to include all directives required by PWA Kit. - * @param {string} original Original Content-Security-Policy header - * @returns {string} Modified Content-Security-Policy header - * @private - */ -const modifyDirectives = (original, required) => { - const directives = original - .trim() - .split(';') - .reduce((acc, directive) => { - const text = directive.trim() - if (text) { - const [name, ...values] = text.split(/ +/) - acc[name] = values - } - return acc - }, {}) - - // Add missing required CSP directives - for (const [name, value] of Object.entries(required)) { - if (value === true) { - // Boolean directive (required) - overwrite original value - directives[name] = [] - } else if (value === false) { - // Boolean directive (disabled) - delete original value - delete directives[name] - } else { - // Regular string[] directive - merge values - // Wrapping with `[...new Set(array)]` removes duplicate entries - directives[name] = [...new Set([...(directives[name] ?? []), ...value])] - } - } - - // Re-construct header string - return Object.entries(directives) - .map(([name, values]) => [name, ...values].join(' ')) - .join(';') -} - /** * ExpressJS middleware that processes any non-proxy request passing * through the Express app. diff --git a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js index 21bbd72c4b..ffda35bbcf 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js +++ b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js @@ -4,8 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import {enforceSecurityHeaders, once} from './build-remote-server' -import {CONTENT_SECURITY_POLICY as CSP, STRICT_TRANSPORT_SECURITY} from './constants' +import {once} from './build-remote-server' describe('the once function', () => { test('should prevent a function being called more than once', () => { @@ -19,114 +18,3 @@ describe('the once function', () => { expect(v1).toBe(v2) // The exact same instance }) }) - -describe('Content-Security-Policy enforcement', () => { - let res - - /** Sets the correct values for `isRemote()` to return true */ - const mockProduction = () => { - process.env.AWS_LAMBDA_FUNCTION_NAME = 'testEnforceSecurityHeaders' - } - /** - * Helper to make expected CSP more readable. Asserts that the actual CSP header contains each - * of the expected directives. - * @param {string[]} expected Array of expected CSP directives - */ - const expectDirectives = (expected) => { - const actual = res.getHeader(CSP).split(';') - expect(actual).toEqual(expect.arrayContaining(expected)) - } - - beforeEach(() => { - const headers = {} - res = { - hasHeader: (key) => Object.prototype.hasOwnProperty.call(headers, key), - getHeader: (key) => headers[key], - setHeader: (key, val) => (headers[key] = val) - } - }) - // Revert state detected by `isRemote()` - afterEach(() => delete process.env.AWS_LAMBDA_FUNCTION_NAME) - - test('adds required directives for development', () => { - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, '') - expectDirectives([ - "connect-src 'self' localhost:*", - 'frame-ancestors localhost:*', - "img-src 'self' data:", - "script-src 'self' 'unsafe-eval' localhost:*" - ]) - }) - test('adds required directives for production', () => { - mockProduction() - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, '') - expectDirectives([ - "connect-src 'self' https://runtime.commercecloud.com", - 'frame-ancestors https://runtime.commercecloud.com', - "img-src 'self' data:", - "script-src 'self' 'unsafe-eval' https://runtime.commercecloud.com", - 'upgrade-insecure-requests' - ]) - }) - test('merges with existing CSP directives', () => { - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, "connect-src test:* ; script-src 'unsafe-eval' test:*") - expectDirectives([ - "connect-src test:* 'self' localhost:*", - "script-src 'unsafe-eval' test:* 'self' localhost:*" - ]) - }) - test('allows other CSP directives', () => { - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, 'fake-directive test:*') - expectDirectives(['fake-directive test:*']) - }) - test('enforces upgrade-insecure-requests disabled on development', () => { - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, 'upgrade-insecure-requests') - expect(res.getHeader(CSP)).not.toContain('upgrade-insecure-requests') - }) - test('enforces upgrade-insecure-requests enabled on production', () => { - mockProduction() - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, 'connect-src localhost:*') - expectDirectives(['upgrade-insecure-requests']) - }) - test('adds directives even if setHeader is never called', () => { - enforceSecurityHeaders({}, res, () => {}) - expectDirectives(["img-src 'self' data:"]) - }) - test('handles multiple CSP headers', () => { - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(CSP, ['connect-src first.header', 'script-src second.header']) - const headers = res.getHeader(CSP) - expect(headers).toHaveLength(2) - expect(headers[0]).toContain('connect-src first.header') - expect(headers[1]).toContain('script-src second.header') - }) - test('does not modify unrelated headers', () => { - const header = 'Contentious-Secret-Police' - const value = 'connect-src unmodified fake directive' - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(header, value) - expect(res.getHeader(header)).toBe(value) - }) - test('blocks Strict-Transport-Security header in development', () => { - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(STRICT_TRANSPORT_SECURITY, 'max-age=12345') - expect(res.hasHeader(STRICT_TRANSPORT_SECURITY)).toBe(false) - }) - test('allows Strict-Transport-Security header in production', () => { - mockProduction() - enforceSecurityHeaders({}, res, () => {}) - res.setHeader(STRICT_TRANSPORT_SECURITY, 'max-age=12345') - expect(res.getHeader(STRICT_TRANSPORT_SECURITY)).toBe('max-age=12345') - }) - test('provides default value for Strict-Transport-Security header in production', () => { - mockProduction() - enforceSecurityHeaders({}, res, () => {}) - expect(res.getHeader(STRICT_TRANSPORT_SECURITY)).toBe('max-age=15552000; includeSubDomains') - }) -}) diff --git a/packages/pwa-kit-runtime/src/utils/middleware/index.js b/packages/pwa-kit-runtime/src/utils/middleware/index.js new file mode 100644 index 0000000000..495c3f2a02 --- /dev/null +++ b/packages/pwa-kit-runtime/src/utils/middleware/index.js @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +export * from './security' diff --git a/packages/pwa-kit-runtime/src/utils/middleware/security.js b/packages/pwa-kit-runtime/src/utils/middleware/security.js new file mode 100644 index 0000000000..8034842d18 --- /dev/null +++ b/packages/pwa-kit-runtime/src/utils/middleware/security.js @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import {CONTENT_SECURITY_POLICY, STRICT_TRANSPORT_SECURITY} from '../../ssr/server/constants' +import {isRemote} from '../ssr-server' + +/** + * This express middleware sets the Content-Security-Policy and Strict-Transport-Security headers to + * default values that are required for PWA Kit to work. It also patches `res.setHeader` to allow + * additional CSP directives to be added without removing the required directives, and it prevents + * the Strict-Transport-Security header from being set on the local dev server. + * @param {express.Request} req Express request object + * @param {express.Response} res Express response object + * @param {express.NextFunction} next Express next callback + */ +export const defaultPwaKitSecurityHeaders = (req, res, next) => { + /** CSP-compatible origin for Runtime Admin. */ + // localhost doesn't include a protocol because different browsers behave differently :\ + const runtimeAdmin = isRemote() ? 'https://runtime.commercecloud.com' : 'localhost:*' + /** + * Map of directive names/values that are required for PWA Kit to work. Array values will be + * merged with user-provided values; boolean values will replace user-provided values. + * @type Object. + */ + const directives = { + 'connect-src': ["'self'", runtimeAdmin], + 'frame-ancestors': [runtimeAdmin], + 'img-src': ["'self'", 'data:'], + 'script-src': ["'self'", "'unsafe-eval'", runtimeAdmin], + // Always upgrade insecure requests when deployed, never upgrade on local dev server + 'upgrade-insecure-requests': isRemote() + } + + const setHeader = res.setHeader + res.setHeader = (name, value) => { + let modifiedValue = value + switch (name?.toLowerCase()) { + case CONTENT_SECURITY_POLICY: { + // If multiple Content-Security-Policy headers are provided, then the most restrictive + // option is chosen for each directive. Therefore, we must modify *all* directives to + // ensure that our required directives will work as expected. + // Ref: https://w3c.github.io/webappsec-csp/#multiple-policies + modifiedValue = Array.isArray(value) + ? value.map((item) => modifyDirectives(item, directives)) + : modifyDirectives(value, directives) + break + } + case STRICT_TRANSPORT_SECURITY: { + // Block setting this header on local development server - it will break things! + if (!isRemote()) return + break + } + default: { + break + } + } + return setHeader.call(res, name, modifiedValue) + } + // Provide an initial CSP (or patch the existing header) + res.setHeader(CONTENT_SECURITY_POLICY, res.getHeader(CONTENT_SECURITY_POLICY) ?? '') + // Provide an initial value for HSTS, if not already set - use default from `helmet` + if (!res.hasHeader(STRICT_TRANSPORT_SECURITY)) { + res.setHeader(STRICT_TRANSPORT_SECURITY, 'max-age=15552000; includeSubDomains') + } + next() +} + +/** + * Updates the given Content-Security-Policy header to include all directives required by PWA Kit. + * @param {string} original Original Content-Security-Policy header + * @returns {string} Modified Content-Security-Policy header + * @private + */ +const modifyDirectives = (original, required) => { + const directives = original + .trim() + .split(';') + .reduce((acc, directive) => { + const text = directive.trim() + if (text) { + const [name, ...values] = text.split(/ +/) + acc[name] = values + } + return acc + }, {}) + + // Add missing required CSP directives + for (const [name, value] of Object.entries(required)) { + if (value === true) { + // Boolean directive (required) - overwrite original value + directives[name] = [] + } else if (value === false) { + // Boolean directive (disabled) - delete original value + delete directives[name] + } else { + // Regular string[] directive - merge values + // Wrapping with `[...new Set(array)]` removes duplicate entries + directives[name] = [...new Set([...(directives[name] ?? []), ...value])] + } + } + + // Re-construct header string + return Object.entries(directives) + .map(([name, values]) => [name, ...values].join(' ')) + .join(';') +} diff --git a/packages/pwa-kit-runtime/src/utils/middleware/security.test.js b/packages/pwa-kit-runtime/src/utils/middleware/security.test.js new file mode 100644 index 0000000000..1668723451 --- /dev/null +++ b/packages/pwa-kit-runtime/src/utils/middleware/security.test.js @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import { + CONTENT_SECURITY_POLICY as CSP, + STRICT_TRANSPORT_SECURITY as HSTS +} from '../../ssr/server/constants' +import {defaultPwaKitSecurityHeaders} from './security' + +// no `Object.hasOwn` in node 14 :( +const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) + +describe('Content-Security-Policy enforcement', () => { + let res + + /** Sets the correct values for `isRemote()` to return true */ + const mockProduction = () => { + process.env.AWS_LAMBDA_FUNCTION_NAME = 'testEnforceSecurityHeaders' + } + /** + * Helper to make expected CSP more readable. Asserts that the actual CSP header contains each + * of the expected directives. + * @param {string[]} expected Array of expected CSP directives + */ + const expectDirectives = (expected) => { + const actual = res.getHeader(CSP).split(';') + expect(actual).toEqual(expect.arrayContaining(expected)) + } + + beforeEach(() => { + const headers = {} + res = { + hasHeader: (key) => hasOwn(headers, key), + getHeader: (key) => headers[key], + setHeader: (key, val) => (headers[key] = val) + } + }) + // Revert state detected by `isRemote()` + afterEach(() => delete process.env.AWS_LAMBDA_FUNCTION_NAME) + + test('adds required directives for development', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, '') + expectDirectives([ + "connect-src 'self' localhost:*", + 'frame-ancestors localhost:*', + "img-src 'self' data:", + "script-src 'self' 'unsafe-eval' localhost:*" + ]) + }) + test('adds required directives for production', () => { + mockProduction() + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, '') + expectDirectives([ + "connect-src 'self' https://runtime.commercecloud.com", + 'frame-ancestors https://runtime.commercecloud.com', + "img-src 'self' data:", + "script-src 'self' 'unsafe-eval' https://runtime.commercecloud.com", + 'upgrade-insecure-requests' + ]) + }) + test('merges with existing CSP directives', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, "connect-src test:* ; script-src 'unsafe-eval' test:*") + expectDirectives([ + "connect-src test:* 'self' localhost:*", + "script-src 'unsafe-eval' test:* 'self' localhost:*" + ]) + }) + test('allows other CSP directives', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, 'fake-directive test:*') + expectDirectives(['fake-directive test:*']) + }) + test('enforces upgrade-insecure-requests disabled on development', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, 'upgrade-insecure-requests') + expect(res.getHeader(CSP)).not.toContain('upgrade-insecure-requests') + }) + test('enforces upgrade-insecure-requests enabled on production', () => { + mockProduction() + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, 'connect-src localhost:*') + expectDirectives(['upgrade-insecure-requests']) + }) + test('adds directives even if setHeader is never called', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + expectDirectives(["img-src 'self' data:"]) + }) + test('handles multiple CSP headers', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(CSP, ['connect-src first.header', 'script-src second.header']) + const headers = res.getHeader(CSP) + expect(headers).toHaveLength(2) + expect(headers[0]).toContain('connect-src first.header') + expect(headers[1]).toContain('script-src second.header') + }) + test('does not modify unrelated headers', () => { + const header = 'Contentious-Secret-Police' + const value = 'connect-src unmodified fake directive' + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(header, value) + expect(res.getHeader(header)).toBe(value) + }) + test('blocks Strict-Transport-Security header in development', () => { + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(HSTS, 'max-age=12345') + expect(res.hasHeader(HSTS)).toBe(false) + }) + test('allows Strict-Transport-Security header in production', () => { + mockProduction() + defaultPwaKitSecurityHeaders({}, res, () => {}) + res.setHeader(HSTS, 'max-age=12345') + expect(res.getHeader(HSTS)).toBe('max-age=12345') + }) + test('provides default value for Strict-Transport-Security header in production', () => { + mockProduction() + defaultPwaKitSecurityHeaders({}, res, () => {}) + expect(res.getHeader(HSTS)).toBe('max-age=15552000; includeSubDomains') + }) +}) diff --git a/packages/template-retail-react-app/CHANGELOG.md b/packages/template-retail-react-app/CHANGELOG.md index cad3ad4cdc..92b00880c8 100644 --- a/packages/template-retail-react-app/CHANGELOG.md +++ b/packages/template-retail-react-app/CHANGELOG.md @@ -1,176 +1,182 @@ +## v2.8.1 (Nov 8, 2023) + +- Use the new opt-in mechanism for enforcing the default security headers required by PWA Kit projects. [#1530](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1530) + ## 2.8.0 (Nov 3, 2023) -- Support Storefront Preview - - [#1468](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1468) - - [#1426](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1426) -- Move Content-Security-Policy logic into pwa-kit-runtime [#1491](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1491) + +- Support Storefront Preview + - [#1468](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1468) + - [#1426](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1426) +- Move Content-Security-Policy logic into pwa-kit-runtime [#1491](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1491) ## 2.7.4 (Aug 28, 2023) -- Support Node 18 and NPM 9 in PWA Kit v2.x [#1265](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1265) + +- Support Node 18 and NPM 9 in PWA Kit v2.x [#1265](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1265) ## v2.7.1 (May 11, 2023) -- Replace invalid row value with nowrap [#1179](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1179) -- Add a redirect to login page after user signs out from checkout page [#1172](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1172) -- PWA Kit should have a mechanism for replacing the access token when a SFRA login state is changed [#1171](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1171) -- Added session bridge call to login for phased launch [#1159](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1159) -- Fix Page Designer ImageWithText Link component [#1092](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1092) -- Remove site alias and locale from location.state.directedFrom path [#1065)](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1065) -- Product list refinements [#957](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/957) -- Prevent modal to open when it fails to add an item to cart [#1053](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1053) -- Make `mergeBasket` conditional more robust [#1048](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1048) -- Fix addresses not having preferred address first. [#1051](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1051) -- Changed type of the phone number field to bring up numberic keyboard on mobile devices - W-9871940 [#1016)](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1016) +- Replace invalid row value with nowrap [#1179](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1179) +- Add a redirect to login page after user signs out from checkout page [#1172](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1172) +- PWA Kit should have a mechanism for replacing the access token when a SFRA login state is changed [#1171](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1171) +- Added session bridge call to login for phased launch [#1159](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1159) +- Fix Page Designer ImageWithText Link component [#1092](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1092) +- Remove site alias and locale from location.state.directedFrom path [#1065)](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1065) +- Product list refinements [#957](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/957) +- Prevent modal to open when it fails to add an item to cart [#1053](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1053) +- Make `mergeBasket` conditional more robust [#1048](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1048) +- Fix addresses not having preferred address first. [#1051](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1051) +- Changed type of the phone number field to bring up numberic keyboard on mobile devices - W-9871940 [#1016)](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1016) ## v2.7.0 (Mar 03, 2023) -- Add Page Designer ImageTile component [#967](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/967) -- Add Page Designer ImageWithText component [#991](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/991) -- Add Page Designer carousel component [#977](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/977) -- Add Page Designer layout components [#993](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/993) -- Support the product-set type [#1019](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1019) +- Add Page Designer ImageTile component [#967](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/967) +- Add Page Designer ImageWithText component [#991](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/991) +- Add Page Designer carousel component [#977](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/977) +- Add Page Designer layout components [#993](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/993) +- Support the product-set type [#1019](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1019) ## v2.6.0 (Jan 25, 2023) -- Mega menu fixes [#875](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/875) and [#910](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/910) -- Cache SLAS callback using request processor [#884](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/884) -- Fix padding of footer drawer component [#899](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/899) -- Update createOrder to send SLAS USID [#920](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/920) -- Fix PropTypes [#924](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/924) -- Remove unnecessary map statement [#929](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/929) +- Mega menu fixes [#875](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/875) and [#910](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/910) +- Cache SLAS callback using request processor [#884](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/884) +- Fix padding of footer drawer component [#899](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/899) +- Update createOrder to send SLAS USID [#920](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/920) +- Fix PropTypes [#924](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/924) +- Remove unnecessary map statement [#929](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/929) ## v2.5.0 (Jan 5, 2023) -- Add instanceType to Einstein activity body [#858](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/858) -- Do not use a proxy to call Einstein [#857](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/857) -- Einstein handle variants [#867](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/867) -- Fix cc exp year [#874](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/874) +- Add instanceType to Einstein activity body [#858](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/858) +- Do not use a proxy to call Einstein [#857](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/857) +- Einstein handle variants [#867](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/867) +- Fix cc exp year [#874](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/874) ## v2.4.0 (Dec 1, 2022) -- Dynamic footer Copyright date [#741](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/741) -- Footer copyright: remove the remaining hardcoded year [#760](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/760) -- ImageGallery uses image.link when DIS is not set [#786](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/786) -- Use default locale as target if none is specified [#788](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/788) -- Password change bug fix [#803](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/803) -- pwa-kit-dev command for tailing logs [#789](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/789) -- Update usages of zzrf-001 ODS instance to the new short URL format [#816](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/816) +- Dynamic footer Copyright date [#741](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/741) +- Footer copyright: remove the remaining hardcoded year [#760](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/760) +- ImageGallery uses image.link when DIS is not set [#786](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/786) +- Use default locale as target if none is specified [#788](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/788) +- Password change bug fix [#803](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/803) +- pwa-kit-dev command for tailing logs [#789](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/789) +- Update usages of zzrf-001 ODS instance to the new short URL format [#816](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/816) ## v2.3.0 (Oct 27, 2022) -- Fix locale `alias` by including `locale` object inside the MultiSite Context. [#716](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/716) -- Updated translations. [#725](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/725) -- Add new Einstein API activities. [#714](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/714) -- Fix search field to recognize `“&”` character. [#736](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/736) -- Fix filters on search results page. [#742](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/742) -- Dynamic footer copyright date. [#741](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/741) -- Bugfix: image gallery thumbnails not working without DIS [#786](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/786) -- Ensure that a valid target locale is use if none is provided [#788](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/788) +- Fix locale `alias` by including `locale` object inside the MultiSite Context. [#716](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/716) +- Updated translations. [#725](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/725) +- Add new Einstein API activities. [#714](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/714) +- Fix search field to recognize `“&”` character. [#736](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/736) +- Fix filters on search results page. [#742](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/742) +- Dynamic footer copyright date. [#741](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/741) +- Bugfix: image gallery thumbnails not working without DIS [#786](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/786) +- Ensure that a valid target locale is use if none is provided [#788](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/788) ## v2.2.0 (Aug 25, 2022) -- Update zzrf-001 url [#694](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/694) -- Optimize Server-side performance [#667](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/667) -- Remove references to session bridging [#684](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/684) +- Update zzrf-001 url [#694](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/694) +- Optimize Server-side performance [#667](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/667) +- Remove references to session bridging [#684](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/684) ## v2.1.0 (Jul 05, 2022) -- Update translations [#643](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/643) -- Update translations [#653](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/653) -- Add bundlesize test back into CI [#652](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/652) -- Fix UI bug on notifications badge [#620](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/620) +- Update translations [#643](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/643) +- Update translations [#653](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/653) +- Add bundlesize test back into CI [#652](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/652) +- Fix UI bug on notifications badge [#620](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/620) ## v2.0.0 (May 16, 2022) -- Update translation docs [#570](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/570) -- Fixed loading correct amount of skeletons [#576] (https://github.com/SalesforceCommerceCloud/pwa-kit/pull/576) -- Remove manifest path [#582](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/582) -- Fix Verbose ShellJS Command [#588](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/588) -- Drop node 12 support for [#589](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/589) -- Multi-site, Fix the case when no site aliases is set [#551](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/551) -- Fix invalid refresh token [#528](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/528) -- Add valid token check before using refresh token on login [#533](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/533) -- Fix localization scripts to output to the correct default locale [#539](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/539) -- Merge guest cart and registered cart [#540](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/540) -- Move retail react app jest setup out from pwa-kit-dev [#545](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/545) -- Remove legacy remote proxy, which allowed remote environments to use proxy configs in package.json [#425](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/425) -- Rename 'pwa' directory into 'template-retail-react-app' [#485](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/485) -- Optimize visibility-off.svg [#512](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/512) -- Support Multi-site implementation using dynamic config [#469](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/469) -- Service worker loading for dev server [#464](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/464) -- Environment Specific Configuration Support [#477](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/447) +- Update translation docs [#570](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/570) +- Fixed loading correct amount of skeletons [#576] () +- Remove manifest path [#582](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/582) +- Fix Verbose ShellJS Command [#588](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/588) +- Drop node 12 support for [#589](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/589) +- Multi-site, Fix the case when no site aliases is set [#551](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/551) +- Fix invalid refresh token [#528](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/528) +- Add valid token check before using refresh token on login [#533](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/533) +- Fix localization scripts to output to the correct default locale [#539](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/539) +- Merge guest cart and registered cart [#540](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/540) +- Move retail react app jest setup out from pwa-kit-dev [#545](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/545) +- Remove legacy remote proxy, which allowed remote environments to use proxy configs in package.json [#425](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/425) +- Rename 'pwa' directory into 'template-retail-react-app' [#485](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/485) +- Optimize visibility-off.svg [#512](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/512) +- Support Multi-site implementation using dynamic config [#469](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/469) +- Service worker loading for dev server [#464](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/464) +- Environment Specific Configuration Support [#477](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/447) ## v1.5.0 (Mar 17, 2022) -- Support storing authentication tokens in cookie [#429](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/429) -- Make sure the forgot-password modal also shows up in the checkout flow [#373](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/373) -- On Windows, the locale selector dropdown in the footer now showing all of the options properly [#381](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/381) -- Import cross-fetch to make OCAPI client isomorphic [#382](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/382) -- Multi-site implementation for Retail React App [#391](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/391) +- Support storing authentication tokens in cookie [#429](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/429) +- Make sure the forgot-password modal also shows up in the checkout flow [#373](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/373) +- On Windows, the locale selector dropdown in the footer now showing all of the options properly [#381](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/381) +- Import cross-fetch to make OCAPI client isomorphic [#382](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/382) +- Multi-site implementation for Retail React App [#391](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/391) ## v1.4.0 (Jan 27, 2022) -- Do not send HSTS header during local development [#288](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/288) -- Add constants for `` tags `theme-color` and `apple-mobile-web-app-title` [#287](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/287) -- Upgrade to React 17 [#278](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/278) -- Import preliminary translations [#324](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/324) -- Remove old dependencies that are no longer used [#317](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/317) +- Do not send HSTS header during local development [#288](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/288) +- Add constants for `` tags `theme-color` and `apple-mobile-web-app-title` [#287](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/287) +- Upgrade to React 17 [#278](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/278) +- Import preliminary translations [#324](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/324) +- Remove old dependencies that are no longer used [#317](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/317) ## v1.3.0 (Jan 06, 2022) -- Remove Einstein from home page [#208](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/208) -- Add git2gus config to allow git2gus integration [210](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/210) -- Set common HTTP security headers [#263](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/263) -- Add message ids to all the translated text, so they provide context for the translators [#239](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/239) [#207](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/207) [#195](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/195) -- Minor translation fixes [260](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/260) [#252](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/252) -- Provide Url Customization for the Retail React App [#228](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/228/files) -- Add an image component to allow for easier-implementation of responsive images [#186](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/186) -- Add shop Products section with products from the Catalog [#216](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/216) -- Remove `upgrade-insecure-requests` for local development [#270](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/270) -- Fix the missing out-of-stock message on mobile screens [#231](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/231) -- Fix order summary prices on the check out page misaligned on mobile [#233](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/233) -- Skip irrelevant jobs on CI on forked PR [#237](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/237) [#240](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/240) -- Add webpack plugin [#255](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/255) -- Combine config files [#256](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/256) -- Improve unsupported locale error message [#225](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/225) -- Add github template [#226](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/226) -- Fix shipping method description overflows the price section [#232](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/232) -- Fix show applied promotion codes case sensitive issue [#224](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/224) -- Fix section subtitle incorrect prop warning [#282](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/282) +- Remove Einstein from home page [#208](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/208) +- Add git2gus config to allow git2gus integration [210](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/210) +- Set common HTTP security headers [#263](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/263) +- Add message ids to all the translated text, so they provide context for the translators [#239](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/239) [#207](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/207) [#195](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/195) +- Minor translation fixes [260](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/260) [#252](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/252) +- Provide Url Customization for the Retail React App [#228](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/228/files) +- Add an image component to allow for easier-implementation of responsive images [#186](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/186) +- Add shop Products section with products from the Catalog [#216](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/216) +- Remove `upgrade-insecure-requests` for local development [#270](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/270) +- Fix the missing out-of-stock message on mobile screens [#231](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/231) +- Fix order summary prices on the check out page misaligned on mobile [#233](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/233) +- Skip irrelevant jobs on CI on forked PR [#237](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/237) [#240](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/240) +- Add webpack plugin [#255](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/255) +- Combine config files [#256](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/256) +- Improve unsupported locale error message [#225](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/225) +- Add github template [#226](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/226) +- Fix shipping method description overflows the price section [#232](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/232) +- Fix show applied promotion codes case sensitive issue [#224](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/224) +- Fix section subtitle incorrect prop warning [#282](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/282) ## v1.2.0 (Nov 18, 2021) -- Simplify homepage for Retail React App [#201](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/201) -- Ensure `cookieId` value is sent always for Einstein recommendations [#179](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/179) -- Remove `x-powered-by` HTTP response header [#165](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/165) -- For search engine crawlers, add `hreflang` links to the current page's html [#137](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/137) -- Use the preferred currency when switching locales. [#105](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/105) -- Integrate wishlist with einstein recommended products. [#131](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/131) -- When adding a new locale, minimize configuring the locale selector UI by having a list of commonly-used locales [#175](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/175) -- Enable adding wishlist item to the cart. [#158](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/158) -- Rename CartItemVariant to ItemVariantProvider [#155](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/155) -- Enabling pseudo locale now affects only the loading of the translation messages. The rest of the app still knows about English and the other locales. [#177](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/177) -- Allow individual Commerce API calls to pass in a different locale/currency and override the global value. [#177](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/177) -- Fix regression with loading the correct translation file [#193](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/193) -- Upgrade `chakra-ui/react` to `^1.7.1` version. [#204](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/204) -- Rename the `extract-messages` and `compile-messages` commands to `extract-default-translations` and `compile-translations` [#160](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/160) -- Enable favourite icons on product tiles for guest users [#173](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/173) -- Fix Missing Locale Param for Commerce API Calls [#174](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/174) -- Add cache control header to product details page [#172](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/172) -- Clear SLAS tokens when OID is changed [#178](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/178) +- Simplify homepage for Retail React App [#201](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/201) +- Ensure `cookieId` value is sent always for Einstein recommendations [#179](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/179) +- Remove `x-powered-by` HTTP response header [#165](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/165) +- For search engine crawlers, add `hreflang` links to the current page's html [#137](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/137) +- Use the preferred currency when switching locales. [#105](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/105) +- Integrate wishlist with einstein recommended products. [#131](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/131) +- When adding a new locale, minimize configuring the locale selector UI by having a list of commonly-used locales [#175](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/175) +- Enable adding wishlist item to the cart. [#158](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/158) +- Rename CartItemVariant to ItemVariantProvider [#155](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/155) +- Enabling pseudo locale now affects only the loading of the translation messages. The rest of the app still knows about English and the other locales. [#177](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/177) +- Allow individual Commerce API calls to pass in a different locale/currency and override the global value. [#177](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/177) +- Fix regression with loading the correct translation file [#193](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/193) +- Upgrade `chakra-ui/react` to `^1.7.1` version. [#204](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/204) +- Rename the `extract-messages` and `compile-messages` commands to `extract-default-translations` and `compile-translations` [#160](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/160) +- Enable favourite icons on product tiles for guest users [#173](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/173) +- Fix Missing Locale Param for Commerce API Calls [#174](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/174) +- Add cache control header to product details page [#172](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/172) +- Clear SLAS tokens when OID is changed [#178](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/178) ## v1.1.0 (Sep 27, 2021) -- Fix wishlist bugs and provide better hooks for wishlist features. [#64](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/64) -- Lazy load Popover component. [#134](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/134) -- Fix pseudo local command to use `en-XB`. [#101](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/101) -- Ensure generated projects ship with a working .gitignore file. [#95](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/95) -- Remove eslint rule which check for Salesforce copyright. [#104](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/104) -- Improve error page design. [#74](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/74) -- Localize cart and checkout messages. [#106](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/106) -- Add default cache control header to home page. [#103](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/103) -- Security - `inquirer` package upgrade. [#121](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/121) -- New quantity picker. [#102](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/102) +- Fix wishlist bugs and provide better hooks for wishlist features. [#64](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/64) +- Lazy load Popover component. [#134](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/134) +- Fix pseudo local command to use `en-XB`. [#101](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/101) +- Ensure generated projects ship with a working .gitignore file. [#95](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/95) +- Remove eslint rule which check for Salesforce copyright. [#104](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/104) +- Improve error page design. [#74](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/74) +- Localize cart and checkout messages. [#106](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/106) +- Add default cache control header to home page. [#103](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/103) +- Security - `inquirer` package upgrade. [#121](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/121) +- New quantity picker. [#102](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/102) ## v1.0.0 (Sep 08, 2021) -- PWA Kit General Availability and open source. 🎉 +- PWA Kit General Availability and open source. 🎉 diff --git a/packages/template-retail-react-app/app/ssr.js b/packages/template-retail-react-app/app/ssr.js index cdeede5a03..02bf2fc278 100644 --- a/packages/template-retail-react-app/app/ssr.js +++ b/packages/template-retail-react-app/app/ssr.js @@ -8,6 +8,7 @@ import path from 'path' import {getRuntime} from 'pwa-kit-runtime/ssr/server/express' +import {defaultPwaKitSecurityHeaders} from 'pwa-kit-runtime/utils/middleware' import {getConfig} from 'pwa-kit-runtime/utils/ssr-config' import helmet from 'helmet' @@ -33,11 +34,11 @@ const options = { const runtime = getRuntime() const {handler} = runtime.createHandler(options, (app) => { - // Set HTTP security headers + // Set default HTTP security headers required by PWA Kit + app.use(defaultPwaKitSecurityHeaders) + // Set custom HTTP security headers app.use( helmet({ - // pwa-kit-runtime ensures that the Content-Security-Policy header always contains the - // directives required for PWA Kit to function. Add custom directives here. contentSecurityPolicy: { useDefaults: true, directives: {