RFC6265 Cookies and Cookie Jar for node.js
—
Domain validation, path matching, date parsing, and other RFC 6265-compliant utility functions for cookie processing including public suffix handling and canonicalization.
Functions for domain validation, canonicalization, and matching per RFC 6265 requirements.
/**
* Transforms a domain name into canonical form (trimmed, lowercased, punycode-encoded)
* @param domainName - Domain name to canonicalize
* @returns Canonical domain string or undefined if invalid
*/
function canonicalDomain(domainName: string | null): string | undefined;
/**
* Tests if a domain matches a cookie domain per RFC 6265 Section 5.1.3
* @param domain - Request domain to test
* @param cookieDomain - Cookie's domain attribute
* @param canonicalize - Whether to canonicalize domains first (default: true)
* @returns True if domain matches cookie domain, undefined if either is invalid
*/
function domainMatch(
domain?: string | null,
cookieDomain?: string | null,
canonicalize?: boolean
): boolean | undefined;
/**
* Generates all possible domain permutations for cookie matching (shortest to longest)
* @param domain - Domain to generate permutations for
* @param allowSpecialUseDomain - Whether to allow special use domains
* @returns Array of domain permutations or undefined if invalid
*/
function permuteDomain(domain: string, allowSpecialUseDomain?: boolean): string[] | undefined;
/**
* Returns the public suffix (shortest domain for cookie setting) using the Public Suffix List
* @param domain - Domain to get public suffix for
* @param options - Options controlling suffix resolution
* @returns Public suffix or undefined if not found
*/
function getPublicSuffix(domain: string, options?: GetPublicSuffixOptions): string | undefined;
interface GetPublicSuffixOptions {
allowSpecialUseDomain?: boolean; // Default: false
ignoreError?: boolean; // Default: false
}Usage Examples:
import {
canonicalDomain,
domainMatch,
permuteDomain,
getPublicSuffix
} from "tough-cookie";
// Canonicalize domains
const canonical = canonicalDomain(" Example.COM ");
console.log(canonical); // "example.com"
const punycoded = canonicalDomain("münchen.de");
console.log(punycoded); // "xn--mnchen-3ya.de"
// Test domain matching
const matches = domainMatch("sub.example.com", "example.com");
console.log(matches); // true
const exactMatch = domainMatch("example.com", "example.com");
console.log(exactMatch); // true
const noMatch = domainMatch("other.com", "example.com");
console.log(noMatch); // false
// Generate domain permutations
const permutations = permuteDomain("a.b.c.example.com");
console.log(permutations);
// ["example.com", "c.example.com", "b.c.example.com", "a.b.c.example.com"]
// Get public suffix
const suffix = getPublicSuffix("subdomain.example.co.uk");
console.log(suffix); // "co.uk"
const comSuffix = getPublicSuffix("example.com");
console.log(comSuffix); // "com"Functions for path matching and default path computation according to RFC 6265.
/**
* Tests if request path matches cookie path per RFC 6265 Section 5.1.4
* @param reqPath - Request path to test
* @param cookiePath - Cookie's path attribute
* @returns True if paths match according to RFC rules
*/
function pathMatch(reqPath: string, cookiePath: string): boolean;
/**
* Computes default cookie path from request path per RFC 6265 Section 5.1.4
* @param path - Request path to compute default from
* @returns Default path for cookies (always starts with '/')
*/
function defaultPath(path?: string | null): string;
/**
* Generates all possible path permutations for cookie matching (longest to shortest)
* @param path - Path to generate permutations for
* @returns Array of path permutations
*/
function permutePath(path: string): string[];Usage Examples:
import { pathMatch, defaultPath, permutePath } from "tough-cookie";
// Test path matching
console.log(pathMatch("/app/page", "/app")); // true
console.log(pathMatch("/app/page", "/app/")); // true
console.log(pathMatch("/app", "/app/page")); // false
console.log(pathMatch("/app/page", "/")); // true
// Compute default paths
console.log(defaultPath("/app/page.html")); // "/app"
console.log(defaultPath("/app/")); // "/app"
console.log(defaultPath("/")); // "/"
console.log(defaultPath("")); // "/"
console.log(defaultPath(null)); // "/"
// Generate path permutations
const pathPermutations = permutePath("/app/admin/users");
console.log(pathPermutations);
// ["/app/admin/users", "/app/admin", "/app", "/"]
const rootPermutations = permutePath("/");
console.log(rootPermutations); // ["/"]Functions for parsing and formatting cookie dates according to RFC 6265 specifications.
/**
* Parses cookie date string per RFC 6265 Section 5.1.1 (not Date.parse())
* Uses RFC-compliant parsing algorithm that handles various date formats
* @param cookieDate - Date string from cookie expires attribute
* @returns Parsed Date object or undefined if invalid
*/
function parseDate(cookieDate: string | null): Date | undefined;
/**
* Formats Date to RFC 822/1123 format for cookie headers
* @param date - Date object to format
* @returns RFC-compliant date string
*/
function formatDate(date: Date): string;Usage Examples:
import { parseDate, formatDate } from "tough-cookie";
// Parse various cookie date formats
const date1 = parseDate("Tue, 19 Jan 2038 03:14:07 GMT");
console.log(date1); // Valid Date object
const date2 = parseDate("Tuesday, 19-Jan-38 03:14:07 GMT");
console.log(date2); // Valid Date object (RFC 850 format)
const date3 = parseDate("Tue Jan 19 03:14:07 2038");
console.log(date3); // Valid Date object (asctime format)
// Invalid formats return undefined
const invalid = parseDate("not a date");
console.log(invalid); // undefined
const nullDate = parseDate(null);
console.log(nullDate); // undefined
// Format dates for cookie headers
const now = new Date();
const formatted = formatDate(now);
console.log(formatted); // "Wed, 07 Sep 2025 12:34:56 GMT"
// Format specific date
const specificDate = new Date("2025-12-25T00:00:00Z");
const christmasFormatted = formatDate(specificDate);
console.log(christmasFormatted); // "Thu, 25 Dec 2025 00:00:00 GMT"Error class for parameter validation failures in tough-cookie operations.
/**
* Error class for parameter validation failures
* @public
*/
class ParameterError extends Error {}Usage Examples:
import { ParameterError } from "tough-cookie";
try {
// Some operation that might throw ParameterError
} catch (error) {
if (error instanceof ParameterError) {
console.log('Parameter validation failed:', error.message);
}
}Cookie-related constants and configuration values.
/**
* Cookie prefix security enforcement levels
*/
const PrefixSecurityEnum = {
SILENT: 'silent', // Silently ignore violations (default)
STRICT: 'strict', // Throw errors on violations
DISABLED: 'unsafe-disabled', // Disable prefix checking
} as const;
/**
* The version of tough-cookie library
*/
const version: string; // Currently "6.0.0"Usage Examples:
import { PrefixSecurityEnum, version } from "tough-cookie";
console.log(version); // "6.0.0"
// Use prefix security constants
const jarOptions = {
prefixSecurity: PrefixSecurityEnum.STRICT,
rejectPublicSuffixes: true
};
console.log(PrefixSecurityEnum.SILENT); // "silent"
console.log(PrefixSecurityEnum.STRICT); // "strict"
console.log(PrefixSecurityEnum.DISABLED); // "unsafe-disabled"import {
canonicalDomain,
domainMatch,
permuteDomain,
getPublicSuffix
} from "tough-cookie";
function processCookieDomain(requestDomain: string, cookieDomain?: string) {
// Canonicalize the request domain
const canonical = canonicalDomain(requestDomain);
if (!canonical) {
throw new Error(`Invalid request domain: ${requestDomain}`);
}
// If no cookie domain specified, use request domain
if (!cookieDomain) {
return {
canonical,
isHostOnly: true,
permutations: [canonical]
};
}
// Canonicalize cookie domain
const cookieCanonical = canonicalDomain(cookieDomain);
if (!cookieCanonical) {
throw new Error(`Invalid cookie domain: ${cookieDomain}`);
}
// Check if request domain matches cookie domain
const matches = domainMatch(canonical, cookieCanonical);
if (!matches) {
throw new Error(`Domain ${canonical} does not match cookie domain ${cookieCanonical}`);
}
// Get public suffix to ensure cookie isn't too broad
const publicSuffix = getPublicSuffix(cookieCanonical);
if (publicSuffix === cookieCanonical) {
throw new Error(`Cannot set cookie on public suffix: ${cookieCanonical}`);
}
// Generate domain permutations for matching
const permutations = permuteDomain(cookieCanonical);
return {
canonical: cookieCanonical,
isHostOnly: false,
permutations: permutations || [cookieCanonical],
publicSuffix
};
}
// Example usage
const result = processCookieDomain("sub.example.com", "example.com");
console.log(result);
// {
// canonical: "example.com",
// isHostOnly: false,
// permutations: ["example.com"],
// publicSuffix: "com"
// }import { pathMatch, defaultPath, permutePath } from "tough-cookie";
function processRequestPath(requestPath: string, cookiePath?: string) {
// Normalize request path
const normalizedRequest = requestPath || '/';
// Determine effective cookie path
const effectivePath = cookiePath || defaultPath(normalizedRequest);
// Validate path match
const matches = pathMatch(normalizedRequest, effectivePath);
if (!matches) {
return null; // Cookie doesn't apply to this request
}
// Generate path permutations for cookie lookup
const permutations = permutePath(normalizedRequest);
return {
requestPath: normalizedRequest,
cookiePath: effectivePath,
pathPermutations: permutations,
isDefault: !cookiePath
};
}
// Example usage
const pathInfo = processRequestPath("/app/admin/users", "/app");
console.log(pathInfo);
// {
// requestPath: "/app/admin/users",
// cookiePath: "/app",
// pathPermutations: ["/app/admin/users", "/app/admin", "/app", "/"],
// isDefault: false
// }interface Callback<T> {
(error: Error, result?: never): void;
(error: null, result: T): void;
}
type Nullable<T> = T | null | undefined;Install with Tessl CLI
npx tessl i tessl/npm-tough-cookie