cb-cookie-manager 0.0.1-security → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cb-cookie-manager might be problematic. Click here for more details.

Files changed (94) hide show
  1. package/.eslintignore +11 -0
  2. package/LICENSE.md +13 -0
  3. package/README.md +477 -3
  4. package/dist/CookieContext.d.ts +10 -0
  5. package/dist/CookieContext.js +182 -0
  6. package/dist/TrackingManagerContext.d.ts +6 -0
  7. package/dist/TrackingManagerContext.js +53 -0
  8. package/dist/analytics.js +119 -0
  9. package/dist/constants.d.ts +11 -0
  10. package/dist/constants.js +32 -0
  11. package/dist/examples/config.d.ts +28 -0
  12. package/dist/examples/config.js +77 -0
  13. package/dist/hooks/useHasConsent.d.ts +2 -0
  14. package/dist/hooks/useHasConsent.js +14 -0
  15. package/dist/hooks/useRequiredCategories.d.ts +3 -0
  16. package/dist/hooks/useRequiredCategories.js +10 -0
  17. package/dist/hooks/useSavedTrackingPreference.d.ts +3 -0
  18. package/dist/hooks/useSavedTrackingPreference.js +38 -0
  19. package/dist/hooks/useSetTrackingPreference.d.ts +3 -0
  20. package/dist/hooks/useSetTrackingPreference.js +27 -0
  21. package/dist/hooks/useTrackingPreference.d.ts +3 -0
  22. package/dist/hooks/useTrackingPreference.js +16 -0
  23. package/dist/index.d.ts +14 -0
  24. package/dist/index.js +39 -0
  25. package/dist/types.d.ts +62 -0
  26. package/dist/types.js +28 -0
  27. package/dist/utils/areCookiesEnabled.d.ts +2 -0
  28. package/dist/utils/areCookiesEnabled.js +14 -0
  29. package/dist/utils/getAllCookies.d.ts +3 -0
  30. package/dist/utils/getAllCookies.js +64 -0
  31. package/dist/utils/getDefaultTrackingPreference.d.ts +3 -0
  32. package/dist/utils/getDefaultTrackingPreference.js +28 -0
  33. package/dist/utils/getDomain.d.ts +2 -0
  34. package/dist/utils/getDomain.js +21 -0
  35. package/dist/utils/getTrackerCategory.d.ts +3 -0
  36. package/dist/utils/getTrackerCategory.js +11 -0
  37. package/dist/utils/getTrackerInfo.d.ts +3 -0
  38. package/dist/utils/getTrackerInfo.js +12 -0
  39. package/dist/utils/hasConsent.d.ts +11 -0
  40. package/dist/utils/hasConsent.js +29 -0
  41. package/dist/utils/isMaxKBSize.d.ts +2 -0
  42. package/dist/utils/isMaxKBSize.js +7 -0
  43. package/dist/utils/isOptOut.d.ts +16 -0
  44. package/dist/utils/isOptOut.js +25 -0
  45. package/dist/utils/persistMobileAppPreferences.d.ts +2 -0
  46. package/dist/utils/persistMobileAppPreferences.js +36 -0
  47. package/dist/utils/setGTMVariables.d.ts +3 -0
  48. package/dist/utils/setGTMVariables.js +14 -0
  49. package/dist/utils/setTrackingPreference.d.ts +4 -0
  50. package/dist/utils/setTrackingPreference.js +22 -0
  51. package/dist/utils/trackerMatches.d.ts +3 -0
  52. package/dist/utils/trackerMatches.js +12 -0
  53. package/jest.config.ts +204 -0
  54. package/package.json +30 -3
  55. package/src/CookieContext.test.tsx +105 -0
  56. package/src/CookieContext.tsx +215 -0
  57. package/src/TrackingManagerContext.tsx +25 -0
  58. package/src/analytics.ts +65 -0
  59. package/src/constants.ts +35 -0
  60. package/src/examples/config.ts +76 -0
  61. package/src/global.d.ts +3 -0
  62. package/src/hooks/useHasConsent.ts +11 -0
  63. package/src/hooks/useRequiredCaregories.test.tsx +43 -0
  64. package/src/hooks/useRequiredCategories.ts +11 -0
  65. package/src/hooks/useSavedTrackingPreference.ts +47 -0
  66. package/src/hooks/useSetTrackingPreference.test.tsx +82 -0
  67. package/src/hooks/useSetTrackingPreference.ts +31 -0
  68. package/src/hooks/useTrackingPreference.ts +15 -0
  69. package/src/index.ts +20 -0
  70. package/src/types.ts +71 -0
  71. package/src/utils/areCookiesEnabled.ts +13 -0
  72. package/src/utils/getAllCookies.test.ts +35 -0
  73. package/src/utils/getAllCookies.ts +68 -0
  74. package/src/utils/getDefaultTrackingPreference.test.ts +16 -0
  75. package/src/utils/getDefaultTrackingPreference.ts +28 -0
  76. package/src/utils/getDomain.test.ts +16 -0
  77. package/src/utils/getDomain.ts +19 -0
  78. package/src/utils/getTrackerCategory.test.ts +34 -0
  79. package/src/utils/getTrackerCategory.ts +11 -0
  80. package/src/utils/getTrackerInfo.test.ts +11 -0
  81. package/src/utils/getTrackerInfo.ts +10 -0
  82. package/src/utils/hasConsent.test.ts +64 -0
  83. package/src/utils/hasConsent.ts +32 -0
  84. package/src/utils/isMaxKBSize.test.ts +10 -0
  85. package/src/utils/isMaxKBSize.ts +7 -0
  86. package/src/utils/isOptOut.test.ts +14 -0
  87. package/src/utils/isOptOut.ts +28 -0
  88. package/src/utils/persistMobileAppPreferences.ts +32 -0
  89. package/src/utils/setGTMVariables.test.ts +20 -0
  90. package/src/utils/setGTMVariables.ts +17 -0
  91. package/src/utils/setTrackingPreference.ts +36 -0
  92. package/src/utils/trackerMatches.test.ts +13 -0
  93. package/src/utils/trackerMatches.ts +12 -0
  94. package/tsconfig.json +112 -0
