cookies.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Cookies.js - 1.2.3 (patched for SameSite=Strict and secure=true)
  3. * https://github.com/ScottHamper/Cookies
  4. *
  5. * This is free and unencumbered software released into the public domain.
  6. */
  7. (function (global, undefined) {
  8. "use strict";
  9. var factory = function (window) {
  10. if (typeof window.document !== "object") {
  11. throw new Error(
  12. "Cookies.js requires a `window` with a `document` object",
  13. );
  14. }
  15. var Cookies = function (key, value, options) {
  16. return arguments.length === 1
  17. ? Cookies.get(key)
  18. : Cookies.set(key, value, options);
  19. };
  20. // Allows for setter injection in unit tests
  21. Cookies._document = window.document;
  22. // Used to ensure cookie keys do not collide with
  23. // built-in `Object` properties
  24. Cookies._cacheKeyPrefix = "cookey."; // Hurr hurr, :)
  25. Cookies._maxExpireDate = new Date("Fri, 31 Dec 9999 23:59:59 UTC");
  26. Cookies.defaults = {
  27. path: "/",
  28. SameSite: "Strict",
  29. secure: true,
  30. };
  31. Cookies.get = function (key) {
  32. if (Cookies._cachedDocumentCookie !== Cookies._document.cookie) {
  33. Cookies._renewCache();
  34. }
  35. var value = Cookies._cache[Cookies._cacheKeyPrefix + key];
  36. return value === undefined ? undefined : decodeURIComponent(value);
  37. };
  38. Cookies.set = function (key, value, options) {
  39. options = Cookies._getExtendedOptions(options);
  40. options.expires = Cookies._getExpiresDate(
  41. value === undefined ? -1 : options.expires,
  42. );
  43. Cookies._document.cookie = Cookies._generateCookieString(
  44. key,
  45. value,
  46. options,
  47. );
  48. return Cookies;
  49. };
  50. Cookies.expire = function (key, options) {
  51. return Cookies.set(key, undefined, options);
  52. };
  53. Cookies._getExtendedOptions = function (options) {
  54. return {
  55. path: (options && options.path) || Cookies.defaults.path,
  56. domain: (options && options.domain) || Cookies.defaults.domain,
  57. SameSite: (options && options.SameSite) || Cookies.defaults.SameSite,
  58. expires: (options && options.expires) || Cookies.defaults.expires,
  59. secure:
  60. options && options.secure !== undefined
  61. ? options.secure
  62. : Cookies.defaults.secure,
  63. };
  64. };
  65. Cookies._isValidDate = function (date) {
  66. return (
  67. Object.prototype.toString.call(date) === "[object Date]" &&
  68. !isNaN(date.getTime())
  69. );
  70. };
  71. Cookies._getExpiresDate = function (expires, now) {
  72. now = now || new Date();
  73. if (typeof expires === "number") {
  74. expires =
  75. expires === Infinity
  76. ? Cookies._maxExpireDate
  77. : new Date(now.getTime() + expires * 1000);
  78. } else if (typeof expires === "string") {
  79. expires = new Date(expires);
  80. }
  81. if (expires && !Cookies._isValidDate(expires)) {
  82. throw new Error(
  83. "`expires` parameter cannot be converted to a valid Date instance",
  84. );
  85. }
  86. return expires;
  87. };
  88. Cookies._generateCookieString = function (key, value, options) {
  89. key = key.replace(/[^#$&+\^`|]/g, encodeURIComponent);
  90. key = key.replace(/\(/g, "%28").replace(/\)/g, "%29");
  91. value = (value + "").replace(
  92. /[^!#$&-+\--:<-\[\]-~]/g,
  93. encodeURIComponent,
  94. );
  95. options = options || {};
  96. var cookieString = key + "=" + value;
  97. cookieString += options.path ? ";path=" + options.path : "";
  98. cookieString += options.domain ? ";domain=" + options.domain : "";
  99. cookieString += options.SameSite ? ";SameSite=" + options.SameSite : "";
  100. cookieString += options.expires
  101. ? ";expires=" + options.expires.toUTCString()
  102. : "";
  103. cookieString += options.secure ? ";secure" : "";
  104. return cookieString;
  105. };
  106. Cookies._getCacheFromString = function (documentCookie) {
  107. var cookieCache = {};
  108. var cookiesArray = documentCookie ? documentCookie.split("; ") : [];
  109. for (var i = 0; i < cookiesArray.length; i++) {
  110. var cookieKvp = Cookies._getKeyValuePairFromCookieString(
  111. cookiesArray[i],
  112. );
  113. if (
  114. cookieCache[Cookies._cacheKeyPrefix + cookieKvp.key] === undefined
  115. ) {
  116. cookieCache[Cookies._cacheKeyPrefix + cookieKvp.key] =
  117. cookieKvp.value;
  118. }
  119. }
  120. return cookieCache;
  121. };
  122. Cookies._getKeyValuePairFromCookieString = function (cookieString) {
  123. // "=" is a valid character in a cookie value according to RFC6265, so cannot `split('=')`
  124. var separatorIndex = cookieString.indexOf("=");
  125. // IE omits the "=" when the cookie value is an empty string
  126. separatorIndex =
  127. separatorIndex < 0 ? cookieString.length : separatorIndex;
  128. var key = cookieString.substr(0, separatorIndex);
  129. var decodedKey;
  130. try {
  131. decodedKey = decodeURIComponent(key);
  132. } catch (e) {
  133. if (console && typeof console.error === "function") {
  134. console.error('Could not decode cookie with key "' + key + '"', e);
  135. }
  136. }
  137. return {
  138. key: decodedKey,
  139. value: cookieString.substr(separatorIndex + 1), // Defer decoding value until accessed
  140. };
  141. };
  142. Cookies._renewCache = function () {
  143. Cookies._cache = Cookies._getCacheFromString(Cookies._document.cookie);
  144. Cookies._cachedDocumentCookie = Cookies._document.cookie;
  145. };
  146. Cookies._areEnabled = function () {
  147. var testKey = "cookies.js";
  148. var areEnabled = Cookies.set(testKey, 1).get(testKey) === "1";
  149. Cookies.expire(testKey);
  150. return areEnabled;
  151. };
  152. Cookies.enabled = Cookies._areEnabled();
  153. return Cookies;
  154. };
  155. var cookiesExport =
  156. global && typeof global.document === "object" ? factory(global) : factory;
  157. // AMD support
  158. if (typeof define === "function" && define.amd) {
  159. define(function () {
  160. return cookiesExport;
  161. });
  162. // CommonJS/Node.js support
  163. } else if (typeof exports === "object") {
  164. // Support Node.js specific `module.exports` (which can be a function)
  165. if (typeof module === "object" && typeof module.exports === "object") {
  166. exports = module.exports = cookiesExport;
  167. }
  168. // But always support CommonJS module 1.1.1 spec (`exports` cannot be a function)
  169. exports.Cookies = cookiesExport;
  170. } else {
  171. global.Cookies = cookiesExport;
  172. }
  173. })(typeof window === "undefined" ? this : window);