ngx-cookie-service 22.1.0 → 22.2.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.
package/README.md CHANGED
@@ -253,6 +253,45 @@ cookieService.deleteAll({ path: '/' });
253
253
  Deletes all cookies that can currently be accessed, using the same attributes for each one. It is best practice to
254
254
  always define a path. If you are unsure about the path value, use `'/'`.
255
255
 
256
+ ## provideCookieOptions( options: CookieOptions ): EnvironmentProviders;
257
+
258
+ ```typescript
259
+ // app.config.ts
260
+ import { provideCookieOptions } from 'ngx-cookie-service'; // or 'ngx-cookie-service-ssr'
261
+
262
+ export const appConfig: ApplicationConfig = {
263
+ providers: [provideCookieOptions({ path: '/', secure: true, sameSite: 'Strict' })],
264
+ };
265
+ ```
266
+
267
+ Sets default options for every `set()`, `delete()` and `deleteAll()` call, so you don't have to repeat them. Options
268
+ passed to a call win over the defaults, and `undefined` values don't override them. A call that passes its own `expires`
269
+ (or `maxAge` in `ngx-cookie-service-ssr`) replaces the default lifetime, so `delete()` always expires the cookie.
270
+
271
+ Setting `path: '/'` here is recommended. Without a path, the browser uses the directory of the URL the page was loaded
272
+ at, so the same code can read or delete different cookies depending on where the user landed.
273
+
274
+ ## provideCookieEncoding( encoding: 'uri' | 'minimal' | CookieCodec ): EnvironmentProviders;
275
+
276
+ ```typescript
277
+ // app.config.ts
278
+ import { provideCookieEncoding } from 'ngx-cookie-service'; // or 'ngx-cookie-service-ssr'
279
+
280
+ export const appConfig: ApplicationConfig = {
281
+ providers: [provideCookieEncoding('minimal')],
282
+ };
283
+ ```
284
+
285
+ Sets how cookie values are encoded when they are written and decoded when they are read. Cookie names keep the
286
+ default encoding.
287
+
288
+ - `'uri'` (default): values are encoded with `encodeURIComponent`, so `ab+/cd==` is stored as `ab%2B%2Fcd%3D%3D`.
289
+ - `'minimal'`: values made only of characters allowed in a cookie value are stored as-is, so `ab+/cd==` stays
290
+ `ab+/cd==`. Other values fall back to `encodeURIComponent`. Use it when a server reads cookies without URL-decoding
291
+ them, for example JWT or base64 values. Express encodes cookie values the same way.
292
+ - A custom `{ encode(value, name), decode(value, name) }` object for any other scheme. If the encoded value contains
293
+ `;` or a control character, the cookie is not written and a warning is logged.
294
+
256
295
  # FAQ
257
296
 
258
297
  ## General tips
@@ -1,15 +1,32 @@
1
- import { isPlatformBrowser } from "@angular/common";
2
1
  import * as i0 from "@angular/core";
3
- import { DOCUMENT, Injectable, PLATFORM_ID, inject } from "@angular/core";
2
+ import { DOCUMENT, Injectable, InjectionToken, PLATFORM_ID, inject, makeEnvironmentProviders } from "@angular/core";
3
+ import { isPlatformBrowser } from "@angular/common";
4
+ const COOKIE_OPTIONS = new InjectionToken("ngx-cookie-service default cookie options");
5
+ function provideCookieOptions(options) {
6
+ return makeEnvironmentProviders([{
7
+ provide: COOKIE_OPTIONS,
8
+ useValue: { ...options }
9
+ }]);
10
+ }
11
+ const COOKIE_ENCODING = new InjectionToken("ngx-cookie-service cookie value encoding");
12
+ function provideCookieEncoding(encoding) {
13
+ return makeEnvironmentProviders([{
14
+ provide: COOKIE_ENCODING,
15
+ useValue: encoding
16
+ }]);
17
+ }
4
18
  const SAME_SITE_VALUES = [
5
19
  "Lax",
6
20
  "Strict",
7
21
  "None"
8
22
  ];
