Last active
November 1, 2019 20:11
-
-
Save gioragutt/aac37fa00f8aadd81cd1fd5edf888107 to your computer and use it in GitHub Desktop.
Reverse engineered HotJar-iframe script, handles analytics action permission handling and passes actions to the parent site.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
function HtmlStorageWrapper(storage) { | |
return { | |
get: function (key) { | |
const valueFromStorage = JSON.parse(storage.getItem(key)); | |
return !valueFromStorage || Date.parse(valueFromStorage.expires) <= (new Date).getTime() | |
? (storage.removeItem(key), null) | |
: valueFromStorage.value | |
}, | |
set: function (key, value, expiresDate) { | |
value = { | |
value: value, | |
expires: expiresDate.toUTCString() | |
}; | |
storage.setItem(key, JSON.stringify(value)) | |
}, | |
remove: function (key) { | |
storage.removeItem(key) | |
} | |
} | |
} | |
let htmlStorages; | |
try { | |
htmlStorages = { | |
cookie: { | |
get: function (key) { | |
return (key = RegExp("(?:^|; )" + key + "=([^;]*)").exec(document.cookie)) ? key[1] : void 0 | |
}, | |
set: function (key, value, expiresInDate) { | |
document.cookie = key + "=" + value + "; path=/; expires=" + expiresInDate.toUTCString() | |
}, | |
remove: function (key) { | |
document.cookie = key + "=; expires=Tue, 13 Mar 1979 00:00:00 UTC; path=/;" | |
} | |
}, | |
localStorage: HtmlStorageWrapper(localStorage), | |
sessionStorage: HtmlStorageWrapper(sessionStorage) | |
} | |
} catch (t) { | |
return | |
} | |
function StoredPermission(storageName, readPermissionList, writePermissionList, excludeSiteIdFromStorageKey) { | |
this.parseCommand = function (eventData, origin) { | |
const storage = htmlStorages[storageName]; | |
const { action, key, messageId, value, siteId } = eventData; | |
const storageKey = excludeSiteIdFromStorageKey ? key : key + ":" + siteId; | |
const expiresInMinutes = eventData.expiresMinutes || 1440 * (eventData.expiresDays || 365); | |
const expiresDate = function () { | |
const a = new Date; | |
a.setTime(a.getTime() + expiresInMinutes * 60 * 1000); | |
return a; | |
}(); | |
if (!function () { | |
const actionToPermissionList = { | |
_hjSet: writePermissionList, | |
_hjGet: readPermissionList, | |
_hjRemove: writePermissionList | |
}[action] || []; | |
return 0 <= actionToPermissionList.indexOf("*") || | |
0 <= actionToPermissionList.indexOf(origin); | |
}()) { | |
throw Error("Command " + action + " not allowed on key: " + key); | |
} | |
function bubbleEventToWindowParent() { | |
const message = JSON.stringify({ | |
messageId: messageId, | |
value: value || !1 | |
}); | |
window.parent.postMessage(message, "*"); | |
} | |
switch (action) { | |
case "_hjSet": | |
storage.set(storageKey, value, expiresDate); | |
break; | |
case "_hjGet": | |
value = storage.get(storageKey); | |
bubbleEventToWindowParent(); | |
break; | |
case "_hjRemove": storage.remove(storageKey); | |
} | |
}; | |
} | |
const permissions = { | |
_hjOptOut: new StoredPermission("cookie", ["*"], [ | |
"https://www.hotjar.com", | |
"https://local.hotjar.com", | |
"http://local.hotjar.com", | |
"https://insights-staging.hotjar.com", | |
"http://insights-staging.hotjar.com" | |
], true), | |
grant_consent: new StoredPermission("cookie", ["*"], ["*"], false), | |
screenshot_retake: new StoredPermission("localStorage", ["*"], ["*"], false), | |
screenshot_active_retake: new StoredPermission("sessionStorage", ["*"], ["*"], false), | |
form_html: new StoredPermission("localStorage", [ | |
"https://insights.hotjar.com", | |
"https://insights-stating.hotjar.com", | |
"https://local.hotjar.com" | |
], ["*"], true) | |
}; | |
function handleEvent(event) { | |
try { | |
const eventData = JSON.parse(event.data); | |
eventData.key && | |
permissions[eventData.key] && | |
permissions[eventData.key].parseCommand(eventData, event.origin) | |
} catch (c) { | |
return null | |
} | |
} | |
window.addEventListener | |
? window.addEventListener("message", handleEvent, false) | |
: window.attachEvent("onmessage", handleEvent) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment