Skip to content

Commit 2b2b485

Browse files
unandyalaclaude
andcommitted
Guard applyScapiAuthHeaders behind HttpOnly flag, remove SLAS auth check, warn on missing x-site-id
Only invoke applyScapiAuthHeaders when HttpOnly session cookies are enabled. Remove the unnecessary SLAS auth endpoint guard since SLAS requests use a separate proxy. Log a warning when x-site-id header is missing on SCAPI requests to aid debugging if the template is misconfigured. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 33eb226 commit 2b2b485

File tree

3 files changed

+36
-47
lines changed

3 files changed

+36
-47
lines changed

packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,10 @@ describe('HttpOnly session cookies', () => {
523523

524524
const response = await request(app)
525525
.post('/mobify/slas/private/shopper/auth/v1/oauth2/logout')
526-
.set('Cookie', 'cc-at_testsite=mock-access-token; cc-nx_testsite=mock-refresh-token')
526+
.set(
527+
'Cookie',
528+
'cc-at_testsite=mock-access-token; cc-nx_testsite=mock-refresh-token'
529+
)
527530
.set('x-site-id', 'testsite')
528531

529532
expect(response.status).toBe(200)

packages/pwa-kit-runtime/src/utils/ssr-server/configure-proxy.basic.test.js

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ jest.mock('./utils', () => ({
1414
...jest.requireActual('./utils'),
1515
isScapiDomain: jest.fn()
1616
}))
17+
jest.mock('../logger-instance', () => ({
18+
__esModule: true,
19+
default: {
20+
warn: jest.fn(),
21+
info: jest.fn(),
22+
error: jest.fn()
23+
}
24+
}))
25+
26+
import logger from '../logger-instance'
1727

1828
describe('applyProxyRequestHeaders', () => {
1929
it('removes a header not present in new headers', () => {
@@ -124,32 +134,6 @@ describe('applyScapiAuthHeaders', () => {
124134
)
125135
})
126136

127-
it('skips all SLAS auth endpoints (handled by SLAS private proxy)', () => {
128-
utils.isScapiDomain.mockReturnValue(true)
129-
cookie.parse.mockReturnValue({'cc-at_RefArch': 'test-access-token'})
130-
131-
const proxyRequest = {
132-
setHeader: jest.fn()
133-
}
134-
const incomingRequest = {
135-
url: '/shopper/auth/v1/oauth2/logout',
136-
headers: {
137-
cookie: 'cc-at_RefArch=test-access-token',
138-
'x-site-id': 'RefArch'
139-
}
140-
}
141-
142-
applyScapiAuthHeaders({
143-
proxyRequest,
144-
incomingRequest,
145-
caching: false,
146-
targetHost: 'abc-001.api.commercecloud.salesforce.com'
147-
})
148-
149-
// SLAS auth endpoints are handled by the SLAS private client proxy
150-
expect(proxyRequest.setHeader).not.toHaveBeenCalled()
151-
})
152-
153137
it('does not apply Bearer token when caching is true', () => {
154138
utils.isScapiDomain.mockReturnValue(true)
155139
cookie.parse.mockReturnValue({'cc-at_RefArch': 'test-access-token'})
@@ -176,7 +160,7 @@ describe('applyScapiAuthHeaders', () => {
176160
expect(proxyRequest.setHeader).not.toHaveBeenCalled()
177161
})
178162

179-
it('does not apply Bearer token when x-site-id header is missing', () => {
163+
it('logs warning and skips when x-site-id header is missing on SCAPI request', () => {
180164
utils.isScapiDomain.mockReturnValue(true)
181165
cookie.parse.mockReturnValue({})
182166

@@ -196,6 +180,10 @@ describe('applyScapiAuthHeaders', () => {
196180
})
197181

198182
expect(proxyRequest.setHeader).not.toHaveBeenCalled()
183+
expect(logger.warn).toHaveBeenCalledWith(
184+
expect.stringContaining('x-site-id header is missing'),
185+
expect.any(Object)
186+
)
199187
})
200188

201189
it('does not apply Bearer token when target is not SCAPI domain', () => {

packages/pwa-kit-runtime/src/utils/ssr-server/configure-proxy.js

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ const generalProxyPathRE = /^\/mobify\/proxy\/([^/]+)(\/.*)$/
3636
* 1. Caching proxies never use auth (skip)
3737
* 2. x-site-id header must be present (skip if not)
3838
* 3. Target must be SCAPI domain (skip if not)
39-
* 4. SLAS auth endpoints (/shopper/auth/*) are skipped — Bearer injection for SLAS
40-
* is handled by the SLAS private client proxy in build-remote-server.js
41-
* 5. For non-SLAS auth endpoints (e.g., /shopper/products, /shopper/baskets): Always apply Bearer token
4239
*
4340
* @private
4441
* @function
@@ -47,21 +44,20 @@ const generalProxyPathRE = /^\/mobify\/proxy\/([^/]+)(\/.*)$/
4744
* @param caching {Boolean} true for a caching proxy, false for a standard proxy
4845
* @param targetHost {String} the target hostname (host+port)
4946
*/
50-
export const applyScapiAuthHeaders = ({
51-
proxyRequest,
52-
incomingRequest,
53-
caching,
54-
targetHost
55-
}) => {
47+
export const applyScapiAuthHeaders = ({proxyRequest, incomingRequest, caching, targetHost}) => {
5648
const url = incomingRequest.url
5749
const resolvedSiteId = incomingRequest.headers?.['x-site-id']
5850

59-
// Skip if: caching proxy, no siteId, not SCAPI domain, or no URL
60-
if (caching || !resolvedSiteId || !isScapiDomain(targetHost) || !url) {
51+
// Skip if: caching proxy, not SCAPI domain, or no URL
52+
if (caching || !isScapiDomain(targetHost) || !url) {
6153
return
6254
}
63-
// SLAS auth endpoints are handled by the SLAS private client proxy
64-
if (url.startsWith('/shopper/auth/')) {
55+
56+
if (!resolvedSiteId) {
57+
logger.warn(
58+
'x-site-id header is missing on SCAPI proxy request. Bearer token injection skipped.',
59+
{namespace: 'configureProxy.applyScapiAuthHeaders'}
60+
)
6561
return
6662
}
6763

@@ -260,12 +256,14 @@ export const configureProxy = ({
260256
})
261257

262258
// Apply Authorization header with shopper's access token from HttpOnly cookie
263-
applyScapiAuthHeaders({
264-
proxyRequest,
265-
incomingRequest,
266-
caching,
267-
targetHost
268-
})
259+
if (process.env.MRT_DISABLE_HTTPONLY_SESSION_COOKIES === 'false') {
260+
applyScapiAuthHeaders({
261+
proxyRequest,
262+
incomingRequest,
263+
caching,
264+
targetHost
265+
})
266+
}
269267
},
270268

271269
onProxyRes: (proxyResponse, req) => {

0 commit comments

Comments
 (0)