From cd9c4400dc1f6721543d6e74528bfb2fb34b5a91 Mon Sep 17 00:00:00 2001 From: Donald Merand Date: Sat, 8 Aug 2026 10:24:56 -0400 Subject: [PATCH 1/2] Redact device authorization debug output Assisted-By: devx/bb1c6644-dd32-425e-b0c8-33f7efa1bb93 --- .changeset/redact-device-authorization-log.md | 5 +++++ .../node/session/device-authorization.test.ts | 21 +++++++++++++++++++ .../node/session/device-authorization.ts | 4 +++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .changeset/redact-device-authorization-log.md diff --git a/.changeset/redact-device-authorization-log.md b/.changeset/redact-device-authorization-log.md new file mode 100644 index 00000000000..cb7de8c8b31 --- /dev/null +++ b/.changeset/redact-device-authorization-log.md @@ -0,0 +1,5 @@ +--- +'@shopify/cli-kit': patch +--- + +Redact sensitive device authorization values from debug output. diff --git a/packages/cli-kit/src/private/node/session/device-authorization.test.ts b/packages/cli-kit/src/private/node/session/device-authorization.test.ts index e87ab4fc703..61352762327 100644 --- a/packages/cli-kit/src/private/node/session/device-authorization.test.ts +++ b/packages/cli-kit/src/private/node/session/device-authorization.test.ts @@ -68,6 +68,27 @@ describe('requestDeviceAuthorization', () => { expect(got).toEqual(dataExpected) }) + test('does not include authorization credentials in debug output', async () => { + // Given + const outputDebug = vi.spyOn(output, 'outputDebug') + const outputInfo = vi.spyOn(output, 'outputInfo') + const response = new Response(JSON.stringify(data), {status: 200}) + vi.mocked(shopifyFetch).mockResolvedValue(response) + vi.mocked(identityFqdn).mockResolvedValue('fqdn.com') + vi.mocked(clientId).mockReturnValue('clientId') + + // When + await requestDeviceAuthorization(['scope1', 'scope2']) + + // Then + const debugOutput = JSON.stringify(outputDebug.mock.calls) + const infoOutput = JSON.stringify(outputInfo.mock.calls) + expect(debugOutput).not.toContain(data.device_code) + expect(debugOutput).not.toContain(data.verification_uri_complete) + expect(infoOutput).toContain(data.user_code) + expect(infoOutput).toContain(data.verification_uri_complete) + }) + test('opens the browser directly in an interactive terminal', async () => { // Given const outputInfo = vi.spyOn(output, 'outputInfo') diff --git a/packages/cli-kit/src/private/node/session/device-authorization.ts b/packages/cli-kit/src/private/node/session/device-authorization.ts index 8ac629e7cc0..0b956260f16 100644 --- a/packages/cli-kit/src/private/node/session/device-authorization.ts +++ b/packages/cli-kit/src/private/node/session/device-authorization.ts @@ -62,7 +62,9 @@ export async function requestDeviceAuthorization(scopes: string[]): Promise Date: Sat, 8 Aug 2026 10:48:35 -0400 Subject: [PATCH 2/2] Strengthen device authorization log coverage Assisted-By: devx/51bab362-9374-42a8-86d0-152326d57949 --- .../node/session/device-authorization.test.ts | 21 +++++++++++++++++++ .../node/session/device-authorization.ts | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/cli-kit/src/private/node/session/device-authorization.test.ts b/packages/cli-kit/src/private/node/session/device-authorization.test.ts index 61352762327..f857302f081 100644 --- a/packages/cli-kit/src/private/node/session/device-authorization.test.ts +++ b/packages/cli-kit/src/private/node/session/device-authorization.test.ts @@ -83,12 +83,33 @@ describe('requestDeviceAuthorization', () => { // Then const debugOutput = JSON.stringify(outputDebug.mock.calls) const infoOutput = JSON.stringify(outputInfo.mock.calls) + expect(debugOutput).toContain('HTTP 200') + expect(debugOutput).toContain('interval=5') + expect(debugOutput).toContain('expires_in=3600') expect(debugOutput).not.toContain(data.device_code) expect(debugOutput).not.toContain(data.verification_uri_complete) expect(infoOutput).toContain(data.user_code) expect(infoOutput).toContain(data.verification_uri_complete) }) + test('uses an explicit marker when the response omits the polling interval', async () => { + // Given + const outputDebug = vi.spyOn(output, 'outputDebug') + outputDebug.mockClear() + const response = new Response(JSON.stringify({...data, interval: undefined}), {status: 200}) + vi.mocked(shopifyFetch).mockResolvedValue(response) + vi.mocked(identityFqdn).mockResolvedValue('fqdn.com') + vi.mocked(clientId).mockReturnValue('clientId') + + // When + await requestDeviceAuthorization(['scope1', 'scope2']) + + // Then + const debugOutput = JSON.stringify(outputDebug.mock.calls) + expect(debugOutput).toContain('interval=not provided') + expect(debugOutput).not.toContain('interval=undefined') + }) + test('opens the browser directly in an interactive terminal', async () => { // Given const outputInfo = vi.spyOn(output, 'outputInfo') diff --git a/packages/cli-kit/src/private/node/session/device-authorization.ts b/packages/cli-kit/src/private/node/session/device-authorization.ts index 0b956260f16..2152a45f6b4 100644 --- a/packages/cli-kit/src/private/node/session/device-authorization.ts +++ b/packages/cli-kit/src/private/node/session/device-authorization.ts @@ -63,7 +63,7 @@ export async function requestDeviceAuthorization(scopes: string[]): Promise