UNPKG

cumulocity-cypress

Version:
271 lines (270 loc) 10.2 kB
import { C8yPact, C8yPactRecord } from "./c8ypact"; /** * Interface for a preprocessor to apply transformations to `C8yPact` records * before critical operations such as matching or saving. A preprocessor can be used to * unify records by removing or obfuscating sensitive data, picking only certain keys to keep, * or applying regex substitutions to values. Preprocessors operate in-place on the * given object, which can be a full `C8yPact`, an individual `C8yPactRecord`, or a * plain object such as `Cypress.Response`. * * The default implementation is `C8yDefaultPactPreprocessor`, which supports the * operations and key-path syntax described in `C8yPactPreprocessorOptions`. * * See {@link C8yDefaultPactPreprocessor} for default implementation. * */ export interface C8yPactPreprocessor { /** * Configuration options used by the preprocessor. */ readonly options?: C8yPactPreprocessorOptions; /** * Applies the preprocessor options (rules) to the given object in-place. * * When `obj` is a `C8yPact` (i.e. contains a `records` array), all records * are processed individually. For a plain object, including `Cypress.Response` * or `C8yPactRecord`, the object itself is processed. * * Operations are applied in this sequence: * 1. **pick** — remove any keys not listed * 2. **obfuscate** — replace values with the obfuscation pattern * 3. **regexReplace** — apply regex substitutions * 4. **ignore** — delete values entirely * * @param obj Object to preprocess. Modified in place. * @param options Options that override the instance-level options for this * single call. */ apply: (obj: Partial<Cypress.Response<any> | C8yPactRecord | C8yPact>, options?: C8yPactPreprocessorOptions) => void; } /** * Configuration options for `C8yPactPreprocessor`. * * All key-path strings support: * - Dot-separated segments: `response.body.password` * - Bracket / numeric-index notation: `response.body.items[0].token` * - Array fan-out: `response.body.users.password` (applied to every element) * - Recursive descent: `response.body..password` (any depth below `body`) * * Key resolution is case-insensitive when `ignoreCase` is `true` (default). */ export interface C8yPactPreprocessorOptions { /** * Key paths whose values should be replaced with `obfuscationPattern`. * * For `Authorization` headers whose value begins with `Bearer` or `Basic`, * the scheme prefix is kept and only the credential token is replaced, e.g. * `Bearer ****`. * * Cookie values can be targeted by appending the cookie name as an extra * segment: `request.headers.cookie.XSRF-TOKEN`. * * @example * obfuscate: [ * "response.body.password", * "request.headers.authorization", * "response.body.users.password", // every user object * "response.body..token", // any depth * ] */ obfuscate?: string[]; /** * Key paths whose values should be deleted entirely from the record. * * Cookie values can be targeted by appending the cookie name as an extra * segment: `request.headers.cookie.XSRF-TOKEN`. * * @example * ignore: [ * "request.headers.accept-encoding", * "response.headers.cache-control", * "response.body..internalDebugField", // any depth * ] */ ignore?: string[]; /** * Restricts which child keys are retained under the specified parent paths. * All other sibling keys are removed. * * Two forms are accepted: * * **Object form** — maps a parent key path to an array of child keys to keep: * ```ts * pick: { * "response.headers": ["content-type", "location"], * "request.headers": ["authorization"] * } * ``` * * **Array form** — keeps only the listed top-level keys of the record: * ```ts * pick: ["request", "response"] * ``` */ pick?: { [key: string]: string[]; } | string[]; /** * Applies one or more regex substitutions to the value at the given key path. * * The key is a key path (same syntax as `obfuscate` / `ignore`). The value * is a single regex string or an ordered array of regex strings applied in * sequence. Each regex string must use the format: * ``` * /pattern/replacement/flags * ``` * Capture groups (`$1`, `$2`, …) and all standard JS regex flags are * supported. * * @example * // Redact all but the first four characters of a token: * // key: "response.body.token" * // value: "/^(.{4}).+$/$1----/" * // * // Normalise a date field, then strip milliseconds in sequence: * // key: "response.body.timestamp" * // value: ["/T\\d{2}:\\d{2}:\\d{2}/THH:MM:SS/", "/\\.\\d+Z$/Z/"] */ regexReplace?: { [key: string]: string | string[]; }; /** * Replacement string used by the `obfuscate` operation. * Defaults to `"****"`. */ obfuscationPattern?: string; /** * When `true` (default), key segments are matched case-insensitively at * every level of the path. The actual casing of the key found in the object * is always used for mutations — the original structure is never changed. */ ignoreCase?: boolean; } /** * Default options for `C8yPactPreprocessor`. Used when constructing an instance * without custom options, and as fallback for missing properties when applying * with partial options. */ export declare const C8yPactPreprocessorDefaultOptions: { ignore: string[]; obfuscate: string[]; obfuscationPattern: string; ignoreCase: boolean; }; /** * Preprocessor for `C8yPact` objects. A preprocessor is applied when a pact * record is **saved** (recording mode) and before it is applied (matched) * against any other record. This is used to unify records before they are * **matched**. A preprocessor transforms objects such as `Cypress.Response`, * `C8yPactRecord` or a full `C8yPact` in-place. It supports various operations * to remove or obfuscate sensitive data, or to pick only certain keys to keep. * * The default implementation is `C8yDefaultPactPreprocessor`. * * ### Supported operations (configured via `C8yPactPreprocessorOptions`) * * | Option | Effect | * |---|---| * | `ignore` | Removes the value at each key path | * | `obfuscate` | Replaces the value at each key path with `obfuscationPattern` | * | `pick` | Keeps only the specified child keys; removes all others | * | `regexReplace` | Applies one or more `/pattern/replacement/flags` expressions | * * ### Key-path syntax * * All key paths use dot-separated segments. Bracket notation and numeric array * indices are supported: * ``` * response.body.password * response.body.items[0].token * response.body.items.0.token * ``` * When a path segment resolves to an **array of objects** and the next segment * is *not* a numeric index, the operation fans out to every element: * ``` * response.body.users.password // applied to every object in `users` * ``` * * ### Recursive-descent operator (`..`) * * Prefix a leaf key with `..` to match it at **any depth** below the optional * prefix path: * ``` * ..password // `password` anywhere in the record * response.body..password // `password` anywhere inside `body` * ``` * * ### Case-insensitive matching * * When `ignoreCase` is `true` (the default), each path segment is resolved * without regard to capitalization. Mutations always use the actual key name * found in the object. * * ### Cookie / Set-Cookie shorthand * * Preprocessors automatically parse `Cookie` and `Set-Cookie` header strings and * apply obfuscation or ignoring to individual cookie values when the key path * is appended with the cookie name as an extra segment: * * ``` * request.headers.cookie.XSRF-TOKEN * response.headers.set-cookie.authorization * ``` * * ### Authorization-header obfuscation * * When obfuscating an `Authorization` header whose value starts with `Bearer` * or `Basic`, the scheme prefix is preserved and only the credential is * replaced: * ``` * Bearer ******** * Basic ******** * ``` */ export declare class C8yDefaultPactPreprocessor implements C8yPactPreprocessor { static defaultObfuscationPattern: string; options?: C8yPactPreprocessorOptions; protected reservedKeys: string[]; constructor(options?: C8yPactPreprocessorOptions); /** {@inheritDoc C8yPactPreprocessor.apply} */ apply(obj: Partial<Cypress.Response<any> | C8yPactRecord | C8yPact>, options?: C8yPactPreprocessorOptions): void; private filterObjectByKeepPaths; private applyKeepArray; private removeKey; private removeSetCookie; private removeCookie; private filterValidKeys; /** * Unified key-path traversal. Calls `fn(parent, resolvedKey)` on every * matching leaf. Handles recursive descent (`..leafKey` / `prefix..leafKey`) * and regular dot-/bracket-separated paths including array indices. */ private traverseKeyPath; /** * Applies a list of regex-replace patterns to the value at the given key path. */ private applyRegexReplace; /** * Recursively walks `obj` (depth-first) and calls `fn` on every node whose * key matches `leafKey` (case-sensitively, or case-insensitively when * `ignoreCase` is true). Traverses into arrays and plain objects. */ private applyRecursive; private obfuscateKey; private obfuscateSetCookie; private obfuscateCookie; protected resolveOptions(options?: Partial<C8yPactPreprocessorOptions>): C8yPactPreprocessorOptions; private hasKey; private getCookieObject; } export declare function parseRegexReplace(input: string): { pattern: RegExp; replacement: string; }; export declare function performRegexReplace(input: string | any, regexes: { pattern: RegExp; replacement: string; }[] | { pattern: RegExp; replacement: string; }): string | any;