Skip to content
This repository has been archived by the owner on Nov 23, 2019. It is now read-only.

Add flag and logic to delete cross domain identifiers #54

Merged
merged 4 commits into from
Jan 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ var Segment = exports = module.exports = integration('Segment.io')
.option('apiKey', '')
.option('apiHost', 'api.segment.io/v1')
.option('crossDomainIdServers', [])
.option('deleteCrossDomainId', false)
.option('retryQueue', true)
.option('addBundledMetadata', false)
.option('unbundledIntegrations', []);
Expand Down Expand Up @@ -179,6 +180,9 @@ Segment.prototype.initialize = function() {
this.cookie('segment_cross_domain_id_timestamp', null);
}

// Delete cross domain identifiers.
this.deleteCrossDomainIdIfNeeded();

// At this moment we intentionally do not want events to be queued while we retrieve the `crossDomainId`
// so `.ready` will get called right away and we'll try to figure out `crossDomainId`
// separately
Expand Down Expand Up @@ -495,6 +499,41 @@ Segment.prototype.retrieveCrossDomainId = function(callback) {
}
};

/**
* Deletes any state persisted by cross domain analytics.
* * seg_xid (and metadata) from cookies
* * crossDomainId from traits in localStorage
*
* The deletion logic is run only if deletion is enabled for this project, and
* when either the seg_xid cookie or crossDomainId localStorage trait exists.
*
* @api private
*/
Segment.prototype.deleteCrossDomainIdIfNeeded = function() {
// Only continue if deletion is enabled for this project.
if (!this.options.deleteCrossDomainId) {
return;
}

// Delete the xid cookie if it exists. We also delete associated metadata.
if (this.cookie('seg_xid')) {
this.cookie('seg_xid', null);
this.cookie('seg_xid_fd', null);
this.cookie('seg_xid_ts', null);
}

// Delete the crossDomainId trait in localStorage if it exists.
if (this.analytics.user().traits().crossDomainId) {
// This intentionally uses an internal API, so that
// we can avoid interacting with lower level localStorage APIs, and instead
// leverage existing functionality inside analytics.js.

var traits = this.analytics.user().traits();
delete traits.crossDomainId;
this.analytics.user()._setTraits(traits);
}
};

/**
* getCrossDomainIdFromServers
* @param {Array} domains
Expand Down
95 changes: 95 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,101 @@ describe('Segment.io', function() {
assert.equal(segment.isCrossDomainAnalyticsEnabled(), true);
});
});

describe('deleteCrossDomainId', function() {
it('should not delete cross domain identifiers by default', function() {
segment.cookie('seg_xid', 'test_xid');
segment.cookie('seg_xid_ts', 'test_xid_ts');
segment.cookie('seg_xid_fd', 'test_xid_fd');
analytics.identify({
crossDomainId: 'test_xid'
});

segment.deleteCrossDomainIdIfNeeded();

assert.equal(segment.cookie('seg_xid'), 'test_xid');
assert.equal(segment.cookie('seg_xid_ts'), 'test_xid_ts');
assert.equal(segment.cookie('seg_xid_fd'), 'test_xid_fd');
assert.equal(analytics.user().traits().crossDomainId, 'test_xid');
});

it('should do not delete cross domain identifiers if disabled', function() {
segment.options.deleteCrossDomainId = false;

segment.cookie('seg_xid', 'test_xid');
segment.cookie('seg_xid_ts', 'test_xid_ts');
segment.cookie('seg_xid_fd', 'test_xid_fd');
analytics.identify({
crossDomainId: 'test_xid'
});

segment.deleteCrossDomainIdIfNeeded();

assert.equal(segment.cookie('seg_xid'), 'test_xid');
assert.equal(segment.cookie('seg_xid_ts'), 'test_xid_ts');
assert.equal(segment.cookie('seg_xid_fd'), 'test_xid_fd');
assert.equal(analytics.user().traits().crossDomainId, 'test_xid');
});

it('should delete cross domain identifiers if enabled', function() {
segment.options.deleteCrossDomainId = true;

segment.cookie('seg_xid', 'test_xid');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we could add seg_xid_fd and seg_xid_ts and then later verify that they are deleted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added!

segment.cookie('seg_xid_ts', 'test_xid_ts');
segment.cookie('seg_xid_fd', 'test_xid_fd');
analytics.identify({
crossDomainId: 'test_xid'
});

segment.deleteCrossDomainIdIfNeeded();

assert.equal(segment.cookie('seg_xid'), null);
assert.equal(segment.cookie('seg_xid_ts'), null);
assert.equal(segment.cookie('seg_xid_fd'), null);
assert.equal(analytics.user().traits().crossDomainId, null);
});

it('should delete localStorage trait even if only traits exists', function() {
segment.options.deleteCrossDomainId = true;

analytics.identify({
crossDomainId: 'test_xid'
});

segment.deleteCrossDomainIdIfNeeded();

assert.equal(analytics.user().traits().crossDomainId, null);
});

it('should delete xid cookie even if only cookie exists', function() {
segment.options.deleteCrossDomainId = true;

segment.cookie('seg_xid', 'test_xid');

segment.deleteCrossDomainIdIfNeeded();

assert.equal(segment.cookie('seg_xid'), null);
assert.equal(segment.cookie('seg_xid_ts'), null);
assert.equal(segment.cookie('seg_xid_fd'), null);
});

it('should not delete any other traits if enabled', function() {
segment.options.deleteCrossDomainId = true;

analytics.identify({
crossDomainId: 'test_xid',
name: 'Prateek',
age: 26
});

segment.deleteCrossDomainIdIfNeeded();

assert.deepEqual(analytics.user().traits(), {
name: 'Prateek',
age: 26
});
});
});
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there could be another test for the case when the cookie doesn't exist but crossDomainId trait in localStorage exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added 2 - one for that and one for reverse.

});
}
Expand Down