diff --git a/packages/pwa-kit-create-app/CHANGELOG.md b/packages/pwa-kit-create-app/CHANGELOG.md index ccc004b7ff..ba58ad9cdc 100644 --- a/packages/pwa-kit-create-app/CHANGELOG.md +++ b/packages/pwa-kit-create-app/CHANGELOG.md @@ -1,6 +1,7 @@ ## [Unreleased] - Add configuration flag `disableHttpOnlySessionCookies` to `ssrParameters` [#3635](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3635) - Add `x-site-id` request header to read HttpOnly cookies on the server [#3700](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3700) +- Rename the configuration flag `disableHttpOnlySessionCookies` to `enableHttpOnlySessionCookies` [#3723](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3723) ## v3.17.0-dev - Clear verdaccio npm cache during project generation [#3652](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3652) diff --git a/packages/pwa-kit-create-app/assets/bootstrap/js/config/default.js.hbs b/packages/pwa-kit-create-app/assets/bootstrap/js/config/default.js.hbs index b3fc98b3d4..8df8b770f6 100644 --- a/packages/pwa-kit-create-app/assets/bootstrap/js/config/default.js.hbs +++ b/packages/pwa-kit-create-app/assets/bootstrap/js/config/default.js.hbs @@ -188,7 +188,7 @@ module.exports = { ssrParameters: { ssrFunctionNodeVersion: '24.x', // Store the session cookies as HttpOnly for enhanced security. - disableHttpOnlySessionCookies: false, + enableHttpOnlySessionCookies: true, proxyConfigs: [ { host: '{{answers.project.commerce.shortCode}}.api.commercecloud.salesforce.com', diff --git a/packages/pwa-kit-create-app/assets/bootstrap/js/overrides/app/components/_app-config/index.jsx.hbs b/packages/pwa-kit-create-app/assets/bootstrap/js/overrides/app/components/_app-config/index.jsx.hbs index 4ee4151c22..3165c74af4 100644 --- a/packages/pwa-kit-create-app/assets/bootstrap/js/overrides/app/components/_app-config/index.jsx.hbs +++ b/packages/pwa-kit-create-app/assets/bootstrap/js/overrides/app/components/_app-config/index.jsx.hbs @@ -107,6 +107,11 @@ const AppConfig = ({children, locals = {}}) => { privateClientProxyEndpoint={slasPrivateClientProxyEndpoint} // Uncomment 'hybridAuthEnabled' if the current site has Hybrid Auth enabled. Do NOT set this flag for hybrid storefronts using Plugin SLAS. // hybridAuthEnabled={true} + useHttpOnlySessionCookies={ + typeof window !== 'undefined' + ? window.__MRT_ENABLE_HTTPONLY_SESSION_COOKIES__ === 'true' + : process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true' + } > diff --git a/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/app/components/_app-config/index.jsx.hbs b/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/app/components/_app-config/index.jsx.hbs index 669a08e995..64c256e736 100644 --- a/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/app/components/_app-config/index.jsx.hbs +++ b/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/app/components/_app-config/index.jsx.hbs @@ -108,6 +108,11 @@ const AppConfig = ({children, locals = {}}) => { privateClientProxyEndpoint={slasPrivateClientProxyEndpoint} // Uncomment 'hybridAuthEnabled' if the current site has Hybrid Auth enabled. Do NOT set this flag for hybrid storefronts using Plugin SLAS. // hybridAuthEnabled={true} + useHttpOnlySessionCookies={ + typeof window !== 'undefined' + ? window.__MRT_ENABLE_HTTPONLY_SESSION_COOKIES__ === 'true' + : process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true' + } > diff --git a/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/config/default.js.hbs b/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/config/default.js.hbs index 44683e0830..10f4566bbc 100644 --- a/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/config/default.js.hbs +++ b/packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/config/default.js.hbs @@ -184,7 +184,7 @@ module.exports = { ssrParameters: { ssrFunctionNodeVersion: '24.x', // Store the session cookies as HttpOnly for enhanced security. - disableHttpOnlySessionCookies: false, + enableHttpOnlySessionCookies: true, proxyConfigs: [ { host: '{{answers.project.commerce.shortCode}}.api.commercecloud.salesforce.com', diff --git a/packages/pwa-kit-dev/CHANGELOG.md b/packages/pwa-kit-dev/CHANGELOG.md index 4b3ac6e2c7..35a7fe5315 100644 --- a/packages/pwa-kit-dev/CHANGELOG.md +++ b/packages/pwa-kit-dev/CHANGELOG.md @@ -1,6 +1,7 @@ ## [Unreleased] - Add configuration flag `disableHttpOnlySessionCookies` to `ssrParameters` [#3635](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3635) - Fix issue to correctly set the environment variable `MRT_DISABLE_HTTPONLY_SESSION_COOKIES` [#3680](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3680) +- Rename the configuration flag `disableHttpOnlySessionCookies` to `enableHttpOnlySessionCookies` [#3723](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3723) ## v3.17.0-dev - Update jest, archiver and remove rimraf dependencies [#3663](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3663) diff --git a/packages/pwa-kit-dev/bin/pwa-kit-dev.js b/packages/pwa-kit-dev/bin/pwa-kit-dev.js index a0faae9f27..f674a91b6a 100755 --- a/packages/pwa-kit-dev/bin/pwa-kit-dev.js +++ b/packages/pwa-kit-dev/bin/pwa-kit-dev.js @@ -253,16 +253,16 @@ const main = async () => { error('Could not determine app entrypoint.') process.exit(1) } - // Load config to get envBasePath and disableHttpOnlySessionCookies from ssrParameters for local development + // Load config to get envBasePath and enableHttpOnlySessionCookies from ssrParameters for local development // This mimics how MRT sets the system environment variable const config = getConfig() || {} - const disableHttpOnlySessionCookies = - config.ssrParameters?.disableHttpOnlySessionCookies ?? true + const enableHttpOnlySessionCookies = + config.ssrParameters?.enableHttpOnlySessionCookies ?? false execSync(`${babelNode} ${inspect ? '--inspect' : ''} ${babelArgs} ${entrypoint}`, { env: { ...process.env, ...(noHMR ? {HMR: 'false'} : {}), - MRT_DISABLE_HTTPONLY_SESSION_COOKIES: String(disableHttpOnlySessionCookies) + MRT_ENABLE_HTTPONLY_SESSION_COOKIES: String(enableHttpOnlySessionCookies) } }) }) diff --git a/packages/pwa-kit-react-sdk/CHANGELOG.md b/packages/pwa-kit-react-sdk/CHANGELOG.md index 1269c0f396..ec2263650d 100644 --- a/packages/pwa-kit-react-sdk/CHANGELOG.md +++ b/packages/pwa-kit-react-sdk/CHANGELOG.md @@ -2,6 +2,7 @@ - Update test setup for Jest 29 compatibility [#3663](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3663) - Add Node 24 support. Drop Node 16 support [#3652](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3652) - Add configuration flag `disableHttpOnlySessionCookies` to `ssrParameters` [#3635](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3635) +- Rename the configuration flag `disableHttpOnlySessionCookies` to `enableHttpOnlySessionCookies` [#3723](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3723) ## v3.16.0 (Feb 12, 2026) diff --git a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js index c57bed655f..cf6e8fed72 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js +++ b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js @@ -365,7 +365,7 @@ const renderApp = (args) => { __CONFIG__: config, __PRELOADED_STATE__: appState, __ERROR__: error, - __MRT_DISABLE_HTTPONLY_SESSION_COOKIES__: process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES, + __MRT_ENABLE_HTTPONLY_SESSION_COOKIES__: process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES, // `window.Progressive` has a long history at Mobify and some // client-side code depends on it. Maintain its name out of tradition. Progressive: getWindowProgressive(req, res) diff --git a/packages/pwa-kit-runtime/CHANGELOG.md b/packages/pwa-kit-runtime/CHANGELOG.md index 309c65ee6e..98714a6b20 100644 --- a/packages/pwa-kit-runtime/CHANGELOG.md +++ b/packages/pwa-kit-runtime/CHANGELOG.md @@ -2,6 +2,7 @@ - Add HttpOnly session cookies for SLAS private client proxy [#3680](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3680) - Handle logout when HttpOnly session cookies is enabled [#3699](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3699) - Add `x-site-id` request header to read HttpOnly cookies on the server [#3700](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3700) +- Rename the configuration flag `disableHttpOnlySessionCookies` to `enableHttpOnlySessionCookies` [#3723](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3723) ## v3.17.0-dev - Add Node 24 support. Migrate deprecated Node.js `url.parse()` and `url.format()` to the WHATWG `URL` [#3652](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3652) 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 56a86dcdd5..50ef17a01a 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 @@ -219,7 +219,7 @@ export const RemoteServerFactory = { // Custom callback to modify the SLAS private client proxy response. This callback is invoked // after the built-in proxy response handling (including HttpOnly session cookie handling when enabled). - // When HttpOnly session cookies are enabled (MRT_DISABLE_HTTPONLY_SESSION_COOKIES=false), the callback + // When HttpOnly session cookies are enabled (MRT_ENABLE_HTTPONLY_SESSION_COOKIES=true), the callback // receives the response with tokens already moved to HttpOnly cookies and stripped from the body. // Custom callbacks must not rely on token fields in the response body in that case; read from // response headers (e.g. Set-Cookie) if needed. @@ -265,7 +265,7 @@ export const RemoteServerFactory = { `${options.slasApiPath.source}(${options.applySLASPrivateClientToEndpoints.source})` ) - // Note: HttpOnly session cookies are controlled by the MRT_DISABLE_HTTPONLY_SESSION_COOKIES + // Note: HttpOnly session cookies are controlled by the MRT_ENABLE_HTTPONLY_SESSION_COOKIES // env var (set by MRT in production, pwa-kit-dev locally). Read directly where needed. return options @@ -1002,7 +1002,7 @@ export const RemoteServerFactory = { // purpose so we don't want to overwrite the header for those calls. proxyRequest.setHeader('Authorization', `Basic ${encodedSlasCredentials}`) } else if ( - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES === 'false' && + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true' && incomingRequest.path?.match(SLAS_LOGOUT_ENDPOINT) ) { setTokensInLogoutRequest(proxyRequest, incomingRequest) @@ -1030,7 +1030,7 @@ export const RemoteServerFactory = { // Check against tokenResponseEndpoints regex (configurable in ssr.js) const isTokenEndpoint = req.path?.match(options.tokenResponseEndpoints) const httpOnlySessionCookiesEnabled = - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES === 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true' if ( httpOnlySessionCookiesEnabled && proxyRes.statusCode === 200 && 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 95899f0af4..a0666516a5 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 @@ -192,7 +192,7 @@ describe('SLAS private proxy', () => { afterEach(() => { // Clean up environment variables delete process.env.PWA_KIT_SLAS_CLIENT_SECRET - delete process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES + delete process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES }) test('returns 404 when useSLASPrivateClient is false', async () => { @@ -378,11 +378,11 @@ describe('HttpOnly session cookies', () => { afterEach(() => { delete process.env.PWA_KIT_SLAS_CLIENT_SECRET - delete process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES + delete process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES }) - test('does not process when MRT_DISABLE_HTTPONLY_SESSION_COOKIES is not set', async () => { - delete process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES + test('does not process when MRT_ENABLE_HTTPONLY_SESSION_COOKIES is not enabled', async () => { + delete process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES const mockSlasServer = mockExpress() mockSlasServer.post('/shopper/auth/v1/oauth2/token', (req, res) => { @@ -434,7 +434,7 @@ describe('HttpOnly session cookies', () => { }) test('returns 500 when siteId is missing', async () => { - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES = 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES = 'true' const mockSlasServer = mockExpress() mockSlasServer.post('/shopper/auth/v1/oauth2/token', (req, res) => { @@ -484,7 +484,7 @@ describe('HttpOnly session cookies', () => { }) test('injects Bearer token and refresh token from HttpOnly cookies for logout endpoint', async () => { - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES = 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES = 'true' let capturedAuthHeader let capturedRefreshToken @@ -540,7 +540,7 @@ describe('HttpOnly session cookies', () => { }) test('x-site-id header takes precedence over static config siteId for logout endpoint', async () => { - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES = 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES = 'true' let capturedAuthHeader let capturedRefreshToken @@ -596,7 +596,7 @@ describe('HttpOnly session cookies', () => { }) test('sets HttpOnly cookies and strips tokens from response body', async () => { - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES = 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES = 'true' const mockSlasServer = mockExpress() mockSlasServer.post('/shopper/auth/v1/oauth2/token', (req, res) => { @@ -656,7 +656,7 @@ describe('HttpOnly session cookies', () => { }) test('returns 500 when JWT decode fails', async () => { - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES = 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES = 'true' const mockSlasServer = mockExpress() mockSlasServer.post('/shopper/auth/v1/oauth2/token', (req, res) => { @@ -706,7 +706,7 @@ describe('HttpOnly session cookies', () => { }) test('processes passwordless token endpoint', async () => { - process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES = 'false' + process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES = 'true' const mockSlasServer = mockExpress() mockSlasServer.post('/shopper/auth/v1/oauth2/passwordless/token', (req, res) => { diff --git a/packages/pwa-kit-runtime/src/utils/ssr-server/configure-proxy.js b/packages/pwa-kit-runtime/src/utils/ssr-server/configure-proxy.js index 504bcb6ecc..0b35be74e1 100644 --- a/packages/pwa-kit-runtime/src/utils/ssr-server/configure-proxy.js +++ b/packages/pwa-kit-runtime/src/utils/ssr-server/configure-proxy.js @@ -261,7 +261,7 @@ export const configureProxy = ({ }) // Apply Authorization header with shopper's access token from HttpOnly cookie - if (process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES === 'false') { + if (process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true') { setScapiAuthRequestHeaders({ proxyRequest, incomingRequest, diff --git a/packages/template-retail-react-app/CHANGELOG.md b/packages/template-retail-react-app/CHANGELOG.md index 9135d98c2f..df61c57d7b 100644 --- a/packages/template-retail-react-app/CHANGELOG.md +++ b/packages/template-retail-react-app/CHANGELOG.md @@ -1,6 +1,7 @@ ## [Unreleased] - Add HttpOnly session cookies for SLAS private client proxy [#3680](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3680) - Add `x-site-id` request header to read HttpOnly cookies on the server [#3700](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3700) +- Rename the configuration flag `disableHttpOnlySessionCookies` to `enableHttpOnlySessionCookies` [#3723](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3723) ## v9.1.0-dev - Update jest-fetch-mock and Jest 29 dependencies [#3663](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3663) diff --git a/packages/template-retail-react-app/app/components/_app-config/index.jsx b/packages/template-retail-react-app/app/components/_app-config/index.jsx index c2f0e03f3d..af093853e5 100644 --- a/packages/template-retail-react-app/app/components/_app-config/index.jsx +++ b/packages/template-retail-react-app/app/components/_app-config/index.jsx @@ -114,8 +114,8 @@ const AppConfig = ({children, locals = {}}) => { // hybridAuthEnabled={true} useHttpOnlySessionCookies={ typeof window !== 'undefined' - ? window.__MRT_DISABLE_HTTPONLY_SESSION_COOKIES__ === 'false' - : process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES === 'false' + ? window.__MRT_ENABLE_HTTPONLY_SESSION_COOKIES__ === 'true' + : process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true' } logger={createLogger({packageName: 'commerce-sdk-react'})} > diff --git a/packages/template-retail-react-app/config/default.js b/packages/template-retail-react-app/config/default.js index 902508ee07..7e6af70b81 100644 --- a/packages/template-retail-react-app/config/default.js +++ b/packages/template-retail-react-app/config/default.js @@ -107,7 +107,7 @@ module.exports = { ssrParameters: { ssrFunctionNodeVersion: '24.x', // Store the session cookies as HttpOnly for enhanced security. - disableHttpOnlySessionCookies: true, + enableHttpOnlySessionCookies: false, proxyConfigs: [ { host: 'kv7kzm78.api.commercecloud.salesforce.com',