diff --git a/docs/generated/changelog.html b/docs/generated/changelog.html
index 0aec23b41..3082cfcf9 100644
--- a/docs/generated/changelog.html
+++ b/docs/generated/changelog.html
@@ -11,6 +11,17 @@
Agent-JS Changelog
Version x.x.x
+
+ Version 0.19.2
+
+ -
+ fix: subdomains on icp0.io and ic0.app were incorrectly sending requests to icp-api and
+ encountering CSP issues
+
+
+ Version 0.19.1
- fix: default host logic fixed and tests added
diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts
index 3adcda2e1..1df6284c7 100644
--- a/packages/agent/src/agent/http/http.test.ts
+++ b/packages/agent/src/agent/http/http.test.ts
@@ -763,7 +763,6 @@ test('should fetch with given call options and fetch options', async () => {
describe('default host', () => {
it('should use a default host of icp-api.io', () => {
const agent = new HttpAgent({ fetch: jest.fn() });
- window.location.hostname; //?
expect((agent as any)._host.hostname).toBe('icp-api.io');
});
it('should use a default of icp-api.io if location is not available', () => {
@@ -783,4 +782,32 @@ describe('default host', () => {
expect((agent as any)._host.hostname).toBe(host);
}
});
+ it('should correctly handle subdomains on known hosts', () => {
+ const knownHosts = ['ic0.app', 'icp0.io', 'localhost', '127.0.0.1'];
+ for (const host of knownHosts) {
+ delete window.location;
+ window.location = {
+ host: `foo.${host}`,
+ hostname: `rrkah-fqaaa-aaaaa-aaaaq-cai.${host}`,
+ protocol: 'https:',
+ } as any;
+ const agent = new HttpAgent({ fetch: jest.fn() });
+ expect((agent as any)._host.hostname).toBe(host);
+ }
+ });
+ it('should handle port numbers for localhost', () => {
+ const knownHosts = ['localhost', '127.0.0.1'];
+ for (const host of knownHosts) {
+ delete window.location;
+ // hostname is different from host when port is specified
+ window.location = {
+ host: `${host}:4943`,
+ hostname: `${host}`,
+ protocol: 'http:',
+ port: '4943',
+ } as any;
+ const agent = new HttpAgent({ fetch: jest.fn() });
+ expect((agent as any)._host.hostname).toBe(host);
+ }
+ });
});
diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts
index d1442f85b..e4b5d1e30 100644
--- a/packages/agent/src/agent/http/index.ts
+++ b/packages/agent/src/agent/http/index.ts
@@ -212,9 +212,17 @@ export class HttpAgent implements Agent {
}
// Mainnet and local will have the api route available
const knownHosts = ['ic0.app', 'icp0.io', 'localhost', '127.0.0.1'];
- if (location && knownHosts.includes(location.hostname)) {
+ const hostname = location?.hostname;
+ let knownHost;
+ if (hostname && typeof hostname === 'string') {
+ knownHost = knownHosts.find(host => hostname.endsWith(host));
+ }
+
+ if (location && knownHost) {
// If the user is on a boundary-node provided host, we can use the same host for the agent
- this._host = new URL(location + '');
+ this._host = new URL(
+ `${location.protocol}//${knownHost}${location.port ? ':' + location.port : ''}`,
+ );
} else {
this._host = new URL('https://icp-api.io');
console.warn(
diff --git a/packages/auth-client/src/index.test.ts b/packages/auth-client/src/index.test.ts
index 56a78e003..4e249d1ba 100644
--- a/packages/auth-client/src/index.test.ts
+++ b/packages/auth-client/src/index.test.ts
@@ -84,6 +84,9 @@ describe('Auth Client', () => {
(window as any).location = {
reload: jest.fn(),
fetch,
+ hostname: 'localhost',
+ protocol: 'http:',
+ port: '4943',
toString: jest.fn(() => 'http://localhost:4943'),
};