Skip to content

Commit

Permalink
Merge pull request #501 from Countly/set_id-addition
Browse files Browse the repository at this point in the history
Set ID method
  • Loading branch information
turtledreams committed Jun 12, 2024
2 parents a6af6d8 + adf8c6e commit 1382f76
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 47 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 24.4.1
- Added types for the SDK
- Added a new method `set_id(newDeviceId)` for managing device id changes according to the device ID Type

## 24.4.0
! Minor breaking change ! For implementations using `salt` the browser compatability is tied to SubtleCrypto's `digest` method support
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/bridge_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function initMain(name, version) {
}

const SDK_NAME = "javascript_native_web";
const SDK_VERSION = "24.4.0";
const SDK_VERSION = "24.4.1";

// tests
describe("Bridged SDK Utilities Tests", () => {
Expand Down
66 changes: 65 additions & 1 deletion cypress/integration/device_id_change.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ describe("Device ID change tests ", ()=>{
});
});
});
it("Check init time temp mode with set_id", () => {
hp.haltAndClearStorage(() => {
initMain(true); // init in offline mode
testDeviceIdInReqs(() => {
Countly.set_id("new ID");
});
});
});

// ========================================
// default init configuration tests
Expand Down Expand Up @@ -209,4 +217,60 @@ describe("Device ID change tests ", ()=>{
});
});
});
});
});

