ngx-cookie-ssr
Version:
Ng Cookie Service is a simple cookie service for Angular applications. This is heavily inspired by [ngx-cookie-service](https://github.com/stevermeister/ngx-cookie-service). But only intended to be used with Angular 19 and onwards.
215 lines (210 loc) • 7.39 kB
JavaScript
import { isPlatformBrowser } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, DOCUMENT, PLATFORM_ID, REQUEST, RESPONSE_INIT, Injectable } from '@angular/core';
class CookieService {
document = inject(DOCUMENT);
platformId = inject(PLATFORM_ID);
request = inject(REQUEST);
responseInit = inject(RESPONSE_INIT);
documentIsAccessible = isPlatformBrowser(this.platformId);
cookie() {
return this.documentIsAccessible
? this.document.cookie
: (this.request?.headers.get('cookie') ?? '');
}
/**
* Get cookie Regular Expression
*
* @param name Cookie name
* @returns property RegExp
*
* @author: Stepan Suvorov
*/
static getCookieRegExp(name) {
const escapedName = name.replace(/([\[\]\{\}\(\)\|\=\;\+\?\,\.\*\^\$])/gi, '\\$1');
return new RegExp('(?:^' + escapedName + '|;\\s*' + escapedName + ')=(.*?)(?:;|$)', 'g');
}
/**
* Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI).
*
* @param encodedURIComponent A value representing an encoded URI component.
*
* @returns The unencoded version of an encoded component of a Uniform Resource Identifier (URI).
*
* @author: Stepan Suvorov
*/
static safeDecodeURIComponent(encodedURIComponent) {
try {
return decodeURIComponent(encodedURIComponent);
}
catch {
// probably it is not uri encoded. return as is
return encodedURIComponent;
}
}
/**
* Return `true` if {@link Document} is accessible, otherwise return `false`
*
* @param name Cookie name
* @returns boolean - whether cookie with specified name exists
*
* @author: Stepan Suvorov
*/
check(name) {
name = encodeURIComponent(name);
const regExp = CookieService.getCookieRegExp(name);
return regExp.test(this.cookie());
}
/**
* Get cookies by name
*
* @param name Cookie name
* @returns property value
*
* @author: Stepan Suvorov
*/
get(name) {
if (this.check(name)) {
name = encodeURIComponent(name);
const regExp = CookieService.getCookieRegExp(name);
const result = regExp.exec(this.cookie());
if (!result?.length)
return '';
return result[1] ? CookieService.safeDecodeURIComponent(result[1]) : '';
}
else {
return '';
}
}
/**
* Get all cookies in JSON format
*
* @returns all the cookies in json
*
* @author: Stepan Suvorov
*/
getAll() {
const cookies = {};
const cookieString = this.cookie();
if (cookieString && cookieString !== '') {
cookieString.split(';').forEach((currentCookie) => {
const [cookieName, cookieValue] = currentCookie.split('=');
cookies[CookieService.safeDecodeURIComponent(cookieName.replace(/^ /, ''))] = CookieService.safeDecodeURIComponent(cookieValue);
});
}
return cookies;
}
set(name, value, expiresOrOptions, path, domain, secure, sameSite, partitioned) {
if (typeof expiresOrOptions === 'number' ||
expiresOrOptions instanceof Date ||
path ||
domain ||
secure ||
sameSite) {
const optionsBody = {
expires: expiresOrOptions,
path,
domain,
secure,
sameSite: sameSite ? sameSite : 'Lax',
partitioned,
};
this.set(name, value, optionsBody);
return;
}
let cookieString = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';';
const options = expiresOrOptions ? expiresOrOptions : {};
if (options.expires) {
if (typeof options.expires === 'number') {
const dateExpires = new Date(new Date().getTime() + options.expires * 1000 * 60 * 60 * 24);
cookieString += 'expires=' + dateExpires.toUTCString() + ';';
}
else {
cookieString += 'expires=' + options.expires.toUTCString() + ';';
}
}
if (options.path) {
cookieString += 'path=' + options.path + ';';
}
if (options.domain) {
cookieString += 'domain=' + options.domain + ';';
}
if (options.secure === false && options.sameSite === 'None') {
options.secure = true;
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`);
}
if (options.secure) {
cookieString += 'secure;';
}
if (!options.sameSite) {
options.sameSite = 'Lax';
}
cookieString += 'sameSite=' + options.sameSite + ';';
if (options.partitioned) {
cookieString += 'Partitioned;';
}
if (this.documentIsAccessible) {
this.document.cookie = cookieString;
}
else {
const headers = this.responseInit?.headers;
headers?.append('Set-Cookie', cookieString);
}
}
/**
* Delete cookie by name
*
* @param name Cookie name
* @param path Cookie path
* @param domain Cookie domain
* @param secure Cookie secure flag
* @param sameSite Cookie sameSite flag - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
*
* @author: Stepan Suvorov
*/
delete(name, path, domain, secure, sameSite = 'Lax') {
const expiresDate = new Date('Thu, 01 Jan 1970 00:00:01 GMT');
this.set(name, '', {
expires: expiresDate,
path,
domain,
secure,
sameSite,
});
}
/**
* Delete all cookies
*
* @param path Cookie path
* @param domain Cookie domain
* @param secure Is the Cookie secure
* @param sameSite Is the cookie same site
*
* @author: Stepan Suvorov
*/
deleteAll(path, domain, secure, sameSite = 'Lax') {
const cookies = this.getAll();
for (const cookieName in cookies) {
if (cookies.hasOwnProperty(cookieName)) {
this.delete(cookieName, path, domain, secure, sameSite);
}
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: CookieService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: CookieService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: CookieService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}] });
/*
* Public API Surface of ngx-cookie-ssr
*/
/**
* Generated bundle index. Do not edit.
*/
export { CookieService };
//# sourceMappingURL=ngx-cookie-ssr.mjs.map