This commit is contained in:
parent
3aaaf10fd9
commit
cc8762e4ec
@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 3.0.0
|
||||
|
||||
- Allows Cookies Parameters to be set
|
||||
|
||||
BREAKING:
|
||||
|
||||
- All cookie_name and refresh_cookie_name properties have been renamed to cookie and refresh_cookie and are now a settings object instead of a string
|
||||
|
||||
## 2.2.0
|
||||
|
||||
- Allow refresh tokens to be sent on a separate cookie
|
||||
|
31
README.md
31
README.md
@ -1,6 +1,6 @@
|
||||
# auth-server-helper
|
||||
|
||||
version: 2.2.x
|
||||
version: 3.0.x
|
||||
|
||||
customizable and simple authentication
|
||||
|
||||
@ -23,8 +23,8 @@ const {create_gateway} = require('@sapphirecode/auth-server-helper');
|
||||
|
||||
const gateway = create_gateway({
|
||||
redirect_url: '/auth', // if defined, unauthorized requests will be redirected
|
||||
cookie_name: 'auth_cookie', // if defined, access tokens will be read from this cookie,
|
||||
refresh_cookie_name: 'refresh_cookie', // if defined, refresh tokens will be read and used to automatically refresh client tokens (requires the refresh_settings attribute)
|
||||
cookie: { name: 'auth_cookie' }, // if defined, access tokens will be read from or written to this cookie,
|
||||
refresh_cookie: { name: 'refresh_cookie' }, // if defined, refresh tokens will be read and used to automatically refresh client tokens (requires the refresh_settings attribute)
|
||||
refresh_settings: {
|
||||
// same as settings for allow_access under section 2
|
||||
// the options data, redirect_to and leave_open are not supported here
|
||||
@ -103,8 +103,8 @@ const handler = create_auth_handler(
|
||||
// the same works in handlers after the gateway, information is always stored in request.connection.auth
|
||||
},
|
||||
},
|
||||
cookie_name: 'auth_cookie', // if defined, access tokens will be stored in this cookie,
|
||||
refresh_cookie_name: 'refresh_cookie' // if defined, refresh tokens will be stored in this cookie
|
||||
cookie: { name: 'auth_cookie' }, // if defined, access tokens will be stored in this cookie,
|
||||
refresh_cookie: { name: 'refresh_cookie' } // if defined, refresh tokens will be stored in this cookie
|
||||
}
|
||||
);
|
||||
|
||||
@ -138,6 +138,27 @@ deny(true);
|
||||
if this flag is set, no data will be written to the response body and no data will be sent.
|
||||
Status code and Headers will still be set.
|
||||
|
||||
### Defining Custom Cookie Settings
|
||||
|
||||
By default all cookies will be sent with 'Secure; HttpOnly; SameSite=Strict' Attributes
|
||||
|
||||
In the appropriate settings object, you can set the following options:
|
||||
|
||||
```js
|
||||
{
|
||||
name: 'foo', // name of the cookies
|
||||
secure: true, // option to enable or disable the Secure option default: true
|
||||
http_only: true, // option to enable or disable HttpOnly default: true
|
||||
same_site: 'Strict', // SameSite property (Strict, Lax or None) default: 'Strict'. Set this to null to disable
|
||||
expires: 'Mon, 10 Jan 2022 09:28:00 GMT', // Expiry date of the cookie
|
||||
max_age: 600, // Maximum age in Seconds
|
||||
domain: 'example.com', // Domain property
|
||||
path: '/cookies_here' // Path property
|
||||
}
|
||||
```
|
||||
|
||||
For Documentation on the different Cookie Attributes see <https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#creating_cookies>
|
||||
|
||||
### Invalidating tokens after they are delivered to the client
|
||||
|
||||
```js
|
||||
|
@ -9,6 +9,7 @@ import { IncomingMessage, ServerResponse } from 'http';
|
||||
import { to_utf8 } from '@sapphirecode/encoding-helper';
|
||||
import auth from './Authority';
|
||||
import { debug } from './debug';
|
||||
import { build_cookie, CookieSettings } from './cookie';
|
||||
|
||||
const logger = debug ('auth');
|
||||
|
||||
@ -37,10 +38,6 @@ interface AccessResponse {
|
||||
type AuthHandler =
|
||||
(req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
||||
|
||||
function build_cookie (name: string, value: string): string {
|
||||
return `${name}=${value}; Secure; HttpOnly; SameSite=Strict`;
|
||||
}
|
||||
|
||||
class AuthRequest {
|
||||
public request: IncomingMessage;
|
||||
public response: ServerResponse;
|
||||
@ -56,8 +53,8 @@ class AuthRequest {
|
||||
|
||||
public body: string;
|
||||
|
||||
private _cookie_name?: string;
|
||||
private _refresh_cookie_name?: string;
|
||||
private _cookie?: CookieSettings;
|
||||
private _refresh_cookie?: CookieSettings;
|
||||
private _is_successful: boolean;
|
||||
|
||||
public get is_successful (): boolean {
|
||||
@ -68,8 +65,8 @@ class AuthRequest {
|
||||
req: IncomingMessage,
|
||||
res: ServerResponse,
|
||||
body: string,
|
||||
cookie?: string,
|
||||
refresh_cookie?: string
|
||||
cookie?: CookieSettings,
|
||||
refresh_cookie?: CookieSettings
|
||||
) {
|
||||
this.request = req;
|
||||
this.response = res;
|
||||
@ -78,8 +75,8 @@ class AuthRequest {
|
||||
this.is_bearer = false;
|
||||
this.user = '';
|
||||
this.password = '';
|
||||
this._cookie_name = cookie;
|
||||
this._refresh_cookie_name = refresh_cookie;
|
||||
this._cookie = cookie;
|
||||
this._refresh_cookie = refresh_cookie;
|
||||
this._is_successful = false;
|
||||
logger ('started processing new auth request');
|
||||
}
|
||||
@ -106,7 +103,6 @@ class AuthRequest {
|
||||
const at = await auth.sign (
|
||||
'access_token',
|
||||
access_token_expires_in,
|
||||
|
||||
{ data }
|
||||
);
|
||||
const result: AccessResult = { access_token_id: at.id };
|
||||
@ -119,8 +115,8 @@ class AuthRequest {
|
||||
|
||||
const cookies = [];
|
||||
|
||||
if (typeof this._cookie_name === 'string')
|
||||
cookies.push (build_cookie (this._cookie_name, at.signature));
|
||||
if (typeof this._cookie !== 'undefined')
|
||||
cookies.push (build_cookie (this._cookie, at.signature));
|
||||
|
||||
if (include_refresh_token) {
|
||||
logger ('including refresh token');
|
||||
@ -135,9 +131,8 @@ class AuthRequest {
|
||||
res.refresh_expires_in = refresh_token_expires_in;
|
||||
result.refresh_token_id = rt.id;
|
||||
|
||||
if (typeof this._refresh_cookie_name === 'string')
|
||||
// eslint-disable-next-line max-len
|
||||
cookies.push (build_cookie (this._refresh_cookie_name, rt.signature));
|
||||
if (typeof this._refresh_cookie !== 'undefined')
|
||||
cookies.push (build_cookie (this._refresh_cookie, rt.signature));
|
||||
}
|
||||
|
||||
if (cookies.length > 0) {
|
||||
@ -228,8 +223,8 @@ type AuthRequestHandler = (req: AuthRequest) => Promise<void> | void;
|
||||
interface CreateHandlerOptions {
|
||||
refresh?: AccessSettings;
|
||||
modules?: Record<string, AuthRequestHandler>;
|
||||
cookie_name?: string;
|
||||
refresh_cookie_name?: string;
|
||||
cookie?: CookieSettings;
|
||||
refresh_cookie?: CookieSettings;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
@ -308,8 +303,9 @@ export default function create_auth_handler (
|
||||
): AuthHandler {
|
||||
logger ('creating new auth handler');
|
||||
if (
|
||||
typeof options?.cookie_name !== 'undefined'
|
||||
&& options.cookie_name === options.refresh_cookie_name
|
||||
typeof options?.cookie !== 'undefined'
|
||||
&& typeof options?.refresh_cookie !== 'undefined'
|
||||
&& options.cookie.name === options.refresh_cookie.name
|
||||
)
|
||||
throw new Error ('access and refresh cookies cannot have the same name');
|
||||
|
||||
@ -331,8 +327,8 @@ export default function create_auth_handler (
|
||||
req,
|
||||
res,
|
||||
body,
|
||||
options?.cookie_name,
|
||||
options?.refresh_cookie_name
|
||||
options?.cookie,
|
||||
options?.refresh_cookie
|
||||
);
|
||||
const token = (/(?<type>\S+) (?<token>.+)/ui)
|
||||
.exec (req.headers.authorization as string);
|
||||
|
@ -9,7 +9,7 @@ import { IncomingMessage, ServerResponse } from 'http';
|
||||
import authority from './Authority';
|
||||
import { AuthRequest, AccessSettings } from './AuthHandler';
|
||||
import { debug } from './debug';
|
||||
import { extract_cookie } from './cookie';
|
||||
import { extract_cookie, CookieSettings } from './cookie';
|
||||
|
||||
const logger = debug ('gateway');
|
||||
|
||||
@ -27,8 +27,8 @@ interface RefreshSettings extends AccessSettings {
|
||||
|
||||
interface GatewayOptions {
|
||||
redirect_url?: string;
|
||||
cookie_name?: string;
|
||||
refresh_cookie_name?: string;
|
||||
cookie?: CookieSettings;
|
||||
refresh_cookie?: CookieSettings;
|
||||
refresh_settings?: RefreshSettings;
|
||||
}
|
||||
|
||||
@ -38,8 +38,9 @@ class GatewayClass {
|
||||
public constructor (options: GatewayOptions = {}) {
|
||||
logger ('creating new gateway');
|
||||
if (
|
||||
typeof options.cookie_name === 'string'
|
||||
&& options.cookie_name === options.refresh_cookie_name
|
||||
typeof options?.cookie !== 'undefined'
|
||||
&& typeof options?.refresh_cookie !== 'undefined'
|
||||
&& options.cookie.name === options.refresh_cookie.name
|
||||
)
|
||||
throw new Error ('access and refresh cookies cannot have the same name');
|
||||
|
||||
@ -80,7 +81,7 @@ class GatewayClass {
|
||||
logger ('authenticating incoming request');
|
||||
let auth = this.get_header_auth (req);
|
||||
if (auth === null)
|
||||
auth = extract_cookie (this._options.cookie_name, req.headers.cookie);
|
||||
auth = extract_cookie (this._options.cookie?.name, req.headers.cookie);
|
||||
if (auth === null) {
|
||||
logger ('found no auth token');
|
||||
return false;
|
||||
@ -101,7 +102,7 @@ class GatewayClass {
|
||||
res: ServerResponse
|
||||
): Promise<boolean> {
|
||||
if (
|
||||
typeof this._options.refresh_cookie_name === 'undefined'
|
||||
typeof this._options.refresh_cookie === 'undefined'
|
||||
|| typeof this._options.refresh_settings === 'undefined'
|
||||
)
|
||||
return false;
|
||||
@ -109,7 +110,7 @@ class GatewayClass {
|
||||
logger ('trying to apply refresh token');
|
||||
|
||||
const refresh = extract_cookie (
|
||||
this._options.refresh_cookie_name,
|
||||
this._options.refresh_cookie.name,
|
||||
req.headers.cookie
|
||||
);
|
||||
if (refresh === null) {
|
||||
@ -124,8 +125,8 @@ class GatewayClass {
|
||||
req,
|
||||
res,
|
||||
''
|
||||
, this._options.cookie_name,
|
||||
this._options.refresh_cookie_name
|
||||
, this._options.cookie,
|
||||
this._options.refresh_cookie
|
||||
);
|
||||
const refresh_result = await auth_request.allow_access ({
|
||||
...this._options.refresh_settings,
|
||||
|
@ -3,8 +3,51 @@ import { debug } from './debug';
|
||||
|
||||
const logger = debug ('cookies');
|
||||
|
||||
function build_cookie (name: string, value: string): string {
|
||||
return `${name}=${value}; Secure; HttpOnly; SameSite=Strict`;
|
||||
type SameSiteValue = 'Lax' | 'None' | 'Strict';
|
||||
|
||||
interface CookieSettings {
|
||||
name: string;
|
||||
secure?: boolean;
|
||||
http_only?: boolean;
|
||||
same_site?: SameSiteValue|null;
|
||||
expires?: string;
|
||||
max_age?: number;
|
||||
domain?: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
const default_settings: Omit<CookieSettings, 'name'> = {
|
||||
secure: true,
|
||||
http_only: true,
|
||||
same_site: 'Strict'
|
||||
};
|
||||
|
||||
function build_cookie (
|
||||
settings: CookieSettings,
|
||||
value: string
|
||||
): string {
|
||||
const local_settings = { ...default_settings, ...settings };
|
||||
const sections = [ `${local_settings.name}=${value}` ];
|
||||
|
||||
if (local_settings.secure)
|
||||
sections.push ('Secure');
|
||||
if (local_settings.http_only)
|
||||
sections.push ('HttpOnly');
|
||||
if (
|
||||
typeof local_settings.same_site !== 'undefined'
|
||||
&& local_settings.same_site !== null
|
||||
)
|
||||
sections.push (`SameSite=${local_settings.same_site}`);
|
||||
if (typeof local_settings.expires !== 'undefined')
|
||||
sections.push (`Expires=${local_settings.expires}`);
|
||||
if (typeof local_settings.max_age !== 'undefined')
|
||||
sections.push (`Max-Age=${local_settings.max_age}`);
|
||||
if (typeof local_settings.domain !== 'undefined')
|
||||
sections.push (`Domain=${local_settings.domain}`);
|
||||
if (typeof local_settings.path !== 'undefined')
|
||||
sections.push (`Path=${local_settings.path}`);
|
||||
|
||||
return sections.join ('; ');
|
||||
}
|
||||
|
||||
function extract_cookie (
|
||||
@ -32,4 +75,4 @@ function extract_cookie (
|
||||
return result;
|
||||
}
|
||||
|
||||
export { build_cookie, extract_cookie };
|
||||
export { build_cookie, extract_cookie, SameSiteValue, CookieSettings };
|
||||
|
@ -34,6 +34,10 @@ import keystore, {
|
||||
KeyStore, KeyStoreExport,
|
||||
LabelledKey, Key
|
||||
} from './KeyStore';
|
||||
import {
|
||||
CookieSettings,
|
||||
SameSiteValue
|
||||
} from './cookie';
|
||||
|
||||
export {
|
||||
create_gateway,
|
||||
@ -63,5 +67,7 @@ export {
|
||||
KeyStore,
|
||||
KeyStoreExport,
|
||||
LabelledKey,
|
||||
Key
|
||||
Key,
|
||||
CookieSettings,
|
||||
SameSiteValue
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sapphirecode/auth-server-helper",
|
||||
"version": "2.2.6",
|
||||
"version": "3.0.0",
|
||||
"main": "dist/index.js",
|
||||
"author": {
|
||||
"name": "Timo Hocker",
|
||||
|
@ -111,8 +111,8 @@ describe ('auth handler', () => {
|
||||
req.deny ();
|
||||
}
|
||||
}, {
|
||||
cookie_name: 'cookie_jar',
|
||||
refresh_cookie_name: 'mint_cookies',
|
||||
cookie: { name: 'cookie_jar' },
|
||||
refresh_cookie: { name: 'mint_cookies' },
|
||||
refresh: {
|
||||
access_token_expires_in: expires_seconds,
|
||||
refresh_token_expires_in: refresh_expires_seconds,
|
||||
@ -159,9 +159,9 @@ describe ('auth handler', () => {
|
||||
expect (res1.data.token_type)
|
||||
.toEqual ('bearer');
|
||||
expect (resp1.headers['set-cookie'])
|
||||
.toContain (build_cookie ('cookie_jar', res1.at as string));
|
||||
.toContain (build_cookie ({ name: 'cookie_jar' }, res1.at as string));
|
||||
expect (resp1.headers['set-cookie'])
|
||||
.toContain (build_cookie ('mint_cookies', res1.rt as string));
|
||||
.toContain (build_cookie ({ name: 'mint_cookies' }, res1.rt as string));
|
||||
|
||||
check_token (res1.at as string, 'access_token');
|
||||
expect (res1.data.expires_in)
|
||||
@ -180,9 +180,9 @@ describe ('auth handler', () => {
|
||||
expect (res2.data.token_type)
|
||||
.toEqual ('bearer');
|
||||
expect (resp2.headers['set-cookie'])
|
||||
.toContain (build_cookie ('cookie_jar', res2.at as string));
|
||||
.toContain (build_cookie ({ name: 'cookie_jar' }, res2.at as string));
|
||||
expect (resp2.headers['set-cookie'])
|
||||
.toContain (build_cookie ('mint_cookies', res2.rt as string));
|
||||
.toContain (build_cookie ({ name: 'mint_cookies' }, res2.rt as string));
|
||||
|
||||
check_token (res2.at as string, 'access_token');
|
||||
expect (res2.data.expires_in)
|
||||
@ -212,9 +212,9 @@ describe ('auth handler', () => {
|
||||
expect (res1.data.token_type)
|
||||
.toEqual ('bearer');
|
||||
expect (resp1.headers['set-cookie'])
|
||||
.toContain (build_cookie ('cookie_jar', res1.at as string));
|
||||
.toContain (build_cookie ({ name: 'cookie_jar' }, res1.at as string));
|
||||
expect (resp1.headers['set-cookie'])
|
||||
.toContain (build_cookie ('mint_cookies', res1.rt as string));
|
||||
.toContain (build_cookie ({ name: 'mint_cookies' }, res1.rt as string));
|
||||
|
||||
check_token (res1.at as string, 'access_token');
|
||||
expect (res1.data.expires_in)
|
||||
@ -237,9 +237,9 @@ describe ('auth handler', () => {
|
||||
expect (res1.data.token_type)
|
||||
.toEqual ('bearer');
|
||||
expect (resp1.headers['set-cookie'])
|
||||
.toContain (build_cookie ('cookie_jar', res1.at as string));
|
||||
.toContain (build_cookie ({ name: 'cookie_jar' }, res1.at as string));
|
||||
expect (resp1.headers['set-cookie'])
|
||||
.toContain (build_cookie ('mint_cookies', res1.rt as string));
|
||||
.toContain (build_cookie ({ name: 'mint_cookies' }, res1.rt as string));
|
||||
|
||||
check_token (res1.at as string, 'access_token');
|
||||
expect (res1.data.expires_in)
|
||||
@ -310,9 +310,9 @@ describe ('auth handler', () => {
|
||||
expect (res2.data.token_type)
|
||||
.toEqual ('bearer');
|
||||
expect (resp2.headers['set-cookie'])
|
||||
.toContain (build_cookie ('cookie_jar', res2.at as string));
|
||||
.toContain (build_cookie ({ name: 'cookie_jar' }, res2.at as string));
|
||||
expect (resp2.headers['set-cookie'])
|
||||
.toContain (build_cookie ('mint_cookies', res2.rt as string));
|
||||
.toContain (build_cookie ({ name: 'mint_cookies' }, res2.rt as string));
|
||||
|
||||
check_token (res2.at as string, 'access_token');
|
||||
expect (res2.data.expires_in)
|
||||
@ -368,8 +368,8 @@ describe ('auth handler', () => {
|
||||
it ('should disallow access and refresh cookies with the same name', () => {
|
||||
expect (() => {
|
||||
create_auth_handler (() => Promise.resolve (), {
|
||||
cookie_name: 'foo',
|
||||
refresh_cookie_name: 'foo'
|
||||
cookie: { name: 'foo' },
|
||||
refresh_cookie: { name: 'foo' }
|
||||
});
|
||||
})
|
||||
.toThrowError ('access and refresh cookies cannot have the same name');
|
||||
|
@ -19,9 +19,9 @@ describe ('gateway', () => {
|
||||
clock_setup ();
|
||||
|
||||
const g = create_gateway ({
|
||||
redirect_url: 'http://localhost/auth',
|
||||
cookie_name: 'cookie_jar',
|
||||
refresh_cookie_name: 'mint_cookies',
|
||||
redirect_url: 'http://localhost/auth',
|
||||
cookie: { name: 'cookie_jar' },
|
||||
refresh_cookie: { name: 'mint_cookies' },
|
||||
refresh_settings: {
|
||||
access_token_expires_in: 600,
|
||||
include_refresh_token: true,
|
||||
@ -162,7 +162,10 @@ describe ('gateway', () => {
|
||||
|
||||
it ('should disallow access and refresh cookies with the same name', () => {
|
||||
expect (() => {
|
||||
create_gateway ({ cookie_name: 'foo', refresh_cookie_name: 'foo' });
|
||||
create_gateway ({
|
||||
cookie: { name: 'foo' },
|
||||
refresh_cookie: { name: 'foo' }
|
||||
});
|
||||
})
|
||||
.toThrowError ('access and refresh cookies cannot have the same name');
|
||||
});
|
||||
|
@ -5,44 +5,124 @@
|
||||
* Created by Timo Hocker <timo@scode.ovh>, January 2022
|
||||
*/
|
||||
|
||||
import { build_cookie, extract_cookie } from '../../lib/cookie';
|
||||
import { build_cookie, CookieSettings, extract_cookie } from '../../lib/cookie';
|
||||
|
||||
interface CreateCookie {
|
||||
settings: CookieSettings
|
||||
value: string
|
||||
result: string
|
||||
}
|
||||
|
||||
const create_cookie_pairs: CreateCookie[] = [
|
||||
{
|
||||
settings: { name: 'foo' },
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Secure; HttpOnly; SameSite=Strict'
|
||||
},
|
||||
{
|
||||
settings: { name: 'foäöüo' },
|
||||
value: 'baäöür',
|
||||
result: 'foäöüo=baäöür; Secure; HttpOnly; SameSite=Strict'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: true,
|
||||
http_only: false,
|
||||
same_site: null
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Secure'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: false,
|
||||
http_only: true,
|
||||
same_site: null
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; HttpOnly'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: false,
|
||||
http_only: false,
|
||||
same_site: 'Lax'
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; SameSite=Lax'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: false,
|
||||
http_only: false,
|
||||
same_site: null,
|
||||
expires: 'Tomorrow'
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Expires=Tomorrow'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: false,
|
||||
http_only: false,
|
||||
same_site: null,
|
||||
max_age: 600
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Max-Age=600'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: false,
|
||||
http_only: false,
|
||||
same_site: null,
|
||||
domain: 'example.com'
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Domain=example.com'
|
||||
},
|
||||
{
|
||||
settings: {
|
||||
name: 'foo',
|
||||
secure: false,
|
||||
http_only: false,
|
||||
same_site: null,
|
||||
path: '/test'
|
||||
},
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Path=/test'
|
||||
}
|
||||
];
|
||||
|
||||
const parse_cookie_pairs = [
|
||||
{
|
||||
header: 'foo=bar; Secure; HttpOnly; SameSite=Strict',
|
||||
name: 'foo',
|
||||
value: 'bar'
|
||||
},
|
||||
{
|
||||
header: '134=567;foäöüo=baäöür;tesT=123',
|
||||
name: 'foäöüo',
|
||||
value: 'baäöür'
|
||||
}
|
||||
];
|
||||
|
||||
describe ('cookie', () => {
|
||||
it ('should create a cookie', () => {
|
||||
const pairs = [
|
||||
{
|
||||
name: 'foo',
|
||||
value: 'bar',
|
||||
result: 'foo=bar; Secure; HttpOnly; SameSite=Strict'
|
||||
},
|
||||
{
|
||||
name: 'foäöüo',
|
||||
value: 'baäöür',
|
||||
result: 'foäöüo=baäöür; Secure; HttpOnly; SameSite=Strict'
|
||||
}
|
||||
];
|
||||
|
||||
for (const pair of pairs) {
|
||||
expect (build_cookie (pair.name, pair.value))
|
||||
for (const pair of create_cookie_pairs) {
|
||||
expect (build_cookie (pair.settings, pair.value))
|
||||
.toEqual (pair.result);
|
||||
}
|
||||
});
|
||||
|
||||
it ('should parse a cookie', () => {
|
||||
const pairs = [
|
||||
{
|
||||
header: 'foo=bar; Secure; HttpOnly; SameSite=Strict',
|
||||
name: 'foo',
|
||||
value: 'bar'
|
||||
},
|
||||
{
|
||||
header: '134=567;foäöüo=baäöür;tesT=123',
|
||||
name: 'foäöüo',
|
||||
value: 'baäöür'
|
||||
}
|
||||
];
|
||||
|
||||
for (const pair of pairs) {
|
||||
for (const pair of parse_cookie_pairs) {
|
||||
expect (extract_cookie (pair.name, pair.header))
|
||||
.toEqual (pair.value);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user