describe("Set ID change tests ", () => {
it("set_id should be non merge as there was dev provided id", () => {
hp.haltAndClearStorage(() => {
Countly.init({
app_key: "YOUR_APP_KEY",
url: "https://your.domain.count.ly",
test_mode: true,
debug: true,
device_id: "old ID"
});
Countly.add_event(eventObj("1")); // record an event.
cy.wait(500); // wait for the request to be sent
cy.fetch_local_request_queue().then((eq) => {
expect(eq[0].device_id).to.equal("old ID");
Countly.set_id("new ID");
Countly.add_event(eventObj("2")); // record another event
cy.wait(500); // wait for the request to be sent
cy.fetch_local_request_queue().then((eq2) => {
expect(eq2.length).to.equal(3); // no merge request
expect(eq2[0].device_id).to.equal("old ID");
expect(eq2[0].events).to.contains("\"key\":\"1\"");
expect(eq2[1].device_id).to.equal("new ID");
expect(eq2[1].begin_session).to.equal(1);
expect(eq2[2].device_id).to.equal("new ID");
expect(eq2[2].events).to.contains("\"key\":\"2\"");
});
});
});
});
it("set_id should be merge as there was sdk generated id", () => {
hp.haltAndClearStorage(() => {
initMain(false); // init normally
Countly.add_event(eventObj("1")); // record an event.
cy.wait(500); // wait for the request to be sent
let generatedID;
cy.fetch_local_request_queue().then((eq) => {
cy.log(eq);
generatedID = eq[0].device_id; // get the new id from first item in the queue
Countly.set_id("new ID");
Countly.add_event(eventObj("2")); // record another event
cy.wait(500); // wait for the request to be sent
cy.fetch_local_request_queue().then((eq2) => {
cy.log(eq2);
expect(eq2.length).to.equal(3); // merge request
expect(eq2[0].device_id).to.equal(generatedID);
expect(eq2[0].events).to.contains("\"key\":\"1\"");
expect(eq2[1].device_id).to.equal("new ID");
expect(eq2[1].old_device_id).to.equal(generatedID);
expect(eq2[2].device_id).to.equal("new ID");
expect(eq2[2].events).to.contains("\"key\":\"2\"");
});
});
});
});
});
8 changes: 7 additions & 1 deletion lib/countly.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,18 @@ declare module "countly-sdk-web" {
function end_session(sec: number, force: boolean): void;

/**
* Change current user/device id
* Change current user/device id (use set_id instead if you are not sure about the merge operation)
* @param {string} newId - new user/device ID to use. Must be a non-empty string value. Invalid values (like null, empty string or undefined) will be rejected
* @param {boolean} merge - move data from old ID to new ID on server
*/
function change_id(newId: string, merge: boolean): void;

/**
* Changes the current device ID according to the device ID type (the preffered method)
* @param {string} newId - new user/device ID to use. Must be a non-empty string value. Invalid values (like null, empty string or undefined) will be rejected
*/
function set_id(newId: string): void;

/**
* Report custom event
* @param {Object} event - Countly {@link Event} object
Expand Down
104 changes: 61 additions & 43 deletions lib/countly.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@
statusCode: "cly_hc_status_code",
errorMessage: "cly_hc_error_message"
});
var SDK_VERSION = "24.4.0";
var SDK_VERSION = "24.4.1";
var SDK_NAME = "javascript_native_web";

// Using this on document.referrer would return an array with 17 elements in it. The 12th element (array[11]) would be the path we are looking for. Others would be things like password and such (use https://regex101.com/ to check more)
Expand Down Expand Up @@ -1752,17 +1752,33 @@
};

/**
* Change current user/device id
* Changes the current device ID according to the device ID type (the preffered method)
* @param {string} newId - new user/device ID to use. Must be a non-empty string value. Invalid values (like null, empty string or undefined) will be rejected
* */
this.set_id = function (newId) {
log(logLevelEnums.INFO, "set_id, Changing the device ID to:[" + newId + "]");
if (newId == null || newId === "") {
log(logLevelEnums.WARNING, "set_id, The provided device is not a valid ID");
return;
}
if (deviceIdType === DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED) {
/*change ID without merge as current ID is Dev supplied, so not first login*/
this.change_id(newId, false);
} else {
/*change ID with merge as current ID is not Dev supplied*/
this.change_id(newId, true);
}
};

/**
* Change current user/device id (use set_id instead if you are not sure about the merge operation)
* @param {string} newId - new user/device ID to use. Must be a non-empty string value. Invalid values (like null, empty string or undefined) will be rejected
* @param {boolean} merge - move data from old ID to new ID on server
* */
this.change_id = function (newId, merge) {
log(logLevelEnums.INFO, "change_id, Changing the ID");
if (merge) {
log(logLevelEnums.INFO, "change_id, Will merge the IDs");
}
log(logLevelEnums.INFO, "change_id, Changing the device ID to: [" + newId + "] with merge:[" + merge + "]");
if (!newId || typeof newId !== "string" || newId.length === 0) {
log(logLevelEnums.ERROR, "change_id, The provided ID: [" + newId + "] is not a valid ID");
log(logLevelEnums.WARNING, "change_id, The provided device ID is not a valid ID");
return;
}
if (offlineMode) {
Expand All @@ -1772,41 +1788,43 @@
}
// eqeq is used here since we want to catch number to string checks too. type conversion might happen at a new init
// eslint-disable-next-line eqeqeq
if (this.device_id != newId) {
if (!merge) {
// process async queue before sending events
processAsyncQueue();
// empty event queue
sendEventsForced();
// end current session
this.end_session(null, true);
// clear timed events
timedEvents = {};
// clear all consents
this.remove_consent_internal(Countly.features, false);
}
var oldId = this.device_id;
this.device_id = newId;
self.device_id = this.device_id;
deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;
setValueInStorage("cly_id", this.device_id);
setValueInStorage("cly_id_type", DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED);
log(logLevelEnums.INFO, "change_id, Changing ID from:[" + oldId + "] to [" + newId + "]");
if (merge) {
// no consent check here since 21.11.0
toRequestQueue({
old_device_id: oldId
});
} else {
// start new session for new ID
this.begin_session(!autoExtend, true);
}
// if init time remote config was enabled with a callback function, remove currently stored remote configs and fetch remote config again
if (this.remote_config) {
remoteConfigs = {};
setValueInStorage("cly_remote_configs", remoteConfigs);
this.fetch_remote_config(this.remote_config);
}
if (this.device_id == newId) {
log(logLevelEnums.DEBUG, "change_id, Provided device ID is equal to the current device ID. Aborting.");
return;
}
if (!merge) {
// process async queue before sending events
processAsyncQueue();
// empty event queue
sendEventsForced();
// end current session
this.end_session(null, true);
// clear timed events
timedEvents = {};
// clear all consents
this.remove_consent_internal(Countly.features, false);
}
var oldId = this.device_id;
this.device_id = newId;
self.device_id = this.device_id;
deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED;
setValueInStorage("cly_id", this.device_id);
setValueInStorage("cly_id_type", DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED);
log(logLevelEnums.INFO, "change_id, Changing ID from:[" + oldId + "] to [" + newId + "]");
if (merge) {
// no consent check here since 21.11.0
toRequestQueue({
old_device_id: oldId
});
} else {
// start new session for new ID TODO: check this when no session tracking is enabled
this.begin_session(!autoExtend, true);
}
// if init time remote config was enabled with a callback function, remove currently stored remote configs and fetch remote config again
if (this.remote_config) {
remoteConfigs = {};
setValueInStorage("cly_remote_configs", remoteConfigs);
this.fetch_remote_config(this.remote_config);
}
};

Expand Down Expand Up @@ -5254,14 +5272,14 @@
isResponseValidBroad: isResponseValidBroad,
secureRandom: secureRandom,
log: log,
calculateChecksum: calculateChecksum,
checkIfLoggingIsOn: checkIfLoggingIsOn,
getMetrics: getMetrics,
getUA: getUA,
prepareRequest: prepareRequest,
generateUUID: generateUUID,
sendEventsForced: sendEventsForced,
isUUID: isUUID,
calculateChecksum: calculateChecksum,
isReferrerUsable: isReferrerUsable,
getId: getStoredIdOrGenerateId,
heartBeat: heartBeat,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "countly-sdk-web",
"version": "24.4.0",
"version": "24.4.1",
"description": "Countly Web SDK",
"main": "lib/countly.js",
"types": "lib/countly.d.ts",
Expand Down

0 comments on commit 1382f76

Please sign in to comment.