ngx-cookie-service 22.0.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 +61 -6
- package/fesm2022/ngx-cookie-service.mjs +231 -210
- package/fesm2022/ngx-cookie-service.mjs.map +1 -1
- package/package.json +2 -2
- package/types/ngx-cookie-service.d.ts +333 -131
package/README.md
CHANGED
|
@@ -148,6 +148,9 @@ server.get('*', (req, res) => {
|
|
|
148
148
|
use `REQUEST.cookies` to access the
|
|
149
149
|
cookies in SSR. Then proceed to use `ngx-cookie-service` as usual.
|
|
150
150
|
4. See the [sample repo](https://github.com/pavankjadda/angular-ssr-docker) for more details.
|
|
151
|
+
5. On the server, `get()`, `check()` and `getAll()` also see cookies set or deleted earlier while rendering the same
|
|
152
|
+
request, whatever their `path` or `domain`. Cookies with `httpOnly: true` can only be set on the server; in the
|
|
153
|
+
browser the call is skipped with a console warning.
|
|
151
154
|
|
|
152
155
|
## Demo
|
|
153
156
|
|
|
@@ -212,17 +215,27 @@ to `Lax`.
|
|
|
212
215
|
Read [this](https://stackoverflow.com/a/1063760) and [this](https://stackoverflow.com/a/17777005/1007003) StackOverflow
|
|
213
216
|
answer for a more in-depth explanation.
|
|
214
217
|
|
|
215
|
-
**Important:** Browsers do not accept cookies flagged sameSite = 'None'
|
|
216
|
-
will override the secure flag to true if sameSite='None'.
|
|
218
|
+
**Important:** Browsers do not accept cookies flagged sameSite = 'None' or partitioned unless the secure flag is set as
|
|
219
|
+
well. CookieService will override the secure flag to true if sameSite='None' or partitioned is true.
|
|
220
|
+
|
|
221
|
+
If `path` or `domain` contains `;` or a control character, the cookie is not written or deleted, and a warning is
|
|
222
|
+
logged to the console. An invalid `expires` or `sameSite` value is ignored with a warning.
|
|
217
223
|
|
|
218
224
|
## delete( name: string, path?: string, domain?: string, secure?: boolean, sameSite: 'Lax' | 'None' | 'Strict' = 'Lax'): void;
|
|
219
225
|
|
|
226
|
+
## delete( name: string, options?: { path?: string, domain?: string, secure?: boolean, sameSite?: 'Lax' | 'None' | 'Strict', partitioned?: boolean }): void;
|
|
227
|
+
|
|
220
228
|
```typescript
|
|
221
229
|
cookieService.delete('test');
|
|
230
|
+
cookieService.delete('test', { path: '/', secure: true, sameSite: 'None', partitioned: true });
|
|
222
231
|
```
|
|
223
232
|
|
|
224
|
-
Deletes a cookie with the specified `name`.
|
|
225
|
-
|
|
233
|
+
Deletes a cookie with the specified `name`. The attributes must match the ones the cookie was set with: `path` and
|
|
234
|
+
`domain` select the cookie, and `partitioned: true` is needed to delete a Partitioned cookie.
|
|
235
|
+
|
|
236
|
+
It is best practice to always define a path. If you are unsure about the path value, use `'/'`. Without a path, the
|
|
237
|
+
browser uses the directory of the URL the page was loaded at, so in a single-page app the result depends on the URL the
|
|
238
|
+
user first landed on.
|
|
226
239
|
|
|
227
240
|
**Important:** For security reasons, it is not possible to delete cookies for other domains. Browsers do not allow this.
|
|
228
241
|
Read [this](https://stackoverflow.com/a/1063760) and [this](https://stackoverflow.com/a/17777005/1007003) StackOverflow
|
|
@@ -230,12 +243,54 @@ answer for a more in-depth explanation.
|
|
|
230
243
|
|
|
231
244
|
## deleteAll( path?: string, domain?: string, secure?: boolean, sameSite: 'Lax' | 'None' | 'Strict' = 'Lax' ): void;
|
|
232
245
|
|
|
246
|
+
## deleteAll( options?: { path?: string, domain?: string, secure?: boolean, sameSite?: 'Lax' | 'None' | 'Strict', partitioned?: boolean }): void;
|
|
247
|
+
|
|
233
248
|
```typescript
|
|
234
249
|
cookieService.deleteAll();
|
|
250
|
+
cookieService.deleteAll({ path: '/' });
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Deletes all cookies that can currently be accessed, using the same attributes for each one. It is best practice to
|
|
254
|
+
always define a path. If you are unsure about the path value, use `'/'`.
|
|
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
|
+
};
|
|
235
265
|
```
|
|
236
266
|
|
|
237
|
-
|
|
238
|
-
the
|
|
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.
|
|
239
294
|
|
|
240
295
|
# FAQ
|
|
241
296
|
|
|
@@ -1,212 +1,233 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Get cookie Regular Expression
|
|
13
|
-
*
|
|
14
|
-
* @param name Cookie name
|
|
15
|
-
* @returns property RegExp
|
|
16
|
-
*
|
|
17
|
-
* @author: Stepan Suvorov
|
|
18
|
-
* @since: 1.0.0
|
|
19
|
-
*/
|
|
20
|
-
static getCookieRegExp(name) {
|
|
21
|
-
const escapedName = name.replace(/([[\]{}()|=;+?,.*^$\\])/gi, '\\$1');
|
|
22
|
-
return new RegExp('(?:^' + escapedName + '|;\\s*' + escapedName + ')=(.*?)(?:;|$)');
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Gets the decoded version of an encoded component of a Uniform Resource Identifier (URI).
|
|
26
|
-
*
|
|
27
|
-
* @param encodedURIComponent A value representing an encoded URI component.
|
|
28
|
-
*
|
|
29
|
-
* @returns The decoded version of an encoded component of a Uniform Resource Identifier (URI).
|
|
30
|
-
*
|
|
31
|
-
* @author: Stepan Suvorov
|
|
32
|
-
* @since: 1.0.0
|
|
33
|
-
*/
|
|
34
|
-
static safeDecodeURIComponent(encodedURIComponent) {
|
|
35
|
-
try {
|
|
36
|
-
return decodeURIComponent(encodedURIComponent);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// probably it is not uri encoded. return as is
|
|
40
|
-
return encodedURIComponent;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Return `true` if {@link Document} is accessible, otherwise return `false`
|
|
45
|
-
*
|
|
46
|
-
* @param name Cookie name
|
|
47
|
-
* @returns boolean - whether cookie with specified name exists
|
|
48
|
-
*
|
|
49
|
-
* @author: Stepan Suvorov
|
|
50
|
-
* @since: 1.0.0
|
|
51
|
-
*/
|
|
52
|
-
check(name) {
|
|
53
|
-
if (!this.documentIsAccessible) {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
name = encodeURIComponent(name);
|
|
57
|
-
const regExp = CookieService.getCookieRegExp(name);
|
|
58
|
-
return regExp.test(this.document.cookie);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Get cookies by name
|
|
62
|
-
*
|
|
63
|
-
* @param name Cookie name
|
|
64
|
-
* @returns property value
|
|
65
|
-
*
|
|
66
|
-
* @author: Stepan Suvorov
|
|
67
|
-
* @since: 1.0.0
|
|
68
|
-
*/
|
|
69
|
-
get(name) {
|
|
70
|
-
if (this.check(name)) {
|
|
71
|
-
name = encodeURIComponent(name);
|
|
72
|
-
const regExp = CookieService.getCookieRegExp(name);
|
|
73
|
-
const result = regExp.exec(this.document.cookie);
|
|
74
|
-
return result?.[1] ? CookieService.safeDecodeURIComponent(result[1]) : '';
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
return '';
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Get all cookies in JSON format
|
|
82
|
-
*
|
|
83
|
-
* @returns all the cookies in json
|
|
84
|
-
*
|
|
85
|
-
* @author: Stepan Suvorov
|
|
86
|
-
* @since: 1.0.0
|
|
87
|
-
*/
|
|
88
|
-
getAll() {
|
|
89
|
-
if (!this.documentIsAccessible) {
|
|
90
|
-
return {};
|
|
91
|
-
}
|
|
92
|
-
const cookies = {};
|
|
93
|
-
const document = this.document;
|
|
94
|
-
if (document.cookie && document.cookie !== '') {
|
|
95
|
-
document.cookie.split(';').forEach((currentCookie) => {
|
|
96
|
-
const [cookieName, cookieValue] = currentCookie.split('=');
|
|
97
|
-
cookies[CookieService.safeDecodeURIComponent(cookieName.replace(/^ /, ''))] = CookieService.safeDecodeURIComponent(cookieValue);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
return cookies;
|
|
101
|
-
}
|
|
102
|
-
set(name, value, expiresOrOptions, path, domain, secure, sameSite, partitioned) {
|
|
103
|
-
if (!this.documentIsAccessible) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (typeof expiresOrOptions === 'number' || expiresOrOptions instanceof Date || path || domain || secure || sameSite) {
|
|
107
|
-
const optionsBody = {
|
|
108
|
-
expires: expiresOrOptions,
|
|
109
|
-
path,
|
|
110
|
-
domain,
|
|
111
|
-
secure,
|
|
112
|
-
sameSite: sameSite || 'Lax',
|
|
113
|
-
partitioned,
|
|
114
|
-
};
|
|
115
|
-
this.set(name, value, optionsBody);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
let cookieString = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';';
|
|
119
|
-
const options = expiresOrOptions ? expiresOrOptions : {};
|
|
120
|
-
if (options.expires) {
|
|
121
|
-
if (typeof options.expires === 'number') {
|
|
122
|
-
const dateExpires = new Date(new Date().getTime() + options.expires * 1000 * 60 * 60 * 24);
|
|
123
|
-
cookieString += 'Expires=' + dateExpires.toUTCString() + ';';
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
cookieString += 'Expires=' + options.expires.toUTCString() + ';';
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (options.path) {
|
|
130
|
-
cookieString += 'Path=' + options.path + ';';
|
|
131
|
-
}
|
|
132
|
-
if (options.domain) {
|
|
133
|
-
cookieString += 'Domain=' + options.domain + ';';
|
|
134
|
-
}
|
|
135
|
-
if (options.secure === false && options.sameSite === 'None') {
|
|
136
|
-
options.secure = true;
|
|
137
|
-
console.warn(`[ngx-cookie-service] Cookie ${name} was forced with secure flag because sameSite=None.` +
|
|
138
|
-
`More details : https://github.com/stevermeister/ngx-cookie-service/issues/86#issuecomment-597720130`);
|
|
139
|
-
}
|
|
140
|
-
if (options.secure) {
|
|
141
|
-
cookieString += 'Secure;';
|
|
142
|
-
}
|
|
143
|
-
if (!options.sameSite) {
|
|
144
|
-
options.sameSite = 'Lax';
|
|
145
|
-
}
|
|
146
|
-
cookieString += 'SameSite=' + options.sameSite + ';';
|
|
147
|
-
if (options.partitioned) {
|
|
148
|
-
cookieString += 'Partitioned;';
|
|
149
|
-
}
|
|
150
|
-
this.document.cookie = cookieString;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Delete cookie by name at given path and domain. If not path is not specified, cookie at '/' path will be deleted.
|
|
154
|
-
*
|
|
155
|
-
* @param name Cookie name
|
|
156
|
-
* @param path Cookie path
|
|
157
|
-
* @param domain Cookie domain
|
|
158
|
-
* @param secure Cookie secure flag
|
|
159
|
-
* @param sameSite Cookie sameSite flag - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
|
160
|
-
*
|
|
161
|
-
* @author: Stepan Suvorov
|
|
162
|
-
* @since: 1.0.0
|
|
163
|
-
*/
|
|
164
|
-
delete(name, path, domain, secure, sameSite = 'Lax') {
|
|
165
|
-
if (!this.documentIsAccessible) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const expiresDate = new Date('Thu, 01 Jan 1970 00:00:01 GMT');
|
|
169
|
-
this.set(name, '', { expires: expiresDate, path, domain, secure, sameSite });
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Delete all cookies at given path and domain. If not path is not specified, all cookies at '/' path will be deleted.
|
|
173
|
-
*
|
|
174
|
-
* @param path Cookie path
|
|
175
|
-
* @param domain Cookie domain
|
|
176
|
-
* @param secure Is the Cookie secure
|
|
177
|
-
* @param sameSite Is the cookie same site
|
|
178
|
-
*
|
|
179
|
-
* @author: Stepan Suvorov
|
|
180
|
-
* @since: 1.0.0
|
|
181
|
-
*/
|
|
182
|
-
deleteAll(path, domain, secure, sameSite = 'Lax') {
|
|
183
|
-
if (!this.documentIsAccessible) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
const cookies = this.getAll();
|
|
187
|
-
for (const cookieName in cookies) {
|
|
188
|
-
if (cookies.hasOwnProperty(cookieName)) {
|
|
189
|
-
this.delete(cookieName, path, domain, secure, sameSite);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: CookieService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
194
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: CookieService, providedIn: 'root' }); }
|
|
1
|
+
import * as i0 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
|
+
}]);
|
|
195
10
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
+
}
|
|
18
|
+
const SAME_SITE_VALUES = [
|
|
19
|
+
"Lax",
|
|
20
|
+
"Strict",
|
|
21
|
+
"None"
|
|
22
|
+
];
|
|
23
|
+
const COOKIE_OCTET_REGEXP = /^[!#$&'()*+\-./0-9:<=>?@A-Z[\]^_`a-z{|}~]*$/;
|
|
24
|
+
var CookieService = class CookieService {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.document = inject(DOCUMENT);
|
|
27
|
+
this.platformId = inject(PLATFORM_ID);
|
|
28
|
+
this.defaultOptions = inject(COOKIE_OPTIONS, { optional: true }) ?? {};
|
|
29
|
+
this.codec = CookieService.toCodec(inject(COOKIE_ENCODING, { optional: true }));
|
|
30
|
+
this.documentIsAccessible = isPlatformBrowser(this.platformId);
|
|
31
|
+
}
|
|
32
|
+
static getCookieRegExp(name) {
|
|
33
|
+
const escapedName = name.replace(/([[\]{}()|=;+?,.*^$\\])/gi, "\\$1");
|
|
34
|
+
return new RegExp("(?:^" + escapedName + "|;\\s*" + escapedName + ")=(.*?)(?:;|$)");
|
|
35
|
+
}
|
|
36
|
+
static safeDecodeURIComponent(encodedURIComponent) {
|
|
37
|
+
try {
|
|
38
|
+
return decodeURIComponent(encodedURIComponent);
|
|
39
|
+
} catch {
|
|
40
|
+
return encodedURIComponent;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
check(name) {
|
|
44
|
+
if (!this.documentIsAccessible) return false;
|
|
45
|
+
name = encodeURIComponent(name);
|
|
46
|
+
return CookieService.getCookieRegExp(name).test(this.document.cookie);
|
|
47
|
+
}
|
|
48
|
+
get(name) {
|
|
49
|
+
if (this.check(name)) {
|
|
50
|
+
const result = CookieService.getCookieRegExp(encodeURIComponent(name)).exec(this.document.cookie);
|
|
51
|
+
return result?.[1] ? this.decodeValue(result[1], name) : "";
|
|
52
|
+
} else return "";
|
|
53
|
+
}
|
|
54
|
+
getAll() {
|
|
55
|
+
if (!this.documentIsAccessible) return {};
|
|
56
|
+
const cookies = {};
|
|
57
|
+
const document = this.document;
|
|
58
|
+
if (document.cookie && document.cookie !== "") document.cookie.split(";").forEach((currentCookie) => {
|
|
59
|
+
const trimmedCookie = currentCookie.trim();
|
|
60
|
+
if (!trimmedCookie) return;
|
|
61
|
+
const equalIndex = trimmedCookie.indexOf("=");
|
|
62
|
+
if (equalIndex === -1) return;
|
|
63
|
+
const cookieName = CookieService.safeDecodeURIComponent(trimmedCookie.substring(0, equalIndex));
|
|
64
|
+
if (Object.hasOwn(cookies, cookieName)) return;
|
|
65
|
+
Object.defineProperty(cookies, cookieName, {
|
|
66
|
+
value: this.decodeValue(trimmedCookie.substring(equalIndex + 1), cookieName),
|
|
67
|
+
enumerable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
configurable: true
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
return cookies;
|
|
73
|
+
}
|
|
74
|
+
set(name, value, expiresOrOptions, path, domain, secure, sameSite, partitioned) {
|
|
75
|
+
if (!this.documentIsAccessible) return;
|
|
76
|
+
if (typeof expiresOrOptions !== "object" || expiresOrOptions === null || expiresOrOptions instanceof Date) {
|
|
77
|
+
const optionsBody = {
|
|
78
|
+
expires: expiresOrOptions,
|
|
79
|
+
path,
|
|
80
|
+
domain,
|
|
81
|
+
secure,
|
|
82
|
+
sameSite,
|
|
83
|
+
partitioned
|
|
84
|
+
};
|
|
85
|
+
this.set(name, value, optionsBody);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const options = CookieService.validateOptions(name, CookieService.withDefaults(this.defaultOptions, expiresOrOptions));
|
|
89
|
+
if (!options) return;
|
|
90
|
+
const encodedValue = this.encodeValue(name, value);
|
|
91
|
+
if (encodedValue === void 0) return;
|
|
92
|
+
let cookieString = encodeURIComponent(name) + "=" + encodedValue + ";";
|
|
93
|
+
if (options.expires) cookieString += "Expires=" + options.expires.toUTCString() + ";";
|
|
94
|
+
if (options.path) cookieString += "Path=" + options.path + ";";
|
|
95
|
+
if (options.domain) cookieString += "Domain=" + options.domain + ";";
|
|
96
|
+
if (options.sameSite === "None" && !options.secure) {
|
|
97
|
+
options.secure = true;
|
|
98
|
+
console.warn(`[ngx-cookie-service] Cookie ${name} was forced with secure flag because sameSite=None.More details : https://github.com/stevermeister/ngx-cookie-service/issues/86#issuecomment-597720130`);
|
|
99
|
+
}
|
|
100
|
+
if (options.partitioned && !options.secure) {
|
|
101
|
+
options.secure = true;
|
|
102
|
+
console.warn(`[ngx-cookie-service] Cookie ${name} was forced with secure flag because Partitioned cookies must be Secure.`);
|
|
103
|
+
}
|
|
104
|
+
if (options.secure) cookieString += "Secure;";
|
|
105
|
+
if (!options.sameSite) options.sameSite = "Lax";
|
|
106
|
+
cookieString += "SameSite=" + options.sameSite + ";";
|
|
107
|
+
if (options.partitioned) cookieString += "Partitioned;";
|
|
108
|
+
this.document.cookie = cookieString;
|
|
109
|
+
}
|
|
110
|
+
delete(name, pathOrOptions, domain, secure, sameSite) {
|
|
111
|
+
if (!this.documentIsAccessible) return;
|
|
112
|
+
const options = CookieService.toDeleteOptions(pathOrOptions, domain, secure, sameSite);
|
|
113
|
+
this.set(name, "", {
|
|
114
|
+
...options,
|
|
115
|
+
expires: /* @__PURE__ */ new Date("Thu, 01 Jan 1970 00:00:01 GMT")
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
deleteAll(pathOrOptions, domain, secure, sameSite) {
|
|
119
|
+
if (!this.documentIsAccessible) return;
|
|
120
|
+
for (const cookieName of Object.keys(this.getAll())) if (typeof pathOrOptions === "object" && pathOrOptions !== null) this.delete(cookieName, pathOrOptions);
|
|
121
|
+
else this.delete(cookieName, pathOrOptions, domain, secure, sameSite);
|
|
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
|
+
}
|
|
160
|
+
static validateOptions(name, options = {}) {
|
|
161
|
+
const { expires, ...valid } = options;
|
|
162
|
+
const result = valid;
|
|
163
|
+
for (const attribute of ["path", "domain"]) {
|
|
164
|
+
const attributeValue = result[attribute];
|
|
165
|
+
if (typeof attributeValue === "string" && CookieService.hasUnsafeCharacter(attributeValue)) {
|
|
166
|
+
console.warn(`[ngx-cookie-service] Cookie ${name} was skipped because its ${attribute} contains ";" or a control character.`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (expires) {
|
|
171
|
+
const date = typeof expires === "number" ? new Date(Date.now() + expires * 1e3 * 60 * 60 * 24) : expires;
|
|
172
|
+
if (date instanceof Date && Number.isFinite(date.getTime())) result.expires = date;
|
|
173
|
+
else console.warn(`[ngx-cookie-service] Cookie ${name}: ignoring invalid expires value "${String(expires)}".`);
|
|
174
|
+
}
|
|
175
|
+
if (result.sameSite !== void 0 && result.sameSite !== null) {
|
|
176
|
+
const sameSite = SAME_SITE_VALUES.find((value) => value.toLowerCase() === String(result.sameSite).toLowerCase());
|
|
177
|
+
if (sameSite) result.sameSite = sameSite;
|
|
178
|
+
else {
|
|
179
|
+
console.warn(`[ngx-cookie-service] Cookie ${name}: ignoring invalid sameSite value "${String(result.sameSite)}".`);
|
|
180
|
+
delete result.sameSite;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
static hasUnsafeCharacter(value) {
|
|
186
|
+
return [...value].some((character) => {
|
|
187
|
+
const code = character.charCodeAt(0);
|
|
188
|
+
return character === ";" || code < 32 || code === 127;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
static toDeleteOptions(pathOrOptions, domain, secure, sameSite) {
|
|
192
|
+
if (typeof pathOrOptions === "object" && pathOrOptions !== null) return { ...pathOrOptions };
|
|
193
|
+
return {
|
|
194
|
+
path: pathOrOptions,
|
|
195
|
+
domain,
|
|
196
|
+
secure,
|
|
197
|
+
sameSite
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
static {
|
|
201
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
202
|
+
minVersion: "12.0.0",
|
|
203
|
+
version: "22.2.2",
|
|
204
|
+
ngImport: i0,
|
|
205
|
+
type: CookieService,
|
|
206
|
+
deps: [],
|
|
207
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
static {
|
|
211
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
212
|
+
minVersion: "12.0.0",
|
|
213
|
+
version: "22.2.2",
|
|
214
|
+
ngImport: i0,
|
|
215
|
+
type: CookieService,
|
|
216
|
+
providedIn: "root"
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
221
|
+
minVersion: "12.0.0",
|
|
222
|
+
version: "22.2.2",
|
|
223
|
+
ngImport: i0,
|
|
224
|
+
type: CookieService,
|
|
225
|
+
decorators: [{
|
|
226
|
+
type: Injectable,
|
|
227
|
+
args: [{ providedIn: "root" }]
|
|
228
|
+
}],
|
|
229
|
+
ctorParameters: () => []
|
|
230
|
+
});
|
|
231
|
+
export { COOKIE_ENCODING, COOKIE_OPTIONS, CookieService, provideCookieEncoding, provideCookieOptions };
|
|
210
232
|
|
|
211
|
-
|
|
212
|
-
//# sourceMappingURL=ngx-cookie-service.mjs.map
|
|
233
|
+
//# sourceMappingURL=ngx-cookie-service.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-cookie-service.mjs","sources":["../../../projects/ngx-cookie-service/src/lib/cookie.service.ts","../../../projects/ngx-cookie-service/src/public-api.ts","../../../projects/ngx-cookie-service/src/ngx-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@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 [cookieName, cookieValue] = currentCookie.split('=');\n cookies[CookieService.safeDecodeURIComponent(cookieName.replace(/^ /, ''))] = CookieService.safeDecodeURIComponent(cookieValue);\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 if (typeof expiresOrOptions === 'number' || expiresOrOptions instanceof Date || path || domain || secure || sameSite) {\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 let cookieString: string = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';';\n\n const options = expiresOrOptions ? expiresOrOptions : {};\n\n if (options.expires) {\n if (typeof options.expires === 'number') {\n const dateExpires: Date = new Date(new Date().getTime() + options.expires * 1000 * 60 * 60 * 24);\n\n cookieString += 'Expires=' + dateExpires.toUTCString() + ';';\n } else {\n cookieString += 'Expires=' + options.expires.toUTCString() + ';';\n }\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.secure === false && options.sameSite === 'None') {\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.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. If not path is not specified, cookie at '/' path will be deleted.\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 = 'Lax'): void {\n if (!this.documentIsAccessible) {\n return;\n }\n const expiresDate = new Date('Thu, 01 Jan 1970 00:00:01 GMT');\n this.set(name, '', { expires: expiresDate, path, domain, secure, sameSite });\n }\n\n /**\n * Delete all cookies at given path and domain. If not path is not specified, all cookies at '/' path will be deleted.\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 = 'Lax'): void {\n if (!this.documentIsAccessible) {\n return;\n }\n\n const cookies: any = this.getAll();\n\n for (const cookieName in cookies) {\n if (cookies.hasOwnProperty(cookieName)) {\n this.delete(cookieName, path, domain, secure, sameSite);\n }\n }\n }\n}\n","/*\n * Public API Surface of ngx-cookie-service\n */\n\nexport * from './lib/cookie.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"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.
|
|
4
|
+
"version": "22.2.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Stepan Suvorov <stevermeister@gmail.com>",
|
|
7
7
|
"keywords": [
|
|
@@ -113,4 +113,4 @@
|
|
|
113
113
|
},
|
|
114
114
|
"sideEffects": false,
|
|
115
115
|
"type": "module"
|
|
116
|
-
}
|
|
116
|
+
}
|
|
@@ -1,133 +1,335 @@
|
|
|
1
|
-
import * as i0 from
|
|
2
|
-
|
|
3
|
-
type SameSite = 'Lax' | 'None' | 'Strict';
|
|
4
|
-
interface CookieOptions {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { EnvironmentProviders, InjectionToken } from "@angular/core";
|
|
3
|
+
export type SameSite = 'Lax' | 'None' | 'Strict';
|
|
4
|
+
export interface CookieOptions {
|
|
5
|
+
expires?: number | Date;
|
|
6
|
+
path?: string;
|
|
7
|
+
domain?: string;
|
|
8
|
+
secure?: boolean;
|
|
9
|
+
sameSite?: SameSite;
|
|
10
|
+
partitioned?: boolean;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Attributes that identify the cookie to delete. They must match the attributes the cookie was set with.
|
|
14
|
+
*/
|
|
15
|
+
export type DeleteCookieOptions = Omit<CookieOptions, 'expires'>;
|
|
16
|
+
export declare class CookieService {
|
|
17
|
+
private readonly documentIsAccessible;
|
|
18
|
+
private readonly document;
|
|
19
|
+
private readonly platformId;
|
|
20
|
+
private readonly defaultOptions;
|
|
21
|
+
private readonly codec;
|
|
22
|
+
constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Get cookie Regular Expression
|
|
25
|
+
*
|
|
26
|
+
* @param name Cookie name
|
|
27
|
+
* @returns property RegExp
|
|
28
|
+
*
|
|
29
|
+
* @author: Stepan Suvorov
|
|
30
|
+
* @since: 1.0.0
|
|
31
|
+
*/
|
|
32
|
+
private static getCookieRegExp;
|
|
33
|
+
/**
|
|
34
|
+
* Gets the decoded version of an encoded component of a Uniform Resource Identifier (URI).
|
|
35
|
+
*
|
|
36
|
+
* @param encodedURIComponent A value representing an encoded URI component.
|
|
37
|
+
*
|
|
38
|
+
* @returns The decoded version of an encoded component of a Uniform Resource Identifier (URI).
|
|
39
|
+
*
|
|
40
|
+
* @author: Stepan Suvorov
|
|
41
|
+
* @since: 1.0.0
|
|
42
|
+
*/
|
|
43
|
+
private static safeDecodeURIComponent;
|
|
44
|
+
/**
|
|
45
|
+
* Return `true` if {@link Document} is accessible, otherwise return `false`
|
|
46
|
+
*
|
|
47
|
+
* @param name Cookie name
|
|
48
|
+
* @returns boolean - whether cookie with specified name exists
|
|
49
|
+
*
|
|
50
|
+
* @author: Stepan Suvorov
|
|
51
|
+
* @since: 1.0.0
|
|
52
|
+
*/
|
|
53
|
+
check(name: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get cookies by name
|
|
56
|
+
*
|
|
57
|
+
* @param name Cookie name
|
|
58
|
+
* @returns property value
|
|
59
|
+
*
|
|
60
|
+
* @author: Stepan Suvorov
|
|
61
|
+
* @since: 1.0.0
|
|
62
|
+
*/
|
|
63
|
+
get(name: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Get all cookies in JSON format
|
|
66
|
+
*
|
|
67
|
+
* @returns all the cookies in json
|
|
68
|
+
*
|
|
69
|
+
* @author: Stepan Suvorov
|
|
70
|
+
* @since: 1.0.0
|
|
71
|
+
*/
|
|
72
|
+
getAll(): Record<string, string>;
|
|
73
|
+
/**
|
|
74
|
+
* Set cookie based on provided information
|
|
75
|
+
*
|
|
76
|
+
* @param name Cookie name
|
|
77
|
+
* @param value Cookie value
|
|
78
|
+
* @param expires Number of days until the cookies expires or an actual `Date`
|
|
79
|
+
* @param path Cookie path
|
|
80
|
+
* @param domain Cookie domain
|
|
81
|
+
* @param secure Secure flag
|
|
82
|
+
* @param partitioned Partitioned flag
|
|
83
|
+
* @param sameSite OWASP same site token `Lax`, `None`, or `Strict`. Defaults to `Lax`
|
|
84
|
+
*
|
|
85
|
+
* @author: Stepan Suvorov
|
|
86
|
+
* @since: 1.0.0
|
|
87
|
+
*/
|
|
88
|
+
set(name: string, value: string, expires?: CookieOptions['expires'], path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite, partitioned?: CookieOptions['partitioned']): void;
|
|
89
|
+
/**
|
|
90
|
+
* Set cookie based on provided information
|
|
91
|
+
*
|
|
92
|
+
* Cookie's parameters:
|
|
93
|
+
* <pre>
|
|
94
|
+
* expires Number of days until the cookies expires or an actual `Date`
|
|
95
|
+
* path Cookie path
|
|
96
|
+
* domain Cookie domain
|
|
97
|
+
* secure flag
|
|
98
|
+
* sameSite OWASP same site token `Lax`, `None`, or `Strict`. Defaults to `Lax`
|
|
99
|
+
* </pre>
|
|
100
|
+
*
|
|
101
|
+
* @param name Cookie name
|
|
102
|
+
* @param value Cookie value
|
|
103
|
+
* @param options Body with cookie's params
|
|
104
|
+
*
|
|
105
|
+
* @author: Stepan Suvorov
|
|
106
|
+
* @since: 1.0.0
|
|
107
|
+
*/
|
|
108
|
+
set(name: string, value: string, options?: CookieOptions): void;
|
|
109
|
+
/**
|
|
110
|
+
* Delete cookie by name at given path and domain.
|
|
111
|
+
*
|
|
112
|
+
* If `path` is not specified, no `Path` attribute is written and the browser uses its default path: the directory of the URL
|
|
113
|
+
* the page was loaded at (not the current router URL). To delete a cookie that was set with `path: '/'`, pass `'/'` here too.
|
|
114
|
+
*
|
|
115
|
+
* @param name Cookie name
|
|
116
|
+
* @param path Cookie path
|
|
117
|
+
* @param domain Cookie domain
|
|
118
|
+
* @param secure Cookie secure flag
|
|
119
|
+
* @param sameSite Cookie sameSite flag - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
|
120
|
+
*
|
|
121
|
+
* @author: Stepan Suvorov
|
|
122
|
+
* @since: 1.0.0
|
|
123
|
+
*/
|
|
124
|
+
delete(name: string, path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite): void;
|
|
125
|
+
/**
|
|
126
|
+
* Delete cookie by name. The options must match the attributes the cookie was set with: `path` and `domain` select the
|
|
127
|
+
* cookie, and `partitioned: true` is required to delete a Partitioned cookie.
|
|
128
|
+
*
|
|
129
|
+
* If `path` is not specified, no `Path` attribute is written and the browser uses its default path: the directory of the URL
|
|
130
|
+
* the page was loaded at (not the current router URL). To delete a cookie that was set with `path: '/'`, pass `'/'` here too.
|
|
131
|
+
*
|
|
132
|
+
* @param name Cookie name
|
|
133
|
+
* @param options Cookie attributes: `path`, `domain`, `secure`, `sameSite` and `partitioned`
|
|
134
|
+
*
|
|
135
|
+
* @author: Pavankumar Jadda
|
|
136
|
+
* @since: 22.1.0
|
|
137
|
+
*/
|
|
138
|
+
delete(name: string, options?: DeleteCookieOptions): void;
|
|
139
|
+
/**
|
|
140
|
+
* Delete all cookies at given path and domain.
|
|
141
|
+
*
|
|
142
|
+
* If `path` is not specified, the browser's default path is used for each cookie, as described for {@link delete}.
|
|
143
|
+
*
|
|
144
|
+
* @param path Cookie path
|
|
145
|
+
* @param domain Cookie domain
|
|
146
|
+
* @param secure Is the Cookie secure
|
|
147
|
+
* @param sameSite Is the cookie same site
|
|
148
|
+
*
|
|
149
|
+
* @author: Stepan Suvorov
|
|
150
|
+
* @since: 1.0.0
|
|
151
|
+
*/
|
|
152
|
+
deleteAll(path?: CookieOptions['path'], domain?: CookieOptions['domain'], secure?: CookieOptions['secure'], sameSite?: SameSite): void;
|
|
153
|
+
/**
|
|
154
|
+
* Delete all cookies that can currently be accessed, using the same attributes for each one.
|
|
155
|
+
*
|
|
156
|
+
* If `path` is not specified, the browser's default path is used for each cookie, as described for {@link delete}.
|
|
157
|
+
*
|
|
158
|
+
* @param options Cookie attributes: `path`, `domain`, `secure`, `sameSite` and `partitioned`
|
|
159
|
+
*
|
|
160
|
+
* @author: Pavankumar Jadda
|
|
161
|
+
* @since: 22.1.0
|
|
162
|
+
*/
|
|
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;
|
|
218
|
+
/**
|
|
219
|
+
* Returns a validated copy of the options, or `undefined` if the cookie must not be written.
|
|
220
|
+
*
|
|
221
|
+
* A `path` or `domain` containing `;` or a control character could inject attributes or change the cookie's scope, so the
|
|
222
|
+
* whole write is skipped. An invalid `expires` is dropped, which makes a session cookie as browsers already did, and an
|
|
223
|
+
* unknown `sameSite` falls back to the `Lax` default. Each case logs a warning. A numeric `expires` (days
|
|
224
|
+
* from now) is converted to a `Date`, and `sameSite` is matched case-insensitively.
|
|
225
|
+
*
|
|
226
|
+
* @param name Cookie name, used in warnings
|
|
227
|
+
* @param options Cookie options
|
|
228
|
+
* @returns A validated copy of the options, or `undefined` to skip the write
|
|
229
|
+
*
|
|
230
|
+
* @author: Pavankumar Jadda
|
|
231
|
+
* @since: 22.1.0
|
|
232
|
+
*/
|
|
233
|
+
private static validateOptions;
|
|
234
|
+
/**
|
|
235
|
+
* Whether a cookie attribute value contains `;` or an ASCII control character, which would end the attribute early or
|
|
236
|
+
* corrupt the header.
|
|
237
|
+
*
|
|
238
|
+
* @param value Attribute value
|
|
239
|
+
* @returns `true` if the value is unsafe to write
|
|
240
|
+
*
|
|
241
|
+
* @author: Pavankumar Jadda
|
|
242
|
+
* @since: 22.1.0
|
|
243
|
+
*/
|
|
244
|
+
private static hasUnsafeCharacter;
|
|
245
|
+
/**
|
|
246
|
+
* Builds delete options from either an options object or the positional `path`, `domain`, `secure` and `sameSite` arguments.
|
|
247
|
+
*
|
|
248
|
+
* @param pathOrOptions Either a DeleteCookieOptions object or the cookie path
|
|
249
|
+
* @param domain Cookie domain
|
|
250
|
+
* @param secure Cookie secure flag
|
|
251
|
+
* @param sameSite Cookie sameSite flag
|
|
252
|
+
* @returns A new DeleteCookieOptions object
|
|
253
|
+
*
|
|
254
|
+
* @author: Pavankumar Jadda
|
|
255
|
+
* @since: 22.1.0
|
|
256
|
+
*/
|
|
257
|
+
private static toDeleteOptions;
|
|
258
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CookieService, never>;
|
|
259
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
130
260
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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;
|