OK, so >90% of this looks like just a dump of the GFK Internet Monitor script, but here goes:
Code: Select all
Error: this.docShell is null
Source File: chrome://global/content/bindings/browser.xml
Line: 323
Warning: Unknown property 'align-self'. Declaration dropped.
Source File: resource://gre-resources/ua.css
Line: 45
Warning: Unknown property 'order'. Declaration dropped.
Source File: resource://gre-resources/ua.css
Line: 46
Warning: XUL box for _moz_generated_content_after element contained an inline #text child, forcing all its children to be wrapped in a block.
Source File: chrome://browser/content/browser.xul
Line: 0
Warning: Expected color but found 'top'. Error in parsing value for 'background-image'. Declaration dropped.
Source File: about:home
Line: 0
Warning: Expected color but found 'top'. Error in parsing value for 'background-image'. Declaration dropped.
Source File: about:home
Line: 0
Messages:
Could not read chrome manifest 'file:///C:/Program%20Files%20(x86)/Mozilla%20Firefox/extensions/%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D/chrome.manifest'.
Using Components.utils.import for global singleton
Imported
Registered for Extension events
Local Tracklet URL=file://C:/Program%20Files%20(x86)/GfK%20Internet-Monitor//tracklet.js
Successful load of local tracklet
/*ScriptletVersion: 270*/
var scriptlet_version = '270';
var component_versions = {"config_version":"69","helper":{"Helper":"103","CustomEventHelper":"104","Logger":"112"},"components":{"GfKBase":"105","GoogleInstantTracker":"106","WWSCookieTracker":"107","PageCookieTracker":"108","Fixes":"109","DomainCookieTracker":"110","GoogleSERPReferrerTracking":"111","ViewTimeMeasurement":"113","GlobalConfiguration":"114","ChromeFixes":"115"}};
//===================================================================
// UCTWinScriptlets: tracklet/helper/Helper.js
//===================================================================
/*jsl:declare Base64 */
/*jsl:declare JSON */
// Return a boolean value telling whether // the first argument is an Array object.
/**
* Encodes a given object to JSON
* @function
* @param object obj The object to be JSON encoded
* @returns string JSON string representing the object
*/
function json_encode(obj) {
var json = null;
if (JSON.stringify) {
json = JSON.stringify(obj);
} else if (JSON.toString) {
json = JSON.toString(obj);
}
return json;
}
/**
* Converts a given object to JSON an encodes the result to Base64
* @function
* @param object obj The object to be JSON encoded
* @returns string Base64 string representing the object
*/
function base64_json_encode(obj) {
return Base64.encode(json_encode(obj));
}
/**
* Checks wether an object is an array
* @function
* @param object obj The object to be checked
* @returns boolean True if the object is an array
* @example
* var test = new Array();
* isArray(test);
*/
function isArray() {
if (typeof arguments[0] == 'object') {
var criterion = arguments[0].constructor.toString().match(/array/i);
return (criterion !== null);
}
return false;
}
// Hilfsfunktion zum browserspezifischen Aufbau einer XHR Verbindung zu AdSimulator und serverseitigem Logging
/**
* Creates a browser independent XMLHTTPRequest
* @function
* @returns object XMLHttpRequest object
* @example
* var xhr=CreateXmlHttp();
* if (xhr) {
* xhr.open('GET', "http://example.de/test.php");
* xhr.send(null);
* }
*/
function CreateXmlHttp() {
if (GacelaStorageService.getStatic("BrowserType")=="Chrome") {
// This creates a simplified XMLHttpRequest Object which does not support all features, but can do Cross-Domain Request on Chrome
return createSimpleXMLHTTPRequest();
}
var xmlhttp = false;
var hasXMLHttpRequest = false;
try {
if (XMLHttpRequest) hasXMLHttpRequest=true;
}
catch (err) {
hasXMLHttpRequest = false;
}
if (hasXMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else if (ActiveXObject) {// code for IE
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (err) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (err2) {
xmlhttp=false;
}
}
}
return xmlhttp;
}
/**
* Sends data to an URL. Automatically checks if a & or a ? is needed when concatenating the extendedparams to the URL. <br />
* Adds a parameter <b>ts</b> to the end, which contains a timestamp to prevent caching effects. The answer of the server is not checked.
* @function
* @param string url The URL where the params should be sent to
* @param string extendedparams A string of GET parameters
* @returns boolean True if request has been sent, otherwise False
* @example
* var url = "http:example.de/test.php?id=12345";
* var extendedparams = "test=daten&daten=mist";
* BlindSend(url, extendedparams);
*/
function BlindSend(url, extendedparams){
try{
var glue = '?';
if(url.indexOf('?') >= 0) glue = '&';
var target = url + glue + extendedparams + "&ts=" + new Date().getTime();
var xhr=CreateXmlHttp();
if (xhr) {
xhr.open('GET', target);
xhr.onreadystatechange = function(){};
xhr.send(null);
return true;
}
return false;
}
catch(e){
return false;
}
}
/**
* Creates HTML Nodes from a JSON Object
* @param object doc The document object.
* @param object value The JSON object to create the node of.
* @returns object HTML Node
*/
function CreateNodeFromJSON(doc, value){
//create and return text node
if(value.tag == "#text") return doc.createTextNode(value.value);
//create node with tag
var node = doc.createElement(value.tag);
if(node === null || typeof(node) == 'undefined'){
Logger.log("ERROR", "CreateNodeFromJSON: Unable to create node for tag " + value.tag);
}
if(typeof(value.attributes) != 'undefined'){
for(var i = 0; i < value.attributes.length; i++){
try{
node.setAttribute(value.attributes[i].name, value.attributes[i].value);
}
catch(e){
Logger.log("ERROR", "CreateNodeFromJSON: Unable to set attribute " + value.attributes[i].name + "=" + value.attributes[i].value + " for tag " + value.tag);
}
}
}
if(typeof(value.styles) != 'undefined'){
for(var j = 0; j < value.styles.length; j++){
try{
node.style[value.styles[j].name] = value.styles[j].value;
}
catch(e){
Logger.log("ERROR", "CreateNodeFromJSON: Unable to set style " + value.styles[j].name + "=" + value.styles[j].value + " for tag " + value.tag);
}
}
}
if(typeof(value.children) != 'undefined'){
for(var k = 0; k < value.children.length; k++){
try{
var child = this.CreateNodeFromJSON(doc, value.children[k]);
node.appendChild(child);
}
catch(e){
Logger.log("ERROR", "CreateNodeFromJSON: Unable to set childnode " + child + " with tag " + value.children[k].tag + " in tag " + value.tag);
}
}
}
try{
if (typeof(value.className) != 'undefined') {
node.className = value.className;
}
}
catch(e){
Logger.log("ERROR", "CreateNodeFromJSON: Unable to set className " + value.className + " in tag " + value.tag);
}
try{
if (typeof(value.innerHTML) != 'undefined') {
node.innerHTML = value.innerHTML;
}
}
catch(e){
Logger.log("ERROR", "CreateNodeFromJSON: Unable to set innerHTML " + value.innerHTML + " in tag " + value.tag);
}
return node;
}
/**
* Compares two version numbers. <br />
* <font color='red'>Only works for Versions which consist of 2 numbers (e.g. <b>1.1</b> <b>10.2</b>)</font>
* @function
* @param string version1 First version number to be compared
* @param string version2 Second version number to be compared
* @returns int Returns <b>1</b> if version1 is bigger and <b>-1</b> if version2 is bigger. Returns <b>0</b> if version numbers are equal
* @example
* if(CompareVersion(curver, '10.2') == 1 || CompareVersion(curver, '10.3') < 1){
* //do something
* }
*/
function CompareVersion(version1, version2){
if(!version1){
return -1;
}
if(!version2){
return 1;
}
if (version1==version2) return 0;
var versionparts1 = version1.split('.');
var versionparts2 = version2.split('.');
var i = 0;
try {
for(; i < versionparts1.length; i++){
var v1=parseInt(versionparts1[i], 10);
var v2=parseInt(versionparts2[i], 10);
if(!v2){
return 1;
}
if(v1 > v2){
return 1;
}
if(v1 < v2){
return -1;
}
}
}
catch(E) {
return 1;
}
if(versionparts1.length < versionparts2.length){
return -1;
}
return 0;
}
//===================================================================
// UCTWinScriptlets: tracklet/helper/CustomEventHelper.js
//===================================================================
/*jsl:option explicit*/
/*jsl:declare GacelaTrackingService*/
/*jsl:declare Base64*/
/*jsl:declare base64_json_encode */
/*global Base64, GacelaTrackingService*/
/**
* @class Provides a method to send CustomEvents
* @author Team Dev
* @dependency tracklet Helper 15
*/
var CustomEventHelper = {
/**
* Creates a CustomEvent. The data from the 4 parameters will be converted to a CustomEvent and the complete CustomEvent is logged.
* @function
* @param event event The Gacela Event whose Id and timestamp should be sent
* @param string key A key which is used for indexing of the CustomEvent
* @param string type The type of the CustomEvent
* @param object messageObject The messageObject which should be sent. It is automatically converted to JSON and Base64 encoded.
*/
sendCustomevent : function (event, key, type, messageObject) {
var message, entry;
message = base64_json_encode(messageObject);
entry = '<customevent ';
entry += 'eid="' + GacelaTrackingService.eventIDToString(event.eid) + '" ';
entry += 'timestamp="' + event.timestamp + '" ';
entry += 'type="' + GacelaTrackingService.makeAttributeValid(type) + '" ';
entry += 'key="' + GacelaTrackingService.makeAttributeValid(key) + '" ';
entry += '>' + message + '</customevent>';
GacelaTrackingService.logData(entry);
}
};
//===================================================================
// UCTWinScriptlets: tracklet/components/GfKBase.js
//===================================================================
/*jsl:option explicit*/
/*jsl:declare GacelaStorageService*/
/*jsl:declare GacelaQuestionnaireService*/
/*jsl:declare GacelaEventService*/
/*jsl:declare GacelaTrackingService*/
/*jsl:declare GacelaNavigateService*/
/*jsl:declare GacelaStatusService*/
/*jsl:declare Base64*/
/*jsl:declare json_encode */
/*jsl:declare base64_json_encode */
/*jsl:declare GacelaWindow*/
/*jsl:declare ActiveXObject*/
/*jsl:declare XMLHttpRequest*/
/*jsl:declare CompareVersion*/
/*jsl:declare persons*/
/*global GacelaStorageService, GacelaStatusService, GacelaTrackingService, GacelaNavigateService, CompareVersion, GacelaEventService, GacelaQuestionnaireService, Logger, alert, persons*/
//======================
// regular GfK Internet-Monitor behaviour
//======================
/**
* Controls the default behaviour of the addon. Handles the authentication routine for Firefox and Microsoft Internet Explorer.
*
* @class Regular GfK Internet-Monitor behaviour
* @author Team Dev
* @public
* @param object configIn The configuration object for GfKBase Component
* @param object personIn The persons object
* @dependency tracklet Helper 15
* @dependency tracklet Logger 15
* @dependency updatescript ConfigureBrowserHostLogin 12
*/
function GfKBase(configIn, personsIn) {
"use strict";
this.config = configIn;
this.persons = personsIn;
this.preventLoginDialog = false;
this.authurl = 'http://127.0.0.1:9768/deliver/dialogs/UserSelectionDialog.html';
this.browserWindowCount = GacelaNavigateService.getBrowserWindowCount();
this.activeSSLException = false;
/**
* Checks if an given registry key exists and if it contains <b>"Yes"</b>.
* @function
* @private
* @param string configName Name of the registry key
* @param bool [def] Value to be returned if key is not defined.
* @returns {bool|string} As default returns a bool, if specified returns <b>def</b> in case the Key not exists or
* not contains "Yes"
*/
this.checkOption = function (configName, def) {
var flag;
if (!def) {
def = false;
}
try {
flag = GacelaStorageService.getStatic(configName);
if (flag === null || typeof (flag) === "undefined") {
return def;
}
return (flag === "Yes");
} catch (e) {
return def;
}
};
/**
* Sets the GacelaTrackingMode.
* @private
* @function
* @param event e NavigateComplete event object
*/
this.startTracking = function (e) {
var user_id, trackingmode, ssltrackingmode, index;
user_id = this.updateTrackingTags(e);
GacelaStatusService.setState('hidden');
GacelaStatusService.allowDisable(false);
trackingmode = this.config.guest_trackingmode;
ssltrackingmode = this.config.guest_ssl_trackingmode;
if (this.getTrack(user_id)) {
trackingmode = this.config.default_trackingmode;
ssltrackingmode = this.config.default_ssl_trackingmode;
if (this.config.default_ssl_trackingmode_exceptions) {
if (e.url) {
if (e.url.indexOf('https://') !== 0) {
this.activeSSLException = false;
} else {
for (index = 0; index < this.config.default_ssl_trackingmode_exceptions.length; index += 1) {
if (e.url.match(this.config.default_ssl_trackingmode_exceptions[index].white_regex)) {
this.activeSSLException = index;
ssltrackingmode = this.config.default_ssl_trackingmode_exceptions[index].mode;
}
}
}
} else {
if (this.activeSSLException !== false) {
ssltrackingmode = this.config.default_ssl_trackingmode_exceptions[this.activeSSLException].mode;
}
}
}
}
GacelaTrackingService.setTrackingMode(trackingmode);
GacelaTrackingService.setSSLTrackingMode(ssltrackingmode);
this.updateAboutUrl(e);
};
/**
* Sets the TrackingTags sent with each PageImpression.
* @private
* @function
* @param event e NavigateComplete or UserChanged event object
* @returns string user_id ID of the current authenticated user
*/
this.updateTrackingTags = function (e) {
var user_id, tags;
user_id = this.getCurrentUserId(e);
tags = {};
tags.household_id = GacelaStorageService.getStatic('GacelaPanelId');
tags.user_id = user_id;
tags.user_id_mapping = GacelaStorageService.get('UserIDMapping');
if (!tags.user_id_mapping) {
tags.user_id_mapping = "undefined";
}
tags.install_id = GacelaStorageService.getStatic('GacelaInstallId');
tags.win_version = GacelaStorageService.getStatic('WinVersion');
tags.addon_version = GacelaStorageService.getStatic('GacelaExtensionVersion');
tags.tracklet_version = GacelaStorageService.getStatic('GacelaTrackletVersion');
tags.snifflet_version = GacelaStorageService.getStatic('GacelaSniffletVersion');
tags.updatelet_version = GacelaStorageService.getStatic('GacelaUpdateletVersion');
tags.browser_version = GacelaStorageService.getStatic('BrowserType') + ' ' + GacelaStorageService.getStatic('BrowserVersion');
GacelaTrackingService.setTrackingTags(tags);
return user_id;
};
/**
* Creates the URL to call the about dialog with all needed parameters.
* @private
* @function
* @param event e UserChanged event object
*/
this.updateAboutUrl = function (e) {
var bitmaskConverter, user_id, abouturl, aboutwidth, aboutheight, index, trackingtext, issimpleabout, multiple_user_id, multiple_user_names, userMapping, userMap, a, b, activeUserID, key, active_user_id, currentversion, name;
/**
* Class to split the 32bit Bitmask-Userid to it's single informations.
* @class Class which handles the user id when it's encoded in the bitmask
* @augments GfKBase
* @private
* @author Team Dev
*/
bitmaskConverter = {
/**
* @property Array users An array containing all logged in user ids from the Bitmask
*/
users: [],
MAX_USERS: 16,
/**
* @property string guest_gender The gender of the guest (Only set if the bitmask contains a guest user, otherwise undefined)
*/
guest_gender: undefined,
/**
* @property int guest_age The age of the guest (Only set if the bitmask contains a guest user, otherwise undefined)
*/
guest_age: undefined,
user_count: 0,
/**
* This function fills the properties of this class with informations.
* @function
* @param int bitmask The bitmask containing the user informations
* @param object config Configuration object of GfKBase component
*/
convertBack: function (bitmask, config) {
var binaryCount, age, index;
for (index = 1; index <= this.MAX_USERS; index += 1) {
if (bitmask & (1 << index)) {
this.users[this.users.length] = index;
}
}
if (bitmask & (1 << 29)) {
this.users[this.users.length] = 99;
if (bitmask & (1 << 17)) {
this.guest_gender = config.text_gender.male;
} else {
this.guest_gender = config.text_gender.female;
}
age = 0;
binaryCount = 1;
for (index = 18; index <= 24; index += 1) {
if (bitmask & (1 << index)) {
age += binaryCount;
}
binaryCount *= 2;
}
this.guest_age = age;
}
}
};
user_id = GacelaStorageService.get("CurrentAuthenticatedUser");
aboutwidth = 324;
aboutheight = 280;
trackingtext = this.config.text_contacts;
if (this.getTrack(user_id)) {
if (GacelaNavigateService.currentURL !== null && typeof (GacelaNavigateService.currentURL) !== "undefined" && !GacelaNavigateService.currentURL.match("https:.*")) {
trackingtext = this.config.text_contacts_with_ads;
}
}
issimpleabout = (user_id == 98);
if (issimpleabout) {
abouturl = "http://127.0.0.1:9768/delivertemplate/dialogs/SimpleAbout.html?ts=" + new Date().getTime();
aboutwidth = GacelaStorageService.getStatic("SimpleAboutWidth");
aboutheight = GacelaStorageService.getStatic("SimpleAboutHeight");
} else {
abouturl = "http://127.0.0.1:9768/delivertemplate/dialogs/About.html?ts=" + new Date().getTime();
if (this.checkOption("AllowConcurrentLogins")) {
bitmaskConverter.convertBack(user_id, this.config);
multiple_user_id = "";
multiple_user_names = "";
userMapping = "";
userMap = {};
a = 0;
b = 0;
activeUserID = bitmaskConverter.users[b];
for (key in this.persons) {
if (this.persons.hasOwnProperty(key)) {
if (key != 99) {
a += 1;
if (a >= activeUserID) {
userMap[activeUserID] = key;
userMapping += activeUserID + ":" + key + ",";
if (b + 1 == bitmaskConverter.users.length) {
break;
}
b += 1;
activeUserID = bitmaskConverter.users[b];
}
}
}
}
if (activeUserID == 99) {
userMap[activeUserID] = 99;
userMapping += "99:99,";
}
userMapping = userMapping.slice(0, -1);
GacelaStorageService.set("UserIDMapping", userMapping);
this.updateTrackingTags(e);
for (index = 0; index < bitmaskConverter.users.length; index += 1) {
active_user_id = bitmaskConverter.users[index];
multiple_user_names += encodeURIComponent(this.getUsername(userMap[active_user_id])) + ", ";
multiple_user_id += userMap[active_user_id] + ", ";
}
multiple_user_names = multiple_user_names.slice(0, -2);
multiple_user_id = multiple_user_id.slice(0, -2);
abouturl += "&name=" + multiple_user_names;
abouturl += "&userid=" + multiple_user_id;
if (this.checkOption("AskForGuestSocio") && (multiple_user_id.search(/99/) != -1)) {
abouturl += "&guest_age=" + bitmaskConverter.guest_age;
abouturl += "&guest_gender=" + bitmaskConverter.guest_gender;
}
} else {
GacelaStorageService.set("UserIDMapping", "undefined");
abouturl += "&name=" + encodeURIComponent(this.getUsername(user_id));
abouturl += "&userid=" + user_id;
}
abouturl += "&tracking=" + encodeURIComponent(trackingtext);
//Use About Size of config
currentversion = GacelaStorageService.getStatic('GacelaExtensionVersion');
if (this.config.aboutsizes) {
for (name in this.config.aboutsizes) {
if (this.config.aboutsizes.hasOwnProperty(name)) {
if (CompareVersion(this.config.aboutsizes[name].min_version, currentversion) <= 0 && CompareVersion(this.config.aboutsizes[name].max_version, currentversion) > 0) {
aboutwidth = this.config.aboutsizes[name].width;
if (this.checkOption("AskForGuestSocio") && (abouturl.search(/userid=(.*)99/) !== -1)) {
aboutheight = this.config.aboutsizes[name].height + 15;
} else {
aboutheight = this.config.aboutsizes[name].height;
}
break;
}
}
}
}
}
GacelaStatusService.setAboutDialog(abouturl, parseInt(aboutwidth, 10), parseInt(aboutheight, 10));
};
/**
* Reads the name of the person with the given person id
* @private
* @function
* @param int person_id ID of a person
* @returns string Name of the person, or in case of failure an empty string
*/
this.getUsername = function (person_id) {
try {
return this.persons[person_id].name;
} catch (e) {
return "";
}
};
/**
* Checks if the given person is member of a group with the name <b>default_tracking</b>
* @private
* @function
* @param int person_id ID of a person
* @returns bool true if the person is member of a group called <b>default_tracking</b>, otherwise false
*/
this.getTrack = function (person_id) {
var groups, index;
try {
groups = this.persons[person_id].groups;
for (index = 0; index < groups.length; index += 1) {
if (groups[index].group_name === 'default_tracking') {
return true;
}
}
} catch (e) {
}
return false;
};
/**
* Gets the id of the current authenticated user from the registry.
* @private
* @function
* @param event e NavigateComplete or UserChanged event object
* @returns string The id of the current authenticated user
*/
this.getCurrentUserId = function (e) {
var now, session_auth_key, last_activity, last_activity_age, muid, cuid, last_login_timestamp;
now = Math.floor(new Date().getTime() / 1000);
session_auth_key = String(e.eid.browsersessionid) + '.authentication';
last_activity = 0;
last_login_timestamp = 0;
try {
last_activity = parseInt(GacelaStorageService.get('LastActivityTstamp'), 10);
} catch (E) {}
try {
last_login_timestamp = GacelaStorageService.getInt('B64_TGFzdExvZ2luVGltZXN0YW1w'); //LastLoginTimestamp set by BrowserHost
} catch (E) {}
last_activity = (last_login_timestamp>last_activity) ? last_login_timestamp : last_activity;
last_activity_age = now - last_activity;
muid = GacelaStorageService.get(session_auth_key);
if (isNaN(last_activity_age) || last_activity_age < 30 * 60) {
cuid = GacelaStorageService.get('CurrentAuthenticatedUser');
if ((cuid !== null) && (typeof (cuid) !== 'undefined') && cuid !== "98") {
this.setCurrentUserId(e, cuid);
return cuid;
}
}
if (muid) {
// This updates LastActivityTstamp in turn.
this.setCurrentUserId(e, muid);
return muid;
}
return "98";
};
/**
* Sets the id of the current authenticated user to the registry.
* @private
* @function
* @param event e NavigateComplete or UserChanged event object
* @param string uid The id to set as the current authenticated user
*/
this.setCurrentUserId = function (e, uid) {
var now, session_auth_key;
now = new Date().getTime() / 1000;
session_auth_key = String(e.eid.browsersessionid) + '.authentication';
GacelaStorageService.set('LastActivityTstamp', now);
GacelaStorageService.set(session_auth_key, uid);
GacelaStorageService.set("LastAuthenticatedUser", uid);
GacelaStorageService.set("LastAuthenticatedUser" + GacelaStorageService.getStatic('BrowserType'), uid);
GacelaStorageService.set("CurrentAuthenticatedUser", uid);
GacelaStorageService.setInt('B64_TGFzdExvZ2luVGltZXN0YW1w', now); //LastLoginTimestamp
};
/**
* Prepares the authentication and sets the registry key for the current session
* @private
* @function
* @param event e NavigateComplete or UserChanged event object
*/
this.initAuthentication = function (e) {
try {
GacelaStorageService.unset('UserLoginShowing');
} catch (exception) {}
GacelaStorageService.setInt('UserLoginShowing', '0');
GacelaStorageService.set(e.eid.browsersessionid + '.authentication', '98');
if (this.browserWindowCount <= 1) {
GacelaStorageService.set('LastAuthenticatedUser' + GacelaStorageService.getStatic('BrowserType'), '98');
}
};
/**
* Unsets the registry key for the current session
* @private
* @function
* @param event e NavigateComplete or UserChanged event object
*/
this.uninitAuthentication = function (e) {
GacelaStorageService.unset(e.eid.browsersessionid + '.authentication');
};
/**
* Sets the id of the current authenticated user to <b>0</b> on GacelaQuestionnaireErrorEvent
* @private
* @function
* @param event e GacelaQuestionnaireErrorEvent event object
*/
this.OnQuestionnaireError = function (e) {
var selectedid, now;
if (e.questionnaire_id === 'Authentication') {
selectedid = '0';
now = new Date().getTime() / 1000;
GacelaStorageService.set(e.eid.browsersessionid + '.authentication', selectedid);
GacelaStorageService.setInt(e.eid.browsersessionid + '.loggedin', 1); // Login has been done, even if unsuccessful
GacelaStorageService.set('LastAuthenticatedUser' + GacelaStorageService.getStatic('BrowserType'), selectedid);
GacelaStorageService.set('LastAuthenticatedUser', selectedid);
GacelaStorageService.set('CurrentAuthenticatedUser', selectedid);
GacelaStorageService.setInt('B64_TGFzdExvZ2luVGltZXN0YW1w', now); // LastLoginTimestamp
}
};
/**
* Sets preventLoginDialog to true on UserLoginShowing event. This variable triggers the visibility of the login dialog.
* @private
* @function
* @param event e UserLoginShowing event object
*/
this.OnUserLoginShowing = function (e) {
this.preventLoginDialog = true;
};
/**
* Formats person ids and the last authenticated user for usage in the dialogs.
* @deprecated Since Nerva
* @private
* @function
* @param object persons persons object
* @param {string|int} lastid Id of the last authenticated user
* @returns string String with formatted persons for the UserSelectionDialog or About dialog URL
*/
this.persons_to_uinfo = function (persons, lastid) {
var result, person_id;
result = String(lastid);
for (person_id in this.persons ) {
if (this.persons.hasOwnProperty(person_id)) {
result += ";" + person_id + ":" + encodeURIComponent(this.persons[person_id].name);
}
}
return result;
};
/**
* Builds the complete URL for the Login Dialog (UserSelectionDialog)
* @private
* @function
* @param {int|string} lastAuthenticatedPerson Id of the last authenticated person
*/
this.prepareLoginUrl = function (lastAuthenticatedPerson) {
var preparedUrl, loginUrl, separator, userInfo, anchorSeparatedLoginUrl = "";
loginUrl = GacelaStorageService.getStatic("LoginURL");
anchorSeparatedLoginUrl = loginUrl.split('#');
separator = (loginUrl.indexOf('?') >= 0) ? '&' : '?';
if (anchorSeparatedLoginUrl[1] && anchorSeparatedLoginUrl[1].indexOf('?') >= 0) {
anchorSeparatedLoginUrl[0] += anchorSeparatedLoginUrl[1].substring(anchorSeparatedLoginUrl[1].indexOf('?'));
anchorSeparatedLoginUrl[1] = anchorSeparatedLoginUrl[1].substring(0, anchorSeparatedLoginUrl[1].indexOf('?'));
}
preparedUrl = anchorSeparatedLoginUrl[0] + separator + "ts=" + new Date().getTime();
preparedUrl += '&LastAuthenticatedUser=' + lastAuthenticatedPerson;
if (anchorSeparatedLoginUrl[1]) {
userInfo = anchorSeparatedLoginUrl[1].replace(/^NoLastSelection;/, lastAuthenticatedPerson + ";");
userInfo = anchorSeparatedLoginUrl[1].replace(/^undefined;/, lastAuthenticatedPerson + ";");
}
preparedUrl += "#" + userInfo;
return preparedUrl;
};
/**
* Handles the authentication for Firefox and Microsoft Internet Explorer. Shows login dialog and starts tracking.
* @private
* @function
* @param event e NavigateComplete event object
*/
this.authenticate = function (e) {
var user_id, loginUrl, loginWidth, loginHeight, loggedin;
if (e.mainframe) {// We don't react on frameload events, this leads to bugs in Chrome
try {
user_id = GacelaStorageService.get(e.eid.browsersessionid + '.authentication');
loggedin = GacelaStorageService.getInt(e.eid.browsersessionid + '.loggedin');
if (user_id === null || typeof (user_id) === 'undefined') {
user_id = "98";
}
if (loggedin!==1) {
if (this.showAuthDialog()) {
if (!this.preventLoginDialog) { //multi userdialog prevention for existing windows
if (GacelaStorageService.getStatic("BrowserType") !== "Chrome") {
if (!this.urlInAuthBlacklist(e.url)) {
if (!this.isInOfflineMode()) {
if (GacelaStorageService.incrementInt('UserLoginShowing', '1') == '0') {//multi userdialog prevention for multiple windows
GacelaEventService.dispatchEventGlobally("UserLoginShowing", {});
loginUrl = this.prepareLoginUrl(GacelaStorageService.get("LastAuthenticatedUser"));
loginWidth = this.config && this.config.userSelectionDialog && this.config.userSelectionDialog.width;
loginWidth = loginWidth || 334;
loginHeight = this.config && this.config.userSelectionDialog && this.config.userSelectionDialog.height;
loginHeight = loginHeight || 280;
GacelaQuestionnaireService.showQuestionnaire(loginUrl, 'Authentication', loginWidth, loginHeight, false);
}
}
}
}
}
} else {
var noLoginUser = GacelaStorageService.getStatic("noLoginUserId");
if (typeof (noLoginUser) !== "undefined" && noLoginUser !== "undefined") {
this.setCurrentUserId(e, noLoginUser);
} else {
this.setCurrentUserId(e, 1);
}
}
this.startTracking(e);
}
} catch (E) {
}
}
};
/**
* Checks if a given version conforms a given match version
* @private
* @function
* @param string version The version to compare
* @param string matchversion The version to compare against. Can contain wildcards.
* @returns bool True if the version is newer than the needed matchversion, otherwise false.
*/
this.MinVersionMatch = function (version, matchversion) {
var versionparts, matchversionparts, index;
versionparts = version.split('.');
matchversionparts = matchversion.split('.');
for (index = 0; index < matchversionparts.length; index += 1) {
if (matchversionparts[index] === "*") {
return true;
}
if (!versionparts[index]) {
return false;
}
if (matchversionparts[index] > versionparts[index]) {
return false;
}
}
return true;
};
/**
* Checks if the browser is in offline mode.
* @private
* @function
* @since 10.1.206 (If version below, returns false)
* @returns bool True if in offline mode, otherwise false.
*/
this.isInOfflineMode = function () {
if (this.MinVersionMatch(GacelaStorageService.getStatic("GacelaExtensionVersion"), '10.1.206')) {
try {
return GacelaNavigateService.isInOfflineMode();
} catch (E) {
return false;
}
}
return false;
};
/*If a new Window is opened and a person is selected throw a UserChange-Event to init the Components.*/
/**
* If a new Window is opened and a person is selected throw a UserChange-Event to init the Components.
* @private
* @function
* @param event e GacelaNewWindow event object
*/
this.AuthNewWindow = function (e) {
var user_id = GacelaStorageService.get("CurrentAuthenticatedUser");
if (user_id !== null || typeof (user_id) !== 'undefined') {
if (user_id != "98") {
GacelaEventService.dispatchEvent("UserChanged", {"user_id": user_id});
}
}
};
/**
* Handles the questionnaire authentication.
* @private
* @function
* @param event e GacelaQuestionnaireEvent event object
*/
this.authQuestionnaireEvent = function (e) {
if (e.questionnaire_id === 'Authentication') {
var selectedid = this.parseUrlQuery(e.url).userlist;
GacelaStorageService.set(e.eid.browsersessionid + '.authentication', selectedid);
GacelaStorageService.setInt(e.eid.browsersessionid + '.loggedin', 1); // Login has been done
GacelaEventService.dispatchEventGlobally("UserChanged", {"user_id": selectedid});
this.setCurrentUserId(e, selectedid);
}
};
/**
* Checks the registry for <b>showLoginDialog</b>. With this key it's possible to control the visibility of the login dialog.
* @private
* @function
* @returns bool True if the key exists and contains <b>true</b> otherwise false.
*/
this.showAuthDialog = function () {
var showLogin = GacelaStorageService.getStatic("showLoginDialog");
if (typeof (showLogin) !== "undefined" && showLogin !== "undefined" && showLogin !== null && showLogin !== "") {
return (showLogin === "true") ? true : false;
} else {
return true;
}
};
// Userlist is filled by URL Parameters in latest version, for Chrome Compatibility
// So this filling function is only needed for older Versions.
/**
* Fills the user list of the login dialog.
* @deprecated Only needed for older versions.
* @private
* @function
* @param event e GacelaQuestionnaireDocumentCompleteEvent event object
*/
this.authDocumentComplete = function (e) {
var lastid, sel, newopt, person_id;
if (e.questionnaire_id === 'Authentication' && e.url.substring(0, e.url.indexOf('?')) === this.authurl) {
lastid = GacelaStorageService.get("LastAuthenticatedUser");
sel = e.document.getElementById('userlist');
if (sel !== null && typeof (sel) !== "undefined") {
for (person_id in this.persons ) {
if (this.persons.hasOwnProperty(person_id)) {
newopt = e.document.createElement('option');
newopt.text = this.persons[person_id].name;
newopt.value = person_id;
try {
sel.add(newopt, null);
} catch (ex) {
sel.add(newopt);
}
if (person_id == lastid) {
sel.selectedIndex = sel.length - 1;
}
if (sel.length === 1) {
sel.selectedIndex = 0;
}
}
}
sel.focus();
}
}
};
/**
* Checks if an URL matches the blacklist which contains pages for that no login dialog should be displayed.
* @private
* @function
* @param string url The url of the page to check
* @returns bool True if url not specified or in auth blacklist, otherwise false.
*/
this.urlInAuthBlacklist = function (url) {
var index;
if (!url) {
return true;
}
for (index = 0; index < this.config.authblacklist.length; index += 1) {
if (url.match(this.config.authblacklist[index])) {
return true;
}
}
return false;
};
/**
* Splits an URL to its GET parameters.
* @private
* @function
* @param string url The url to check
* @returns Array Array of GET parameters contained in the given url.
*/
this.parseUrlQuery = function (urlstr) {
var url, qPos, params, paramstr, paramParts, parts, name, value, index;
url = String(urlstr);
qPos = url.indexOf('?');
params = {};
if (qPos === -1) {
return params;
}
paramstr = url.substr(qPos + 1);
if (paramstr) {
paramParts = paramstr.split('&');
for (index = 0; index < paramParts.length; index += 1) {
parts = paramParts[index].split('=');
if (parts.length === 2) {
name = parts[0];
value = decodeURIComponent(parts[1].replace(/\+/g, '%20'));
params[name] = value;
} else {
Logger.log(Logger.logLevelWarning, "Invalid GET Parameter in GfKBase.parseUrlQuery (missing =): '" + paramParts[index] + "' in " + url);
}
}
}
return params;
};
/**
* Handles the behaviour when the user tries to close the authentication dialog.
* @private
* @function
* @param event e GacelaQuestionnaireCancelEvent event object
*/
this.authAbortDialog = function (e) {
e.allowCancel = false;
if (this.config.text_choose_user) {
alert(this.config.text_choose_user);
} else {
alert("Please choose a user");
}
};
/**
* Starts tracking on new window
* @private
* @function
* @param event e GacelaNewWindow event object
*/
//start tracking
this.newwindow = function (e) {
this.startTracking(e);
};
/**
* Starts tracking on browser startup.
* @private
* @function
* @param event e GacelaBrowserStartup event object
*/
//start tracking
this.startup = function (e) {
this.startTracking(e);
};
GacelaQuestionnaireService.setUrlErrorPattern('^res:.*');
GacelaStatusService.allowDisable(false);
var self = this;
GacelaEventService.addListener('GacelaBrowserStartup', function (e) {self.initAuthentication(e); });
GacelaEventService.addListener('GacelaBrowserShutdown', function (e) {self.uninitAuthentication(e); });
GacelaEventService.addListener('GacelaQuestionnaireErrorEvent', function (e) {self.OnQuestionnaireError(e); });
GacelaEventService.addListener("UserLoginShowing", function (e) {self.OnUserLoginShowing(e); });
GacelaEventService.addListener('GacelaNavigateComplete', function (e) {self.authenticate(e); self.startTracking(e); });
GacelaEventService.addListener('GacelaNewWindow', function (e) {self.AuthNewWindow(e); });
GacelaEventService.addListener('GacelaQuestionnaireEvent', function (e) {self.authQuestionnaireEvent(e); });
GacelaEventService.addListener('UserChanged', function (e) {self.updateAboutUrl(e); });
GacelaEventService.addListener('UserChanged', function (e) {self.startTracking(e); });
if (CompareVersion("10.1.397", GacelaStorageService.getStatic('GacelaExtensionVersion')) >= 0) {
GacelaEventService.addListener('GacelaQuestionnaireDocumentCompleteEvent', function (e) {self.authDocumentComplete(e); });
}
GacelaEventService.addListener("GacelaQuestionnaireCancelEvent", function (e) {self.authAbortDialog(e); });
GacelaEventService.addListener('GacelaBeforeNavigate', function (e) {if (e.mainframe) {self.startTracking(e); } });
GacelaEventService.addListener('GacelaDocumentComplete', function (e) {if (e.mainframe) {self.startTracking(e); } });
GacelaEventService.addListener('GacelaNewWindow', function (e) {self.newwindow(e); });
GacelaEventService.addListener('GacelaBrowserStartup', function (e) {self.startup(e); });
}