{"id":47633381,"url":"https://github.com/ngx-zen/mat-password-meter","last_synced_at":"2026-04-12T12:03:16.793Z","repository":{"id":345877810,"uuid":"1187364195","full_name":"ngx-zen/mat-password-meter","owner":"ngx-zen","description":"Three Angular Material password strength components: rule-based, entropy-based, and a combined full meter, all with a signals-based API.","archived":false,"fork":false,"pushed_at":"2026-04-01T11:23:38.000Z","size":381,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-01T13:24:06.308Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://ngx-zen.github.io/mat-password-meter/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngx-zen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-20T16:34:27.000Z","updated_at":"2026-04-01T11:20:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ngx-zen/mat-password-meter","commit_stats":null,"previous_names":["ngx-zen/mat-password-meter"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/ngx-zen/mat-password-meter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-zen%2Fmat-password-meter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-zen%2Fmat-password-meter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-zen%2Fmat-password-meter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-zen%2Fmat-password-meter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngx-zen","download_url":"https://codeload.github.com/ngx-zen/mat-password-meter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-zen%2Fmat-password-meter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-01T23:54:28.379Z","updated_at":"2026-04-12T12:03:16.785Z","avatar_url":"https://github.com/ngx-zen.png","language":"TypeScript","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Form Controls"],"readme":"# @ngx-zen/mat-password-meter\r\n\r\n[![npm](https://img.shields.io/npm/v/@ngx-zen/mat-password-meter?color=crimson\u0026logo=npm)](https://www.npmjs.com/package/@ngx-zen/mat-password-meter)\r\n[![CI](https://github.com/ngx-zen/mat-password-meter/actions/workflows/ci.yml/badge.svg)](https://github.com/ngx-zen/mat-password-meter/actions/workflows/ci.yml)\r\n[![codecov](https://codecov.io/gh/ngx-zen/mat-password-meter/branch/main/graph/badge.svg)](https://codecov.io/gh/ngx-zen/mat-password-meter)\r\n[![Known Vulnerabilities](https://snyk.io/test/npm/@ngx-zen/mat-password-meter/badge.svg)](https://snyk.io/test/npm/@ngx-zen/mat-password-meter)\r\n[![bundle size](https://badgen.net/bundlephobia/minzip/@ngx-zen/mat-password-meter)](https://bundlephobia.com/package/@ngx-zen/mat-password-meter)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\r\n\r\nThree Angular Material password strength components with a signals-based API. **[Live Demo →](https://ngx-zen.github.io/mat-password-meter/)**\r\n\r\n| Rule-based | Entropy-based |\r\n|:---:|:---:|\r\n| ![PasswordRulesComponent preview](docs/preview-rules.png) | ![PasswordAnalysisComponent preview](docs/preview-analysis.png) |\r\n\r\n- **`PasswordStrengthComponent`** — combines rule enforcement + [zxcvbn](https://github.com/dropbox/zxcvbn) entropy in two phases.\r\n- **`PasswordRulesComponent`** — policy checks only; zxcvbn is never loaded.\r\n- **`PasswordAnalysisComponent`** — zxcvbn entropy only; no policy enforcement.\r\n\r\n## Features\r\n\r\n- Three components: rules-only, entropy-only, or combined — use only what you need\r\n- Signals-based API — reactive `input()`, `output()`, and `computed()` throughout\r\n- Three feedback modes: `'contextual'` hint, `'full'` panel, or `'hidden'`\r\n- Extensible with app-specific rules via `customRules` — e.g. \"must not contain username\"\r\n- Fully customizable display strings via `messages` — tailor labels, hints, and nudges to your brand or UX\r\n- [zxcvbn](https://github.com/dropbox/zxcvbn) lazy-loaded — no bundle cost when using only `PasswordRulesComponent`\r\n- Fully themeable via CSS custom properties; adapts to light/dark themes automatically\r\n\r\n## Version compatibility\r\n\r\n| Library | Angular | Angular Material | zxcvbn |\r\n|---------|---------|------------------|--------|\r\n| `3.x` | `^21` | `^21` | `^4.4.2` |\r\n| `2.x` | `^20` | `^20` | `^4.4.2` |\r\n| `1.x` | `^19` | `^19` | `^4.4.2` |\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @ngx-zen/mat-password-meter zxcvbn\r\n```\r\n\r\n\u003e [!TIP]\r\n\u003e **Only using `PasswordRulesComponent`?** You can skip `zxcvbn` — it's not needed for that entry point.\r\n\r\n\u003e [!NOTE]\r\n\u003e Requires Angular Material with animations and a theme. See the [Angular Material getting started guide](https://material.angular.io/guide/getting-started).\r\n\r\n---\r\n\r\n## Usage\r\n\r\n```ts\r\nimport { PasswordStrengthComponent } from '@ngx-zen/mat-password-meter/strength';\r\nimport { PasswordRulesComponent }    from '@ngx-zen/mat-password-meter/rules';\r\nimport { PasswordAnalysisComponent } from '@ngx-zen/mat-password-meter/analysis';\r\n```\r\n\r\nAdd to `imports` and bind `[password]` to your form control value:\r\n\r\n```html\r\n\u003c!-- PasswordStrengthComponent --\u003e\r\n\u003cmat-password-strength [password]=\"password\" [options]=\"{ min: 12 }\" (isValid)=\"submitDisabled = !$event\" /\u003e\r\n\r\n\u003c!-- PasswordRulesComponent --\u003e\r\n\u003cmat-password-rules [password]=\"password\" [options]=\"{ min: 12, specialChar: false }\" (isValid)=\"submitDisabled = !$event\" /\u003e\r\n\r\n\u003c!-- PasswordAnalysisComponent --\u003e\r\n\u003cmat-password-analysis [password]=\"password\" [userInputs]=\"[user.name, user.email]\" (isValid)=\"submitDisabled = !$event\" /\u003e\r\n```\r\n\r\n`feedback` defaults to `'contextual'` (single inline hint). Use `feedback=\"full\"` for the progressive panel or `feedback=\"hidden\"` to hide all feedback text.\r\n\r\n---\r\n\r\n## API\r\n\r\nAll three components share the same base inputs and outputs. Differences are noted in the descriptions.\r\n\r\n**Inputs**\r\n\r\n| Input | Type | Default | Description |\r\n|-------|------|---------|-------------|\r\n| `password` | `string` | `''` | Password to evaluate |\r\n| `options` | `PasswordRuleOptions` | see below | Policy rules. Not used by `PasswordAnalysisComponent`. |\r\n| `hideStrength` | `boolean` | `true` | Hide the strength label below the bar |\r\n| `feedback` | `FeedbackMode` | `'contextual'` | `'contextual'`, `'full'`, or `'hidden'` |\r\n| `userInputs` | `string[]` | `[]` | Strings passed to zxcvbn to penalize personal info. Not used by `PasswordRulesComponent`. |\r\n| `customRules` | `CustomRulesFn` | — | App-specific policy gates. Block `isValid` and show as failing hints when violated; do not affect score. Not used by `PasswordAnalysisComponent`. |\r\n| `messages` | `PasswordMeterMessages` | see below | Override any subset of display strings |\r\n\r\n**Outputs**\r\n\r\n| Output | Type | Description |\r\n|--------|------|-------------|\r\n| `strengthChange` | `number` | Current 0–100 score on every password change |\r\n| `isValid` | `boolean` | `true` when fully satisfied (both rules + zxcvbn for `PasswordStrengthComponent`) |\r\n\r\n---\r\n\r\n## Shared types\r\n\r\n```ts\r\nimport type { PasswordRuleOptions, PasswordMeterMessages, CustomRulesFn } from '@ngx-zen/mat-password-meter';\r\n```\r\n\r\n\u003e **Types:** `PasswordRuleOptions`, `PasswordRuleCheck`, `FeedbackMode`, `ZxcvbnResult`, `PasswordMeterMessages`, `PasswordStrengthLabels`, `PasswordRuleLabels`, `DisabledOptionKey`, `CustomRulesFn`  \r\n\u003e **Constants:** `DEFAULT_PASSWORD_RULE_OPTIONS`, `DEFAULT_PASSWORD_METER_MESSAGES`  \r\n\u003e **Utilities:** `evaluateRules`, `scoreFromChecks`\r\n\r\n### `PasswordRuleOptions`\r\n\r\nAll properties optional; omitted keys fall back to defaults. Pass `false` to disable a rule (e.g. `{ specialChar: false }`).\r\n\r\n| Property | Type | Default |\r\n|----------|------|---------|\r\n| `min` | `number` | `8` |\r\n| `lowercase` | `boolean` | `true` |\r\n| `uppercase` | `boolean` | `true` |\r\n| `number` | `boolean` | `true` |\r\n| `specialChar` | `boolean` | `true` |\r\n\r\n### `PasswordMeterMessages`\r\n\r\nAll properties optional; omitted keys fall back to defaults. For string keys, pass `''` to suppress that message entirely. Not all keys apply to every component.\r\n\r\n| Property | Type | Default | Description |\r\n|----------|------|---------|-------------|\r\n| `looksGreat` | `string` | `'Looks great!'` | Shown when strength is perfect |\r\n| `nudge` | `string` | `'Make it harder to guess.'` | Shown when zxcvbn score \u003c 4 with no warning or suggestions. Not used by `PasswordRulesComponent`. |\r\n| `disabledNudge` | `(missingKeys: DisabledOptionKey[]) =\u003e string` | — | Replaces the auto-generated disabled-options nudge. Not used by `PasswordRulesComponent`. Receives the keys of disabled composition options whose character classes are missing (e.g. `['uppercase', 'number']`). Return `''` to suppress. |\r\n| `strengthLabels` | `PasswordStrengthLabels` | `{}` | Override the strength level labels below the bar |\r\n| `ruleLabels` | `PasswordRuleLabels` | `{}` | Override the per-rule checklist labels. Not used by `PasswordAnalysisComponent`. |\r\n\r\n**Example** — customizing display strings to match your app's tone:\r\n```ts\r\nreadonly messages: PasswordMeterMessages = {\r\n  looksGreat: 'Excellent!',\r\n  nudge: 'Try making it harder to guess.',\r\n  // Replace the default \"Try adding …\" nudge, or return '' to suppress\r\n  disabledNudge: (keys) =\u003e `Consider adding ${keys.join(' or ')} for extra security.`,\r\n  strengthLabels: { veryWeak: 'Too simple', veryStrong: 'Excellent' },\r\n  ruleLabels: { minLength: (n) =\u003e `Use at least ${n} characters` },\r\n};\r\n```\r\n```html\r\n\u003cmat-password-strength [password]=\"password\" [messages]=\"messages\" /\u003e\r\n```\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003ccode\u003ePasswordStrengthLabels\u003c/code\u003e\u003c/summary\u003e\r\n\r\n| Key | Default |\r\n|-----|---------|\r\n| `veryWeak` | `'Very Weak'` |\r\n| `weak` | `'Weak'` |\r\n| `fair` | `'Fair'` |\r\n| `good` | `'Good'` |\r\n| `strong` | `'Strong'` |\r\n| `veryStrong` | `'Very Strong'` |\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003ccode\u003ePasswordRuleLabels\u003c/code\u003e\u003c/summary\u003e\r\n\r\n| Key | Default |\r\n|-----|---------|\r\n| `minLength` | `` `At least ${n} characters` `` (also accepts `(n: number) =\u003e string`) |\r\n| `lowercase` | `'At least 1 lowercase letter'` |\r\n| `uppercase` | `'At least 1 uppercase letter'` |\r\n| `number` | `'At least 1 number'` |\r\n| `specialChar` | `'At least 1 special character'` |\r\n\r\n\u003c/details\u003e\r\n\r\n---\r\n\r\n## Configuration\r\n\r\n### Custom rules\r\n\r\nUse the `customRules` input to add app-specific checks (e.g. \"must not contain username\"). Custom rules act as **gates** — they block `isValid` and appear as failing hints when violated, but they do **not** affect the strength score. The progress bar color switches to `warn` while any custom rule fails, even if the strength score is 100%. Only failing custom rules are shown; passing ones are hidden.\r\n\r\n```ts\r\nimport type { CustomRulesFn } from '@ngx-zen/mat-password-meter';\r\n\r\nreadonly customRules: CustomRulesFn = (password) =\u003e [\r\n  { label: 'Must not contain username', passed: !password.includes(this.username) },\r\n  { label: 'Must not match a previous password', passed: !this.previousPasswords.includes(password) },\r\n];\r\n```\r\n\r\n```html\r\n\u003cmat-password-strength [password]=\"password\" [customRules]=\"customRules\" /\u003e\r\n\u003cmat-password-rules    [password]=\"password\" [customRules]=\"customRules\" /\u003e\r\n```\r\n\r\n\u003e `customRules` is not used by `PasswordAnalysisComponent` — it has no rule phase.\r\n\r\n### NIST alignment\r\n\r\n[NIST SP 800-63B](https://pages.nist.gov/800-63-4/sp800-63b.html#passwordver) recommends **against** composition rules (mixed case, digits, special characters) and instead favors a longer minimum length. You can opt in to a NIST-aligned configuration with `PasswordStrengthComponent`:\r\n\r\n```ts\r\nconst NIST_OPTIONS: PasswordRuleOptions = {\r\n  min: 15,\r\n  lowercase: false,\r\n  uppercase: false,\r\n  number: false,\r\n  specialChar: false,\r\n};\r\n```\r\n\r\n```html\r\n\u003cmat-password-strength [password]=\"password\" [options]=\"NIST_OPTIONS\" /\u003e\r\n```\r\n\r\nWith all composition rules disabled, only `min` is enforced. `PasswordStrengthComponent` will still evaluate entropy via zxcvbn and may show a contextual nudge (e.g. *\"→ Try adding uppercase letters…\"*) when the score is low. This also applies to `PasswordAnalysisComponent`. Customize or suppress the nudge via the `disabledNudge` callback in `messages`.\r\n\r\n\u003e [!WARNING]\r\n\u003e This configuration is not recommended for `PasswordRulesComponent`, which has no zxcvbn phase — it would reduce to a minimum-length check with no quality feedback.\r\n\r\n---\r\n\r\n## Direct signal access\r\n\r\nPublic computed signals accessible via `viewChild`:\r\n\r\n| Component | Signals |\r\n|-----------|--------|\r\n| `PasswordStrengthComponent` | `strength`, `ruleChecks`, `customRuleChecks`, `zxcvbnResult`, `mergedHint`, `color`, `strengthLabel` |\r\n| `PasswordRulesComponent` | `strength`, `ruleChecks`, `customRuleChecks`, `contextualHint`, `color`, `strengthLabel` |\r\n| `PasswordAnalysisComponent` | `strength`, `zxcvbnResult`, `color`, `strengthLabel` |\r\n\r\n```ts\r\nreadonly meter = viewChild(PasswordStrengthComponent);\r\n\r\nprotected readonly isValid   = computed(() =\u003e this.meter()?.strength() === 100);\r\nprotected readonly firstFail = computed(() =\u003e this.meter()?.ruleChecks().find(r =\u003e !r.passed)?.label);\r\n```\r\n\r\n---\r\n\r\n## Theming\r\n\r\nComponents adapt to light/dark themes via Angular Material design tokens (`--mat-sys-*`). Override colors via CSS custom properties:\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003eAvailable CSS custom properties\u003c/summary\u003e\r\n\r\n```css\r\nmat-password-rules,\r\nmat-password-analysis,\r\nmat-password-strength {\r\n  /* Progress bar colors */\r\n  --pm-weak-color:      #e53935;\r\n  --pm-medium-color:    #fdd835;\r\n  --pm-strong-color:    #43a047;\r\n  --pm-buffer-color:    #888888;\r\n\r\n  /* Text colors */\r\n  --pm-rule-pass-color: light-dark(#2e9244, #66bb6a);\r\n  --pm-rule-fail-color: light-dark(#d32f2f, #ef5350);\r\n  --pm-warning-color:   light-dark(#7a6000, #c9a200);\r\n  --pm-secondary-text:  light-dark(#555, #aaa);\r\n}\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n---\r\n\r\n## Acknowledgments\r\n\r\nInspired by [`angular-material-extensions/password-strength`](https://github.com/angular-material-extensions/password-strength).  \r\nNIST alignment guidance suggested by [u/JimTheEarthling](https://www.reddit.com/user/JimTheEarthling) on Reddit.\r\n\r\n## Contributing · Changelog · License\r\n\r\n[CONTRIBUTING.md](CONTRIBUTING.md) · [CHANGELOG.md](CHANGELOG.md) · [MIT](LICENSE)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngx-zen%2Fmat-password-meter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngx-zen%2Fmat-password-meter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngx-zen%2Fmat-password-meter/lists"}