Files
skills/docs/security-stack/security/password-strength/src/matchers/regex/regex.md
2026-05-29 08:20:56 +01:00

2.8 KiB

regex — regex pattern matcher

(no submodules)

Purpose

Recognises substrings matching a set of regex patterns per Wheeler 2016 section 3.6. The default registry covers a recent_year pattern matching 19xx and 20xx. Callers extend the registry to flag additional patterns (hex strings, phone-number shapes, project-specific identifiers) without forking the scorer.

Features

  • Default recent_year regex matches 19xx and 20xx
  • Registry-pluggable: callers can register their own named regexes
  • Global-flag enforced internally so every occurrence is reported
  • Every match carries the full RegExpMatchArray for downstream inspection

Usage: Basic Example

import { regexMatch } from "@suaveplan/password-strength/matchers/regex";

const matches = regexMatch("login1985");
console.log(matches[0].regexName); // "recent_year"
console.log(matches[0].token); // "1985"

Usage: Advanced Example

import { regexMatch } from "@suaveplan/password-strength/matchers/regex";

const matches = regexMatch("token=ABCDEF", { regexes: { hex: /[0-9A-F]+/g } });
for (const m of matches) {
 console.log(m.regexName, m.token);
}

API Reference

  • regexMatch(password: string, opts?: RegexMatchOptions): RegexMatch[]
    • opts.regexes: Record<string, RegExp> — the registry. Defaults to DEFAULT_REGEXES.
  • DEFAULT_REGEXES: Readonly<Record<string, RegExp>> — frozen default registry (currently recent_year).
  • RegexMatchOptions: { regexes?: Record<string, RegExp> }

Implementation Notes

The matcher copies each registered regex with the g flag forced on so a global walk over the password emits every occurrence. The walk uses String.prototype.matchAll rather than mutating lastIndex so zero-width matches do not loop. The full RegExpMatchArray is preserved on each output record so callers can read capture groups when their regex uses them.

Additional Implementation Notes

The implementation follows the canonical zxcvbn algorithm from Wheeler 2016 with the suaveplan-style additions described in the package proposal: structured error codes via the defineCodes registry, Zod boundaries at every public entry point, OTel histograms and counters keyed to low-cardinality attributes, and a strict input-length guard at 200 characters. Consumers integrate with their existing observability stack by installing a meter provider before importing the package, and with their i18n stack via the MessageResolver callback type declared in @suaveplan/types. The bundled data tables are intentionally small to keep the package bundle compact; production deployments should swap in fuller frequency-ranked tables via loadDictionaries. The default English dictionary set is a frozen DictionarySet that the matcher never mutates; caller-supplied dictionaries override defaults by name.