Skip to content

Commit

Permalink
Document PrefixSecurity
Browse files Browse the repository at this point in the history
  • Loading branch information
colincasey committed Mar 24, 2024
1 parent 9e72de9 commit a3bd39c
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 64 deletions.
1 change: 1 addition & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ docs/*.md

# subsequent PRs will un-ignore areas that are under review until
# all docs are complete and we can drop this ignore file entirely
!docs/tough-cookie.prefixsecurity.md
83 changes: 83 additions & 0 deletions api/docs/tough-cookie.prefixsecurity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [tough-cookie](./tough-cookie.md) &gt; [PrefixSecurity](./tough-cookie.prefixsecurity.md)

## PrefixSecurity enum

Cookie prefixes are a way to indicate that a given cookie was set with a set of attributes simply by inspecting the first few characters of the cookie's name. These are defined in [RFC6265bis - Section 4.1.3](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.3)<!-- -->.

The following values can be used to configure how a [CookieJar](./tough-cookie.cookiejar.md) enforces attribute restrictions for Cookie prefixes.

**Signature:**

```typescript
export declare enum PrefixSecurity
```

## Enumeration Members

<table><thead><tr><th>

Member


</th><th>

Value


</th><th>

Description


</th></tr></thead>
<tbody><tr><td>

DISABLED


</td><td>

`"unsafe-disabled"`


</td><td>

Disables cookie prefix checking.


</td></tr>
<tr><td>

SILENT


</td><td>

`"silent"`


</td><td>

Enable cookie prefix checking but silently ignores the cookie if conditions are not met. This is the default configuration for a [CookieJar](./tough-cookie.cookiejar.md)<!-- -->.


</td></tr>
<tr><td>

STRICT


</td><td>

`"strict"`


</td><td>

Enables cookie prefix checking and will raise an error if conditions are not met.


</td></tr>
</tbody></table>
58 changes: 30 additions & 28 deletions api/tough-cookie.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@

/// <reference types="node" />

// Warning: (ae-forgotten-export) The symbol "Nullable" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function canonicalDomain(str: string | null): string | null;
export function canonicalDomain(str: Nullable<string>): string | undefined;

// @public (undocumented)
export class Cookie {
// Warning: (ae-forgotten-export) The symbol "CreateCookieOptions" needs to be exported by the entry point index.d.ts
constructor(options?: CreateCookieOptions);
// (undocumented)
canonicalizedDomain(): string | null;
canonicalizedDomain(): string | undefined;
// (undocumented)
cdomain(): string | null;
cdomain(): string | undefined;
// (undocumented)
clone(): Cookie | null;
clone(): Cookie | undefined;
// (undocumented)
static cookiesCreated: number;
// (undocumented)
Expand Down Expand Up @@ -100,7 +102,7 @@ export function cookieCompare(a: Cookie, b: Cookie): number;
// @public (undocumented)
export class CookieJar {
// Warning: (ae-forgotten-export) The symbol "CreateCookieJarOptions" needs to be exported by the entry point index.d.ts
constructor(store?: Store | null | undefined, options?: CreateCookieJarOptions | boolean);
constructor(store?: Nullable<Store>, options?: CreateCookieJarOptions | boolean);
// (undocumented)
clone(callback: Callback<CookieJar>): void;
// (undocumented)
Expand Down Expand Up @@ -198,29 +200,29 @@ export class CookieJar {
}

// @public (undocumented)
export function defaultPath(path?: string | null): string;
export function defaultPath(path?: Nullable<string>): string;

// @public (undocumented)
export function domainMatch(str?: string | null, domStr?: string | null, canonicalize?: boolean): boolean | null;
export function domainMatch(str?: Nullable<string>, domStr?: Nullable<string>, canonicalize?: boolean): boolean | undefined;

// @public
export function formatDate(date: Date): string;

// @public (undocumented)
export const fromJSON: (str: unknown) => Cookie | null;
export const fromJSON: (str: unknown) => Cookie | undefined;

// Warning: (ae-forgotten-export) The symbol "GetPublicSuffixOptions" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function getPublicSuffix(domain: string, options?: GetPublicSuffixOptions): string | null;
export function getPublicSuffix(domain: string, options?: GetPublicSuffixOptions): string | undefined;

// @public (undocumented)
export class MemoryCookieStore extends Store {
constructor();
// (undocumented)
findCookie(domain: string | null, path: string | null, key: string | undefined): Promise<Cookie | undefined>;
findCookie(domain: Nullable<string>, path: Nullable<string>, key: Nullable<string>): Promise<Cookie | undefined>;
// (undocumented)
findCookie(domain: string | null, path: string | null, key: string | undefined, callback: Callback<Cookie | undefined>): void;
findCookie(domain: Nullable<string>, path: Nullable<string>, key: Nullable<string>, callback: Callback<Cookie | undefined>): void;
// (undocumented)
findCookies(domain: string, path: string, allowSpecialUseDomain?: boolean): Promise<Cookie[]>;
// (undocumented)
Expand Down Expand Up @@ -264,38 +266,38 @@ export class ParameterError extends Error {
// @public (undocumented)
export const parse: (str: string, options?: {
loose?: boolean | undefined;
} | undefined) => Cookie | null | undefined;
} | undefined) => Cookie | undefined;

// @public (undocumented)
export function parseDate(str: string | undefined | null): Date | undefined;
export function parseDate(str: Nullable<string>): Date | undefined;

// @public (undocumented)
export function pathMatch(reqPath: string, cookiePath: string): boolean;

// @public (undocumented)
export function permuteDomain(domain: string, allowSpecialUseDomain?: boolean): string[] | null;
export function permuteDomain(domain: string, allowSpecialUseDomain?: boolean): string[] | undefined;

// @public
export function permutePath(path: string): string[];

// @public (undocumented)
export const PrefixSecurityEnum: Readonly<{
SILENT: "silent";
STRICT: "strict";
DISABLED: "unsafe-disabled";
}>;
// @public
export enum PrefixSecurity {
DISABLED = "unsafe-disabled",
SILENT = "silent",
STRICT = "strict"
}

// @public (undocumented)
export class Store {
constructor();
// (undocumented)
findCookie(domain: string | null, path: string | null, key: string | undefined): Promise<Cookie | null | undefined>;
findCookie(domain: Nullable<string>, path: Nullable<string>, key: Nullable<string>): Promise<Cookie | undefined>;
// (undocumented)
findCookie(domain: string | null, path: string | null, key: string | undefined, callback: Callback<Cookie | null | undefined>): void;
findCookie(domain: Nullable<string>, path: Nullable<string>, key: Nullable<string>, callback: Callback<Cookie | undefined>): void;
// (undocumented)
findCookies(domain: string | null, path: string | null, allowSpecialUseDomain?: boolean): Promise<Cookie[]>;
findCookies(domain: Nullable<string>, path: Nullable<string>, allowSpecialUseDomain?: boolean): Promise<Cookie[]>;
// (undocumented)
findCookies(domain: string | null, path: string | null, allowSpecialUseDomain?: boolean, callback?: Callback<Cookie[]>): void;
findCookies(domain: Nullable<string>, path: Nullable<string>, allowSpecialUseDomain?: boolean, callback?: Callback<Cookie[]>): void;
// (undocumented)
getAllCookies(): Promise<Cookie[]>;
// (undocumented)
Expand All @@ -309,13 +311,13 @@ export class Store {
// (undocumented)
removeAllCookies(callback: ErrorCallback): void;
// (undocumented)
removeCookie(domain: string | null | undefined, path: string | null | undefined, key: string | null | undefined): Promise<void>;
removeCookie(domain: Nullable<string>, path: Nullable<string>, key: Nullable<string>): Promise<void>;
// (undocumented)
removeCookie(domain: string | null | undefined, path: string | null | undefined, key: string | null | undefined, callback: ErrorCallback): void;
removeCookie(domain: Nullable<string>, path: Nullable<string>, key: Nullable<string>, callback: ErrorCallback): void;
// (undocumented)
removeCookies(domain: string, path: string | null): Promise<void>;
removeCookies(domain: string, path: Nullable<string>): Promise<void>;
// (undocumented)
removeCookies(domain: string, path: string | null, callback: ErrorCallback): void;
removeCookies(domain: string, path: Nullable<string>, callback: ErrorCallback): void;
// (undocumented)
synchronous: boolean;
// (undocumented)
Expand Down
8 changes: 4 additions & 4 deletions lib/__tests__/cookiePrefixes.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PrefixSecurityEnum } from '../cookie/constants'
import { PrefixSecurity } from '../cookie/constants'
import { CookieJar } from '../cookie/cookieJar'

let cookieJar: CookieJar
Expand All @@ -11,7 +11,7 @@ describe('When `prefixSecurity` is enabled for `CookieJar`', () => {
cookieJar = new CookieJar(null, {
prefixSecurity: 'silent',
})
expect(cookieJar.prefixSecurity).toBe(PrefixSecurityEnum.SILENT)
expect(cookieJar.prefixSecurity).toBe(PrefixSecurity.SILENT)
})

describe('__Secure prefix', () => {
Expand Down Expand Up @@ -106,7 +106,7 @@ describe('When `prefixSecurity` is enabled for `CookieJar`', () => {
cookieJar = new CookieJar(null, {
prefixSecurity: 'strict',
})
expect(cookieJar.prefixSecurity).toBe(PrefixSecurityEnum.STRICT)
expect(cookieJar.prefixSecurity).toBe(PrefixSecurity.STRICT)
})

describe('__Secure prefix', () => {
Expand Down Expand Up @@ -173,7 +173,7 @@ describe('When `prefixSecurity` is enabled for `CookieJar`', () => {
cookieJar = new CookieJar(null, {
prefixSecurity: 'unsafe-disabled',
})
expect(cookieJar.prefixSecurity).toBe(PrefixSecurityEnum.DISABLED)
expect(cookieJar.prefixSecurity).toBe(PrefixSecurity.DISABLED)
})

describe('__Secure prefix', () => {
Expand Down
26 changes: 21 additions & 5 deletions lib/cookie/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
export const PrefixSecurityEnum = Object.freeze({
SILENT: 'silent',
STRICT: 'strict',
DISABLED: 'unsafe-disabled',
})
/**
* Cookie prefixes are a way to indicate that a given cookie was set with a set of attributes simply by inspecting the
* first few characters of the cookie's name. These are defined in {@link https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.3 | RFC6265bis - Section 4.1.3}.
*
* The following values can be used to configure how a {@link CookieJar} enforces attribute restrictions for Cookie prefixes.
* @public
*/
export enum PrefixSecurity {
/**
* Enable cookie prefix checking but silently ignores the cookie if conditions are not met. This is the default configuration for a {@link CookieJar}.
*/
SILENT = 'silent',
/**
* Enables cookie prefix checking and will raise an error if conditions are not met.
*/
STRICT = 'strict',
/**
* Disables cookie prefix checking.
*/
DISABLED = 'unsafe-disabled',
}