package/.eslintignore ADDED
@@ -0,0 +1,11 @@
1
+ # specific files to ignore
2
+ *.md
3
+ .eslintrc.js
4
+ .eslintignore
5
+ webpack.*.js
6
+
7
+ # folders to ignore
8
+ build
9
+ chrome
10
+ **/dist/*
11
+ node_modules
package/LICENSE.md ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2018-2023 Coinbase, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md CHANGED
@@ -1,5 +1,479 @@
1
- # Security holding package
1
+ # Cookie Manager
2
2
 
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
3
+ **Helps with managaing first-party client side cookies to adhere to CCPA and GDPR Cookie regulations**
4
4
 
5
- Please refer to www.npmjs.com/advisories?search=cb-cookie-manager for more information.
5
+ # Contents
6
+
7
+ - [Introduction](#Introduction)
8
+ - [Installation](#installation)
9
+ - [Methods](#methods)
10
+ - [Provider](#provider)
11
+ - [useCookie](#usecookie)
12
+ - [useHasConsent](#usehasconsent)
13
+ - [useRequiredCategories](#userequiredcategories)
14
+ - [useSavedTrackingPreference](#usesavedtrackingpreference)
15
+ - [useSetTrackingPreference](#usesettrackingpreference)
16
+ - [useTrackingPreference](#usesettrackingpreference)
17
+ - [areCookiesEnabled](#arecookiesenabled)
18
+ - [getDefaultTrackingPreference](#getdefaulttrackingpreference)
19
+ - [useTrackingManager](#usetrackingmanager)
20
+ - [isOptOut](#isoptout)
21
+ - [License](#license)
22
+
23
+ ## Introduction
24
+
25
+ `cb-cookie-manager` helps manage the following first party client side cookie categories:
26
+
27
+ - `Necessary Cookies`: Cookies that are necessary for the site to the function
28
+ - `Performance Cookies`: Cookies that impact site performance and help mesaure performance
29
+ - `Functional Cookies`: Cookies to improve the functionality of the site
30
+ - `Targeting Cookies`: Cookies used for advertising and ad targeting
31
+
32
+ The preferences is stored as `cm_eu_preference` cookie in case the user is from EU or as `cm_default_preference` cookie in any other case
33
+
34
+ A `cm_default_preference` cookie looks like the following:
35
+
36
+ ```json
37
+ {
38
+ "region": "DEFAULT",
39
+ "consent": ["necessary", "performance", "functional", "targeting"]
40
+ }
41
+ ```
42
+
43
+ Where region is `DEFAULT` and consent specifies what types of cookie categories the user has given preference too. This is stored as a strictly necessary cookie and has an expiration duration of 1 year.
44
+
45
+ Cookie Manager accepts a config like this:
46
+
47
+ ```typescript
48
+ import {
49
+ Framework,
50
+ Region,
51
+ TrackerType,
52
+ TrackingCategory,
53
+ } from 'cb-cookie-manager';
54
+
55
+ export default {
56
+ categories: [
57
+ {
58
+ id: TrackingCategory.NECESSARY,
59
+ required: true,
60
+ trackers: [
61
+ {
62
+ id: 'locale',
63
+ type: TrackerType.COOKIE,
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ id: TrackingCategory.PERFORMANCE,
69
+ trackers: [
70
+ {
71
+ id: 'some_cookie',
72
+ type: TrackerType.COOKIE,
73
+ },
74
+ ],
75
+ },
76
+ {
77
+ id: TrackingCategory.FUNCTIONAL,
78
+ trackers: [
79
+ {
80
+ id: 'mode',
81
+ type: TrackerType.COOKIE,
82
+ },
83
+ ],
84
+ },
85
+ {
86
+ id: TrackingCategory.TARGETING,
87
+ trackers: [
88
+ {
89
+ id: 'id-regex',
90
+ type: TrackerType.COOKIE,
91
+ regex: 'id(?:_[a-f0-9]{32}|undefined)(?:.*)',
92
+ },
93
+ ],
94
+ },
95
+ {
96
+ id: TrackingCategory.DELETE_IF_SEEN,
97
+ trackers: [
98
+ {
99
+ id: 'cgl_prog',
100
+ type: TrackerType.COOKIE,
101
+ },
102
+ ],
103
+ },
104
+ ],
105
+ geolocationRules: [
106
+ {
107
+ region: Region.DEFAULT,
108
+ framework: Framework.OPT_OUT,
109
+ },
110
+ {
111
+ region: Region.EU,
112
+ framework: Framework.OPT_IN,
113
+ },
114
+ ],
115
+ };
116
+ ```
117
+
118
+ In this config, under each category you can specify what all cookies should be allowed. Everything else, if detected will be deleted at an interval of 500 ms.
119
+
120
+ `DELETE_IF_SEEN` can be used to specify the cookies which should be deleted if seen on the browser
121
+
122
+ You can also specify regex for a given cookie as follows:
123
+
124
+ ```json
125
+ {
126
+ id: 'id-regex',
127
+ type: TrackerType.COOKIE,
128
+ regex: 'id(?:_[a-f0-9]{32}|undefined)(?:.*)',
129
+ }
130
+ ```
131
+
132
+ Any id with `-regex` at the end should contain a `regex` which will be used to match different cookies.
133
+
134
+ In this example: `id_ac7a5c3da45e3612b44543a702e42b01` will also be allowed
135
+
136
+ ## Installation
137
+
138
+ Install the package as follows:
139
+
140
+ ```shell
141
+ yarn add cb-cookie-manager
142
+
143
+ npm install cb-cookie-manager
144
+
145
+ pnpm install cb-cookie-manager
146
+ ```
147
+
148
+ ## Methods
149
+
150
+ ### Provider
151
+
152
+ The provider must wrap the entire application and only be instantiated once. On mount, it will remove all blocked cookies (i.e. cookies that do not have user consent). It takes the following props:
153
+
154
+ `onError: (error: Error) => void`: Error function
155
+
156
+ `projectName: string`: Current project name
157
+
158
+ `locale: string`: Locale to be displayed
159
+
160
+ `region: 'EU' | 'DEFAULT'`; `DEFAULT` refers to non-EU countries
161
+
162
+ `onPreferenceChange?: (preference: TrackingPreference) => void`: Callback for when user consent preferences change. This will also be called on mount.
163
+
164
+ `config: Config`: Cookie manager config. See [Config](#config) section below
165
+
166
+ `shadowMode?: boolean`: Cookies will not be removed in this mode
167
+
168
+ `log: (str: string, options?: Record<string, any>) => void`: Log function
169
+
170
+ Example usage:
171
+
172
+ ```typescript
173
+ import { Provider, Region, TrackingCategory, TrackingPreference } from 'cb-cookie-manager';
174
+
175
+ <Provider
176
+ onError={notifyError}
177
+ onPreferenceChange={() => {}}
178
+ locale={localeCode}
179
+ region={isInEU(locale.country) ? Region.EU : Region.Default}
180
+ projectName="consumer-marketing"
181
+ config={cookieManagerConfig}
182
+ log={eventTracking.track}
183
+ shadowMode
184
+ >
185
+ {children}
186
+ </Provider>
187
+
188
+ ```
189
+
190
+ ### useCookie
191
+
192
+ You should replace all usages of setting, removing or getting cookies with the `useCookie` hook. The cookie manager will prevent any non-consented cookies from being set. Passing `undefined` or `null` to the set cookie function will remove that cookie. You can also pass optional parameters to change the cookie properties.
193
+
194
+ It accepts the following props:
195
+
196
+ ```
197
+ `cookieName`: Name of the cookie for which you want to perform operations
198
+ ```
199
+
200
+ `useCookie` returns the current `cookie` value and a `setCookieFunction`
201
+
202
+ `setCookieFunction` can take in the following props:
203
+
204
+ - `value`: The value to be set for the cookie
205
+ - `CookieAttributes`: This is optional but you can specify the following properties for a cookie:
206
+
207
+ ```typescript
208
+ interface CookieAttributes {
209
+ /**
210
+ * Define when the cookie will be removed. Value can be a Number
211
+ * which will be interpreted as days from time of creation or a
212
+ * Date instance. If omitted, the cookie becomes a session cookie.
213
+ */
214
+ expires?: number | Date;
215
+
216
+ /**
217
+ * Define the path where the cookie is available. Defaults to '/'
218
+ */
219
+ path?: string;
220
+
221
+ /**
222
+ * Define the domain where the cookie is available. Defaults to
223
+ * the domain of the page where the cookie was created.
224
+ */
225
+ domain?: string;
226
+
227
+ /**
228
+ * A Boolean indicating if the cookie transmission requires a
229
+ * secure protocol (https). Defaults to false.
230
+ */
231
+ secure?: boolean;
232
+
233
+ /**
234
+ * Asserts that a cookie must not be sent with cross-origin requests,
235
+ * providing some protection against cross-site request forgery
236
+ * attacks (CSRF)
237
+ */
238
+ sameSite?: 'strict' | 'lax' | 'none';
239
+
240
+ /**
241
+ * An attribute which will be serialized, conformably to RFC 6265
242
+ * section 5.2.
243
+ */
244
+ [property: string]: any;
245
+ }
246
+ ```
247
+
248
+ Example usage:
249
+
250
+ ```typescript
251
+ import { useCookie } from '@cb/cookie-manager';
252
+
253
+ const SomeComponent = () => {
254
+ const [cookie, setCookie] = useCookie('some_cookie');
255
+ const handleClick = () => {
256
+ setCookie('hello')
257
+ };
258
+
259
+ return (
260
+ <div>
261
+ <button onClick={handleClick}>Set cookie</button>
262
+ <span>Current cookie: </span>
263
+ <span>{cookie}</span>
264
+ </div>
265
+ }
266
+ ```
267
+
268
+ ### useHasConsent
269
+
270
+ This is a hook for programmatically determining if a tracker (e.g. cookie) has been consented to by the user.
271
+
272
+ ```typescript
273
+ import { useHasConsent } from 'cb-cookie-manager';
274
+
275
+ const SomeComponent = () => {
276
+ const hasConsent = useHasConsent('cookie');
277
+
278
+ return (
279
+ <div>
280
+ {hasConsent && <div> Cookie has consent </div>
281
+ </div>
282
+ }
283
+ ```
284
+
285
+ ### useRequiredCategories
286
+
287
+ This hook is used to determine which category of cookies is required.
288
+
289
+ Example Usage:
290
+
291
+ ```typescript
292
+ import { useRequiredCategories, TRACKER_CATEGORIES } from 'cb-cookie-manager';
293
+
294
+ const SomeComponent = () => {
295
+ const requiredCategories = useRequiredCategories();
296
+
297
+ return (
298
+ <div>
299
+ <CategoryContainer>
300
+ {TRACKER_CATEGORIES.map(t => (
301
+ <CheckBoxContainer key={t}>
302
+ <CheckBox
303
+ disabled={requiredCategories.includes(t)}
304
+ checked={state.consent.includes(t)}
305
+ onChange={(val: boolean) => dispatch({ name: t, value: val })}
306
+ >
307
+ <CategoryLabel name={t} />
308
+ </CheckBox>
309
+ </CheckBoxContainer>
310
+ ))}
311
+ </CategoryContainer>
312
+ </div>
313
+ }
314
+ ```
315
+
316
+ ### useSavedTrackingPreference
317
+
318
+ This hook is used to retrieve the saved cookie preference in cache
319
+
320
+ Example Usage:
321
+
322
+ ```typescript
323
+ import { useSavedTrackingPreference } from 'cb-cookie-manager';
324
+
325
+ const SomeComponent = () => {
326
+ const preference = useSavedTrackingPreference();
327
+
328
+ return (
329
+ <div>
330
+ {preference}
331
+ </div>
332
+ )
333
+ }
334
+ ```
335
+
336
+ ### useSetTrackingPreference
337
+
338
+ This hook is used to set the saved cookie preference in cache
339
+
340
+ Example Usage:
341
+
342
+ ```typescript
343
+ import { useSetTrackingPreference, Region, TrackingCategory } from 'cb-cookie-manager';
344
+
345
+ const SomeComponent = () => {
346
+ const setTrackingPreference = useSetTrackingPreference();
347
+
348
+ const handleSave = useCallback(() => {
349
+ setTrackingPreference({
350
+ region: Region.Default,
351
+ consent: [TrackingCategory.Functional],
352
+ });
353
+ console.log('cookie_consent_manager_saved_tapped');
354
+ }, [setTrackingPreference]);
355
+
356
+ return (
357
+ <div>
358
+ <Button onClick={handleSave} large>
359
+ Save Preference
360
+ </Button>
361
+ </div>
362
+ )
363
+ }
364
+ ```
365
+
366
+ ### useTrackingPreference
367
+
368
+ This hook returns the cached preference and if no preference is cached, it returns the default preference based on user's region
369
+
370
+ Example Usage:
371
+
372
+ ```typescript
373
+ import { useTrackingPreference } from 'cb-cookie-manager';
374
+
375
+ const SomeComponent = () => {
376
+ const initialTrackingPreference = useTrackingPreference();
377
+
378
+ return (
379
+ <div>
380
+ {initialTrackingPreference}
381
+ </div>
382
+ )
383
+ }
384
+ ```
385
+
386
+ ### areCookiesEnabled
387
+
388
+ This hook is used to determine if cookies have been enabled on user's browser
389
+
390
+ Example usage:
391
+
392
+ ```typescript
393
+
394
+ import { areCookiesEnabled } from 'cb-cookie-manager';
395
+
396
+
397
+ const SomeComponent = () => {
398
+ const enabled = areCookiesEnabled();
399
+
400
+ return (
401
+ <div>
402
+ {enabled? <div> Cookies Enabled </div> : <div> Cookies not enabled </div>}
403
+ </div>
404
+ )
405
+ }
406
+ ```
407
+
408
+ ### getDefaultTrackingPreference
409
+
410
+ This hook is used to retrieve the default tracking preference for a given user based on their region
411
+
412
+ Example usage:
413
+
414
+ ```typescript
415
+ import { getDefaultTrackingPreference } from 'cb-cookie-manager';
416
+
417
+ const SomeComponent = () => {
418
+ const preference = getDefaultTrackingPreference();
419
+
420
+ return (
421
+ <div>
422
+ {preference}
423
+ </div>
424
+ )
425
+ }
426
+ ```
427
+
428
+ ### useTrackingManager
429
+
430
+ This hook is used to return `TrackingManagerDependencies` which includes all the values/methods which were passed into Cookie Manager Provider
431
+
432
+ Example usage:
433
+
434
+ ```typescript
435
+ import { isOptOut, useTrackingManager } from 'cb-cookie-manager';
436
+
437
+ const SomeComponent = () => {
438
+ const { region } = useTrackingManager();
439
+ const optOut = isOptOut(region);
440
+
441
+ return (
442
+ <div>
443
+ `Region for the given user is ${region}`
444
+ </div>
445
+ )
446
+ }
447
+ ```
448
+
449
+ ### isOptOut
450
+
451
+ Used for determining if the current region is using the `optOut` framework
452
+
453
+ It follows the following logic in order:
454
+
455
+ - If there's no geolocation rule for the specified region then use the rule for DEFAULT region
456
+ - Otherwise use the following rules:
457
+ - optIn: Users must opt in to tracking (EU)
458
+ - optOut: Users must opt out of tracking (non-EU)
459
+
460
+ Example usage:
461
+
462
+ ```typescript
463
+ import { isOptOut, useTrackingManager } from 'cb-cookie-manager';
464
+
465
+ const SomeComponent = () => {
466
+ const { region } = useTrackingManager();
467
+ const optOut = isOptOut(region);
468
+
469
+ return (
470
+ <div>
471
+ {isOptOut ? <div> In default region </div> : <div> In Eu </div>}
472
+ </div>
473
+ )
474
+ }
475
+ ```
476
+
477
+ ## License
478
+
479
+ Licensed under the Apache License. See [LICENSE](./LICENSE) for more information.
@@ -0,0 +1,10 @@
1
+ import { CookieAttributes } from 'js-cookie';
2
+ import React from 'react';
3
+ import { SetCookieFunction } from './types';
4
+ type Props = {
5
+ children: React.ReactNode;
6
+ };
7
+ export declare const CookieProvider: ({ children }: Props) => React.JSX.Element;
8
+ export declare const useSetCookie: () => (cookieName: string, value: any, options?: CookieAttributes) => void;
9
+ export declare const useCookie: (cookieName: string) => [any | undefined, SetCookieFunction];
10
+ export {};
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.useCookie = exports.useSetCookie = exports.CookieProvider = void 0;
30
+ const js_cookie_1 = __importDefault(require("js-cookie"));
31
+ const react_1 = __importStar(require("react"));
32
+ const constants_1 = require("./constants");
33
+ const TrackingManagerContext_1 = require("./TrackingManagerContext");
34
+ const types_1 = require("./types");
35
+ const getAllCookies_1 = __importStar(require("./utils/getAllCookies"));
36
+ const getDefaultTrackingPreference_1 = __importDefault(require("./utils/getDefaultTrackingPreference"));
37
+ const getDomain_1 = require("./utils/getDomain");
38
+ const getTrackerInfo_1 = __importDefault(require("./utils/getTrackerInfo"));
39
+ const hasConsent_1 = __importDefault(require("./utils/hasConsent"));
40
+ const isMaxKBSize_1 = __importDefault(require("./utils/isMaxKBSize"));
41
+ const setGTMVariables_1 = __importDefault(require("./utils/setGTMVariables"));
42
+ const CookieContext = (0, react_1.createContext)([{}]);
43
+ const CookieProvider = ({ children }) => {
44
+ const { config, region, shadowMode, log, onPreferenceChange } = (0, TrackingManagerContext_1.useTrackingManager)();
45
+ const POLL_INTERVAL = 500;
46
+ let cookieValues = {};
47
+ let trackingPreference;
48
+ let adTrackingPreference;
49
+ const removeCookies = (0, react_1.useCallback)((cookies) => {
50
+ cookies.forEach((c) => {
51
+ if (!shadowMode) {
52
+ js_cookie_1.default.remove(c, { domain: (0, getDomain_1.getDomainWithoutSubdomain)(), path: '/' });
53
+ js_cookie_1.default.remove(c, { domain: (0, getDomain_1.getHostname)(), path: '/' });
54
+ }
55
+ log('Cookie does not have consent and will be removed', {
56
+ cookie: c,
57
+ });
58
+ });
59
+ }, [shadowMode, log]);
60
+ (0, react_1.useEffect)(() => {
61
+ if (typeof window !== 'undefined') {
62
+ const checkCookies = () => {
63
+ const currentCookie = (0, getAllCookies_1.default)();
64
+ if (!(0, getAllCookies_1.areRecordsEqual)(cookieValues, currentCookie)) {
65
+ cookieValues = currentCookie;
66
+ trackingPreference = getTrackingPreference(cookieValues, region, config);
67
+ adTrackingPreference = getAdTrackingPreference(cookieValues);
68
+ (0, setGTMVariables_1.default)(trackingPreference, adTrackingPreference);
69
+ const cookiesToRemove = [];
70
+ Object.keys(cookieValues).forEach((c) => {
71
+ const trackerInfo = (0, getTrackerInfo_1.default)(c, config);
72
+ if (constants_1.REQUIRED_COOKIE_MANAGER_COOKIES.includes(c)) {
73
+ return;
74
+ }
75
+ if (!trackerInfo) {
76
+ // This cookie is not present in the config. For legal/compliance
77
+ // reasons, any cookies not listed in the config may not be set.
78
+ cookiesToRemove.push(c);
79
+ return;
80
+ }
81
+ if (!(0, hasConsent_1.default)(c, config, trackingPreference) &&
82
+ trackerInfo.type === types_1.TrackerType.COOKIE) {
83
+ cookiesToRemove.push(c);
84
+ }
85
+ });
86
+ removeCookies(cookiesToRemove);
87
+ }
88
+ };
89
+ checkCookies();
90
+ // Call the function once before setting the interval
91
+ const intervalId = setInterval(checkCookies, POLL_INTERVAL);
92
+ return () => {
93
+ clearInterval(intervalId);
94
+ };
95
+ }
96
+ }, []);
97
+ (0, react_1.useEffect)(() => {
98
+ if (onPreferenceChange) {
99
+ onPreferenceChange(trackingPreference);
100
+ }
101
+ }, []);
102
+ return react_1.default.createElement(CookieContext.Provider, { value: cookieValues }, children);
103
+ };
104
+ exports.CookieProvider = CookieProvider;
105
+ const useSetCookie = () => {
106
+ const cookieChangedRef = (0, react_1.useContext)(CookieContext);
107
+ const { config, region, log, shadowMode, onError } = (0, TrackingManagerContext_1.useTrackingManager)();
108
+ const trackingPreference = getTrackingPreference(cookieChangedRef, region, config);
109
+ return (0, react_1.useCallback)((cookieName, value, options) => {
110
+ const setCookieFunc = setCookieFunction({
111
+ cookieName,
112
+ trackingPreference,
113
+ config,
114
+ log,
115
+ shadowMode,
116
+ onError,
117
+ });
118
+ setCookieFunc(value, options);
119
+ }, [trackingPreference, config, log, shadowMode, onError]);
120
+ };
121
+ exports.useSetCookie = useSetCookie;
122
+ const setCookieFunction = ({ cookieName, trackingPreference, config, shadowMode, log, onError, }) => {
123
+ return (value, options) => {
124
+ var _a;
125
+ if (value === undefined || value === null) {
126
+ js_cookie_1.default.remove(cookieName, options);
127
+ return;
128
+ }
129
+ const cookieHasConsent = (0, hasConsent_1.default)(cookieName, config, trackingPreference);
130
+ if (cookieHasConsent || shadowMode) {
131
+ const stringValue = JSON.stringify(value);
132
+ const cookieSize = (_a = options === null || options === void 0 ? void 0 : options.size) !== null && _a !== void 0 ? _a : constants_1.MAX_COOKIE_SIZE;
133
+ /*
134
+ Url encoded cookie string (since that is what Cookies.set coverts the string into) including its name must not exceed 4KB
135
+ For example, "," becomes %22%2C%2C making it go from 3 characters to now 9. The size has tripled.
136
+ This is why we need to compare the url encoded stringValue instead of the stringValue itself to account for the extra characters.
137
+ */
138
+ if ((0, isMaxKBSize_1.default)(encodeURIComponent(stringValue) + cookieName, cookieSize)) {
139
+ onError(new Error(`${cookieName} value exceeds ${cookieSize}KB`));
140
+ }
141
+ else {
142
+ const newOptions = options ? Object.assign({}, options) : undefined;
143
+ if (newOptions === null || newOptions === void 0 ? void 0 : newOptions.size) {
144
+ delete newOptions.size;
145
+ }
146
+ js_cookie_1.default.set(cookieName, stringValue, newOptions);
147
+ }
148
+ }
149
+ if (!cookieHasConsent) {
150
+ log('Cookie does not have consent and will not be set', {
151
+ cookie: cookieName,
152
+ });
153
+ }
154
+ };
155
+ };
156
+ const getTrackingPreference = (cookieCache, region, config) => {
157
+ const trackingPreference = region === 'EU'
158
+ ? cookieCache[constants_1.EU_CONSENT_PREFERENCES_COOKIE]
159
+ : cookieCache[constants_1.DEFAULT_CONSENT_PREFERENCES_COOKIE];
160
+ return trackingPreference || (0, getDefaultTrackingPreference_1.default)(region, config);
161
+ };
162
+ const adTrackingDefault = { value: 'true' };
163
+ const getAdTrackingPreference = (cookieCache) => {
164
+ const adTrackingPreference = cookieCache[constants_1.ADVERTISING_SHARING_ALLOWED];
165
+ return adTrackingPreference || adTrackingDefault;
166
+ };
167
+ const useCookie = (cookieName) => {
168
+ const cookieCache = (0, react_1.useContext)(CookieContext);
169
+ const { config, region, log, shadowMode, onError } = (0, TrackingManagerContext_1.useTrackingManager)();
170
+ const trackingPreference = getTrackingPreference(cookieCache, region, config);
171
+ const setCookie = setCookieFunction({
172
+ cookieName,
173
+ trackingPreference,
174
+ config,
175
+ log,
176
+ shadowMode,
177
+ onError,
178
+ });
179
+ const cookieValue = (0, react_1.useContext)(CookieContext)[cookieName];
180
+ return [cookieValue, setCookie];
181
+ };
182
+ exports.useCookie = useCookie;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { TrackingManagerDependencies } from './types';
3
+ export declare const useTrackingManager: () => TrackingManagerDependencies;
4
+ export declare function Provider({ children, ...restProps }: {
5
+ children: React.ReactNode;
6
+ } & TrackingManagerDependencies): React.JSX.Element;