Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.68] Fix cart requests in the local proxy to avoid 401-Unauthorized errors #4610

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/six-bugs-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/theme': patch
---

Fix cart requests in the local proxy to avoid 401-Unauthorized errors
56 changes: 54 additions & 2 deletions packages/theme/src/cli/utilities/theme-environment/proxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import {getProxyStorefrontHeaders, injectCdnProxy, patchRenderingResponse} from './proxy.js'
import {canProxyRequest, getProxyStorefrontHeaders, injectCdnProxy, patchRenderingResponse} from './proxy.js'
import {describe, test, expect} from 'vitest'
import {createEvent} from 'h3'
import {Response as NodeResponse} from '@shopify/cli-kit/node/http'
import {IncomingMessage, ServerResponse} from 'node:http'
import {Socket} from 'node:net'
import type {DevServerContext} from './types.js'

function createH3Event() {
function createH3Event(method = 'GET', path = '/', headers = {}) {
const req = new IncomingMessage(new Socket())
const res = new ServerResponse(req)

req.method = method
req.url = path
req.headers = headers

return createEvent(req, res)
}

Expand Down Expand Up @@ -218,4 +223,51 @@ describe('dev proxy', () => {
`)
})
})

describe('canProxyRequest', () => {
test('should proxy non-GET requests', () => {
const event = createH3Event('POST', '/some-path.html')
expect(canProxyRequest(event)).toBe(true)
})

test('should proxy Cart requests as they are not supported by the SFR client', () => {
const event = createH3Event('GET', '/cart/some-path')
expect(canProxyRequest(event)).toBe(true)
})

test('should proxy CDN requests', () => {
const event = createH3Event('GET', '/cdn/some-path')
expect(canProxyRequest(event)).toBe(true)
})

test('should proxy CDN requests for extensions', () => {
const event = createH3Event('GET', '/ext/cdn/some-path')
expect(canProxyRequest(event)).toBe(true)
})

test('should proxy requests with file extensions', () => {
const event = createH3Event('GET', '/some-path.js')
expect(canProxyRequest(event)).toBe(true)
})

test('should proxy requests with a non-default accept header', () => {
const event = createH3Event('GET', '/some-path', {accept: 'application/json'})
expect(canProxyRequest(event)).toBe(true)
})

test('should not proxy requests with a default accept header and no extension, allowing them to be rendered by the SFR client', () => {
const event = createH3Event('GET', '/some-path', {accept: '*/*'})
expect(canProxyRequest(event)).toBe(false)
})

test('should not proxy HTML requests (based on the extension), allowing them to be rendered by the SFR client', () => {
const event = createH3Event('GET', '/some-path.html')
expect(canProxyRequest(event)).toBe(false)
})

test('should not proxy HTML requests (based on the "accept" header), allowing them to be rendered by the SFR client', () => {
const event = createH3Event('GET', '/some-path', {accept: 'text/html'})
expect(canProxyRequest(event)).toBe(false)
})
})
})
5 changes: 4 additions & 1 deletion packages/theme/src/cli/utilities/theme-environment/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {Theme} from '@shopify/cli-kit/node/themes/types'
import type {Response as NodeResponse} from '@shopify/cli-kit/node/http'
import type {DevServerContext} from './types.js'

const CART_PREFIX = '/cart/'
const VANITY_CDN_PREFIX = '/cdn/'
const EXTENSION_CDN_PREFIX = '/ext/cdn/'
const IGNORED_ENDPOINTS = [
Expand Down Expand Up @@ -62,13 +63,15 @@ export function getProxyHandler(_theme: Theme, ctx: DevServerContext) {
* | /cdn/... | | Proxy |
* | /ext/cdn/... | | Proxy |
* | /.../file.js | | Proxy |
* | /cart/... | | Proxy |
* | /payments/config | application/json | Proxy |
* | /search/suggest | * / * | No proxy |
* | /.../index.html | | No Proxy |
*
*/
function canProxyRequest(event: H3Event) {
export function canProxyRequest(event: H3Event) {
if (event.method !== 'GET') return true
if (event.path.startsWith(CART_PREFIX)) return true
if (event.path.startsWith(VANITY_CDN_PREFIX)) return true
if (event.path.startsWith(EXTENSION_CDN_PREFIX)) return true

Expand Down