purecloud-client-app-sdk
Advanced tools
Comparing version 2.5.0 to 2.6.0
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
import { PcEnv } from './utils/env'; | ||
import { PcEnv, EnvironmentParser } from './utils/env'; | ||
import AlertingApi from './modules/alerting'; | ||
@@ -39,3 +39,4 @@ import LifecycleApi from './modules/lifecycle'; | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -52,3 +53,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -65,3 +67,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -78,3 +81,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -93,3 +97,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -107,3 +112,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -120,3 +126,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -135,3 +142,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -150,3 +158,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -158,11 +167,34 @@ * ``` | ||
constructor(cfg?: { | ||
/** Name of a query param to auto parse into the pcEnvironment; Must be valid and a single param. Best Practice. */ | ||
/** Name of a query param to auto parse into the pcEnvironment; Must be valid and a single param. */ | ||
pcEnvironmentQueryParam?: string; | ||
/** The PC top-level domain (e.g. mypurecloud.com, mypurecloud.au); Must be a valid PC Env tld; Prefered over pcOrigin. */ | ||
/** The PC top-level domain (e.g. mypurecloud.com, mypurecloud.au); Must be a valid PC Env tld; Preferred over pcOrigin. */ | ||
pcEnvironment?: string; | ||
/** The full origin (protocol, host, port) of the Genesys Cloud host environment (e.g. https://apps.mypurecloud.com). Prefer using pcEnvironment[QueryParam] over this property. */ | ||
pcOrigin?: string; | ||
/** | ||
* Name of a query param to auto parse into the gcHostOrigin. | ||
* Must be valid and used with gcTargetEnvQueryParam. | ||
* Best Practice. | ||
*/ | ||
gcHostOriginQueryParam?: string; | ||
/** | ||
* Name of a query param to auto parse into the gcTargetEnv. | ||
* Must be valid and used with gcHostOriginQueryParam. | ||
* Best Practice. | ||
*/ | ||
gcTargetEnvQueryParam?: string; | ||
/** | ||
* The GC host origin (e.g. https://apps.mypurecloud.com, https://apps.mypurecloud.au). | ||
* Must be a valid origin and used with gcTargetEnv. | ||
*/ | ||
gcHostOrigin?: string; | ||
/** | ||
* The GC env target (e.g. prod, prod-euw2). | ||
* Must be a valid environment name and used with gcHostOrigin. | ||
*/ | ||
gcTargetEnv?: string; | ||
}); | ||
private assertNonEmptyString; | ||
protected lookupEnv(env: string, envTlds?: string[], hostAppDevOrigin?: string): PcEnv; | ||
protected lookupGcEnv(hostOrigin: string, targetEnv: string, parseEnvironment?: EnvironmentParser): PcEnv; | ||
/** | ||
@@ -169,0 +201,0 @@ * Returns the pcEnvironment (e.g. mypurecloud.com, mypurecloud.jp) if known; null otherwise. |
@@ -0,1 +1,3 @@ | ||
import { parse } from 'genesys-cloud-service-discovery-web'; | ||
export declare type EnvironmentParser = typeof parse; | ||
export interface PcEnv { | ||
@@ -17,1 +19,9 @@ pcEnvTld: string; | ||
export declare const lookupPcEnv: (pcEnvTld: string, lenient?: boolean, envTlds?: string[], hostAppDevOrigin?: string) => PcEnv | null; | ||
/** | ||
* Attempts to locate a GC environment corresponding to the provided origin/targetEnv combination | ||
* @param url A string representing the Genesys Cloud environment url | ||
* @param targetEnv A string representing the Genesys Cloud environment target | ||
* @param parseEnvironment A method used to parse the Genesys Cloud environment url | ||
* @returns A Genesys Cloud environment object if found; null otherwise. | ||
*/ | ||
export declare const lookupGcEnv: (url: string, targetEnv: string, parseEnvironment?: EnvironmentParser) => PcEnv | null; |
{ | ||
"name": "purecloud-client-app-sdk", | ||
"version": "2.5.0", | ||
"version": "2.6.0", | ||
"description": "Javascript API for integrating 3rd-party apps with Genesys Cloud", | ||
@@ -89,2 +89,3 @@ "main": "dist/main.js", | ||
"child-process-promise": "^2.0.2", | ||
"dotenv": "^16.0.3", | ||
"eslint": "^7.2.0", | ||
@@ -91,0 +92,0 @@ "eslint-config-standard": "^11.0.0-beta.0", |
@@ -142,4 +142,179 @@ import ClientApp from './index'; | ||
}); | ||
describe('gcHostOriginQueryParam and gcTargetEnvQueryParam config', () => { | ||
it('should allow a user to pass valid query param names into the constructor', () => { | ||
// External | ||
let query = '?gcHostOrigin=https://apps.mypurecloud.com&gcTargetEnv=prod'; | ||
spyOn(ClientApp, '_getQueryString').and.callFake(() => query); | ||
let myClientApp = new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
expect(myClientApp.pcEnvironment).toBe('mypurecloud.com'); | ||
// Localhost | ||
query = '?gcHostOrigin=https://localhost:1337&gcTargetEnv=prod'; | ||
myClientApp = new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
expect(myClientApp.pcEnvironment).toBe('localhost'); | ||
}); | ||
it('should fail if is not targeting a valid env', () => { | ||
// Mismatch Environment | ||
let query = '?gcHostOrigin=https://apps.mypurecloud.jp&gcTargetEnv=prod'; | ||
spyOn(ClientApp, '_getQueryString').and.callFake(() => query); | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
}).toThrow(); | ||
// Mismatch Localhost | ||
query = '?gcHostOrigin=https://localhost:1337&gcTargetEnv=unknown'; | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
}).toThrow(); | ||
// External | ||
query = '?gcHostOrigin=https://invalid.com&gcTargetEnv=prod'; | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
}).toThrow(); | ||
// Invalid target env | ||
query = '?gcHostOrigin=https://apps.mypurecloud.com&gcTargetEnv=invalid'; | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
}).toThrow(); | ||
}); | ||
it('should fail if the query params are badly configured or not set', () => { | ||
// Missing gcHostOrigin config option | ||
expect(() => { | ||
new ClientApp({ gcHostOriginQueryParam: 'gcHostOrigin' }); | ||
}).toThrow(); | ||
// Missing gcTargetEnv config option | ||
expect(() => { | ||
new ClientApp({ gcTargetEnvQueryParam: 'gcTargetEnv' }); | ||
}).toThrow(); | ||
// Missing gcHostOrigin query param | ||
let query = '?gcTargetEnv=prod'; | ||
spyOn(ClientApp, '_getQueryString').and.callFake(() => query); | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
}).toThrow(); | ||
// Missing gcTargetEnv query param | ||
query = '?gcHostOrigin=https://apps.mypurecloud.com'; | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
gcTargetEnvQueryParam: 'gcTargetEnv' | ||
}); | ||
}).toThrow(); | ||
}); | ||
it('should fail if the query params are badly configured or not set', () => { | ||
const invalidQueryParamNames = [undefined, null, 3, [], {}, '', ' ']; | ||
invalidQueryParamNames.forEach((currInvalidParamName) => { | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOriginQueryParam: 'gcHostOrigin', | ||
// @ts-expect-error | ||
gcTargetEnvQueryParam: currInvalidParamName | ||
}); | ||
}).toThrow(); | ||
expect(() => { | ||
new ClientApp({ | ||
gcTargetEnvQueryParam: 'gcTargetEnv', | ||
// @ts-expect-error | ||
gcHostOriginQueryParam: currInvalidParamName | ||
}); | ||
}).toThrow(); | ||
}); | ||
}); | ||
}); | ||
describe('gcHostOrigin and gcTargetEnv config', () => { | ||
it('should allow a user to pass valid origin and target env into the constructor', () => { | ||
// External | ||
let myClientApp = new ClientApp({ | ||
gcHostOrigin: 'https://apps.mypurecloud.com', | ||
gcTargetEnv: 'prod' | ||
}); | ||
expect(myClientApp.pcEnvironment).toBe('mypurecloud.com'); | ||
// Localhost | ||
myClientApp = new ClientApp({ | ||
gcHostOrigin: 'https://localhost:1337', | ||
gcTargetEnv: 'prod' | ||
}); | ||
expect(myClientApp.pcEnvironment).toBe('localhost'); | ||
}); | ||
it('should fail if is not targeting a valid env', () => { | ||
// Mismatch Environment | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOrigin: 'https://apps.mypurecloud.jp', | ||
gcTargetEnv: 'prod' | ||
}); | ||
}).toThrow(); | ||
// Mismatch Localhost | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOrigin: 'https://localhost:1337', | ||
gcTargetEnv: 'unknown' | ||
}); | ||
}).toThrow(); | ||
// External | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOrigin: 'https://invalid.com', | ||
gcTargetEnv: 'prod' | ||
}); | ||
}).toThrow(); | ||
// Invalid target env | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOrigin: 'https://apps.mypurecloud.com', | ||
gcTargetEnv: 'invalid' | ||
}); | ||
}).toThrow(); | ||
}); | ||
it('should fail if the host origin and target env are not set', () => { | ||
// Missing gcHostOrigin config option | ||
expect(() => { | ||
new ClientApp({ gcHostOrigin: 'https://apps.mypurecloud.com' }); | ||
}).toThrow(); | ||
// Missing gcTargetEnv config option | ||
expect(() => { | ||
new ClientApp({ gcTargetEnv: 'prod' }); | ||
}).toThrow(); | ||
}); | ||
it('should fail if the host origin and target env are not configured', () => { | ||
const invalidValues = [undefined, null, 3, [], {}, '', ' ']; | ||
invalidValues.forEach((invalidValue) => { | ||
expect(() => { | ||
new ClientApp({ | ||
gcHostOrigin: 'https://apps.mypurecloud.com', | ||
// @ts-expect-error | ||
gcTargetEnv: invalidValue | ||
}); | ||
}).toThrow(); | ||
expect(() => { | ||
new ClientApp({ | ||
gcTargetEnv: 'prod', | ||
// @ts-expect-error | ||
gcHostOrigin: invalidValue | ||
}); | ||
}).toThrow(); | ||
}); | ||
}); | ||
}); | ||
/* eslint-enable no-new */ | ||
}); | ||
}); |
@@ -0,4 +1,7 @@ | ||
type Environment = import('genesys-cloud-service-discovery-web').Environment; | ||
declare const __PACKAGE_NAME__: string; | ||
declare const __PACKAGE_VERSION__: string; | ||
declare const __PC_DEV_ENVS__: string[]; | ||
declare const __GC_DEV_EXTRA_ENVS__: Environment[]; | ||
declare const __HOST_APP_DEV_ORIGIN__: string; |
@@ -13,3 +13,3 @@ /** | ||
import * as queryString from 'query-string'; | ||
import { lookupPcEnv, PcEnv, DEFAULT_PC_ENV } from './utils/env'; | ||
import { lookupPcEnv, lookupGcEnv, PcEnv, DEFAULT_PC_ENV, EnvironmentParser } from './utils/env'; | ||
import AlertingApi from './modules/alerting'; | ||
@@ -44,3 +44,4 @@ import LifecycleApi from './modules/lifecycle'; | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -58,3 +59,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -72,3 +74,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -86,3 +89,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -102,3 +106,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -117,3 +122,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -131,3 +137,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -147,3 +154,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -163,3 +171,4 @@ * | ||
* let clientApp = new ClientApp({ | ||
* pcEnvironmentQueryParam: 'pcEnvironment' | ||
* gcHostOriginQueryParam: 'gcHostOrigin', | ||
* gcTargetEnvQueryParam: 'gcTargetEnv' | ||
* }); | ||
@@ -171,14 +180,44 @@ * ``` | ||
constructor(cfg: { | ||
/** Name of a query param to auto parse into the pcEnvironment; Must be valid and a single param. Best Practice. */ | ||
/** Name of a query param to auto parse into the pcEnvironment; Must be valid and a single param. */ | ||
pcEnvironmentQueryParam?: string; | ||
/** The PC top-level domain (e.g. mypurecloud.com, mypurecloud.au); Must be a valid PC Env tld; Prefered over pcOrigin. */ | ||
/** The PC top-level domain (e.g. mypurecloud.com, mypurecloud.au); Must be a valid PC Env tld; Preferred over pcOrigin. */ | ||
pcEnvironment?: string; | ||
/** The full origin (protocol, host, port) of the Genesys Cloud host environment (e.g. https://apps.mypurecloud.com). Prefer using pcEnvironment[QueryParam] over this property. */ | ||
pcOrigin?: string; | ||
/** | ||
* Name of a query param to auto parse into the gcHostOrigin. | ||
* Must be valid and used with gcTargetEnvQueryParam. | ||
* Best Practice. | ||
*/ | ||
gcHostOriginQueryParam?: string; | ||
/** | ||
* Name of a query param to auto parse into the gcTargetEnv. | ||
* Must be valid and used with gcHostOriginQueryParam. | ||
* Best Practice. | ||
*/ | ||
gcTargetEnvQueryParam?: string; | ||
/** | ||
* The GC host origin (e.g. https://apps.mypurecloud.com, https://apps.mypurecloud.au). | ||
* Must be a valid origin and used with gcTargetEnv. | ||
*/ | ||
gcHostOrigin?: string; | ||
/** | ||
* The GC env target (e.g. prod, prod-euw2). | ||
* Must be a valid environment name and used with gcHostOrigin. | ||
*/ | ||
gcTargetEnv?: string; | ||
} = {}) { | ||
if (cfg) { | ||
if ('pcEnvironmentQueryParam' in cfg) { | ||
const parsedQueryString = queryString.parse(ClientApp._getQueryString() || ''); | ||
if ('gcHostOriginQueryParam' in cfg || 'gcTargetEnvQueryParam' in cfg) { | ||
this.assertNonEmptyString(cfg.gcHostOriginQueryParam, 'host origin query param name'); | ||
this.assertNonEmptyString(cfg.gcTargetEnvQueryParam, 'target env query param name'); | ||
this._pcEnv = this.lookupGcEnv(parsedQueryString[cfg.gcHostOriginQueryParam], parsedQueryString[cfg.gcTargetEnvQueryParam]); | ||
} else if ('gcHostOrigin' in cfg || 'gcTargetEnv' in cfg) { | ||
this.assertNonEmptyString(cfg.gcHostOrigin, 'gcHostOrigin'); | ||
this.assertNonEmptyString(cfg.gcTargetEnv, 'gcTargetEnv'); | ||
this._pcEnv = this.lookupGcEnv(cfg.gcHostOrigin, cfg.gcTargetEnv); | ||
} else if ('pcEnvironmentQueryParam' in cfg) { | ||
const paramName = cfg.pcEnvironmentQueryParam; | ||
this.assertNonEmptyString(paramName, 'query param name'); | ||
const parsedQueryString = queryString.parse(ClientApp._getQueryString() || ''); | ||
const paramValue = parsedQueryString[paramName]; | ||
@@ -226,2 +265,7 @@ this.assertNonEmptyString(paramValue, `value for query param '${paramName}'`); | ||
} | ||
protected lookupGcEnv(hostOrigin: string, targetEnv: string, parseEnvironment?: EnvironmentParser) { | ||
const pcEnv = lookupGcEnv(hostOrigin, targetEnv, parseEnvironment); | ||
if (!pcEnv) throw new Error(`Could not parse ${hostOrigin} (${targetEnv}) into a known GenesysCloud environment`); | ||
return pcEnv; | ||
} | ||
@@ -228,0 +272,0 @@ /** |
@@ -1,3 +0,4 @@ | ||
import { getEnvironments } from 'genesys-cloud-service-discovery-web'; | ||
import { getEnvironments, parse } from 'genesys-cloud-service-discovery-web'; | ||
export type EnvironmentParser = typeof parse; | ||
export interface PcEnv { | ||
@@ -14,3 +15,2 @@ pcEnvTld: string; | ||
const DEFAULT_ENV_REGION = 'us-east-1'; | ||
const environments = getEnvironments({ env: ['prod', 'fedramp'], status: ['beta', 'stable'] }); | ||
@@ -25,2 +25,3 @@ | ||
.concat(__PC_DEV_ENVS__); | ||
const GC_ENV_NAMES = new Set<string>([...environments, ...__GC_DEV_EXTRA_ENVS__].map((e) => e.name)); | ||
@@ -31,2 +32,28 @@ const [defaultEnv] = environments.filter(env => env.region === DEFAULT_ENV_REGION); | ||
function isKnownEnvName(toCheck: string) { | ||
return GC_ENV_NAMES.has(toCheck); | ||
} | ||
function findPcEnvironment(location: URL, targetEnv: string, parseEnvironment: EnvironmentParser): PcEnv|null { | ||
const parsedEnv = parseEnvironment(location.origin, {}); | ||
if (parsedEnv && parsedEnv.name === targetEnv) { | ||
return { | ||
pcEnvTld: parsedEnv.publicDomainName, | ||
pcAppOrigin: location.origin | ||
}; | ||
} else { | ||
for (const environment of __GC_DEV_EXTRA_ENVS__) { | ||
const publicDomains = [environment.publicDomainName, ...(environment.publicDomainAliases || [])]; | ||
const matchingDomain = publicDomains.find((p) => location.hostname === p || location.hostname.endsWith(`.${p}`)); | ||
if (matchingDomain && environment.name === targetEnv) { | ||
return { | ||
pcEnvTld: environment.publicDomainName, | ||
pcAppOrigin: location.origin | ||
}; | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
/** | ||
@@ -71,1 +98,27 @@ * Attempts to locate a PC environment corresponding to the provided search params | ||
}; | ||
/** | ||
* Attempts to locate a GC environment corresponding to the provided origin/targetEnv combination | ||
* @param url A string representing the Genesys Cloud environment url | ||
* @param targetEnv A string representing the Genesys Cloud environment target | ||
* @param parseEnvironment A method used to parse the Genesys Cloud environment url | ||
* @returns A Genesys Cloud environment object if found; null otherwise. | ||
*/ | ||
export const lookupGcEnv = (url: string, targetEnv: string, parseEnvironment: EnvironmentParser = parse): PcEnv|null => { | ||
if (!isKnownEnvName(targetEnv)) { | ||
return null; | ||
} | ||
try { | ||
const hostLocation = new URL(url); | ||
if (['localhost', '127.0.0.1'].includes(hostLocation.hostname)) { | ||
return { | ||
pcEnvTld: 'localhost', | ||
pcAppOrigin: hostLocation.origin | ||
}; | ||
} else { | ||
return findPcEnvironment(hostLocation, targetEnv, parseEnvironment); | ||
} | ||
} catch { | ||
return null; | ||
} | ||
}; |
@@ -8,82 +8,151 @@ import * as envUtils from './env'; | ||
}); | ||
describe('lookupPcEnv', () => { | ||
it('should parse a valid TLD and return the environment object', () => { | ||
const resolvedEnv = envUtils.lookupPcEnv('mypurecloud.com')!; | ||
expect(resolvedEnv).not.toBeNull(); | ||
expect(resolvedEnv.pcEnvTld).toBe('mypurecloud.com'); | ||
expect(resolvedEnv.pcAppOrigin).toBe('https://apps.mypurecloud.com'); | ||
}); | ||
it('should resolve a local environment object with a custom dev origin if passed', () => { | ||
const env = envUtils.lookupPcEnv('localhost', true, [], 'https://localhost:3000')!; | ||
expect(env).not.toBeNull(); | ||
expect(env.pcEnvTld).toBe('localhost'); | ||
expect(env.pcAppOrigin).toBe('https://localhost:3000'); | ||
}); | ||
it('should resolve an env when in the list of TLDs passed in via param', () => { | ||
const resolvedEnv = envUtils.lookupPcEnv('example.com', true, ['example.com'])!; | ||
expect(resolvedEnv).not.toBeNull(); | ||
expect(resolvedEnv.pcEnvTld).toBe('example.com'); | ||
expect(resolvedEnv.pcAppOrigin).toBe('https://apps.example.com'); | ||
}); | ||
it('should not resolve an env when it is not in the list of TLDs passed in via param', () => { | ||
const env = envUtils.lookupPcEnv('example2.com', true, ['example.com']); | ||
expect(env).toBeNull(); | ||
}); | ||
it('should allow lenient parsing of TLDs and return the environment object', () => { | ||
const seedTld = 'mypurecloud.com'; | ||
it('should parse a valid TLD and return the environment object', () => { | ||
const resolvedEnv = envUtils.lookupPcEnv('mypurecloud.com')!; | ||
expect(resolvedEnv).not.toBeNull(); | ||
expect(resolvedEnv.pcEnvTld).toBe('mypurecloud.com'); | ||
expect(resolvedEnv.pcAppOrigin).toBe('https://apps.mypurecloud.com'); | ||
}); | ||
const variations = [ | ||
` ${seedTld}`, // Leading whitespace | ||
` ${seedTld}`, // Leading multi-whitespace | ||
`${seedTld} `, // Trailing whitespace | ||
`${seedTld} `, // Trailing multi-whitespace | ||
` ${seedTld} `, // Both Leading and Trailing whitespace | ||
`.${seedTld}`, // Leading dot | ||
` .${seedTld}`, // Leading whitespace and dot | ||
`${seedTld}/`, // Trailing slash | ||
`${seedTld}/ `, // Trailing slash and whitespace | ||
` .${seedTld}/ ` // All of the above | ||
]; | ||
it('should resolve a local environment object with a custom dev origin if passed', () => { | ||
const env = envUtils.lookupPcEnv('localhost', true, [], 'https://localhost:3000')!; | ||
expect(env).not.toBeNull(); | ||
expect(env.pcEnvTld).toBe('localhost'); | ||
expect(env.pcAppOrigin).toBe('https://localhost:3000'); | ||
}); | ||
variations.forEach(currTld => { | ||
const resolvedEnv = envUtils.lookupPcEnv(currTld, true)!; | ||
expect(resolvedEnv.pcEnvTld).toBe(seedTld); | ||
expect(resolvedEnv.pcAppOrigin).toBe(`https://apps.${seedTld}`); | ||
}); | ||
}); | ||
it('should return null if the pcEnvTld cannot be parsed or is unknown', () => { | ||
const seedTld = 'mypurecloud.com'; | ||
it('should resolve an env when in the list of TLDs passed in via param', () => { | ||
const resolvedEnv = envUtils.lookupPcEnv('example.com', true, ['example.com'])!; | ||
expect(resolvedEnv).not.toBeNull(); | ||
expect(resolvedEnv.pcEnvTld).toBe('example.com'); | ||
expect(resolvedEnv.pcAppOrigin).toBe('https://apps.example.com'); | ||
}); | ||
const variations = [ | ||
undefined, | ||
null, | ||
3, | ||
{foo: 1}, | ||
[], | ||
'', // Empty string | ||
' ', // Blank string | ||
`apps.${seedTld}`, // Subdomain | ||
`https://apps.${seedTld}`, // FQDN | ||
`. ${seedTld} /`, // Inner whitespace | ||
'mypurecloud.io', // Valid TLD, but invalid PC Env TLD | ||
'mypurecloud.com.evil.com', // Evil subdomains | ||
'usw3.pure.cloud' // Valid PC Env TLD, but invalid subdomain | ||
]; | ||
it('should not resolve an env when it is not in the list of TLDs passed in via param', () => { | ||
const env = envUtils.lookupPcEnv('example2.com', true, ['example.com']); | ||
expect(env).toBeNull(); | ||
}); | ||
variations.forEach(currTld => { | ||
// @ts-expect-error | ||
let resolvedEnv = envUtils.lookupPcEnv(currTld); | ||
expect(resolvedEnv).toBe(null); | ||
it('should allow lenient parsing of TLDs and return the environment object', () => { | ||
const seedTld = 'mypurecloud.com'; | ||
const variations = [ | ||
` ${seedTld}`, // Leading whitespace | ||
` ${seedTld}`, // Leading multi-whitespace | ||
`${seedTld} `, // Trailing whitespace | ||
`${seedTld} `, // Trailing multi-whitespace | ||
` ${seedTld} `, // Both Leading and Trailing whitespace | ||
`.${seedTld}`, // Leading dot | ||
` .${seedTld}`, // Leading whitespace and dot | ||
`${seedTld}/`, // Trailing slash | ||
`${seedTld}/ `, // Trailing slash and whitespace | ||
` .${seedTld}/ ` // All of the above | ||
]; | ||
variations.forEach(currTld => { | ||
const resolvedEnv = envUtils.lookupPcEnv(currTld, true)!; | ||
expect(resolvedEnv.pcEnvTld).toBe(seedTld); | ||
expect(resolvedEnv.pcAppOrigin).toBe(`https://apps.${seedTld}`); | ||
// Doesn't matter if it's lenient | ||
// @ts-expect-error | ||
resolvedEnv = envUtils.lookupPcEnv(currTld, true); | ||
expect(resolvedEnv).toBe(null); | ||
}); | ||
}); | ||
}); | ||
describe('lookupGcEnv', () => { | ||
it('should return null if the url cannot be parsed', () => { | ||
const variations = [ | ||
undefined, | ||
null, | ||
3, | ||
{foo: 1}, | ||
[], | ||
'', // Empty string | ||
' ', // Blank string | ||
'. https://apps.mypurecloud.io /', // Inner whitespace | ||
'apps.mypurecloud.com', // Missing protocol | ||
]; | ||
variations.forEach((currentVariation) => { | ||
// @ts-expect-error | ||
const resolvedEnv = envUtils.lookupGcEnv(currentVariation, 'prod'); | ||
expect(resolvedEnv).toBe(null); | ||
}); | ||
}); | ||
it('should fail if the targetEnv does not point to a valid env name', () => { | ||
expect(envUtils.lookupGcEnv('https://localhost:8443', 'prod-noMatch')).toBe(null); | ||
expect(envUtils.lookupGcEnv('https://apps.mypurecloud.com', 'prod-noMatch')).toBe(null); | ||
}); | ||
it('should fail if the targetOrigin does not match a known environment', () => { | ||
expect(envUtils.lookupGcEnv('https://apps.mypurecloud.com.nomatch', 'prod')).toBe(null); | ||
}); | ||
it('should allow localhost origins with a valid targetEnv', () => { | ||
expect(envUtils.lookupGcEnv('http://127.0.0.1:8080', 'prod')).toEqual({ | ||
pcEnvTld: 'localhost', | ||
pcAppOrigin: 'http://127.0.0.1:8080' | ||
}); | ||
expect(envUtils.lookupGcEnv('https://localhost:8443', 'prod-apne1')).toEqual({ | ||
pcEnvTld: 'localhost', | ||
pcAppOrigin: 'https://localhost:8443' | ||
}); | ||
}); | ||
it('should enforce that targetEnv matches the matched origin for a given env', () => { | ||
const prodApne1Origin = 'https://apps.mypurecloud.jp'; | ||
it('should return null if the pcEnvTld cannot be parsed or is unknown', () => { | ||
const seedTld = 'mypurecloud.com'; | ||
const variations = [ | ||
undefined, | ||
null, | ||
3, | ||
{foo: 1}, | ||
[], | ||
'', // Empty string | ||
' ', // Blank string | ||
`apps.${seedTld}`, // Subdomain | ||
`https://apps.${seedTld}`, // FQDN | ||
`. ${seedTld} /`, // Inner whitespace | ||
'mypurecloud.io', // Valid TLD, but invalid PC Env TLD | ||
'mypurecloud.com.evil.com', // Evil subdomains | ||
'usw3.pure.cloud' // Valid PC Env TLD, but invalid subdomain | ||
]; | ||
variations.forEach(currTld => { | ||
// @ts-expect-error | ||
let resolvedEnv = envUtils.lookupPcEnv(currTld); | ||
expect(resolvedEnv).toBe(null); | ||
// Doesn't matter if it's lenient | ||
// @ts-expect-error | ||
resolvedEnv = envUtils.lookupPcEnv(currTld, true); | ||
expect(resolvedEnv).toBe(null); | ||
expect(envUtils.lookupGcEnv(prodApne1Origin, 'prod')).toBe(null); | ||
expect(envUtils.lookupGcEnv(prodApne1Origin, 'prod-apne1')).toEqual({ | ||
pcEnvTld: 'mypurecloud.jp', | ||
pcAppOrigin: 'https://apps.mypurecloud.jp' | ||
}); | ||
}); | ||
it('should use the specified url origin as the pcAppOrigin used for communicating with the host app', () => { | ||
expect(envUtils.lookupGcEnv('https://app.mypurecloud.jp', 'prod-apne1')).toEqual({ | ||
pcEnvTld: 'mypurecloud.jp', | ||
pcAppOrigin: 'https://app.mypurecloud.jp' | ||
}); | ||
// This case of non-standard port is allowed, but, unlikely to be used | ||
expect(envUtils.lookupGcEnv('https://apps.mypurecloud.jp:8443', 'prod-apne1')).toEqual({ | ||
pcEnvTld: 'mypurecloud.jp', | ||
pcAppOrigin: 'https://apps.mypurecloud.jp:8443' | ||
}); | ||
}); | ||
it('should support custom envs provided via environment variables', () => { | ||
// Tests assume a prod-unit-testing env has been configured in this unit testing env (see karma.conf.js) | ||
expect(envUtils.lookupGcEnv('https://localhost:8443', 'prod-unit-testing')).toEqual({ | ||
pcEnvTld: 'localhost', | ||
pcAppOrigin: 'https://localhost:8443' | ||
}); | ||
expect(envUtils.lookupGcEnv('https://apps.unit1.pure.cloud', 'prod-unit-testing')).toEqual({ | ||
pcEnvTld: 'unit1.pure.cloud', | ||
pcAppOrigin: 'https://apps.unit1.pure.cloud' | ||
}); | ||
expect(envUtils.lookupGcEnv('https://app.unit1.test.ftw', 'prod-unit-testing')).toEqual({ | ||
pcEnvTld: 'unit1.pure.cloud', | ||
pcAppOrigin: 'https://app.unit1.test.ftw' | ||
}); | ||
expect(envUtils.lookupGcEnv('https://app.unit1.test.ftw.nomatch', 'prod-unit-testing')).toBe(null); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
618918
10821
48