101 lines
3.5 KiB
JavaScript
101 lines
3.5 KiB
JavaScript
|
|
import CookieSameSiteEnum from '../enums/CookieSameSiteEnum.js';
|
||
|
|
import DefaultCookie from '../DefaultCookie.js';
|
||
|
|
/**
|
||
|
|
* Cookie string.
|
||
|
|
*/
|
||
|
|
export default class CookieStringUtility {
|
||
|
|
/**
|
||
|
|
* Returns cookie.
|
||
|
|
*
|
||
|
|
* @param originURL Origin URL.
|
||
|
|
* @param cookieString Cookie string.
|
||
|
|
* @returns Cookie.
|
||
|
|
*/
|
||
|
|
static stringToCookie(originURL, cookieString) {
|
||
|
|
const parts = cookieString.split(';');
|
||
|
|
const part = parts.shift();
|
||
|
|
if (!part) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const index = part.indexOf('=');
|
||
|
|
const key = index !== -1 ? part.slice(0, index).trim() : part.trim();
|
||
|
|
const value = index !== -1 ? part.slice(index + 1).trim() : null;
|
||
|
|
const cookie = Object.assign({}, DefaultCookie, {
|
||
|
|
// Required
|
||
|
|
key,
|
||
|
|
value,
|
||
|
|
originURL
|
||
|
|
});
|
||
|
|
// Invalid if key is empty.
|
||
|
|
if (!cookie.key) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
for (const part of parts) {
|
||
|
|
const index = part.indexOf('=');
|
||
|
|
const key = index !== -1 ? part.slice(0, index).trim().toLowerCase() : part.trim().toLowerCase();
|
||
|
|
const value = index !== -1 ? part.slice(index + 1).trim() : '';
|
||
|
|
switch (key) {
|
||
|
|
case 'expires':
|
||
|
|
cookie.expires = new Date(value);
|
||
|
|
break;
|
||
|
|
case 'max-age':
|
||
|
|
cookie.expires = new Date(parseInt(value, 10) * 1000 + Date.now());
|
||
|
|
break;
|
||
|
|
case 'domain':
|
||
|
|
cookie.domain = value;
|
||
|
|
break;
|
||
|
|
case 'path':
|
||
|
|
cookie.path = value[0] === '/' ? value : `/${value}`;
|
||
|
|
break;
|
||
|
|
case 'httponly':
|
||
|
|
cookie.httpOnly = true;
|
||
|
|
break;
|
||
|
|
case 'secure':
|
||
|
|
cookie.secure = true;
|
||
|
|
break;
|
||
|
|
case 'samesite':
|
||
|
|
switch (value.toLowerCase()) {
|
||
|
|
case 'strict':
|
||
|
|
cookie.sameSite = CookieSameSiteEnum.strict;
|
||
|
|
break;
|
||
|
|
case 'lax':
|
||
|
|
cookie.sameSite = CookieSameSiteEnum.lax;
|
||
|
|
break;
|
||
|
|
case 'none':
|
||
|
|
cookie.sameSite = CookieSameSiteEnum.none;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const lowerKey = cookie.key.toLowerCase();
|
||
|
|
// Invalid if __secure- prefix is used and cookie is not secure.
|
||
|
|
if (lowerKey.startsWith('__secure-') && !cookie.secure) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
// Invalid if __host- prefix is used and cookie is not secure, not on root path or has a domain.
|
||
|
|
if (lowerKey.startsWith('__host-') &&
|
||
|
|
(!cookie.secure || cookie.path !== '/' || cookie.domain)) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return cookie;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Returns cookie string with key and value.
|
||
|
|
*
|
||
|
|
* @param cookies Cookies.
|
||
|
|
* @returns Cookie string.
|
||
|
|
*/
|
||
|
|
static cookiesToString(cookies) {
|
||
|
|
const cookieString = [];
|
||
|
|
for (const cookie of cookies) {
|
||
|
|
if (cookie.value !== null) {
|
||
|
|
cookieString.push(`${cookie.key}=${cookie.value}`);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
cookieString.push(cookie.key);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return cookieString.join('; ');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=CookieStringUtility.js.map
|