From 4667d6c97650d47714b0030ce8a38ae0ed74bf1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Thu, 26 Jan 2023 17:51:15 +0100 Subject: [PATCH] fix: host URL for instances in different regions --- src/lib/config/api-url.ts | 12 ++++++++++++ src/lib/config/index.ts | 5 ++--- test/jest/unit/config/api-url.spec.ts | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/lib/config/api-url.ts b/src/lib/config/api-url.ts index d455d4cb5e..84e459b238 100644 --- a/src/lib/config/api-url.ts +++ b/src/lib/config/api-url.ts @@ -180,3 +180,15 @@ export function getHiddenApiUrl(restUrl: string): string { return parsedBaseUrl.toString(); } + +export function getRootUrl(apiUrlString: string): string { + // based on https://docs.snyk.io/snyk-processes/data-residency-at-snyk#what-regions-are-available the pattern is as follows + // https://app.[region.]snyk.io + // given an api url that starts with api means, that we can replace "api" by "app". + + const apiUrl = new URL(apiUrlString); + apiUrl.host = apiUrl.host.replace(/^api\./, ''); + + const rootUrl = apiUrl.protocol + '//' + apiUrl.host; + return rootUrl; +} diff --git a/src/lib/config/index.ts b/src/lib/config/index.ts index ba1fa2fc01..be83b39a8a 100644 --- a/src/lib/config/index.ts +++ b/src/lib/config/index.ts @@ -5,6 +5,7 @@ import { getRestApiUrl, getV1ApiUrl, getHiddenApiUrl, + getRootUrl, } from './api-url'; const DEFAULT_TIMEOUT = 5 * 60; // in seconds @@ -79,9 +80,7 @@ if (!config.timeout) { // this is a bit of an assumption that our web site origin is the same // as our API origin, but for now it's okay - RS 2015-10-16 if (!config.ROOT) { - const apiUrl = new URL(config.API); - apiUrl.host = apiUrl.host.replace(/^ap[pi]\./, ''); - config.ROOT = apiUrl.protocol + '//' + apiUrl.host; + config.ROOT = getRootUrl(config.API); } config.PUBLIC_VULN_DB_URL = 'https://security.snyk.io'; diff --git a/test/jest/unit/config/api-url.spec.ts b/test/jest/unit/config/api-url.spec.ts index 0b78eff58f..aeca776b21 100644 --- a/test/jest/unit/config/api-url.spec.ts +++ b/test/jest/unit/config/api-url.spec.ts @@ -2,6 +2,7 @@ import { getBaseApiUrl, getV1ApiUrl, getRestApiUrl, + getRootUrl, } from '../../../../src/lib/config/api-url'; const urls = [ @@ -10,72 +11,84 @@ const urls = [ expectedBase: 'https://snyk.io/api/', expectedV1: 'https://snyk.io/api/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://snyk.io', }, { userInput: 'https://snyk.io/api', expectedBase: 'https://snyk.io/api', expectedV1: 'https://snyk.io/api/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://snyk.io', }, { userInput: 'https://app.snyk.io/api', expectedBase: 'https://app.snyk.io/api', expectedV1: 'https://app.snyk.io/api/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://app.snyk.io', }, { userInput: 'https://app.snyk.io/api/v1', expectedBase: 'https://app.snyk.io/api/', expectedV1: 'https://app.snyk.io/api/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://app.snyk.io', }, { userInput: 'https://api.snyk.io/v1', expectedBase: 'https://api.snyk.io/', expectedV1: 'https://api.snyk.io/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://snyk.io', }, { userInput: 'https://api.snyk.io', expectedBase: 'https://api.snyk.io', expectedV1: 'https://api.snyk.io/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://snyk.io', }, { userInput: 'https://api.snyk.io/', expectedBase: 'https://api.snyk.io/', expectedV1: 'https://api.snyk.io/v1', expectedRest: 'https://api.snyk.io/rest', + expectedRoot: 'https://snyk.io', }, { userInput: 'https://api.custom.snyk.io', expectedBase: 'https://api.custom.snyk.io', expectedV1: 'https://api.custom.snyk.io/v1', expectedRest: 'https://api.custom.snyk.io/rest', + expectedRoot: 'https://custom.snyk.io', }, { userInput: 'http://localhost:9000/', expectedBase: 'http://localhost:9000/', expectedV1: 'http://localhost:9000/v1', expectedRest: 'http://localhost:9000/rest', + expectedRoot: 'http://localhost:9000', }, { userInput: 'http://localhost:9000/api/v1', expectedBase: 'http://localhost:9000/api/', expectedV1: 'http://localhost:9000/api/v1', expectedRest: 'http://localhost:9000/rest', + expectedRoot: 'http://localhost:9000', }, { userInput: 'http://alpha:omega@localhost:9000', expectedBase: 'http://alpha:omega@localhost:9000', expectedV1: 'http://alpha:omega@localhost:9000/v1', expectedRest: 'http://alpha:omega@localhost:9000/rest', + expectedRoot: 'http://localhost:9000', }, { userInput: 'https://app.dev.snyk.io/api/v1', expectedBase: 'https://app.dev.snyk.io/api/', expectedV1: 'https://app.dev.snyk.io/api/v1', expectedRest: 'https://api.dev.snyk.io/rest', + expectedRoot: 'https://app.dev.snyk.io', }, ]; @@ -152,4 +165,12 @@ describe('CLI config - API URL', () => { }); }); }); + + describe('getRootUrl', () => { + urls.forEach((url) => { + it(`returns ROOT URL ${url.userInput}`, () => { + expect(getRootUrl(url.userInput)).toEqual(url.expectedRoot); + }); + }); + }); });