/** * Created by Thomas on 09.02.2015. */ var defaultConfig = { sendInterval: 5000, URL: "/" }; function Analytics(config) { if (config) { if(!config.server) { throw "you have to set a least the server variable to valid url"; } if(!config.sendInterval) { config.sendInterval = defaultConfig.sendInterval; } } else { throw "you've to insert a config object example: { server: 'ajaxurl' }"; } var server = config.server; var SendInterval = config.sendInterval; var currentURL = config.URL; var userID = config.UserID; var intervalHandle = null; var clientSession = new UserIdentifier(config.clientSession); var serverSession = config.serverSession || undefined; var eventMsgQueue = new MsgQueue("eventsQueue"); var pageTrackingQueue = new MsgQueue("pagesQueue"); var mouseMovementQueue = new MsgQueue("mouseMovementQueue"); var events = new Array(); var metaEvents = new Array(); var lastMousePos = { x: null, y: null }; var asyncAjax = true; this.PushEvents = function (eventObjects) { var obj = {//Example eventObject Name: "", EventType: "", domElement: "asdf", CustomCallBack: function () { }, TimeOut: 50, Storage: "MouseMovement" //optional } if(eventObjects instanceof Array) { eventObjects.forEach( function (eventDef) { createEvent(eventDef); }); } else { createEvent(eventObjects); } } this.PushInlineEvent = function (eventObject) { eventObject.EventRaisedTime = new Date().getTime(); var obj = createEventObjToSend(eventObject); eventMsgQueue.Push(obj); if (eventObject.Flush) { SendIntervalCallback(); } return this; }; this.Flush = function () { SendIntervalCallback(); }; this.PushMetaEvent = function (eventObject) { /*var metaEvent1 = { Name: " ", EventType: " ", Events: [event1, event2] SendToServer: false, CustomCallback: function (data) { console.log(data.Name + " occured"); } }; // Example eventObject*/ metaEvents.push(eventObject); } this.TrackPage = function (data) { var that = this; var pageEventObj = { PageTitle: data.pageTitle, EventType: "PageLoaded", ClientSessionID: clientSession.GetID(), ServerSessionID: serverSession, UserID: userID, Domain: window.location.host, UTCTime: new Date().getTime() }; if(!data.URL) { pageEventObj.URL = window.location.href; } pageTrackingQueue.Push(pageEventObj); if(data.UseUnloadEvent) { my$.windowUnload(function(event) { event.data.EventType = "PageUnloaded"; var timeStamp = new Date().getTime(); event.data.Duration = timeStamp - event.data.UTCTime; event.data.UTCTime = timeStamp; pageTrackingQueue.Push(event.data); asyncAjax = false; that.Flush(); asyncAjax = true; }, pageEventObj); } } this.Start = function () { intervalHandle = setInterval( SendIntervalCallback, SendInterval); my$(document).mousemove(MouseMoveEventCallBack); //console.log(Date.now()/1000) } this.Stop = function () { clearInterval(intervalHandle); } this.UploadData = function (identifier, data) { var d = { }; d[identifier] = data; my$.ajax({ url: server, method: "post", dataType: "json", contentType: "application/json", async: true, data: JSON.stringify(d) }); } /*-------------------------------- sub classes -----------------------------*/ function MsgQueue(key) { var key = key; this.Push = function (msg) { var q = GetQueueObj(); q.push(msg); localStorage.setObj(key, q); } this.Clear = function() { var q = GetQueueObj(); q.splice(0, q.length); localStorage.setObj(key, q); } this.GetData = function () { return GetQueueObj(); } this.Length = function() { return GetQueueObj().length; } function GetQueueObj() { var obj = localStorage.getObj(key); if(obj == null) { obj = new Array(); localStorage.setObj(key, obj); } return obj; } } function UserIdentifier(startId) { var key = "identifier"; this.GetID = function() { if(startId) { var id = localStorage.getObj(key); if(!id) { localStorage.setObj(key, startId); } } return localStorage.getObj(key); } } /*----------------------------------- private Methods ------------------------------*/ function createEvent(eventDef) { var callback = (eventDef.hasOwnProperty("CustomCallBack")) ? eventDef.CustomCallBack : null; eventDef.CustomCallBack = callback; my$(eventDef.domElement).on(eventDef.EventType, BasicEventCallBack, eventDef); events.push(eventDef); } function SendData(events, trackedPages, mouseMovement) { my$.ajax({ url: server, method: "post", dataType: "json", contentType: "application/json", async: asyncAjax, data: JSON.stringify({ events: events, trackedPages: trackedPages, mouseMovement: mouseMovement }) }); } Storage.prototype.setObj = function(key, obj) { return this.setItem(key, JSON.stringify(obj)) } Storage.prototype.getObj = function(key) { try{ return JSON.parse(this.getItem(key)) } catch (err) { return null; } } function createEventObjToSend(data) { var obj = { Name: data.Name, DOMElem: data.domElem, EventType: data.EventType, UTCTime: data.EventRaisedTime, ClientSessionID: clientSession.GetID(), ServerSessionID: serverSession, UserID: userID, Domain: window.location.host, MousePos: { x: lastMousePos.x, y: lastMousePos.y }, DocumentSize: { width: my$.documentWidth(), height: my$.documentHeight() } }; if(!obj.URL) { obj.URL = window.location.href; } if (data.EventCallback != null) { obj.customVal = event.data.EventCallback(obj); } return obj; } function checkMetaEventMatched(metaEvent, eventMsgs) { var eventsToCheck = $.map(metaEvent.Events, function (item) { return item.Name; }); var allEvents = $.map(eventMsgs, function (item) { return item.Name; }); var index = allEvents.indexOf(eventsToCheck[0]); if(index >= 0) { for (var i = index; i < eventsToCheck.length; i++) { if (eventsToCheck[i] !== allEvents[i]) { return; //returns if doesnt match the sequence } } var duration = eventMsgs[i - 1].UTCTime - eventMsgs[index].UTCTime; var obj = { Name: metaEvent.Name, EventType: metaEvent.EventType, UTCTime: new Date().getTime(), ClientSessionID: clientSession.GetID(), ServerSessionID: serverSession, UserID: userID, Domain: window.location.host, URL: window.location.href, Duration: duration }; if(typeof(metaEvent.CustomCallback) == "function") { metaEvent.CustomCallback(obj); } if(metaEvent.SendToServer === true) { eventMsgQueue.Push(obj); } } return; } /* ------------------------------------------- Callbacks --------------------------------------------------------------*/ function SendIntervalCallback() { if(eventMsgQueue.Length() > 0 || pageTrackingQueue.Length() > 0 || mouseMovementQueue.Length() > 0) { if(metaEvents.length > 0) { checkMetaEventMatched(metaEvents[0], eventMsgQueue.GetData()); } SendData(eventMsgQueue.GetData(), pageTrackingQueue.GetData(), mouseMovementQueue.GetData()); eventMsgQueue.Clear(); pageTrackingQueue.Clear(); mouseMovementQueue.Clear(); } } function BasicEventCallBack(event) { var dateNow = new Date().getTime(); var timeOuted = event.data.EventRaisedTime != null && dateNow - event.data.EventRaisedTime <= event.data.TimeOut; if (!timeOuted) { event.data.EventRaisedTime = dateNow; if(event.data.CustomCallback && !event.data.CustomCallback(event)){ return; } var obj = createEventObjToSend(event.data); if (event.data.Storage) { switch (event.data.Storage) { case "MouseMovement": mouseMovementQueue.Push(obj); break; default: eventMsgQueue.Push(obj); break; } } else { eventMsgQueue.Push(obj); } if (event.data.Flush) { SendIntervalCallback(); } } } function MouseMoveEventCallBack(eventdata) { if(eventdata.pageX && eventdata.pageY){ lastMousePos.x = eventdata.pageX; lastMousePos.y = eventdata.pageY; } } } Analytics.adblockerDetect = function () { if (my$("script[src='/js/ads.js'").first() && window.canRunAds === undefined) { return true; } else { return false; } }; function UnfinishedUpdater(url, blocked) { this.url = url || '/unfinished'; this.blocked = [ 'loan-amount', 'loan-term', 'consents.marketing-consents.email-consent', 'consents.marketing-consents.sms-consent', 'consents.marketing-consents.call-consent', 'consents.marketing-consents.sms-call-consent', 'consents.marketing-consents.clientzone-consent', 'consents.marketing-consents-es.sell-rejected-loans', 'select-all-below', 'select-all', 'privacycontract_0' ].concat(blocked || []); this.updateFieldsSelector = '.regform select, .regform input'; UnfinishedUpdater.prototype.listen = function () { var that = this; $(this.updateFieldsSelector).change(function () { that.update(this); }); }; UnfinishedUpdater.prototype.update = function (field, value) { var that = this; var data = { }; if (!my$(field).isEmpty()) { if (this.blocked.indexOf(my$(field).attrb('name')) > -1) { return; } } if (value === null || value == undefined) { if ($(field).is('[type=checkbox]')) { data[$(field).attr('name')] = $(field).is(':checked'); } else { data[$(field).attr('name')] = $(field).val(); } } else { data[field] = value; } my$.ajax({ url: that.url, method: "post", dataType: "json", contentType: "application/json", async: true, data: JSON.stringify({ data: data }) }); }; UnfinishedUpdater.prototype.delete = function (field) { var that = this; if (!my$(field).isEmpty()) { if (this.blocked.indexOf(my$(field).attrb('name')) > -1) { return; } } my$.ajax({ url: that.url + '?unfinished_key=' + field, method: "DELETE", async: true }); }; } function testPasswordComplexity(passwd) { var intScore = 0; var strVerdict = "weak"; if (passwd.length<5) { intScore = (intScore+3) } else if (passwd.length>4 && passwd.length<8) { intScore = (intScore+6) } else if (passwd.length>7 && passwd.length<16) { intScore = (intScore+12) } else if (passwd.length>15) { intScore = (intScore+18) } if (passwd.match(/[a-z]/)) { intScore = (intScore+1) } if (passwd.match(/[A-Z]/)) { intScore = (intScore+5) } if (passwd.match(/\d+/)) { intScore = (intScore+5) } if (passwd.match(/(.*[0-9].*[0-9].*[0-9])/)) { intScore = (intScore+5) } if (passwd.match(/.[!,@,#,$,%,^,&,*,?,_,~]/)) { intScore = (intScore+5) } if (passwd.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) { intScore = (intScore+5) } if (passwd.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) { intScore = (intScore+2) } if (passwd.match(/([a-zA-Z])/) && passwd.match(/([0-9])/)) { intScore = (intScore+2) } if (passwd.match(/([a-zA-Z0-9].*[!,@,#,$,%,^,&,*,?,_,~])|([!,@,#,$,%,^,&,*,?,_,~].*[a-zA-Z0-9])/)) { intScore = (intScore+2) } if (intScore < 25) { strVerdict = "weak"; scoreVerdict = 0; } else if (intScore > 24 && intScore < 35) { strVerdict = "medium"; scoreVerdict = 1; } else { strVerdict = "strong" scoreVerdict = 2; } return { score: intScore, verdict: strVerdict, }; } function initPasswordChecker(inputName, verdictFieldId, progressBarId, verdictsObject) { var verdicts = verdictsObject; var field = $(inputName); var testPassword = function () { var result = testPasswordComplexity(field.val()); $(verdictFieldId + ', ' + progressBarId).removeClass('weak medium strong'); if (field.val() == '') { $(verdictFieldId).text(verdicts.weak); return; } $(verdictFieldId + ', ' + progressBarId).addClass(result.verdict); $(verdictFieldId).text(verdicts[result.verdict]); }; field.keyup(testPassword); field.change(testPassword); $(document).ready(testPassword); }