Ghost/ghost/member-attribution/lib/history.js
Fabien "egg" O'Carroll 4718171b1d Removed out of date history items from UrlHistory
In case there is an issue with the filtering of items in our client
side attribution script, we also check for and remove out of date
items here. This ensures that we do not erroneously attribute signups
or conversions to webpages from more than 24h ago.
2022-08-25 16:09:34 -04:00

77 lines
1.5 KiB
JavaScript

/**
* @typedef {Object} UrlHistoryItem
* @prop {string} path
* @prop {number} time
*/
/**
* @typedef {UrlHistoryItem[]} UrlHistoryArray
*/
/**
* Represents a validated history
*/
class UrlHistory {
/**
* @private
* @param {UrlHistoryArray} urlHistory
*/
constructor(urlHistory) {
/** @private */
this.history = urlHistory;
}
get length() {
return this.history.length;
}
/**
* Iterate from latest item to newest item (reversed!)
*/
*[Symbol.iterator]() {
yield* this.history.slice().reverse();
}
/**
* @private
* @param {any[]} history
* @returns {boolean}
*/
static isValidHistory(history) {
for (const item of history) {
if (typeof item?.path !== 'string' || !Number.isSafeInteger(item?.time)) {
return false;
}
}
return true;
}
/**
* @param {unknown} urlHistory
* @returns {UrlHistory}
*/
static create(urlHistory) {
if (!Array.isArray(urlHistory)) {
return new UrlHistory([]);
}
if (!this.isValidHistory(urlHistory)) {
return new UrlHistory([]);
}
const now = Date.now();
const filteredHistory = urlHistory.filter((item) => {
return now - item.time < this.MAX_AGE;
});
return new UrlHistory(filteredHistory);
}
/**
* @private
*/
static MAX_AGE = 1000 * 60 * 60 * 24;
}
module.exports = UrlHistory;