23
+ const COOKIE_OCTET_REGEXP = /^[!#$&'()*+\-./0-9:<=>?@A-Z[\]^_`a-z{|}~]*$/;
9
24
  var CookieService = class CookieService {
10
25
  constructor() {
11
26
  this.document = inject(DOCUMENT);
12
27
  this.platformId = inject(PLATFORM_ID);
28
+ this.defaultOptions = inject(COOKIE_OPTIONS, { optional: true }) ?? {};
29
+ this.codec = CookieService.toCodec(inject(COOKIE_ENCODING, { optional: true }));
13
30
  this.documentIsAccessible = isPlatformBrowser(this.platformId);
14
31
  }
15
32
  static getCookieRegExp(name) {
@@ -30,9 +47,8 @@ var CookieService = class CookieService {
30
47
  }
31
48
  get(name) {
32
49
  if (this.check(name)) {
33
- name = encodeURIComponent(name);
34
- const result = CookieService.getCookieRegExp(name).exec(this.document.cookie);
35
- return result?.[1] ? CookieService.safeDecodeURIComponent(result[1]) : "";
50
+ const result = CookieService.getCookieRegExp(encodeURIComponent(name)).exec(this.document.cookie);
51
+ return result?.[1] ? this.decodeValue(result[1], name) : "";
36
52
  } else return "";
37
53
  }
38
54
  getAll() {
@@ -47,7 +63,7 @@ var CookieService = class CookieService {
47
63
  const cookieName = CookieService.safeDecodeURIComponent(trimmedCookie.substring(0, equalIndex));
48
64
  if (Object.hasOwn(cookies, cookieName)) return;
49
65
  Object.defineProperty(cookies, cookieName, {
50
- value: CookieService.safeDecodeURIComponent(trimmedCookie.substring(equalIndex + 1)),
66
+ value: this.decodeValue(trimmedCookie.substring(equalIndex + 1), cookieName),
51
67
  enumerable: true,
52
68
  writable: true,
53
69
  configurable: true
@@ -63,15 +79,17 @@ var CookieService = class CookieService {
63
79
  path,
64
80
  domain,
65
81
  secure,
66
- sameSite: sameSite || "Lax",
82
+ sameSite,
67
83
  partitioned
68
84
  };
69
85
  this.set(name, value, optionsBody);
70
86
  return;
71
87
  }
72
- const options = CookieService.validateOptions(name, expiresOrOptions);
88
+ const options = CookieService.validateOptions(name, CookieService.withDefaults(this.defaultOptions, expiresOrOptions));
73
89
  if (!options) return;
74
- let cookieString = encodeURIComponent(name) + "=" + encodeURIComponent(value) + ";";
90
+ const encodedValue = this.encodeValue(name, value);
91
+ if (encodedValue === void 0) return;
92
+ let cookieString = encodeURIComponent(name) + "=" + encodedValue + ";";
75
93
  if (options.expires) cookieString += "Expires=" + options.expires.toUTCString() + ";";
76
94
  if (options.path) cookieString += "Path=" + options.path + ";";
77
95
  if (options.domain) cookieString += "Domain=" + options.domain + ";";
@@ -89,7 +107,7 @@ var CookieService = class CookieService {
89
107
  if (options.partitioned) cookieString += "Partitioned;";
90
108
  this.document.cookie = cookieString;
91
109
  }
92
- delete(name, pathOrOptions, domain, secure, sameSite = "Lax") {
110
+ delete(name, pathOrOptions, domain, secure, sameSite) {
93
111
  if (!this.documentIsAccessible) return;
94
112
  const options = CookieService.toDeleteOptions(pathOrOptions, domain, secure, sameSite);
95
113
  this.set(name, "", {
@@ -97,11 +115,48 @@ var CookieService = class CookieService {
97
115
  expires: /* @__PURE__ */ new Date("Thu, 01 Jan 1970 00:00:01 GMT")
98
116
  });
99
117
  }
100
- deleteAll(pathOrOptions, domain, secure, sameSite = "Lax") {
118
+ deleteAll(pathOrOptions, domain, secure, sameSite) {
101
119
  if (!this.documentIsAccessible) return;
102
120
  for (const cookieName of Object.keys(this.getAll())) if (typeof pathOrOptions === "object" && pathOrOptions !== null) this.delete(cookieName, pathOrOptions);
103
121
  else this.delete(cookieName, pathOrOptions, domain, secure, sameSite);
104
122
  }
123
+ static {
124
+ this.uriCodec = {
125
+ encode: (value) => encodeURIComponent(value),
126
+ decode: (value) => CookieService.safeDecodeURIComponent(value)
127
+ };
128
+ }
129
+ static {
130
+ this.minimalCodec = {
131
+ encode: (value) => COOKIE_OCTET_REGEXP.test(value) ? value : encodeURIComponent(value),
132
+ decode: (value) => CookieService.safeDecodeURIComponent(value)
133
+ };
134
+ }
135
+ static toCodec(encoding) {
136
+ if (encoding === "minimal") return CookieService.minimalCodec;
137
+ if (typeof encoding === "object" && encoding !== null) return encoding;
138
+ return CookieService.uriCodec;
139
+ }
140
+ encodeValue(name, value) {
141
+ const encodedValue = this.codec.encode(value, name);
142
+ if (typeof encodedValue !== "string" || CookieService.hasUnsafeCharacter(encodedValue)) {
143
+ console.warn(`[ngx-cookie-service] Cookie ${name} was skipped because its encoded value isn't a string without ";" or control characters.`);
144
+ return;
145
+ }
146
+ return encodedValue;
147
+ }
148
+ decodeValue(value, name) {
149
+ try {
150
+ return this.codec.decode(value, name);
151
+ } catch {
152
+ return value;
153
+ }
154
+ }
155
+ static withDefaults(defaults, options = {}) {
156
+ const merged = { ...defaults };
157
+ for (const [key, value] of Object.entries(options)) if (value !== void 0 && value !== null) merged[key] = value;
158
+ return merged;
159
+ }
105
160
  static validateOptions(name, options = {}) {
106
161
  const { expires, ...valid } = options;
107
162
  const result = valid;
@@ -173,6 +228,6 @@ i0.ɵɵngDeclareClassMetadata({
173
228
  }],
174
229
  ctorParameters: () => []
175
230
  });
176
- export { CookieService };
231
+ export { COOKIE_ENCODING, COOKIE_OPTIONS, CookieService, provideCookieEncoding, provideCookieOptions };
177
232
 
178
233
  //# sourceMappingURL=ngx-cookie-service.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-cookie-service.mjs","names":[],"sources":["../../../projects/ngx-cookie-service/src/lib/cookie.service.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport { DOCUMENT, inject, Injectable, PLATFORM_ID } from '@angular/core';\n\nexport type SameSite = 'Lax' | 'None' | 'Strict';\n\nexport interface CookieOptions {\n expires?: number | Date;\n path?: string;\n domain?: string;\n secure?: boolean;\n sameSite?: SameSite;\n partitioned?: boolean;\n}\n\n/**\n * Attributes that identify the cookie to delete. They must match the attributes the cookie was set with.\n */\nexport type DeleteCookieOptions = Omit<CookieOptions, 'expires'>;\n\n/**\n * Cookie options after validation: invalid values are removed and `expires` is always a `Date`.\n */\ntype ValidCookieOptions = Omit<CookieOptions, 'expires'> & { expires?: Date };\n\n/**\n * The `SameSite` values browsers accept, in their canonical spelling.\n */\nconst SAME_SITE_VALUES: readonly SameSite[] = ['Lax', 'Strict', 'None'];\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CookieService {\n private readonly documentIsAccessible: boolean;\n private readonly document = inject<Document>(DOCUMENT);\n private readonly platformId = inject<object>(PLATFORM_ID);\n\n constructor() {\n this.documentIsAccessible = isPlatformBrowser(this.platformId);\n }\n\n /**\n * Get cookie Regular Expression\n *\n * @param name Cookie name\n * @returns property RegExp\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n private static getCookieRegExp(name: string): RegExp {\n const escapedName: string = name.replace(/([[\\]{}()|=;+?,.*^$\\\\])/gi, '\\\\$1');\n\n return new RegExp('(?:^' + escapedName + '|;\\\\s*' + escapedName + ')=(.*?)(?:;|$)');\n }\n\n /**\n * Gets the decoded version of an encoded component of a Uniform Resource Identifier (URI).\n *\n * @param encodedURIComponent A value representing an encoded URI component.\n *\n * @returns The decoded version of an encoded component of a Uniform Resource Identifier (URI).\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n private static safeDecodeURIComponent(encodedURIComponent: string): string {\n try {\n return decodeURIComponent(encodedURIComponent);\n } catch {\n // probably it is not uri encoded. return as is\n return encodedURIComponent;\n }\n }\n\n /**\n * Return `true` if {@link Document} is accessible, otherwise return `false`\n *\n * @param name Cookie name\n * @returns boolean - whether cookie with specified name exists\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n check(name: string): boolean {\n if (!this.documentIsAccessible) {\n return false;\n }\n name = encodeURIComponent(name);\n const regExp = CookieService.getCookieRegExp(name);\n return regExp.test(this.document.cookie);\n }\n\n /**\n * Get cookies by name\n *\n * @param name Cookie name\n * @returns property value\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n get(name: string): string {\n if (this.check(name)) {\n name = encodeURIComponent(name);\n const regExp: RegExp = CookieService.getCookieRegExp(name);\n const result = regExp.exec(this.document.cookie);\n return result?.[1] ? CookieService.safeDecodeURIComponent(result[1]) : '';\n } else {\n return '';\n }\n }\n\n /**\n * Get all cookies in JSON format\n *\n * @returns all the cookies in json\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n getAll(): Record<string, string> {\n if (!this.documentIsAccessible) {\n return {};\n }\n\n const cookies: Record<string, string> = {};\n const document: Document = this.document;\n\n if (document.cookie && document.cookie !== '') {\n document.cookie.split(';').forEach((currentCookie: string) => {\n const trimmedCookie = currentCookie.trim();\n if (!trimmedCookie) {\n return;\n }\n // Split on the first '=' only, so values containing '=' (e.g. base64 padding) are preserved\n const equalIndex = trimmedCookie.indexOf('=');\n if (equalIndex === -1) {\n // Cookie without value (invalid, but handle gracefully)\n return;\n }\n const cookieName = CookieService.safeDecodeURIComponent(trimmedCookie.substring(0, equalIndex));\n // Browsers list the most specific cookie first when several share a name. Keep that one, as get() does.\n if (Object.hasOwn(cookies, cookieName)) {\n return;\n }\n // defineProperty stores names such as \"__proto__\" as normal entries instead of touching the object's prototype\n Object.defineProperty(cookies, cookieName, {\n value: CookieService.safeDecodeURIComponent(trimmedCookie.substring(equalIndex + 1)),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n });\n }\n\n return cookies;\n }\n\n /**\n * Set cookie based on provided information\n *\n * @param name Cookie name\n * @param value Cookie value\n * @param expires Number of days until the cookies expires or an actual `Date`\n * @param path Cookie path\n * @param domain Cookie domain\n * @param secure Secure flag\n * @param partitioned Partitioned flag\n * @param sameSite OWASP same site token `Lax`, `None`, or `Strict`. Defaults to `Lax`\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n set(\n name: string,\n value: string,\n expires?: CookieOptions['expires'],\n path?: CookieOptions['path'],\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite,\n partitioned?: CookieOptions['partitioned']\n ): void;\n\n /**\n * Set cookie based on provided information\n *\n * Cookie's parameters:\n * <pre>\n * expires Number of days until the cookies expires or an actual `Date`\n * path Cookie path\n * domain Cookie domain\n * secure flag\n * sameSite OWASP same site token `Lax`, `None`, or `Strict`. Defaults to `Lax`\n * </pre>\n *\n * @param name Cookie name\n * @param value Cookie value\n * @param options Body with cookie's params\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n set(name: string, value: string, options?: CookieOptions): void;\n\n set(\n name: string,\n value: string,\n expiresOrOptions?: CookieOptions['expires'] | CookieOptions,\n path?: CookieOptions['path'],\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite,\n partitioned?: CookieOptions['partitioned']\n ): void {\n if (!this.documentIsAccessible) {\n return;\n }\n\n // Anything but an options object means the positional form, so no positional argument (e.g. a lone `partitioned`) is dropped\n if (typeof expiresOrOptions !== 'object' || expiresOrOptions === null || expiresOrOptions instanceof Date) {\n const optionsBody = {\n expires: expiresOrOptions as CookieOptions['expires'],\n path,\n domain,\n secure,\n sameSite: sameSite || 'Lax',\n partitioned,\n };\n\n this.set(name, value, optionsBody);\n return;\n }\n\n // validateOptions() returns a copy, so the defaults applied below don't leak back into the caller's object\n const options = CookieService.validateOptions(name, expiresOrOptions);\n if (!options) {\n return;\n }\n\n let cookieString: string = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';';\n\n if (options.expires) {\n cookieString += 'Expires=' + options.expires.toUTCString() + ';';\n }\n\n if (options.path) {\n cookieString += 'Path=' + options.path + ';';\n }\n\n if (options.domain) {\n cookieString += 'Domain=' + options.domain + ';';\n }\n\n if (options.sameSite === 'None' && !options.secure) {\n options.secure = true;\n console.warn(\n `[ngx-cookie-service] Cookie ${name} was forced with secure flag because sameSite=None.` +\n `More details : https://github.com/stevermeister/ngx-cookie-service/issues/86#issuecomment-597720130`\n );\n }\n if (options.partitioned && !options.secure) {\n options.secure = true;\n console.warn(`[ngx-cookie-service] Cookie ${name} was forced with secure flag because Partitioned cookies must be Secure.`);\n }\n if (options.secure) {\n cookieString += 'Secure;';\n }\n\n if (!options.sameSite) {\n options.sameSite = 'Lax';\n }\n\n cookieString += 'SameSite=' + options.sameSite + ';';\n\n if (options.partitioned) {\n cookieString += 'Partitioned;';\n }\n\n this.document.cookie = cookieString;\n }\n\n /**\n * Delete cookie by name at given path and domain.\n *\n * If `path` is not specified, no `Path` attribute is written and the browser uses its default path: the directory of the URL\n * the page was loaded at (not the current router URL). To delete a cookie that was set with `path: '/'`, pass `'/'` here too.\n *\n * @param name Cookie name\n * @param path Cookie path\n * @param domain Cookie domain\n * @param secure Cookie secure flag\n * @param sameSite Cookie sameSite flag - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n delete(name: string, path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite): void;\n\n /**\n * Delete cookie by name. The options must match the attributes the cookie was set with: `path` and `domain` select the\n * cookie, and `partitioned: true` is required to delete a Partitioned cookie.\n *\n * If `path` is not specified, no `Path` attribute is written and the browser uses its default path: the directory of the URL\n * the page was loaded at (not the current router URL). To delete a cookie that was set with `path: '/'`, pass `'/'` here too.\n *\n * @param name Cookie name\n * @param options Cookie attributes: `path`, `domain`, `secure`, `sameSite` and `partitioned`\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n delete(name: string, options?: DeleteCookieOptions): void;\n\n delete(\n name: string,\n pathOrOptions?: CookieOptions['path'] | DeleteCookieOptions,\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite: SameSite = 'Lax'\n ): void {\n if (!this.documentIsAccessible) {\n return;\n }\n const options = CookieService.toDeleteOptions(pathOrOptions, domain, secure, sameSite);\n this.set(name, '', { ...options, expires: new Date('Thu, 01 Jan 1970 00:00:01 GMT') });\n }\n\n /**\n * Delete all cookies at given path and domain.\n *\n * If `path` is not specified, the browser's default path is used for each cookie, as described for {@link delete}.\n *\n * @param path Cookie path\n * @param domain Cookie domain\n * @param secure Is the Cookie secure\n * @param sameSite Is the cookie same site\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n deleteAll(path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite): void;\n\n /**\n * Delete all cookies that can currently be accessed, using the same attributes for each one.\n *\n * If `path` is not specified, the browser's default path is used for each cookie, as described for {@link delete}.\n *\n * @param options Cookie attributes: `path`, `domain`, `secure`, `sameSite` and `partitioned`\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n deleteAll(options?: DeleteCookieOptions): void;\n\n deleteAll(\n pathOrOptions?: CookieOptions['path'] | DeleteCookieOptions,\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite: SameSite = 'Lax'\n ): void {\n if (!this.documentIsAccessible) {\n return;\n }\n\n // Object.keys() rather than for...in with cookies.hasOwnProperty(): a cookie named \"hasOwnProperty\" would shadow that method\n for (const cookieName of Object.keys(this.getAll())) {\n // Call delete() the same way deleteAll() was called, so overrides and spies of the positional form keep working\n if (typeof pathOrOptions === 'object' && pathOrOptions !== null) {\n this.delete(cookieName, pathOrOptions);\n } else {\n this.delete(cookieName, pathOrOptions, domain, secure, sameSite);\n }\n }\n }\n\n /**\n * Returns a validated copy of the options, or `undefined` if the cookie must not be written.\n *\n * A `path` or `domain` containing `;` or a control character could inject attributes or change the cookie's scope, so the\n * whole write is skipped. An invalid `expires` is dropped, which makes a session cookie as browsers already did, and an\n * unknown `sameSite` falls back to the `Lax` default. Each case logs a warning. A numeric `expires` (days\n * from now) is converted to a `Date`, and `sameSite` is matched case-insensitively.\n *\n * @param name Cookie name, used in warnings\n * @param options Cookie options\n * @returns A validated copy of the options, or `undefined` to skip the write\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n private static validateOptions(name: string, options: CookieOptions = {}): ValidCookieOptions | undefined {\n const { expires, ...valid }: CookieOptions = options;\n const result: ValidCookieOptions = valid;\n\n for (const attribute of ['path', 'domain'] as const) {\n const attributeValue = result[attribute];\n if (typeof attributeValue === 'string' && CookieService.hasUnsafeCharacter(attributeValue)) {\n console.warn(`[ngx-cookie-service] Cookie ${name} was skipped because its ${attribute} contains \";\" or a control character.`);\n return undefined;\n }\n }\n if (expires) {\n const date = typeof expires === 'number' ? new Date(Date.now() + expires * 1000 * 60 * 60 * 24) : expires;\n if (date instanceof Date && Number.isFinite(date.getTime())) {\n result.expires = date;\n } else {\n console.warn(`[ngx-cookie-service] Cookie ${name}: ignoring invalid expires value \"${String(expires)}\".`);\n }\n }\n if (result.sameSite !== undefined && result.sameSite !== null) {\n const sameSite = SAME_SITE_VALUES.find((value) => value.toLowerCase() === String(result.sameSite).toLowerCase());\n if (sameSite) {\n result.sameSite = sameSite;\n } else {\n console.warn(`[ngx-cookie-service] Cookie ${name}: ignoring invalid sameSite value \"${String(result.sameSite)}\".`);\n delete result.sameSite;\n }\n }\n return result;\n }\n\n /**\n * Whether a cookie attribute value contains `;` or an ASCII control character, which would end the attribute early or\n * corrupt the header.\n *\n * @param value Attribute value\n * @returns `true` if the value is unsafe to write\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n private static hasUnsafeCharacter(value: string): boolean {\n return [...value].some((character) => {\n const code = character.charCodeAt(0);\n return character === ';' || code < 0x20 || code === 0x7f;\n });\n }\n\n /**\n * Builds delete options from either an options object or the positional `path`, `domain`, `secure` and `sameSite` arguments.\n *\n * @param pathOrOptions Either a DeleteCookieOptions object or the cookie path\n * @param domain Cookie domain\n * @param secure Cookie secure flag\n * @param sameSite Cookie sameSite flag\n * @returns A new DeleteCookieOptions object\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n private static toDeleteOptions(\n pathOrOptions?: CookieOptions['path'] | DeleteCookieOptions,\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite\n ): DeleteCookieOptions {\n if (typeof pathOrOptions === 'object' && pathOrOptions !== null) {\n return { ...pathOrOptions };\n }\n return { path: pathOrOptions, domain, secure, sameSite };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ngx-cookie-service.mjs","names":[],"sources":["../../../projects/ngx-cookie-service/src/lib/cookie.config.ts","../../../projects/ngx-cookie-service/src/lib/cookie.service.ts"],"sourcesContent":["import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport type { CookieOptions } from './cookie.service';\n\n/**\n * App-wide default options for {@link CookieService}. Provide them with {@link provideCookieOptions}.\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\nexport const COOKIE_OPTIONS = new InjectionToken<CookieOptions>('ngx-cookie-service default cookie options');\n\n/**\n * Sets default options for every `set()`, `delete()` and `deleteAll()` call of {@link CookieService}.\n *\n * Options passed to a call win over these defaults, and `undefined` values don't override them. A call that passes its own\n * `expires` replaces the default one, so `delete()` always expires the cookie.\n *\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [provideCookieOptions({ path: '/', secure: true, sameSite: 'Strict' })],\n * };\n * ```\n *\n * @param options Default cookie options\n * @returns Providers to add to the application config\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\nexport function provideCookieOptions(options: CookieOptions): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: COOKIE_OPTIONS, useValue: { ...options } }]);\n}\n\n/**\n * A custom encoding for cookie values, used with {@link provideCookieEncoding}.\n *\n * `encode` runs on every value written by `set()`, and `decode` on every value read by `get()` and `getAll()`. Cookie names\n * keep the default encoding. If `decode` throws, the raw value is returned instead.\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\nexport interface CookieCodec {\n encode(value: string, name: string): string;\n decode(value: string, name: string): string;\n}\n\n/**\n * How {@link CookieService} encodes cookie values:\n *\n * - `'uri'` (default): `encodeURIComponent` and `decodeURIComponent`.\n * - `'minimal'`: values made only of characters allowed in a cookie value (RFC 6265 cookie-octets, except `%`) are written\n * as-is, and other values are encoded with `encodeURIComponent`. This is the default of the jshttp `cookie` package used\n * by Express, and keeps values such as JWTs and base64 readable by servers that don't URL-decode cookies.\n * - A {@link CookieCodec} for a custom scheme.\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\nexport type CookieEncoding = 'uri' | 'minimal' | CookieCodec;\n\n/**\n * The cookie value encoding for {@link CookieService}. Provide it with {@link provideCookieEncoding}.\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\nexport const COOKIE_ENCODING = new InjectionToken<CookieEncoding>('ngx-cookie-service cookie value encoding');\n\n/**\n * Sets how {@link CookieService} encodes cookie values when writing them and decodes them when reading.\n *\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [provideCookieEncoding('minimal')],\n * };\n * ```\n *\n * @param encoding `'uri'` (default), `'minimal'`, or a custom {@link CookieCodec}\n * @returns Providers to add to the application config\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\nexport function provideCookieEncoding(encoding: CookieEncoding): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: COOKIE_ENCODING, useValue: encoding }]);\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport { DOCUMENT, inject, Injectable, PLATFORM_ID } from '@angular/core';\nimport { COOKIE_ENCODING, COOKIE_OPTIONS, CookieCodec, CookieEncoding } from './cookie.config';\n\nexport type SameSite = 'Lax' | 'None' | 'Strict';\n\nexport interface CookieOptions {\n expires?: number | Date;\n path?: string;\n domain?: string;\n secure?: boolean;\n sameSite?: SameSite;\n partitioned?: boolean;\n}\n\n/**\n * Attributes that identify the cookie to delete. They must match the attributes the cookie was set with.\n */\nexport type DeleteCookieOptions = Omit<CookieOptions, 'expires'>;\n\n/**\n * Cookie options after validation: invalid values are removed and `expires` is always a `Date`.\n */\ntype ValidCookieOptions = Omit<CookieOptions, 'expires'> & { expires?: Date };\n\n/**\n * The `SameSite` values browsers accept, in their canonical spelling.\n */\nconst SAME_SITE_VALUES: readonly SameSite[] = ['Lax', 'Strict', 'None'];\n\n/**\n * RFC 6265 cookie-octets except `%`: values made only of these are written as-is by the `'minimal'` encoding and still\n * decode to themselves. Same pattern as the jshttp `cookie` package (2.x) used by Express.\n */\nconst COOKIE_OCTET_REGEXP = /^[!#$&'()*+\\-./0-9:<=>?@A-Z[\\]^_`a-z{|}~]*$/;\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CookieService {\n private readonly documentIsAccessible: boolean;\n private readonly document = inject<Document>(DOCUMENT);\n private readonly platformId = inject<object>(PLATFORM_ID);\n private readonly defaultOptions: CookieOptions = inject(COOKIE_OPTIONS, { optional: true }) ?? {};\n private readonly codec: CookieCodec = CookieService.toCodec(inject(COOKIE_ENCODING, { optional: true }));\n\n constructor() {\n this.documentIsAccessible = isPlatformBrowser(this.platformId);\n }\n\n /**\n * Get cookie Regular Expression\n *\n * @param name Cookie name\n * @returns property RegExp\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n private static getCookieRegExp(name: string): RegExp {\n const escapedName: string = name.replace(/([[\\]{}()|=;+?,.*^$\\\\])/gi, '\\\\$1');\n\n return new RegExp('(?:^' + escapedName + '|;\\\\s*' + escapedName + ')=(.*?)(?:;|$)');\n }\n\n /**\n * Gets the decoded version of an encoded component of a Uniform Resource Identifier (URI).\n *\n * @param encodedURIComponent A value representing an encoded URI component.\n *\n * @returns The decoded version of an encoded component of a Uniform Resource Identifier (URI).\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n private static safeDecodeURIComponent(encodedURIComponent: string): string {\n try {\n return decodeURIComponent(encodedURIComponent);\n } catch {\n // probably it is not uri encoded. return as is\n return encodedURIComponent;\n }\n }\n\n /**\n * Return `true` if {@link Document} is accessible, otherwise return `false`\n *\n * @param name Cookie name\n * @returns boolean - whether cookie with specified name exists\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n check(name: string): boolean {\n if (!this.documentIsAccessible) {\n return false;\n }\n name = encodeURIComponent(name);\n const regExp = CookieService.getCookieRegExp(name);\n return regExp.test(this.document.cookie);\n }\n\n /**\n * Get cookies by name\n *\n * @param name Cookie name\n * @returns property value\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n get(name: string): string {\n if (this.check(name)) {\n const regExp: RegExp = CookieService.getCookieRegExp(encodeURIComponent(name));\n const result = regExp.exec(this.document.cookie);\n return result?.[1] ? this.decodeValue(result[1], name) : '';\n } else {\n return '';\n }\n }\n\n /**\n * Get all cookies in JSON format\n *\n * @returns all the cookies in json\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n getAll(): Record<string, string> {\n if (!this.documentIsAccessible) {\n return {};\n }\n\n const cookies: Record<string, string> = {};\n const document: Document = this.document;\n\n if (document.cookie && document.cookie !== '') {\n document.cookie.split(';').forEach((currentCookie: string) => {\n const trimmedCookie = currentCookie.trim();\n if (!trimmedCookie) {\n return;\n }\n // Split on the first '=' only, so values containing '=' (e.g. base64 padding) are preserved\n const equalIndex = trimmedCookie.indexOf('=');\n if (equalIndex === -1) {\n // Cookie without value (invalid, but handle gracefully)\n return;\n }\n const cookieName = CookieService.safeDecodeURIComponent(trimmedCookie.substring(0, equalIndex));\n // Browsers list the most specific cookie first when several share a name. Keep that one, as get() does.\n if (Object.hasOwn(cookies, cookieName)) {\n return;\n }\n // defineProperty stores names such as \"__proto__\" as normal entries instead of touching the object's prototype\n Object.defineProperty(cookies, cookieName, {\n value: this.decodeValue(trimmedCookie.substring(equalIndex + 1), cookieName),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n });\n }\n\n return cookies;\n }\n\n /**\n * Set cookie based on provided information\n *\n * @param name Cookie name\n * @param value Cookie value\n * @param expires Number of days until the cookies expires or an actual `Date`\n * @param path Cookie path\n * @param domain Cookie domain\n * @param secure Secure flag\n * @param partitioned Partitioned flag\n * @param sameSite OWASP same site token `Lax`, `None`, or `Strict`. Defaults to `Lax`\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n set(\n name: string,\n value: string,\n expires?: CookieOptions['expires'],\n path?: CookieOptions['path'],\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite,\n partitioned?: CookieOptions['partitioned']\n ): void;\n\n /**\n * Set cookie based on provided information\n *\n * Cookie's parameters:\n * <pre>\n * expires Number of days until the cookies expires or an actual `Date`\n * path Cookie path\n * domain Cookie domain\n * secure flag\n * sameSite OWASP same site token `Lax`, `None`, or `Strict`. Defaults to `Lax`\n * </pre>\n *\n * @param name Cookie name\n * @param value Cookie value\n * @param options Body with cookie's params\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n set(name: string, value: string, options?: CookieOptions): void;\n\n set(\n name: string,\n value: string,\n expiresOrOptions?: CookieOptions['expires'] | CookieOptions,\n path?: CookieOptions['path'],\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite,\n partitioned?: CookieOptions['partitioned']\n ): void {\n if (!this.documentIsAccessible) {\n return;\n }\n\n // Anything but an options object means the positional form, so no positional argument (e.g. a lone `partitioned`) is dropped\n if (typeof expiresOrOptions !== 'object' || expiresOrOptions === null || expiresOrOptions instanceof Date) {\n const optionsBody = {\n expires: expiresOrOptions as CookieOptions['expires'],\n path,\n domain,\n secure,\n sameSite,\n partitioned,\n };\n\n this.set(name, value, optionsBody);\n return;\n }\n\n // validateOptions() returns a copy, so the defaults applied below don't leak back into the caller's object\n const options = CookieService.validateOptions(name, CookieService.withDefaults(this.defaultOptions, expiresOrOptions));\n if (!options) {\n return;\n }\n\n const encodedValue = this.encodeValue(name, value);\n if (encodedValue === undefined) {\n return;\n }\n\n let cookieString: string = encodeURIComponent(name) + '=' + encodedValue + ';';\n\n if (options.expires) {\n cookieString += 'Expires=' + options.expires.toUTCString() + ';';\n }\n\n if (options.path) {\n cookieString += 'Path=' + options.path + ';';\n }\n\n if (options.domain) {\n cookieString += 'Domain=' + options.domain + ';';\n }\n\n if (options.sameSite === 'None' && !options.secure) {\n options.secure = true;\n console.warn(\n `[ngx-cookie-service] Cookie ${name} was forced with secure flag because sameSite=None.` +\n `More details : https://github.com/stevermeister/ngx-cookie-service/issues/86#issuecomment-597720130`\n );\n }\n if (options.partitioned && !options.secure) {\n options.secure = true;\n console.warn(`[ngx-cookie-service] Cookie ${name} was forced with secure flag because Partitioned cookies must be Secure.`);\n }\n if (options.secure) {\n cookieString += 'Secure;';\n }\n\n if (!options.sameSite) {\n options.sameSite = 'Lax';\n }\n\n cookieString += 'SameSite=' + options.sameSite + ';';\n\n if (options.partitioned) {\n cookieString += 'Partitioned;';\n }\n\n this.document.cookie = cookieString;\n }\n\n /**\n * Delete cookie by name at given path and domain.\n *\n * If `path` is not specified, no `Path` attribute is written and the browser uses its default path: the directory of the URL\n * the page was loaded at (not the current router URL). To delete a cookie that was set with `path: '/'`, pass `'/'` here too.\n *\n * @param name Cookie name\n * @param path Cookie path\n * @param domain Cookie domain\n * @param secure Cookie secure flag\n * @param sameSite Cookie sameSite flag - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n delete(name: string, path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite): void;\n\n /**\n * Delete cookie by name. The options must match the attributes the cookie was set with: `path` and `domain` select the\n * cookie, and `partitioned: true` is required to delete a Partitioned cookie.\n *\n * If `path` is not specified, no `Path` attribute is written and the browser uses its default path: the directory of the URL\n * the page was loaded at (not the current router URL). To delete a cookie that was set with `path: '/'`, pass `'/'` here too.\n *\n * @param name Cookie name\n * @param options Cookie attributes: `path`, `domain`, `secure`, `sameSite` and `partitioned`\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n delete(name: string, options?: DeleteCookieOptions): void;\n\n delete(\n name: string,\n pathOrOptions?: CookieOptions['path'] | DeleteCookieOptions,\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite\n ): void {\n if (!this.documentIsAccessible) {\n return;\n }\n const options = CookieService.toDeleteOptions(pathOrOptions, domain, secure, sameSite);\n this.set(name, '', { ...options, expires: new Date('Thu, 01 Jan 1970 00:00:01 GMT') });\n }\n\n /**\n * Delete all cookies at given path and domain.\n *\n * If `path` is not specified, the browser's default path is used for each cookie, as described for {@link delete}.\n *\n * @param path Cookie path\n * @param domain Cookie domain\n * @param secure Is the Cookie secure\n * @param sameSite Is the cookie same site\n *\n * @author: Stepan Suvorov\n * @since: 1.0.0\n */\n deleteAll(path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite): void;\n\n /**\n * Delete all cookies that can currently be accessed, using the same attributes for each one.\n *\n * If `path` is not specified, the browser's default path is used for each cookie, as described for {@link delete}.\n *\n * @param options Cookie attributes: `path`, `domain`, `secure`, `sameSite` and `partitioned`\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n deleteAll(options?: DeleteCookieOptions): void;\n\n deleteAll(\n pathOrOptions?: CookieOptions['path'] | DeleteCookieOptions,\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite\n ): void {\n if (!this.documentIsAccessible) {\n return;\n }\n\n // Object.keys() rather than for...in with cookies.hasOwnProperty(): a cookie named \"hasOwnProperty\" would shadow that method\n for (const cookieName of Object.keys(this.getAll())) {\n // Call delete() the same way deleteAll() was called, so overrides and spies of the positional form keep working\n if (typeof pathOrOptions === 'object' && pathOrOptions !== null) {\n this.delete(cookieName, pathOrOptions);\n } else {\n this.delete(cookieName, pathOrOptions, domain, secure, sameSite);\n }\n }\n }\n\n /**\n * Built-in `'uri'` encoding: `encodeURIComponent`, decoded with {@link CookieService.safeDecodeURIComponent}.\n */\n private static readonly uriCodec: CookieCodec = {\n encode: (value) => encodeURIComponent(value),\n decode: (value) => CookieService.safeDecodeURIComponent(value),\n };\n\n /**\n * Built-in `'minimal'` encoding: values made only of cookie-octets are written as-is, others use `encodeURIComponent`.\n */\n private static readonly minimalCodec: CookieCodec = {\n encode: (value) => (COOKIE_OCTET_REGEXP.test(value) ? value : encodeURIComponent(value)),\n decode: (value) => CookieService.safeDecodeURIComponent(value),\n };\n\n /**\n * Resolves the encoding provided with {@link provideCookieEncoding} to a codec, defaulting to `'uri'`.\n *\n * @param encoding Provided encoding, or `null` when none was provided\n * @returns The codec to use\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\n private static toCodec(encoding: CookieEncoding | null): CookieCodec {\n if (encoding === 'minimal') {\n return CookieService.minimalCodec;\n }\n if (typeof encoding === 'object' && encoding !== null) {\n return encoding;\n }\n return CookieService.uriCodec;\n }\n\n /**\n * Encodes a cookie value with the configured encoding. Returns `undefined`, with a warning, when the result can't be\n * written safely because it isn't a string or contains `;` or a control character.\n *\n * @param name Cookie name\n * @param value Cookie value\n * @returns The encoded value, or `undefined` to skip the write\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\n private encodeValue(name: string, value: string): string | undefined {\n const encodedValue = this.codec.encode(value, name);\n if (typeof encodedValue !== 'string' || CookieService.hasUnsafeCharacter(encodedValue)) {\n console.warn(`[ngx-cookie-service] Cookie ${name} was skipped because its encoded value isn't a string without \";\" or control characters.`);\n return undefined;\n }\n return encodedValue;\n }\n\n /**\n * Decodes a cookie value with the configured encoding. If a custom `decode` throws, the raw value is returned.\n *\n * @param value Raw cookie value\n * @param name Decoded cookie name\n * @returns The decoded value\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\n private decodeValue(value: string, name: string): string {\n try {\n return this.codec.decode(value, name);\n } catch {\n return value;\n }\n }\n\n /**\n * Merges the app-wide defaults from {@link provideCookieOptions} under the options of one call.\n *\n * Values passed to the call win, and `undefined` or `null` values don't override a default.\n *\n * @param defaults Default cookie options\n * @param options Options passed to the call\n * @returns A new, merged CookieOptions object\n *\n * @author: Pavankumar Jadda\n * @since: 22.2.0\n */\n private static withDefaults(defaults: CookieOptions, options: CookieOptions = {}): CookieOptions {\n const merged: Record<string, unknown> = { ...defaults };\n for (const [key, value] of Object.entries(options)) {\n if (value !== undefined && value !== null) {\n merged[key] = value;\n }\n }\n return merged as CookieOptions;\n }\n\n /**\n * Returns a validated copy of the options, or `undefined` if the cookie must not be written.\n *\n * A `path` or `domain` containing `;` or a control character could inject attributes or change the cookie's scope, so the\n * whole write is skipped. An invalid `expires` is dropped, which makes a session cookie as browsers already did, and an\n * unknown `sameSite` falls back to the `Lax` default. Each case logs a warning. A numeric `expires` (days\n * from now) is converted to a `Date`, and `sameSite` is matched case-insensitively.\n *\n * @param name Cookie name, used in warnings\n * @param options Cookie options\n * @returns A validated copy of the options, or `undefined` to skip the write\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n private static validateOptions(name: string, options: CookieOptions = {}): ValidCookieOptions | undefined {\n const { expires, ...valid }: CookieOptions = options;\n const result: ValidCookieOptions = valid;\n\n for (const attribute of ['path', 'domain'] as const) {\n const attributeValue = result[attribute];\n if (typeof attributeValue === 'string' && CookieService.hasUnsafeCharacter(attributeValue)) {\n console.warn(`[ngx-cookie-service] Cookie ${name} was skipped because its ${attribute} contains \";\" or a control character.`);\n return undefined;\n }\n }\n if (expires) {\n const date = typeof expires === 'number' ? new Date(Date.now() + expires * 1000 * 60 * 60 * 24) : expires;\n if (date instanceof Date && Number.isFinite(date.getTime())) {\n result.expires = date;\n } else {\n console.warn(`[ngx-cookie-service] Cookie ${name}: ignoring invalid expires value \"${String(expires)}\".`);\n }\n }\n if (result.sameSite !== undefined && result.sameSite !== null) {\n const sameSite = SAME_SITE_VALUES.find((value) => value.toLowerCase() === String(result.sameSite).toLowerCase());\n if (sameSite) {\n result.sameSite = sameSite;\n } else {\n console.warn(`[ngx-cookie-service] Cookie ${name}: ignoring invalid sameSite value \"${String(result.sameSite)}\".`);\n delete result.sameSite;\n }\n }\n return result;\n }\n\n /**\n * Whether a cookie attribute value contains `;` or an ASCII control character, which would end the attribute early or\n * corrupt the header.\n *\n * @param value Attribute value\n * @returns `true` if the value is unsafe to write\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n private static hasUnsafeCharacter(value: string): boolean {\n return [...value].some((character) => {\n const code = character.charCodeAt(0);\n return character === ';' || code < 0x20 || code === 0x7f;\n });\n }\n\n /**\n * Builds delete options from either an options object or the positional `path`, `domain`, `secure` and `sameSite` arguments.\n *\n * @param pathOrOptions Either a DeleteCookieOptions object or the cookie path\n * @param domain Cookie domain\n * @param secure Cookie secure flag\n * @param sameSite Cookie sameSite flag\n * @returns A new DeleteCookieOptions object\n *\n * @author: Pavankumar Jadda\n * @since: 22.1.0\n */\n private static toDeleteOptions(\n pathOrOptions?: CookieOptions['path'] | DeleteCookieOptions,\n domain?: CookieOptions['domain'],\n secure?: CookieOptions['secure'],\n sameSite?: SameSite\n ): DeleteCookieOptions {\n if (typeof pathOrOptions === 'object' && pathOrOptions !== null) {\n return { ...pathOrOptions };\n }\n return { path: pathOrOptions, domain, secure, sameSite };\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ngx-cookie-service",
3
3
  "description": "Angular cookie service",
4
- "version": "22.1.0",
4
+ "version": "22.2.0",
5
5
  "license": "MIT",
6
6
  "author": "Stepan Suvorov <stevermeister@gmail.com>",
7
7
  "keywords": [
@@ -1,4 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
+ import { EnvironmentProviders, InjectionToken } from "@angular/core";
2
3
  export type SameSite = 'Lax' | 'None' | 'Strict';
3
4
  export interface CookieOptions {
4
5
  expires?: number | Date;
@@ -16,6 +17,8 @@ export declare class CookieService {
16
17
  private readonly documentIsAccessible;
17
18
  private readonly document;
18
19
  private readonly platformId;
20
+ private readonly defaultOptions;
21
+ private readonly codec;
19
22
  constructor();
20
23
  /**
21
24
  * Get cookie Regular Expression
@@ -158,6 +161,60 @@ export declare class CookieService {
158
161
  * @since: 22.1.0
159
162
  */
160
163
  deleteAll(options?: DeleteCookieOptions): void;
164
+ /**
165
+ * Built-in `'uri'` encoding: `encodeURIComponent`, decoded with {@link CookieService.safeDecodeURIComponent}.
166
+ */
167
+ private static readonly uriCodec;
168
+ /**
169
+ * Built-in `'minimal'` encoding: values made only of cookie-octets are written as-is, others use `encodeURIComponent`.
170
+ */
171
+ private static readonly minimalCodec;
172
+ /**
173
+ * Resolves the encoding provided with {@link provideCookieEncoding} to a codec, defaulting to `'uri'`.
174
+ *
175
+ * @param encoding Provided encoding, or `null` when none was provided
176
+ * @returns The codec to use
177
+ *
178
+ * @author: Pavankumar Jadda
179
+ * @since: 22.2.0
180
+ */
181
+ private static toCodec;
182
+ /**
183
+ * Encodes a cookie value with the configured encoding. Returns `undefined`, with a warning, when the result can't be
184
+ * written safely because it isn't a string or contains `;` or a control character.
185
+ *
186
+ * @param name Cookie name
187
+ * @param value Cookie value
188
+ * @returns The encoded value, or `undefined` to skip the write
189
+ *
190
+ * @author: Pavankumar Jadda
191
+ * @since: 22.2.0
192
+ */
193
+ private encodeValue;
194
+ /**
195
+ * Decodes a cookie value with the configured encoding. If a custom `decode` throws, the raw value is returned.
196
+ *
197
+ * @param value Raw cookie value
198
+ * @param name Decoded cookie name
199
+ * @returns The decoded value
200
+ *
201
+ * @author: Pavankumar Jadda
202
+ * @since: 22.2.0
203
+ */
204
+ private decodeValue;
205
+ /**
206
+ * Merges the app-wide defaults from {@link provideCookieOptions} under the options of one call.
207
+ *
208
+ * Values passed to the call win, and `undefined` or `null` values don't override a default.
209
+ *
210
+ * @param defaults Default cookie options
211
+ * @param options Options passed to the call
212
+ * @returns A new, merged CookieOptions object
213
+ *
214
+ * @author: Pavankumar Jadda
215
+ * @since: 22.2.0
216
+ */
217
+ private static withDefaults;
161
218
  /**
162
219
  * Returns a validated copy of the options, or `undefined` if the cookie must not be written.
163
220
  *
@@ -200,4 +257,79 @@ export declare class CookieService {
200
257
  private static toDeleteOptions;
201
258
  static ɵfac: i0.ɵɵFactoryDeclaration<CookieService, never>;
202
259
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
203
- }
260
+ }
261
+ /**
262
+ * App-wide default options for {@link CookieService}. Provide them with {@link provideCookieOptions}.
263
+ *
264
+ * @author: Pavankumar Jadda
265
+ * @since: 22.2.0
266
+ */
267
+ export declare const COOKIE_OPTIONS: InjectionToken<CookieOptions>;
268
+ /**
269
+ * Sets default options for every `set()`, `delete()` and `deleteAll()` call of {@link CookieService}.
270
+ *
271
+ * Options passed to a call win over these defaults, and `undefined` values don't override them. A call that passes its own
272
+ * `expires` replaces the default one, so `delete()` always expires the cookie.
273
+ *
274
+ * ```ts
275
+ * export const appConfig: ApplicationConfig = {
276
+ * providers: [provideCookieOptions({ path: '/', secure: true, sameSite: 'Strict' })],
277
+ * };
278
+ * ```
279
+ *
280
+ * @param options Default cookie options
281
+ * @returns Providers to add to the application config
282
+ *
283
+ * @author: Pavankumar Jadda
284
+ * @since: 22.2.0
285
+ */
286
+ export declare function provideCookieOptions(options: CookieOptions): EnvironmentProviders;
287
+ /**
288
+ * A custom encoding for cookie values, used with {@link provideCookieEncoding}.
289
+ *
290
+ * `encode` runs on every value written by `set()`, and `decode` on every value read by `get()` and `getAll()`. Cookie names
291
+ * keep the default encoding. If `decode` throws, the raw value is returned instead.
292
+ *
293
+ * @author: Pavankumar Jadda
294
+ * @since: 22.2.0
295
+ */
296
+ export interface CookieCodec {
297
+ encode(value: string, name: string): string;
298
+ decode(value: string, name: string): string;
299
+ }
300
+ /**
301
+ * How {@link CookieService} encodes cookie values:
302
+ *
303
+ * - `'uri'` (default): `encodeURIComponent` and `decodeURIComponent`.
304
+ * - `'minimal'`: values made only of characters allowed in a cookie value (RFC 6265 cookie-octets, except `%`) are written
305
+ * as-is, and other values are encoded with `encodeURIComponent`. This is the default of the jshttp `cookie` package used
306
+ * by Express, and keeps values such as JWTs and base64 readable by servers that don't URL-decode cookies.
307
+ * - A {@link CookieCodec} for a custom scheme.
308
+ *
309
+ * @author: Pavankumar Jadda
310
+ * @since: 22.2.0
311
+ */
312
+ export type CookieEncoding = 'uri' | 'minimal' | CookieCodec;
313
+ /**
314
+ * The cookie value encoding for {@link CookieService}. Provide it with {@link provideCookieEncoding}.
315
+ *
316
+ * @author: Pavankumar Jadda
317
+ * @since: 22.2.0
318
+ */
319
+ export declare const COOKIE_ENCODING: InjectionToken<CookieEncoding>;
320
+ /**
321
+ * Sets how {@link CookieService} encodes cookie values when writing them and decodes them when reading.
322
+ *
323
+ * ```ts
324
+ * export const appConfig: ApplicationConfig = {
325
+ * providers: [provideCookieEncoding('minimal')],
326
+ * };
327
+ * ```
328
+ *
329
+ * @param encoding `'uri'` (default), `'minimal'`, or a custom {@link CookieCodec}
330
+ * @returns Providers to add to the application config
331
+ *
332
+ * @author: Pavankumar Jadda
333
+ * @since: 22.2.0
334
+ */
335
+ export declare function provideCookieEncoding(encoding: CookieEncoding): EnvironmentProviders;