Skip to content

Commit a9ff324

Browse files
authored
fix: skip top domain when cookie is disabled (#580)
1 parent 04ed78d commit a9ff324

10 files changed

+82
-42
lines changed

src/amplitude-client.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import utils from './utils';
1515
import UUID from './uuid';
1616
import base64Id from './base64Id';
1717
import DEFAULT_OPTIONS from './options';
18-
import getHost from './get-host';
1918
import baseCookie from './base-cookie';
2019
import { AmplitudeServerZone, getEventLogApi } from './server-zone';
2120
import ConfigManager from './config-manager';
@@ -309,7 +308,7 @@ AmplitudeClient.prototype._runNewSessionStartCallbacks = function () {
309308
};
310309

311310
AmplitudeClient.prototype.deleteLowerLevelDomainCookies = function () {
312-
const host = getHost();
311+
const host = utils.getHost();
313312

314313
const cookieHost =
315314
this.options.domain && this.options.domain[0] === '.' ? this.options.domain.slice(1) : this.options.domain;

src/base-cookie.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Constants from './constants';
2-
import base64Id from './base64Id';
32
import utils from './utils';
43

54
const get = (name) => {
@@ -94,7 +93,7 @@ const sortByEventTime = (cookies) => {
9493

9594
// test that cookies are enabled - navigator.cookiesEnabled yields false positives in IE, need to test directly
9695
const areCookiesEnabled = (opts = {}) => {
97-
const cookieName = Constants.COOKIE_TEST_PREFIX + base64Id();
96+
const cookieName = Constants.COOKIE_TEST_PREFIX;
9897
if (typeof document === 'undefined') {
9998
return false;
10099
}

src/cookie.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import Base64 from './base64';
66
import utils from './utils';
7-
import getLocation from './get-location';
87
import baseCookie from './base-cookie';
98
import topDomain from './top-domain';
109

@@ -31,7 +30,7 @@ var options = function (opts) {
3130
_options.secure = opts.secure;
3231
_options.sameSite = opts.sameSite;
3332

34-
var domain = !utils.isEmptyString(opts.domain) ? opts.domain : '.' + topDomain(getLocation().href);
33+
var domain = !utils.isEmptyString(opts.domain) ? opts.domain : '.' + topDomain(utils.getLocation().href);
3534
var token = Math.random();
3635
_options.domain = domain;
3736
set('amplitude_test', token);

src/get-host.js

-19
This file was deleted.

src/get-location.js

-7
This file was deleted.

src/metadata-storage.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import Base64 from './base64';
77
import baseCookie from './base-cookie';
88
import Constants from './constants';
9-
import getLocation from './get-location';
109
import ampLocalStorage from './localstorage';
1110
import topDomain from './top-domain';
1211
import utils from './utils';
@@ -35,8 +34,8 @@ class MetadataStorage {
3534
this.expirationDays = expirationDays;
3635

3736
this.cookieDomain = '';
38-
const loc = getLocation() ? getLocation().href : undefined;
39-
const writableTopDomain = topDomain(loc);
37+
const loc = utils.getLocation() ? utils.getLocation().href : undefined;
38+
const writableTopDomain = !disableCookies ? topDomain(loc) : '';
4039
this.cookieDomain = domain || (writableTopDomain ? '.' + writableTopDomain : null);
4140

4241
if (storageOptionExists[storage]) {

src/top-domain.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import baseCookie from './base-cookie';
22
import base64Id from './base64Id';
3-
import getHost from './get-host';
43
import utils from './utils';
54

65
// Utility that finds top level domain to write to
76
const topDomain = (url) => {
8-
const host = getHost(url);
7+
const host = utils.getHost(url);
98
const parts = host.split('.');
109
const levels = [];
1110
const cname = '_tldtest_' + base64Id();

src/utils.js

+22
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,26 @@ const validateSessionId = (sessionId) => {
287287
return false;
288288
};
289289

290+
const getLocation = () => {
291+
return GlobalScope.location;
292+
};
293+
294+
const getHost = (url) => {
295+
const defaultHostname = GlobalScope.location ? GlobalScope.location.hostname : '';
296+
if (url) {
297+
if (typeof document !== 'undefined') {
298+
const a = document.createElement('a');
299+
a.href = url;
300+
return a.hostname || defaultHostname;
301+
}
302+
if (typeof URL === 'function') {
303+
const u = new URL(url);
304+
return u.hostname || defaultHostname;
305+
}
306+
}
307+
return defaultHostname;
308+
};
309+
290310
export default {
291311
setLogLevel,
292312
getLogLevel,
@@ -303,4 +323,6 @@ export default {
303323
validateDeviceId,
304324
validateTransport,
305325
validateSessionId,
326+
getLocation,
327+
getHost,
306328
};

test/amplitude-client.js

+36-5
Original file line numberDiff line numberDiff line change
@@ -2739,23 +2739,54 @@ describe('AmplitudeClient', function () {
27392739
});
27402740
});
27412741

2742-
it('should not create any cookies if disabledCookies = true', function () {
2742+
it('should not use any cookies with simple host if disabledCookies = true', function () {
27432743
deleteAllCookies();
27442744
clock.tick(20);
27452745

27462746
var cookieArray = getAllCookies();
27472747
assert.equal(cookieArray.length, 0);
27482748

27492749
var deviceId = 'test_device_id';
2750-
var amplitude2 = new AmplitudeClient();
2750+
var amplitude = new AmplitudeClient();
27512751

2752-
amplitude2.init(apiKey, null, {
2752+
amplitude.init(apiKey, null, {
2753+
deviceId: deviceId,
2754+
disableCookies: true,
2755+
});
2756+
2757+
cookieArray = getAllCookies();
2758+
assert.equal(cookieArray.length, 0);
2759+
});
2760+
2761+
it('should not use any cookies with multiple domains in host if disabledCookies = true', function () {
2762+
const stubbedGetLocation = sinon.stub(utils, 'getLocation').returns({ href: 'https://abc.def.xyz/test' });
2763+
const spiedSet = sinon.spy(baseCookie, 'set');
2764+
const spiedGet = sinon.spy(baseCookie, 'get');
2765+
deleteAllCookies();
2766+
clock.tick(20);
2767+
2768+
var cookieArray = getAllCookies();
2769+
assert.equal(cookieArray.length, 0);
2770+
2771+
var deviceId = 'test_device_id';
2772+
var amplitude = new AmplitudeClient();
2773+
2774+
amplitude.init(apiKey, null, {
27532775
deviceId: deviceId,
27542776
disableCookies: true,
27552777
});
27562778

27572779
cookieArray = getAllCookies();
27582780
assert.equal(cookieArray.length, 0);
2781+
2782+
// spied cookie operations should not be fired
2783+
assert.equal(spiedSet.called, false);
2784+
assert.equal(spiedGet.called, false);
2785+
2786+
// restore stub, spy
2787+
stubbedGetLocation.restore();
2788+
spiedSet.restore();
2789+
spiedGet.restore();
27592790
});
27602791

27612792
it('should create cookies if disabledCookies = false', function () {
@@ -2766,9 +2797,9 @@ describe('AmplitudeClient', function () {
27662797
assert.equal(cookieArray.length, 0);
27672798

27682799
var deviceId = 'test_device_id';
2769-
var amplitude2 = new AmplitudeClient();
2800+
var amplitude = new AmplitudeClient();
27702801

2771-
amplitude2.init(apiKey, null, {
2802+
amplitude.init(apiKey, null, {
27722803
deviceId: deviceId,
27732804
disableCookies: false,
27742805
});

test/utils.js

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sinon from 'sinon';
22
import utils from '../src/utils.js';
33
import constants from '../src/constants.js';
4+
import GlobalScope from '../src/global-scope';
45

56
describe('utils', function () {
67
describe('isEmptyString', function () {
@@ -280,4 +281,21 @@ describe('utils', function () {
280281
assert.isFalse(utils.validateSessionId(false));
281282
});
282283
});
284+
285+
describe('getHost', function () {
286+
it('should return hostname for url', function () {
287+
const url = 'https://amplitude.is.good.com/test';
288+
assert.equal(utils.getHost(url), 'amplitude.is.good.com');
289+
});
290+
291+
it('should return current hostname if no url is provided', function () {
292+
assert.equal(utils.getHost(), GlobalScope.location.hostname);
293+
});
294+
});
295+
296+
describe('getLocation', function () {
297+
it('should return global location', function () {
298+
assert.equal(utils.getLocation(), GlobalScope.location);
299+
});
300+
});
283301
});

0 commit comments

Comments
 (0)