Skip to content

Commit

Permalink
feat: add timestamp to session generations in o-tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
danail-s committed Oct 24, 2024
1 parent 010162c commit 37ed21f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 9 deletions.
1 change: 1 addition & 0 deletions libraries/o-tracking/src/javascript/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function track(config, callback = function(){ /* empty */}) {
device: {
spoor_session: currentSession.id,
spoor_session_is_new: currentSession.isNew,
spoor_session_timestamp: currentSession.timestamp,
spoor_id: userID(),
},
};
Expand Down
40 changes: 32 additions & 8 deletions libraries/o-tracking/src/javascript/core/session.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {is, merge, isUndefined, guid} from '../utils.js';
import {is, merge, isUndefined, guid, namedLog} from '../utils.js';
import {Store} from './store.js';

/**
* @typedef {object} Session
* @property {string} id - The id of the session
* @property {boolean} isNew - Whether it is a brand new session
* @property {number} timestamp - The timestamp of the session generation
*/

let store;
const logger = namedLog('Core.Session')
const defaultSessionConfig = {
storage: 'best',
name: 'session',
Expand All @@ -20,14 +22,20 @@ const defaultSessionConfig = {
* @param {string} session - The session to be stored.
* @returns {void}
*/
function setSession(session) {
function setSession(session, timestamp) {
const d = new Date();
d.setTime(d.getTime() + store.config.expires);

store.write({
const sessionData = {
value: session,
expiry: d.valueOf()
});
expiry: d.valueOf(),
}
if(timestamp) {
sessionData.timestamp = timestamp;
}
logger('Setting session', sessionData)

store.write(sessionData);
}

/**
Expand All @@ -39,32 +47,48 @@ function getSession() {
const s = store.read();
let session;
let isNew = false;
let sessionTimestamp;

if (s) {
const d = new Date().valueOf();
logger("Found session", s)
const currentDate = new Date();
const d = currentDate.valueOf();
const timestamp = currentDate.getTime();
const exp = parseInt(s.expiry, 10);

// If current session is active.
if (exp >= d) {
session = s.value;
sessionTimestamp = s.timestamp;

// session is active but no generated timestamp
if(!sessionTimestamp) {
logger("Session is valid but no timestamp, generating timestamp.")
sessionTimestamp = timestamp;
}
} else {
// session has expired, generate a new one
// session has expired, generate a new one along with a new timestamp
logger("Session has expired, generating new one")
sessionTimestamp = timestamp;
session = guid();
isNew = true;
}
}

// No active session, gen a new one.
if (!session) {
logger("No session found, generating new one")
session = guid();
sessionTimestamp = new Date().getTime();
isNew = true;
}

// Refreshes the cookie...
setSession(session);
setSession(session, sessionTimestamp);

return {
id: session,
timestamp: sessionTimestamp,
isNew: isNew
};
}
Expand Down
21 changes: 21 additions & 0 deletions libraries/o-tracking/src/javascript/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,26 @@ function log(...args) {
}
}

/**
* Creates a logging function that logs messages to the console with a specified namespace.
*
* @function namedLog
* @param {string} namespace - The namespace to be prefixed to each log message.
* @returns {function} A function that logs messages to the console with the given namespace if the configuration allows.
*
* @example
* const log = namedLog('MyNamespace');
* log('This is a message');
* // Output: [MyNamespace]: This is a message
*/
function namedLog(namespace) {
return function(...args) {
if(get('config').test && window.console) {
window.console.log(`%c[${namespace}]:`, 'color: teal', ...args)
}
}
}

/**
* Tests if variable is a certain type. Defaults to check for undefined if no type specified.
*
Expand Down Expand Up @@ -389,6 +409,7 @@ function isDeepEqual(a, b) {

export {
log,
namedLog,
is,
is as isUndefined,
merge,
Expand Down
3 changes: 2 additions & 1 deletion libraries/o-tracking/test/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ describe('Core', function () {
proclaim.equal(sent_data.user.user_id, "userID");

// Device
proclaim.deepEqual(Object.keys(sent_data.device), ["spoor_session","spoor_session_is_new","spoor_id"]);
proclaim.deepEqual(Object.keys(sent_data.device), ["spoor_session","spoor_session_is_new","spoor_session_timestamp", "spoor_id"]);
proclaim.equal(sent_data.device.spoor_session, session().id);
proclaim.equal(sent_data.device.spoor_session_is_new, session().isNew);
proclaim.equal(sent_data.device.spoor_session_timestamp, session().timestamp);

});

Expand Down
15 changes: 15 additions & 0 deletions libraries/o-tracking/test/core/session.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('Core.Session', function () {
const newSession = getSession();
proclaim.equal(newSession.id, session.id);
proclaim.equal(newSession.isNew, false);
proclaim.equal(newSession.timestamp, session.timestamp)
});
});

Expand All @@ -59,6 +60,20 @@ describe('Core.Session', function () {
proclaim.isTrue(newSession.isNew);
done();
}, 2)
});

it('should generate timestamp for session', () => {
const currentTimestamp = new Date().getTime();
proclaim.equal(currentTimestamp, getSession().timestamp)
})

it('should generate a new timestamp if session has expired', (done) => {
const prevSession = initSession({expires: 1});
setTimeout(function() {
const newSession = getSession();
proclaim.notEqual(prevSession.timestamp, newSession.timestamp);
done()
}, 2)
})
})
});

0 comments on commit 37ed21f

Please sign in to comment.