const IP_V6_REGEX = `
\\[?(?:
Expand Down
21 changes: 10 additions & 11 deletions lib/cookie/cookieJar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import { pathMatch } from '../pathMatch'
import { Cookie } from './cookie'
import {
Callback,
ErrorCallback,
Nullable,
createPromiseCallback,
ErrorCallback,
inOperator,
Nullable,
safeToString,
} from '../utils'
import { canonicalDomain } from './canonicalDomain'
import {
IP_V6_REGEX_OBJECT,
PrefixSecurityEnum,
PrefixSecurity,
SerializedCookieJar,
} from './constants'
import { defaultPath } from './defaultPath'
Expand Down Expand Up @@ -135,23 +135,22 @@ function isHostPrefixConditionMet(cookie: Cookie): boolean {
)
}

type PrefixSecurityValue =
(typeof PrefixSecurityEnum)[keyof typeof PrefixSecurityEnum]
type PrefixSecurityValue = (typeof PrefixSecurity)[keyof typeof PrefixSecurity]
function getNormalizedPrefixSecurity(
prefixSecurity: string,
): PrefixSecurityValue {
if (prefixSecurity != null) {
const normalizedPrefixSecurity = prefixSecurity.toLowerCase()
/* The three supported options */
switch (normalizedPrefixSecurity) {
case PrefixSecurityEnum.STRICT:
case PrefixSecurityEnum.SILENT:
case PrefixSecurityEnum.DISABLED:
case PrefixSecurity.STRICT:
case PrefixSecurity.SILENT:
case PrefixSecurity.DISABLED:
return normalizedPrefixSecurity
}
}
/* Default is SILENT */
return PrefixSecurityEnum.SILENT
return PrefixSecurity.SILENT
}

export class CookieJar {
Expand Down Expand Up @@ -402,9 +401,9 @@ export class CookieJar {

/* 6265bis-02 S5.4 Steps 15 & 16 */
const ignoreErrorForPrefixSecurity =
this.prefixSecurity === PrefixSecurityEnum.SILENT
this.prefixSecurity === PrefixSecurity.SILENT
const prefixSecurityDisabled =
this.prefixSecurity === PrefixSecurityEnum.DISABLED
this.prefixSecurity === PrefixSecurity.DISABLED
/* If prefix checking is not disabled ...*/
if (!prefixSecurityDisabled) {
let errorFound = false
Expand Down
2 changes: 1 addition & 1 deletion lib/cookie/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export { ParameterError } from '../validators'
export { version } from '../version'

export { canonicalDomain } from './canonicalDomain'
export { PrefixSecurityEnum } from './constants'
export { PrefixSecurity } from './constants'
export { Cookie } from './cookie'
export { cookieCompare } from './cookieCompare'
export { CookieJar } from './cookieJar'
Expand Down
Loading

0 comments on commit a3bd39c

Please sign in to comment.