Skip to content

Commit

Permalink
docs(project): improve and cleanup documentation (#285)
Browse files Browse the repository at this point in the history
* docs(project): improve and cleanup documentation

* docs(project): improve and cleanup documentation
  • Loading branch information
MrWook authored Jan 2, 2025
1 parent f27cd20 commit 39de4ad
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 73 deletions.
4 changes: 2 additions & 2 deletions docs/.vuepress/nav.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// @ts-ignore
import pkg from '../../package.json'
import { NavbarItem } from '@vuepress/theme-default/lib/shared/nav'
import { AutoLinkOptions } from '@vuepress/theme-default/lib/shared/nav'

export const navbar: NavbarItem[] = [
export const navbar: AutoLinkOptions[] = [
{
text: 'Guide',
link: '/guide/',
Expand Down
24 changes: 14 additions & 10 deletions docs/.vuepress/sidebar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SidebarGroupCollapsible } from '@vuepress/theme-default/lib/shared/nav'
import { SidebarGroupOptions } from '@vuepress/theme-default/lib/shared/sidebar'

export const sidebar: SidebarGroupCollapsible[] = [
export const sidebar: SidebarGroupOptions[] = [
{
text: 'Guide',
collapsible: false,
Expand All @@ -14,8 +14,12 @@ export const sidebar: SidebarGroupCollapsible[] = [
link: '/guide/getting-started/',
},
{
text: 'Migration',
link: '/guide/migration/',
text: 'Examples',
link: '/guide/examples/',
},
{
text: 'Best Practices',
link: '/guide/best-practices/',
},
{
text: 'Comparison',
Expand All @@ -25,6 +29,10 @@ export const sidebar: SidebarGroupCollapsible[] = [
text: 'Languages',
link: '/guide/languages/',
},
{
text: 'Filtering custom words',
link: '/guide/filtering-custom-words/',
},
{
text: 'Lazy loading',
link: '/guide/lazy-loading/',
Expand All @@ -37,17 +45,13 @@ export const sidebar: SidebarGroupCollapsible[] = [
text: 'Options',
link: '/guide/options/',
},
{
text: 'User input',
link: '/guide/user-input/',
},
{
text: 'Framework examples',
link: '/guide/framework-examples/',
},
{
text: 'Examples',
link: '/guide/examples/',
text: 'Migration',
link: '/guide/migration/',
},
],
},
Expand Down
23 changes: 23 additions & 0 deletions docs/guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,26 @@ Thanks to the original creators [dropbox](https://github.com/dropbox) for their
**zxcvbn** operates below human perception of delay for most input: ~5-20ms for ~25 character passwords on modern browsers/CPUs, ~100ms for passwords around 100 characters.
To curb runtime latency for really long passwords, consider sending `zxcvbn.check()` only the first 100 characters or so of user input.
For security reasons a limit was implemented for 256 characters by default but can be customized it with `maxLength`.


## Change prior to original library

- I18n support for feedback, dictionaries and keyboard patterns. By default, the feedback are keys now
- All dictionaries are optional, but the `en` dictionary is highly recommend (wished feature in some issues)
- Dictionaries are separate from the core library. This means zxcvbn-ts is relatively small without its dictionaries
- compress dictionaries for smaller bundle size => up to 33% smaller dictionaries while having more entries
- The project is a monorepo with a core library `@zxcvbn-ts/core` and language packages `@txcvbn-ts/language-en`.
- Keyboard layouts can be customised. This means you can overwrite the default set of layouts with your own or extend it.
E.g., if you are developing a Russian website, you need to include a Cyrillic keyboard set. Create a PR so that others can benefit from it.
- You can use multiple keyboard layouts, which means that the library will check against them by default.
- the tests are Jest based, so we get a coverage score
- eslint/prettier for consistent code style
- Added static page docs https://zxcvbn-ts.github.io/zxcvbn/
- esm, commonJS
- Custom matcher can be added which means you can create your own matcher
- Async matcher can be added which means you can create a matcher that makes an API call
- [haveibeenpwned](https://haveibeenpwned.com/Passwords) matcher
- included debounce helper
- levenshtein check for the dictionaries
- diceware dictionary
- extended l33t matcher for substitutions like `|_| => u`
62 changes: 62 additions & 0 deletions docs/guide/best-practices/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Best Practices
For optimal scoring results, we recommend always including both the common and English language packages. If a language package is available for your specific language, import that as well. If your language is missing, feel free to contribute by opening a pull request (PR). In the meantime, you can extend the default set.

## Language Dictionaries
To achieve robust password strength scoring, we suggest using the dictionaries for English, common words, and the user’s language (if available). These dictionaries ensure that passwords are compared against a comprehensive set of words for more accurate scoring.

## Levenshtein Distance
Enable the Levenshtein distance calculation to better identify variations of words within dictionaries. This helps catch slight modifications to common words that might otherwise go undetected (e.g., password vs. p@ssw0rd).

## Pwned Password Matcher
The Pwned Matcher should be used to check passwords against databases of leaked or compromised passwords. This informs users if their password has already been exposed in previous data breaches.

## User Input Context
Incorporate a user inputs dictionary to check passwords against personal information, such as the user's name, email address, or other relevant data. Additionally, include application-specific context where the password is being used. For instance, if the application relates to animals, you can add relevant keywords (e.g., "dog," "cat," "pet") to the dictionary for more effective matching. Custom dictionaries can be as large as needed; for instance, the password dictionary alone can reach nearly 400 KB in size.

## Lazy Loading
Since language dictionaries can be large, they should only be loaded when necessary—specifically, when a user navigates to a page with a password input field. Use lazy loading techniques to minimize unnecessary data usage and improve performance.

## Example Implementation
When following all the best practices, your implementation might look something like this:

```typescript
import { ZxcvbnFactory } from '@zxcvbn-ts/core'
import { matcherPwnedFactory } from '@zxcvbn-ts/matcher-pwned'

const loadOptions = async () => {
// common has some dictionaries which are not bound the any real language like a password list
const zxcvbnCommonPackage = await import(
/* webpackChunkName: "zxcvbnCommonPackage" */ '@zxcvbn-ts/language-common'
)
// As english is the language of the world it should always be included
const zxcvbnEnPackage = await import(
/* webpackChunkName: "zxcvbnEnPackage" */ '@zxcvbn-ts/language-en'
)
// The primary language of your website should align with the language predominantly used by your user base.
const zxcvbnDePackage = await import(
/* webpackChunkName: "zxcvbnDePackage" */ '@zxcvbn-ts/language-de'
)

return {
translations: zxcvbnePackage.translations,
graphs: zxcvbnCommonPackage.adjacencyGraphs,
dictionary: {
...zxcvbnCommonPackage.dictionary,
...zxcvbnEnPackage.dictionary,
...zxcvbnDePackage.dictionary
// Enhance the dictionary search by adding custom-defined keywords to a personalized dictionary, enabling seamless and consistent searches for application-wide terms.
userInputs: ['MrWook', 'zxcvbn-ts', 'vuepress', 'npm', 'github', 'typescript']
},
useLevenshtein: true,
}
}

const customMatcher = {
pwned: matcherPwnedFactory(fetch)
}
const options = await loadOptions()
const zxcvbn = new ZxcvbnFactory(options, customMatcher)

zxcvbn.checkAsync('thePasswordInUse', ['username', 'user email', 'other dynamic user content'])
```

40 changes: 40 additions & 0 deletions docs/guide/filtering-custom-words/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Filtering custom words
Zxcvbn-ts comes with pre-built dictionaries for various languages. However, it’s often beneficial to extend these dictionaries with custom entries specific to your application. Custom dictionaries can help improve password strength by identifying unique terms relevant to your user base.

The dictionary is provided as a Record<string, string[]>, which allows you to add key-value pairs, where the key is a custom label, and the value is an array of strings. You can extend this object as needed.

## UserInput

In many cases, you may want to check if a password matches any user-specific content, such as their username or email address. For this purpose, you can add a userInputs dictionary along with its own sanitizer.

```js
import { ZxcvbnFactory } from '@zxcvbn-ts/core'

const password = 'somePassword'
const options = {
dictionary: {
userInputs: ['[email protected]', 'someUsername'],
},
}
const zxcvbn = new ZxcvbnFactory(options)
zxcvbn.check(password)
```

If you need to dynamically add user inputs (e.g., during user registration when they enter their name, email, etc.), you can pass the user inputs as the second argument to the check method.
```js
import { ZxcvbnFactory } from '@zxcvbn-ts/core'

const password = 'somePassword'

const zxcvbn = new ZxcvbnFactory()
zxcvbn.check(password, ['[email protected]', 'someUsername'])
```
This is especially useful during registration when the user provides personal information that should not be included in their password.

## Handling Duplicate Entries in Dictionaries
If you have large dictionaries and are unsure whether some entries overlap, don't worry. The algorithm will automatically prioritize the first match it finds for any word present in multiple dictionaries, ensuring efficient processing.

## Performance of large dictionaries
The recommended dictionaries in Zxcvbn-ts already contain over 100,000 words, and even with these large dictionaries, the algorithm performs efficiently, processing results in under 100ms.

While using large dictionaries can seem like it may slow down the process, the library is optimized to handle these dictionaries quickly, making it suitable for real-world applications without compromising performance.
44 changes: 10 additions & 34 deletions docs/guide/getting-started/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# Getting started
The `.mjs` build is for modern browsers and includes ES5 or higher.
If you want to use it and want to include your own polyfills, you need to transpile it within your build process.

## Installation

### npm:
::: code-tabs#shell

`npm install @zxcvbn-ts/core @zxcvbn-ts/language-common @zxcvbn-ts/language-en --save`
@tab pnpm

### yarn:
pnpm create @zxcvbn-ts/core @zxcvbn-ts/language-common @zxcvbn-ts/language-en
@tab yarn

`yarn add @zxcvbn-ts/core @zxcvbn-ts/language-common @zxcvbn-ts/language-en`
yarn create @zxcvbn-ts/core @zxcvbn-ts/language-common @zxcvbn-ts/language-en
@tab npm

npm install @zxcvbn-ts/core @zxcvbn-ts/language-common @zxcvbn-ts/language-en
:::
## Usage

### Bundler like webpack

```js
import { ZxcvbnFactory } from '@zxcvbn-ts/core'
import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common'
Expand Down Expand Up @@ -99,31 +103,3 @@ result.sequence # the list of patterns that zxcvbn based the
result.calcTime # how long it took zxcvbn to calculate an answer,
# in milliseconds.
```

We highly recommend always using the common and English language packages for the optimal scoring result.
If your language is available as a package, you should import it as well. If your language is missing, feel free to open a PR. For the time being, you could extend the default set.

The `esm` build is for modern browsers and includes ES5 or higher.
If you want to use it and want to include your own polyfills, you need to transpile it within your build process.

## Change prior to original library

- I18n support for feedback, dictionaries and keyboard patterns. By default, the feedback are keys now
- All dictionaries are optional, but the `en` dictionary is highly recommend (wished feature in some issues)
- Dictionaries are separate from the core library. This means zxcvbn-ts is relatively small without its dictionaries
- compress dictionaries for smaller bundle size => up to 33% smaller dictionaries while having more entries
- The project is a monorepo with a core library `@zxcvbn-ts/core` and language packages `@txcvbn-ts/language-en`.
- Keyboard layouts can be customised. This means you can overwrite the default set of layouts with your own or extend it.
E.g., if you are developing a Russian website, you need to include a Cyrillic keyboard set. Create a PR so that others can benefit from it.
- You can use multiple keyboard layouts, which means that the library will check against them by default.
- the tests are Jest based, so we get a coverage score
- eslint/prettier for consistent code style
- Added static page docs https://zxcvbn-ts.github.io/zxcvbn/
- esm, commonJS
- Custom matcher can be added which means you can create your own matcher
- Async matcher can be added which means you can create a matcher that makes an API call
- [haveibeenpwned](https://haveibeenpwned.com/Passwords) matcher
- included debounce helper
- levenshtein check for the dictionaries
- diceware dictionary
- extended l33t matcher for substitutions like `|_| => u`
4 changes: 4 additions & 0 deletions docs/guide/matcher/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ The sequence matcher identifies sequences by looking for repeated differences in

The spatial matcher searches for patterns based on keyboard layout, for example, qwertz.

### Separator

The separator matcher searches for common separators like a space or a hyphen

## Custom Matcher

Custom matchers can be created if needed, including asynchronous matchers. If creating an asynchronous matcher, the function should be debounced using the included debounce function.
Expand Down
27 changes: 0 additions & 27 deletions docs/guide/user-input/README.md

This file was deleted.

0 comments on commit 39de4ad

Please sign in to comment.