supercookie-8.x-1.x-dev/supercookie.js

supercookie.js
/**
 * @file
 * Code for the supercookie module.
 */

(function ($, Drupal, drupalSettings, navigator, document, storageLocal, storageSession) {

  'use strict';

  Drupal.behaviors.supercookie = {
    entitiesTracked: false,
    attach: function (context) {
      // Honor user's DNT header.
      if (drupalSettings.supercookie.dnt === true) {
        return;
      }
      if ($.isEmptyObject(navigator)) {
        return;
      }

      // Add request header to all AJAX requests.
      $.ajaxSetup({
        global: true,
        beforeSend: function (xhr, options) {
          if (options.url.indexOf(drupalSettings.supercookie.json) < 0) {
            if (!drupalSettings.supercookie.hash) {
              // This condition occurs when the original writeCookie() call
              // below fails due to high security browser settings; we'll assume
              // the user still has JavaScript enabled, though and force our
              // headers upon them.
              Drupal.behaviors.supercookie.failOver(xhr, options);
            }
            else {
              xhr.setRequestHeader(drupalSettings.supercookie.name_header, drupalSettings.supercookie.hash);
              if (options.headers) {
                options.headers[drupalSettings.supercookie.name_header] = drupalSettings.supercookie.hash;
              }
            }
          }
        }
      });

      this
        .fingerprint()
        .then(function (result) {
          return result.callback;
        })
        .then(this.writeCookie);
    },
    failOver: function (xhr, xhrOptions) {
      // Kill current AJAX request.
      xhr.abort();

      // Force a new supercookie request first.
      this
        .fingerprint()
        .then(function (result) {
          return result.callback;
        })
        .then(this.writeCookie)
        .then(function (data) {
          // Force the supercookie request header on to the original request.
          xhrOptions.headers[drupalSettings.supercookie.name_header] = data.hash;
          // Now send the original (manipulated) request.
          $.ajax(xhrOptions);
        });
    },
    fingerprint: function () {

      // Loop navigator object and fingerprint this user.
      var data = {};
      for (var member in navigator) {
        // 2016-04-01, Tory:
        // Firefox - a private browsing window does not have this property on
        // navigator object, while a normal window does. Bypass it so our
        // fingerprint is not different between the two window modes.
        // @see https://bugzilla.mozilla.org/show_bug.cgi?id=1112136
        if (member === 'serviceWorker') {
          continue;
        }

        switch (typeof navigator[member]) {
          case 'object':
          case 'string':
          case 'boolean':
            data[member] = navigator[member];
            break;
        }
      }
      // Do deep recursion on navigator data collected.
      data = JSON.prune(data);
      // Set hash of data string.
      var hash = CryptoJS.MD5(data);
      // Get local date/time. TODO: NOTE SAFARI AND IE'S MISHANDLING OF ECMA DATE OBJECT FORMAT!!!!
      var date = new Date($.now());
      date = date.toLocaleString();
      date = encodeURIComponent(date);

      var url = drupalSettings.supercookie.json + '?client=' + hash + '&date=' + date;
      if (!this.entitiesTracked) {
        url += '&ref=' + document.location.pathname;
      }

      // Do not attempt to geolocate users.
      if (!drupalSettings.supercookie.geolocation) {
        var deferred = $.Deferred();
        deferred.resolve({
          callback: url
        });
        return deferred.promise();
      }

      // Now attempt to append geolocation coords to url and return.
      var getCurrentPositionDeferred = function (options) {
        var deferred = $.Deferred();
        // Note the 2nd deferred.resolve arg here (vs. deferred.reject). We want
        // this to always "succeed" and eval result (which could be a
        // PositionError or Geoposition object) in the single done() callback.
        navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.resolve, options);
        return deferred.promise();
      };

      return getCurrentPositionDeferred({
        enableHighAccuracy: true
      })
        .done(function (result) {
          if (result.coords) {
            url += '&geo=' + result.coords.latitude + ',' + result.coords.longitude;
          }
          result.callback = url;
          return result;
        });
    },
    writeCookie: function (url) {

      var xhrCookie = {
        method: 'GET',
        url: url,
        beforeSend: function (xhr, options) {
          xhr.setRequestHeader(drupalSettings.supercookie.name_header, drupalSettings.supercookie.hash);
          xhr.setRequestHeader('Accept', 'application/json');

          // Ensures that the "ref" query param is only sent to the server once.
          Drupal.behaviors.supercookie.entitiesTracked = true;
        },
        complete: function (xhr) {
          if (xhr.status === 200) {
            // Set client-side cookie + localStorage.
            var response = (xhr.responseJSON ? xhr.responseJSON : JSON.parse(xhr.responseText));
            var expires = new Date(response.expires * 1000);

            document.cookie = drupalSettings.supercookie.name_server + '=""; expires=-1';
            document.cookie = drupalSettings.supercookie.name_server + '=' + response.hash + '; expires=' + expires.toGMTString() + '; path=/';

            if (storageLocal) {
              storageLocal.setItem(drupalSettings.supercookie.name_server, response.hash);
            }
            if (storageSession) {
              storageSession.setItem(drupalSettings.supercookie.name_server, response.hash);
            }

            drupalSettings.supercookie.scid = response.scid;
            drupalSettings.supercookie.hash = response.hash;

            return response.hash;
          }
        }
      };

      // Get server response.
      return $.ajax(xhrCookie);
    }
  };

})(jQuery, Drupal, drupalSettings, window.navigator, document, window.localStorage, window.sessionStorage);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc