UNPKG

has-consent

Version:

GDPR consent string validation library

138 lines (125 loc) 18 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./source/index.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./source/ConsentStringParser.js": /*!***************************************!*\ !*** ./source/ConsentStringParser.js ***! \***************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return ConsentStringParser; });\n/* harmony import */ var _decode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./decode.js */ \"./source/decode.js\");\n/* harmony import */ var _VendorRangeEntry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./VendorRangeEntry.js */ \"./source/VendorRangeEntry.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\nvar CMP_ID_OFFSET = 78;\nvar CMP_ID_SIZE = 12;\nvar CMP_VERSION_OFFSET = 90;\nvar CMP_VERSION_SIZE = 12;\nvar DEFAULT_CONSENT_OFFSET = 173;\nvar ENCODING_TYPE_OFFSET = 172;\nvar ENCODING_TYPE_SIZE = 1;\nvar NUM_ENTRIES_OFFSET = 174;\nvar NUM_ENTRIES_SIZE = 12;\nvar PURPOSES_OFFSET = 132;\nvar PURPOSES_SIZE = 24;\nvar RANGE_ENTRY_OFFSET = 186;\nvar VENDOR_BITFIELD_OFFSET = 173;\nvar VENDOR_ENCODING_RANGE = 1;\nvar VENDOR_ID_SIZE = 16;\nvar VERSION_BIT_OFFSET = 0;\nvar VERSION_BIT_SIZE = 6;\n/**\n * Parser instance for processing IAB consent strings\n * @class ConsentStringParser\n */\n\nvar ConsentStringParser =\n/*#__PURE__*/\nfunction () {\n /**\n * Constructor for the parser\n * @param {String} consentString The consent string\n * @throws {Error} Throws for invalid consent strings\n * @memberof ConsentStringParser\n */\n function ConsentStringParser(consentString) {\n _classCallCheck(this, ConsentStringParser);\n\n if (!consentString) {\n throw new Error(\"Invalid consent string value\");\n }\n\n this.consentString = consentString;\n var buff = Object(_decode_js__WEBPACK_IMPORTED_MODULE_0__[\"decodeBase64ToArrayBuffer\"])(consentString);\n this.consentData = buff.reduce(function (binStr, nextByte) {\n return \"\".concat(binStr).concat(Object(_decode_js__WEBPACK_IMPORTED_MODULE_0__[\"convertByteToBitstring\"])(nextByte));\n }, \"\");\n\n this._processPurposes();\n\n if (this.vendorEncodingType === VENDOR_ENCODING_RANGE) {\n this._processVendorsList();\n }\n }\n /**\n * CMP ID\n * @type {Number}\n * @memberof ConsentStringParser\n * @readonly\n */\n\n\n _createClass(ConsentStringParser, [{\n key: \"purposeAllowed\",\n\n /**\n * Check if a purpose is allowed\n * @param {Number} purposeID The ID of the purpose to check\n * @returns {Boolean} True if the purpose is allowed, false otherwise\n * @memberof ConsentStringParser\n */\n value: function purposeAllowed(purposeID) {\n if (purposeID < 1 || purposeID > this.allowedPurposes.length) {\n return false;\n }\n\n return Boolean(this.allowedPurposes[purposeID - 1]);\n }\n /**\n * Check if a vendor is allowed\n * @param {Number} vendorID The ID of the vendor to check\n * @returns {Boolean} True if the vendor is allowed, false otherwise\n * @memberof ConsentStringParser\n */\n\n }, {\n key: \"vendorAllowed\",\n value: function vendorAllowed(vendorID) {\n if (this.vendorEncodingType === VENDOR_ENCODING_RANGE) {\n var present = this._vendorInRange(vendorID);\n\n return present !== Boolean(this.defaultConsent);\n }\n\n try {\n return Boolean(this._getBit(VENDOR_BITFIELD_OFFSET + vendorID - 1));\n } catch (_unused) {\n return false;\n }\n }\n /**\n * Get a bit of data from the parsed consent string\n * @param {Number} offset The offset to fetch from\n * @returns {Number} The requested bit\n * @memberof ConsentStringParser\n * @protected\n */\n\n }, {\n key: \"_getBit\",\n value: function _getBit(offset) {\n var binStr = this.consentData.substr(offset, 1);\n return parseInt(binStr, 10);\n }\n /**\n * Get a number from the parsed consent data\n * Takes a range of bits and converts them into an integer\n * @param {Number} offset The offset to read from\n * @param {Number} size The amount of bits to read\n * @returns {Number} The integer value of the bit range\n * @memberof ConsentStringParser\n * @protected\n */\n\n }, {\n key: \"_getInt\",\n value: function _getInt(offset, size) {\n var binStr = this.consentData.substr(offset, size);\n return Object(_decode_js__WEBPACK_IMPORTED_MODULE_0__[\"convertBitstringToInteger\"])(binStr);\n }\n /**\n * Process purposes from allowed purposes ID range\n * @memberof ConsentStringParser\n * @protected\n */\n\n }, {\n key: \"_processPurposes\",\n value: function _processPurposes() {\n this.allowedPurposes = [];\n\n for (var i = PURPOSES_OFFSET, max = PURPOSES_OFFSET + PURPOSES_SIZE; i < max; i += 1) {\n this.allowedPurposes.push(this._getBit(i));\n }\n\n this.purposes = [];\n\n for (var _i = 1, _max = this.allowedPurposes.length; _i <= _max; _i += 1) {\n if (this.purposeAllowed(_i)) {\n this.purposes.push(_i);\n }\n }\n }\n /**\n * Process the vendors list by creating ranges of vendor IDs\n * @memberof ConsentStringParser\n * @protected\n */\n\n }, {\n key: \"_processVendorsList\",\n value: function _processVendorsList() {\n this.rangeEntries = [];\n this.defaultConsent = this._getBit(DEFAULT_CONSENT_OFFSET);\n\n var numEntries = this._getInt(NUM_ENTRIES_OFFSET, NUM_ENTRIES_SIZE);\n\n var currentOffset = RANGE_ENTRY_OFFSET;\n\n for (var i = 0; i < numEntries; i += 1) {\n var range = Boolean(this._getBit(currentOffset));\n currentOffset += 1;\n\n if (range) {\n var vendorIDStart = this._getInt(currentOffset, VENDOR_ID_SIZE);\n\n currentOffset += VENDOR_ID_SIZE;\n\n var vendorIDEnd = this._getInt(currentOffset, VENDOR_ID_SIZE);\n\n currentOffset += VENDOR_ID_SIZE;\n this.rangeEntries.push(new _VendorRangeEntry_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](vendorIDStart, vendorIDEnd));\n } else {\n var vendorID = this._getInt(currentOffset, VENDOR_ID_SIZE);\n\n currentOffset += VENDOR_ID_SIZE;\n this.rangeEntries.push(new _VendorRangeEntry_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](vendorID));\n }\n }\n }\n /**\n * Check if a vendor ID appears in any ID range\n * @param {Number} vendorID The vendor ID number\n * @returns {Boolean} True if the vendor ID appears in a range,\n * false otherwise\n * @memberof ConsentStringParser\n * @protected\n */\n\n }, {\n key: \"_vendorInRange\",\n value: function _vendorInRange(vendorID) {\n var limit = this.rangeEntries.length;\n\n if (limit === 0) {\n return false;\n }\n\n var index = Math.floor(limit / 2);\n\n while (index >= 0 && index < limit) {\n var entry = this.rangeEntries[index];\n\n if (entry.containsVendorID(vendorID)) {\n return true;\n }\n\n if (index === 0 || index === limit - 1) {\n return false;\n }\n\n if (entry.vendorIDGreaterThanMax(vendorID)) {\n index = index + Math.floor((limit - index) / 2);\n } else {\n index = Math.floor(index / 2);\n }\n }\n\n return false;\n }\n }, {\n key: \"cmpID\",\n get: function get() {\n return this._getInt(CMP_ID_OFFSET, CMP_ID_SIZE);\n }\n /**\n * CMP version\n * @type {Number}\n * @memberof ConsentStringParser\n * @readonly\n */\n\n }, {\n key: \"cmpVersion\",\n get: function get() {\n return this._getInt(CMP_VERSION_OFFSET, CMP_VERSION_SIZE);\n }\n /**\n * The encoding type used for the vendor(s) list\n * @type {Number}\n * @memberof ConsentStringParser\n * @readonly\n */\n\n }, {\n key: \"vendorEncodingType\",\n get: function get() {\n return this._getInt(ENCODING_TYPE_OFFSET, ENCODING_TYPE_SIZE);\n }\n /**\n * The consent string version used by the CMP\n * @type {Number}\n * @memberof ConsentStringParser\n * @readonly\n */\n\n }, {\n key: \"version\",\n get: function get() {\n return this._getInt(VERSION_BIT_OFFSET, VERSION_BIT_SIZE);\n }\n }]);\n\n return ConsentStringParser;\n}();\n\n\n\n//# sourceURL=webpack:///./source/ConsentStringParser.js?"); /***/ }), /***/ "./source/VendorRangeEntry.js": /*!************************************!*\ !*** ./source/VendorRangeEntry.js ***! \************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return VendorRangeEntry; });\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar VendorRangeEntry =\n/*#__PURE__*/\nfunction () {\n function VendorRangeEntry() {\n _classCallCheck(this, VendorRangeEntry);\n\n this.maxVendorID = null;\n this.minVendorID = null;\n this.vendorIDs = [];\n\n if (arguments.length === 1) {\n this.vendorIDs.push(arguments.length <= 0 ? undefined : arguments[0]);\n this.maxVendorID = this.minVendorID = arguments.length <= 0 ? undefined : arguments[0];\n } else if (arguments.length === 2) {\n this.minVendorID = arguments.length <= 0 ? undefined : arguments[0];\n this.maxVendorID = arguments.length <= 1 ? undefined : arguments[1];\n\n for (var i = this.minVendorID; i <= this.maxVendorID; i += 1) {\n this.vendorIDs.push(i);\n }\n } else {\n throw new Error(\"Expected 1 or 2 arguments, received \".concat(arguments.length));\n }\n }\n\n _createClass(VendorRangeEntry, [{\n key: \"containsVendorID\",\n value: function containsVendorID(vendorID) {\n return this.vendorIDs.indexOf(vendorID) >= 0;\n }\n }, {\n key: \"vendorIDGreaterThanMax\",\n value: function vendorIDGreaterThanMax(vendorID) {\n return vendorID > this.maxVendorID;\n }\n }]);\n\n return VendorRangeEntry;\n}();\n\n\n\n//# sourceURL=webpack:///./source/VendorRangeEntry.js?"); /***/ }), /***/ "./source/decode.js": /*!**************************!*\ !*** ./source/decode.js ***! \**************************/ /*! exports provided: convertBitstringToInteger, convertByteToBitstring, decodeBase64ToArrayBuffer */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"convertBitstringToInteger\", function() { return convertBitstringToInteger; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"convertByteToBitstring\", function() { return convertByteToBitstring; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"decodeBase64ToArrayBuffer\", function() { return decodeBase64ToArrayBuffer; });\nfunction convertBitstringToInteger(binStr) {\n return parseInt(binStr, 2);\n}\nfunction convertByteToBitstring(byte) {\n return zeroPad(byte.toString(2));\n}\nfunction decodeBase64ToArrayBuffer(b64) {\n var win = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;\n var binaryString = win.atob(prepareBase64ForDecode(b64));\n var len = binaryString.length;\n var bytes = new Uint8Array(len);\n\n for (var i = 0; i < len; i += 1) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n return bytes;\n}\n\nfunction prepareBase64ForDecode(b64) {\n var unsafe = b64;\n\n while (unsafe.length % 4 !== 0) {\n unsafe += \"=\";\n }\n\n unsafe = unsafe.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return unsafe;\n}\n\nfunction zeroPad(text) {\n var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 8;\n var output = text;\n\n while (output.length < size) {\n output = \"0\".concat(output);\n }\n\n return output;\n}\n\n//# sourceURL=webpack:///./source/decode.js?"); /***/ }), /***/ "./source/index.js": /*!*************************!*\ !*** ./source/index.js ***! \*************************/ /*! exports provided: ConsentStringParser */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ConsentStringParser_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ConsentStringParser.js */ \"./source/ConsentStringParser.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"ConsentStringParser\", function() { return _ConsentStringParser_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; });\n\n\n/** @module HasConsent */\n\n\n\n//# sourceURL=webpack:///./source/index.js?"); /***/ }) /******/ });