From 01f3db1af3286540d712658b33989129744b8741 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 6 Jul 2026 07:10:50 +0000 Subject: [PATCH] fix: handle 401 responses for domain operations following registry changes (SWG-20526) Registry PR #2958 (SWG-20526) updated domain operations (saveDomainDefinition, deleteDomain, deleteDomainVersion) to return 401 for invalid tokens instead of the previous undocumented behavior, and to return 400/415 instead of 500 for malformed/unsupported requests. - Add 401 to filterResponseMessaging as defense-in-depth: if 401 ever reaches this function via resolveStatus it is rejected rather than silently passed to onResolve - Add 401 tests for domain:create, domain:delete, and domain:update - Add 415 tests for domain:create and domain:update (saveDomainDefinition now returns 415 for unsupported content types instead of 500) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_016stuqDZQnQDtZD5XTqj635 --- src/support/command/handle-response.js | 2 +- test/commands/domain/create.test.js | 32 ++++++++++++++++++++++++++ test/commands/domain/delete.test.js | 13 +++++++++++ test/commands/domain/update.test.js | 32 ++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/support/command/handle-response.js b/src/support/command/handle-response.js index a29e686e..9d9caae8 100644 --- a/src/support/command/handle-response.js +++ b/src/support/command/handle-response.js @@ -27,7 +27,7 @@ const checkForErrors = ({ resolveStatus = [] } = {}) => response => { } const filterResponseMessaging = response => { - if (response.status === 403) { + if (response.status === 401 || response.status === 403) { return Promise.reject(response) } diff --git a/test/commands/domain/create.test.js b/test/commands/domain/create.test.js index 883e5ee2..0f2c6af9 100644 --- a/test/commands/domain/create.test.js +++ b/test/commands/domain/create.test.js @@ -115,6 +115,38 @@ describe('invalid domain:create', () => { expect(ctx.message).to.equal('You have reached the limit of domains') }) .it('runs domain:create with org that doesn\'t exist') + + test + .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) + .nock(`${shubUrl}/domains`, domain => domain + .get('/org/domain') + .reply(404) + ) + .nock(`${shubUrl}/domains`, domain => domain + .post('/org/domain?version=1.0.0&isPrivate=true') + .reply(401, '{"code":401,"message":"Invalid API key"}') + ) + .command(['domain:create', `${validIdentifier}`, '--file=test/resources/valid_domain.json']) + .catch(ctx => { + expect(ctx.message).to.equal('Invalid API key') + }) + .it('runs domain:create with invalid API key returns 401') + + test + .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) + .nock(`${shubUrl}/domains`, domain => domain + .get('/org/domain') + .reply(404) + ) + .nock(`${shubUrl}/domains`, domain => domain + .post('/org/domain?version=1.0.0&isPrivate=true') + .reply(415, '{"code":415,"message":"Unsupported Media Type"}') + ) + .command(['domain:create', `${validIdentifier}`, '--file=test/resources/valid_domain.json']) + .catch(ctx => { + expect(ctx.message).to.equal('Unsupported Media Type') + }) + .it('runs domain:create with unsupported content type returns 415') test .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) diff --git a/test/commands/domain/delete.test.js b/test/commands/domain/delete.test.js index 8f703495..4e6be7e3 100644 --- a/test/commands/domain/delete.test.js +++ b/test/commands/domain/delete.test.js @@ -73,6 +73,19 @@ describe('domain:delete error responses', () => { expect(ctx.message).to.contain(`Unknown domain ${domainId}`) }) .it('runs domain:delete with domain that does not exist') + + test + .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) + .nock(`${shubUrl}/domains`, domain => domain + .delete('/org/domain/1.0.0') + .query({ force: 'true' }) + .reply(401, '{"code":401,"message":"Invalid API key"}') + ) + .command(['domain:delete', versionId]) + .catch(ctx => { + expect(ctx.message).to.contain('Invalid API key') + }) + .it('runs domain:delete with invalid API key returns 401') }) diff --git a/test/commands/domain/update.test.js b/test/commands/domain/update.test.js index 745ba431..012e6dda 100644 --- a/test/commands/domain/update.test.js +++ b/test/commands/domain/update.test.js @@ -103,6 +103,38 @@ describe('invalid domain:update', () => { .exit(2) .it('runs domain:update with error on updating domain') + test + .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) + .nock(`${shubUrl}/domains`, domain => domain + .get('/org/domain/1.0.0') + .reply(200) + ) + .nock(`${shubUrl}/domains`, domain => domain + .post('/org/domain?version=1.0.0') + .reply(401, '{"code":401,"message":"Invalid API key"}') + ) + .command(['domain:update', `${validIdentifier}`, '--file=test/resources/valid_domain.json']) + .catch(ctx => { + expect(ctx.message).to.equal('Invalid API key') + }) + .it('runs domain:update with invalid API key returns 401') + + test + .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) + .nock(`${shubUrl}/domains`, domain => domain + .get('/org/domain/1.0.0') + .reply(200) + ) + .nock(`${shubUrl}/domains`, domain => domain + .post('/org/domain?version=1.0.0') + .reply(415, '{"code":415,"message":"Unsupported Media Type"}') + ) + .command(['domain:update', `${validIdentifier}`, '--file=test/resources/valid_domain.json']) + .catch(ctx => { + expect(ctx.message).to.equal('Unsupported Media Type') + }) + .it('runs domain:update with unsupported content type returns 415') + test .stub(config, 'getConfig', stub => stub.returns({ SWAGGERHUB_URL: shubUrl })) .nock(`${shubUrl}/domains`, domain => domain