generate-pw 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -16
- package/docs/LICENSE.md +12 -0
- package/docs/SECURITY.md +12 -0
- package/docs/zh-cn/LICENSE.md +21 -0
- package/docs/zh-cn/README.md +214 -0
- package/docs/zh-cn/SECURITY.md +17 -0
- package/docs/zh-tw/LICENSE.md +21 -0
- package/docs/zh-tw/README.md +214 -0
- package/docs/zh-tw/SECURITY.md +17 -0
- package/generate-pw.js +146 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
English |
|
|
8
|
+
<a href="https://github.com/adamlui/js-utils/tree/main/minify.js/docs/zh-cn#readme">简体中文</a> |
|
|
9
|
+
<a href="https://github.com/adamlui/js-utils/tree/main/minify.js/docs/zh-tw#readme">繁體中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
1
13
|
# > generate-pw
|
|
2
14
|
|
|
3
15
|
### Randomly generate cryptographically-secure passwords.
|
|
4
16
|
|
|
5
|
-
<a href="#%EF%B8%8F-mit-license"><img height=
|
|
6
|
-
<a href="https://www.npmjs.com/package/generate-pw?activeTab=versions"><img height=
|
|
7
|
-
<a href="https://www.npmjs.com/package/generate-pw?activeTab=code"><img height=
|
|
8
|
-
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/generate-pw.js"><img height=
|
|
17
|
+
<a href="#%EF%B8%8F-mit-license"><img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/generate-pw?activeTab=versions"><img height=31 src="https://img.shields.io/badge/Latest_Build-1.2.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/generate-pw?activeTab=code"><img height=31 src="https://img.shields.io/npm/unpacked-size/generate-pw?style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
|
|
20
|
+
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/generate-pw.js"><img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Agenerate-pw%2Fgenerate-pw.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
|
|
21
|
+
|
|
22
|
+
<br>
|
|
23
|
+
|
|
24
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
9
25
|
|
|
10
26
|
## ⚡ Installation
|
|
11
27
|
|
|
@@ -21,6 +37,10 @@ As a **runtime dependency**, from your project root:
|
|
|
21
37
|
$ npm install generate-pw
|
|
22
38
|
```
|
|
23
39
|
|
|
40
|
+
<br>
|
|
41
|
+
|
|
42
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
43
|
+
|
|
24
44
|
## 🔌 API usage
|
|
25
45
|
|
|
26
46
|
**generate-pw** can be imported into your app as an ECMAScript module or a CommonJS module.
|
|
@@ -37,6 +57,8 @@ import * as pw from 'generate-pw';
|
|
|
37
57
|
const pw = require('generate-pw');
|
|
38
58
|
```
|
|
39
59
|
|
|
60
|
+
#
|
|
61
|
+
|
|
40
62
|
### `generatePassword([options])`
|
|
41
63
|
|
|
42
64
|
Generates **one** password if `qty` option is not given, returning a string:
|
|
@@ -44,7 +66,7 @@ Generates **one** password if `qty` option is not given, returning a string:
|
|
|
44
66
|
```js
|
|
45
67
|
const password = pw.generatePassword({ length: 11, numbers: true });
|
|
46
68
|
console.log(password);
|
|
47
|
-
// sample output: '
|
|
69
|
+
// sample output: 'bAsZm3mq6Qn'
|
|
48
70
|
```
|
|
49
71
|
|
|
50
72
|
...or **multiple** passwords if `qty` option is given, returning an array of strings:
|
|
@@ -57,6 +79,10 @@ console.log(passwords);
|
|
|
57
79
|
|
|
58
80
|
**💡 Note:** If no options are passed, passwords will be 8-chars long, consisting of upper/lower cased letters.
|
|
59
81
|
|
|
82
|
+
See: [Available options](#available-options-for-generate-functions)
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
|
|
60
86
|
### `generatePasswords(qty[, options])`
|
|
61
87
|
|
|
62
88
|
Generates **multiple** passwords based on `qty` given, returning an array of strings:
|
|
@@ -67,16 +93,60 @@ console.log(passwords);
|
|
|
67
93
|
// sample output: [ 'yilppxru', 'ckvkyjfp', 'zolcpyfb' ]
|
|
68
94
|
```
|
|
69
95
|
|
|
70
|
-
|
|
96
|
+
**💡 Note:** If no `qty` arg is passed, just one password will be generated, returned as a string.
|
|
97
|
+
|
|
98
|
+
See: [Available options](#available-options-for-generate-functions)
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
|
|
102
|
+
### `strictify(password[, requiredCharTypes])`
|
|
71
103
|
|
|
72
|
-
|
|
104
|
+
Modifies `password` given to use at least one character of each `requiredCharTypes` element passed, returning a string.
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
const password = 'abcdef',
|
|
108
|
+
strictPW = pw.strictify(password, ['numbers', 'symbols']);
|
|
109
|
+
|
|
110
|
+
console.log(strictPW);
|
|
111
|
+
// sample output: 'a!c2eR'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Available `requiredCharTypes` are: `['number', 'symbol', 'lower', 'upper']`
|
|
115
|
+
|
|
116
|
+
**💡 Note:** If no `requiredCharTypes` array is passed, all available types will be required.
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
|
|
120
|
+
### `validateStrength(password)`
|
|
121
|
+
|
|
122
|
+
Validates the strength of a password, returning an object containing `strengthScore` (out of 100) + `recommendations` array.
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
const password = 'AawiddsE',
|
|
126
|
+
pwStrength = pw.validateStrength(password);
|
|
127
|
+
|
|
128
|
+
console.log(pwStrength);
|
|
129
|
+
|
|
130
|
+
/* outputs:
|
|
131
|
+
{
|
|
132
|
+
strengthScore: 60,
|
|
133
|
+
recommendations: [ 'Include at least one number.', 'Include at least one symbol.' ]
|
|
134
|
+
}
|
|
135
|
+
*/
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#
|
|
139
|
+
|
|
140
|
+
### Available options for `generate*()` functions
|
|
141
|
+
|
|
142
|
+
Any of these can be passed into the options object for each `generate*()` function:
|
|
73
143
|
|
|
74
144
|
Name | Type | Description | Default Value
|
|
75
145
|
------------|---------|--------------------------------------------------------------------------------|---------------
|
|
76
146
|
`length` | Integer | Length of password(s). | `8`
|
|
77
147
|
`qty`* | Integer | Number of passwords to generate. | `1`
|
|
78
|
-
`charset` | String | Characters to include in password(s). | ''
|
|
79
|
-
`exclude` | String | Characters to exclude from password(s). | ''
|
|
148
|
+
`charset` | String | Characters to include in password(s). | `''`
|
|
149
|
+
`exclude` | String | Characters to exclude from password(s). | `''`
|
|
80
150
|
`numbers` | Boolean | Allow numbers in password(s). | `false`
|
|
81
151
|
`symbols` | Boolean | Allow symbols in password(s). | `false`
|
|
82
152
|
`lowercase` | Boolean | Allow lowercase letters in password(s). | `true`
|
|
@@ -87,9 +157,11 @@ Name | Type | Description
|
|
|
87
157
|
|
|
88
158
|
<br>
|
|
89
159
|
|
|
160
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
161
|
+
|
|
90
162
|
## 💻 Command line usage
|
|
91
163
|
|
|
92
|
-
**generate-pw** can also be used from the command line. The basic
|
|
164
|
+
When installed globally, **generate-pw** can also be used from the command line. The basic command is:
|
|
93
165
|
|
|
94
166
|
```
|
|
95
167
|
$ generate-pw
|
|
@@ -97,10 +169,12 @@ $ generate-pw
|
|
|
97
169
|
|
|
98
170
|
**💡 Note:** To generate multiple results, pass `--qty=n` where `n` is the number of passwords to generate.
|
|
99
171
|
|
|
172
|
+
#
|
|
173
|
+
|
|
100
174
|
### Command line options
|
|
101
175
|
|
|
102
176
|
```
|
|
103
|
-
|
|
177
|
+
Parameter options:
|
|
104
178
|
--length=n Generate password(s) of n length.
|
|
105
179
|
--qty=n Generate n password(s).
|
|
106
180
|
--charset=chars Only include chars in password(s).
|
|
@@ -113,16 +187,13 @@ Boolean options:
|
|
|
113
187
|
-U, --no-uppercase Disallow uppercase letters in password(s).
|
|
114
188
|
|
|
115
189
|
Info commands:
|
|
116
|
-
-h, --help Display
|
|
190
|
+
-h, --help Display help screen.
|
|
117
191
|
-v, --version Show version number.
|
|
118
192
|
```
|
|
119
193
|
|
|
120
194
|
<br>
|
|
121
195
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Please consider [giving a GitHub ⭐](https://github.com/adamlui/js-utils) or [funding](https://github.com/sponsors/adamlui) this project if it helped you!
|
|
125
|
-
<br><br>
|
|
196
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
126
197
|
|
|
127
198
|
## 🏛️ MIT License
|
|
128
199
|
|
package/docs/LICENSE.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
English |
|
|
8
|
+
<a href="zh-cn/LICENSE.md">简体中文</a> |
|
|
9
|
+
<a href="zh-tw/LICENSE.md">繁體中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
1
13
|
# 🏛️ MIT License
|
|
2
14
|
|
|
3
15
|
**Copyright © 2024 [Adam Lui](https://github.com/adamlui)**
|
package/docs/SECURITY.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
English |
|
|
8
|
+
<a href="zh-cn/SECURITY.md">简体中文</a> |
|
|
9
|
+
<a href="zh-tw/SECURITY.md">繁體中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
1
13
|
# 🛡️ Security Policy
|
|
2
14
|
|
|
3
15
|
If you find a vulnerability, please open a [draft security advisory](https://github.com/adamlui/js-utils/security/advisories/new).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
简体中文 |
|
|
8
|
+
<a href="../LICENSE.md">English</a> |
|
|
9
|
+
<a href="../zh-tw/LICENSE.md">繁體中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
# 🏛️ MIT 许可证
|
|
14
|
+
|
|
15
|
+
**版权所有 © 2024 [刘展鹏 (Adam Lui)](https://github.com/adamlui)**
|
|
16
|
+
|
|
17
|
+
特此免费向任何获得副本的人授予许可本软件和相关文档文件(『软件』),处理在软件中不受限制,包括但不限于权利使用、复制、修改、合并、发布、分发、再许可和/或出售该软件的副本,并允许该软件是提供这样做,但须满足以下条件:
|
|
18
|
+
|
|
19
|
+
上述版权声明和本许可声明应包含在所有软件的副本或重要部分。
|
|
20
|
+
|
|
21
|
+
本软件『按原样』提供,不提供任何形式的明示或保证暗示的,包括但不限于适销性保证,适用于特定目的和非侵权。 在任何情况下都不得作者或版权持有人对任何索赔、损害或其他责任,无论是在合同、侵权或其他方面的行为中,由以下原因引起,出于或与软件或使用或其他交易有关软件。
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
简体中文 |
|
|
8
|
+
<a href="../..#readme">English</a> |
|
|
9
|
+
<a href="../zh-tw#readme">繁體中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
# > generate-pw
|
|
14
|
+
|
|
15
|
+
### 随机生成加密安全密码。
|
|
16
|
+
|
|
17
|
+
<a href="#%EF%B8%8F-mit-%E8%AE%B8%E5%8F%AF%E8%AF%81"><img height=31 src="https://img.shields.io/badge/许可证-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/generate-pw?activeTab=versions"><img height=31 src="https://img.shields.io/badge/最新版本-1.2.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/generate-pw?activeTab=code"><img height=31 src="https://img.shields.io/npm/unpacked-size/generate-pw?label=%E6%8B%86%E5%B0%81%E5%B0%BA%E5%AF%B8&style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
|
|
20
|
+
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/generate-pw.js"><img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Agenerate-pw%2Fgenerate-pw.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=%E6%BC%8F%E6%B4%9E&color=gold"></a>
|
|
21
|
+
|
|
22
|
+
<br>
|
|
23
|
+
|
|
24
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
25
|
+
|
|
26
|
+
## ⚡ 安装
|
|
27
|
+
|
|
28
|
+
作为**全局实用程序**:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
$ npm install -g generate-pw
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
作为 **运行时依赖项**,从项目根目录:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
$ npm install generate-pw
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
<br>
|
|
41
|
+
|
|
42
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
43
|
+
|
|
44
|
+
## 🔌 API 使用
|
|
45
|
+
|
|
46
|
+
**generate-pw** 可以作为 ECMAScript 模块或 CommonJS 模块导入到您的应用程序中。
|
|
47
|
+
|
|
48
|
+
#### ESM:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import * as pw from 'generate-pw';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### CJS:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const pw = require('generate-pw');
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
|
|
62
|
+
### `generatePassword([options])`
|
|
63
|
+
|
|
64
|
+
如果未给出 `qty` 选项,则生成**一个**密码,并返回一个字符串:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const password = pw.generatePassword({ length: 11, numbers: true });
|
|
68
|
+
console.log(password);
|
|
69
|
+
// 示例输出:'bAsZm3mq6Qn'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
...或 **多个** 密码(如果给出了 `qty` 选项),返回一个字符串数组:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
const passwords = pw.generatePassword({ qty: 5, length: 8, symbols: true });
|
|
76
|
+
console.log(passwords);
|
|
77
|
+
// 示例输出:[ '!zSf@Q.s', '!,HT\\;m=', '?Lq&FV>^', 'gf}Y;}Ne', 'Stsx(GqE' ]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**💡 注意:**如果不传递任何选项,密码将为 8 个字符长,由大小写字母组成。
|
|
81
|
+
|
|
82
|
+
请参阅:[可用选项](#available-options-for-generate-functions)
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
|
|
86
|
+
### `generatePasswords(qty[, options])`
|
|
87
|
+
|
|
88
|
+
根据给定的 `qty` 生成**多个**密码,返回字符串数组:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
const passwords = pw.generatePasswords(5, { length: 3, uppercase: false });
|
|
92
|
+
console.log(passwords);
|
|
93
|
+
// 示例输出:[ 'yilppxru', 'ckvkyjfp', 'zolcpyfb' ]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**💡 注意:**如果没有传递 `qty` 参数,则只会生成一个密码,并以字符串形式返回。
|
|
97
|
+
|
|
98
|
+
请参阅:[可用选项](#available-options-for-generate-functions)
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
|
|
102
|
+
### `strictify(password[, requiredCharTypes])`
|
|
103
|
+
|
|
104
|
+
修改指定的 `password`,以使用传递的每个 `requiredCharTypes` 元素中的至少一个字符,返回一个字符串。
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
const password = 'abcdef',
|
|
108
|
+
strictPW = pw.strictify(password, ['numbers', 'symbols']);
|
|
109
|
+
|
|
110
|
+
console.log(strictPW);
|
|
111
|
+
// 示例输出:'a!c2eR'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
可用的 `requiredCharTypes` 有:`['number', 'symbol', 'lower', 'upper']`
|
|
115
|
+
|
|
116
|
+
**💡注意:**如果没有传递 `requiredCharTypes` 数组,则所有可用类型都将是必需的。
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
|
|
120
|
+
### `validateStrength(password)`
|
|
121
|
+
|
|
122
|
+
验证密码的强度,返回一个包含 `strengthScore`(满分 100)+ `recommendations` 数组的对象。
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
const password = 'AawiddsE',
|
|
126
|
+
pwStrength = pw.validateStrength(password);
|
|
127
|
+
|
|
128
|
+
console.log(pwStrength);
|
|
129
|
+
|
|
130
|
+
/* 输出:
|
|
131
|
+
{
|
|
132
|
+
strengthScore: 60,
|
|
133
|
+
recommendations: [ 'Include at least one number.', 'Include at least one symbol.' ]
|
|
134
|
+
}
|
|
135
|
+
*/
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#
|
|
139
|
+
|
|
140
|
+
### `generate*()` 函数的可用选项
|
|
141
|
+
|
|
142
|
+
其中任何一个都可以传递到每个 `generate*()` 函数的选项对象中:
|
|
143
|
+
|
|
144
|
+
姓名 | 类型 | 描述 | 默认值
|
|
145
|
+
------------|--------|-----------------------------------------|--------
|
|
146
|
+
`length` | 整数 | 密码的长度。 | `8`
|
|
147
|
+
`qty`* | 整数 | 要生成的密码数量。 | `1`
|
|
148
|
+
`charset` | 字符串 | 密码中包含的字符。 | `''`
|
|
149
|
+
`exclude` | 字符串 | 要从密码中排除的字符。 | `''`
|
|
150
|
+
`numbers` | 布尔值 | 允许密码中包含数字。 | `false`
|
|
151
|
+
`symbols` | 布尔值 | 允许密码中包含符号。 | `false`
|
|
152
|
+
`lowercase` | 布尔值 | 密码中允许使用小写字母。 | `true`
|
|
153
|
+
`uppercase` | 布尔值 | 密码中允许使用大写字母。 | `true`
|
|
154
|
+
`strict` | 布尔值 | 要求密码中每个允许的字符集中至少有一个字符。 | `false`
|
|
155
|
+
|
|
156
|
+
##### _*仅在 [`generatePassword([options])`](#generatepasswordoptions) 中可用,因为 [`generatePasswords(qty[, options])`](#generatepasswordsqty-options) 采用 `qty` 参数_
|
|
157
|
+
|
|
158
|
+
<br>
|
|
159
|
+
|
|
160
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
161
|
+
|
|
162
|
+
## 💻 命令行使用
|
|
163
|
+
|
|
164
|
+
全局安装时,**generate-pw** 也可以从命令行使用。 基本命令是:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
$ generate-pw
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**💡 注意:**要生成多个结果,请传递 `--qty=n`,其中 `n` 是要生成的密码数量。
|
|
171
|
+
|
|
172
|
+
#
|
|
173
|
+
|
|
174
|
+
### 命令行选项
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
参数选项:
|
|
178
|
+
--length=n 生成 n 长度的密码。
|
|
179
|
+
--qty=n 生成 n 个密码。
|
|
180
|
+
--charset=chars 密码中仅包含 chars。
|
|
181
|
+
--exclude=chars 从密码中排除 chars。
|
|
182
|
+
|
|
183
|
+
布尔选项:
|
|
184
|
+
-n, --include-numbers 允许密码中包含数字。
|
|
185
|
+
-s, --include-symbols 允许密码中包含符号。
|
|
186
|
+
-L, --no-lowercase 密码中不允许使用小写字母。
|
|
187
|
+
-U, --no-uppercase 密码中不允许使用大写字母。
|
|
188
|
+
|
|
189
|
+
信息命令:
|
|
190
|
+
-h, --help 显示帮助屏幕。
|
|
191
|
+
-v, --version 显示版本号。
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
<br>
|
|
195
|
+
|
|
196
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
197
|
+
|
|
198
|
+
## 🏛️ MIT 许可证
|
|
199
|
+
|
|
200
|
+
**版权所有 © 2024 [刘展鹏 (Adam Lui)](https://github.com/adamlui)**
|
|
201
|
+
|
|
202
|
+
特此免费向任何获得副本的人授予许可本软件和相关文档文件(『软件』),处理在软件中不受限制,包括但不限于权利使用、复制、修改、合并、发布、分发、再许可和/或出售该软件的副本,并允许该软件是提供这样做,但须满足以下条件:
|
|
203
|
+
|
|
204
|
+
上述版权声明和本许可声明应包含在所有软件的副本或重要部分。
|
|
205
|
+
|
|
206
|
+
本软件『按原样』提供,不提供任何形式的明示或保证暗示的,包括但不限于适销性保证,适用于特定目的和非侵权。 在任何情况下都不得作者或版权持有人对任何索赔、损害或其他责任,无论是在合同、侵权或其他方面的行为中,由以下原因引起,出于或与软件或使用或其他交易有关软件。
|
|
207
|
+
|
|
208
|
+
<br>
|
|
209
|
+
|
|
210
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
211
|
+
|
|
212
|
+
<a href="https://github.com/adamlui/js-utils">**家**</a> /
|
|
213
|
+
<a href="https://github.com/adamlui/js-utils/discussions">讨论</a> /
|
|
214
|
+
<a href="#-generate-pw">回到顶部 ↑</a>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
简体中文 |
|
|
8
|
+
<a href="../SECURITY.md">English</a> |
|
|
9
|
+
<a href="../zh-tw/SECURITY.md">繁體中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
# 🛡️ 安全政策
|
|
14
|
+
|
|
15
|
+
如果您发现漏洞,请打开[安全公告草案](https://github.com/adamlui/js-utils/security/advisories/new)。
|
|
16
|
+
|
|
17
|
+
也欢迎拉取请求,但出于安全原因,请发送电子邮件至 <adam@kudoai.com> 并等待回复后再公开。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
繁體中文 |
|
|
8
|
+
<a href="../LICENSE.md">English</a> |
|
|
9
|
+
<a href="../zh-cn/LICENSE.md">简体中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
# 🏛️ MIT 许可证
|
|
14
|
+
|
|
15
|
+
**版權所有 © 2024 [刘展鹏 (Adam Lui)](https://github.com/adamlui)**
|
|
16
|
+
|
|
17
|
+
特此免費授予任何取得副本的人許可本軟體和相關文件文件(『軟體』),處理在軟體中不受限制,包括但不限於權利使用、複製、修改、合併、發布、分發、再授權和/或出售該軟體的副本,並允許該軟體是提供這樣做,但須滿足以下條件:
|
|
18
|
+
|
|
19
|
+
上述版權聲明和本許可聲明應包含在所有軟體的副本或重要部分。
|
|
20
|
+
|
|
21
|
+
本軟體『依現況』提供,不提供任何形式的明示或保證暗示的,包括但不限於適銷性保證,適用於特定目的和非侵權。 在任何情況下都不得作者或版權持有人對任何索賠、損害或其他責任,無論是在合約、侵權或其他方面的行為中,由以下原因引起,出於或與軟體或使用或其他交易有關軟體。
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
繁體中文 |
|
|
8
|
+
<a href="../..#readme">English</a> |
|
|
9
|
+
<a href="../zh-cn#readme">简体中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
# > generate-pw
|
|
14
|
+
|
|
15
|
+
### 隨機產生加密安全密碼。
|
|
16
|
+
|
|
17
|
+
<a href="#%EF%B8%8F-mit-%E8%AE%B8%E5%8F%AF%E8%AF%81"><img height=31 src="https://img.shields.io/badge/許可證-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/generate-pw?activeTab=versions"><img height=31 src="https://img.shields.io/badge/最新版本-1.2.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/generate-pw?activeTab=code"><img height=31 src="https://img.shields.io/npm/unpacked-size/generate-pw?label=%E6%8B%86%E5%B0%81%E5%B0%BA%E5%AF%B8&style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
|
|
20
|
+
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/generate-pw.js"><img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Agenerate-pw%2Fgenerate-pw.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=%E6%BC%8F%E6%B4%9E&color=gold"></a>
|
|
21
|
+
|
|
22
|
+
<br>
|
|
23
|
+
|
|
24
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
25
|
+
|
|
26
|
+
## ⚡ 安裝
|
|
27
|
+
|
|
28
|
+
作為**全域實用程式**:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
$ npm install -g generate-pw
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
作為 **運行時依賴項**,從專案根目錄:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
$ npm install generate-pw
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
<br>
|
|
41
|
+
|
|
42
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
43
|
+
|
|
44
|
+
## 🔌 API 使用
|
|
45
|
+
|
|
46
|
+
**generate-pw** 可以作為 ECMAScript 模組或 CommonJS 模組匯入到您的應用程式中。
|
|
47
|
+
|
|
48
|
+
#### ESM:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import * as pw from 'generate-pw';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### CJS:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const pw = require('generate-pw');
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
|
|
62
|
+
### `generatePassword([options])`
|
|
63
|
+
|
|
64
|
+
如果未給予 `qty` 選項,則產生**一個**密碼,並傳回字串:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const password = pw.generatePassword({ length: 11, numbers: true });
|
|
68
|
+
console.log(password);
|
|
69
|
+
// 範例輸出:'bAsZm3mq6Qn'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
...或 **多個** 密碼(如果給了 `qty` 選項),傳回一個字串陣列:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
const passwords = pw.generatePassword({ qty: 5, length: 8, symbols: true });
|
|
76
|
+
console.log(passwords);
|
|
77
|
+
// 範例輸出:[ '!zSf@Q.s', '!,HT\\;m=', '?Lq&FV>^', 'gf}Y;}Ne', 'Stsx(GqE' ]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**💡注意:**如果不傳遞任何選項,密碼將為 8 個字元長,由大小寫字母組成。
|
|
81
|
+
|
|
82
|
+
請參閱:[可用選項](#available-options-for-generate-functions)
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
|
|
86
|
+
### `generatePasswords(qty[, options])`
|
|
87
|
+
|
|
88
|
+
根據給定的 `qty` 產生**多個**密碼,傳回字串陣列:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
const passwords = pw.generatePasswords(5, { length: 3, uppercase: false });
|
|
92
|
+
console.log(passwords);
|
|
93
|
+
// 範例輸出:[ 'yilppxru', 'ckvkyjfp', 'zolcpyfb' ]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**💡 注意:** 如果沒有傳遞 `qty` 參數,則只會產生一個密碼,並以字串形式傳回。
|
|
97
|
+
|
|
98
|
+
請參閱:[可用選項](#available-options-for-generate-functions)
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
|
|
102
|
+
### `strictify(password[, requiredCharTypes])`
|
|
103
|
+
|
|
104
|
+
修改指定的 `password`,以使用傳遞的每個 `requiredCharTypes` 元素中的至少一個字符,傳回一個字串。
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
const password = 'abcdef',
|
|
108
|
+
strictPW = pw.strictify(password, ['numbers', 'symbols']);
|
|
109
|
+
|
|
110
|
+
console.log(strictPW);
|
|
111
|
+
// 範例輸出:'a!c2eR'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
可用的 `requiredCharTypes` 有:`['number', 'symbol', 'lower', 'upper']`
|
|
115
|
+
|
|
116
|
+
**💡注意:**如果沒有傳遞 `requiredCharTypes` 數組,則所有可用類型都將是必需的。
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
|
|
120
|
+
### `validateStrength(password)`
|
|
121
|
+
|
|
122
|
+
驗證密碼的強度,傳回一個包含 `strengthScore`(滿分 100)+ `recommendations` 陣列的物件。
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
const password = 'AawiddsE',
|
|
126
|
+
pwStrength = pw.validateStrength(password);
|
|
127
|
+
|
|
128
|
+
console.log(pwStrength);
|
|
129
|
+
|
|
130
|
+
/* 輸出:
|
|
131
|
+
{
|
|
132
|
+
strengthScore: 60,
|
|
133
|
+
recommendations: [ 'Include at least one number.', 'Include at least one symbol.' ]
|
|
134
|
+
}
|
|
135
|
+
*/
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#
|
|
139
|
+
|
|
140
|
+
### `generate*()` 函數的可用選項
|
|
141
|
+
|
|
142
|
+
其中任何一個都可以傳遞到每個 `generate*()` 函數的選項物件中:
|
|
143
|
+
|
|
144
|
+
姓名 | 類型 | 描述 | 預設值
|
|
145
|
+
------------|--------|-----------------------------------------|---------
|
|
146
|
+
`length` | 整數 | 密碼的長度。 | `8`
|
|
147
|
+
`qty`* | 整數 | 要產生的密碼數量。 | `1`
|
|
148
|
+
`charset` | 字串 | 密碼中包含的字元。 | `''`
|
|
149
|
+
`exclude` | 字串 | 要從密碼中排除的字元。 | `''`
|
|
150
|
+
`numbers` | 布林值 | 允許密碼中包含數字。 | `false`
|
|
151
|
+
`symbols` | 布林值 | 允許密碼中包含符號。 | `false`
|
|
152
|
+
`lowercase` | 布林值 | 密碼中允許使用小寫字母。 | `true`
|
|
153
|
+
`uppercase` | 布林值 | 密碼中允許使用大寫字母。 | `true`
|
|
154
|
+
`strict` | 布林值 | 要求密碼中每個允許的字元集中至少有一個字元。 | `false`
|
|
155
|
+
|
|
156
|
+
##### _*只在 [`generatePassword([options])`](#generatepasswordoptions) 中可用,因為 [`generatePasswords(qty[, options])`](#generatepasswordsqty-options) 採用 `qty` 參數_
|
|
157
|
+
|
|
158
|
+
<br>
|
|
159
|
+
|
|
160
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
161
|
+
|
|
162
|
+
## 💻 命令列使用
|
|
163
|
+
|
|
164
|
+
全域安裝時,**generate-pw** 也可以從命令列使用。 基本指令是:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
$ generate-pw
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**💡 注意:** 若要產生多個結果,請傳遞 `--qty=n`,其中 `n` 是要產生的密碼數量。
|
|
171
|
+
|
|
172
|
+
#
|
|
173
|
+
|
|
174
|
+
### 命令列選項
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
參數選項:
|
|
178
|
+
--length=n 產生 n 長度的密碼。
|
|
179
|
+
--qty=n 產生 n 個密碼。
|
|
180
|
+
--charset=chars 密碼中僅包含 chars。
|
|
181
|
+
--exclude=chars 從密碼中排除 chars。
|
|
182
|
+
|
|
183
|
+
布林選項:
|
|
184
|
+
-n, --include-numbers 允許密碼中包含數字。
|
|
185
|
+
-s, --include-symbols 允許密碼中包含符號。
|
|
186
|
+
-L, --no-lowercase 密碼中不允許使用小寫字母。
|
|
187
|
+
-U, --no-uppercase 密碼中不允許使用大寫字母。
|
|
188
|
+
|
|
189
|
+
訊息命令:
|
|
190
|
+
-h, --help 顯示幫助畫面。
|
|
191
|
+
-v, --version 顯示版本號。
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
<br>
|
|
195
|
+
|
|
196
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
197
|
+
|
|
198
|
+
## 🏛️ MIT 许可证
|
|
199
|
+
|
|
200
|
+
**版權所有 © 2024 [刘展鹏 (Adam Lui)](https://github.com/adamlui)**
|
|
201
|
+
|
|
202
|
+
特此免費授予任何取得副本的人許可本軟體和相關文件文件(『軟體』),處理在軟體中不受限制,包括但不限於權利使用、複製、修改、合併、發布、分發、再授權和/或出售該軟體的副本,並允許該軟體是提供這樣做,但須滿足以下條件:
|
|
203
|
+
|
|
204
|
+
上述版權聲明和本許可聲明應包含在所有軟體的副本或重要部分。
|
|
205
|
+
|
|
206
|
+
本軟體『依現況』提供,不提供任何形式的明示或保證暗示的,包括但不限於適銷性保證,適用於特定目的和非侵權。 在任何情況下都不得作者或版權持有人對任何索賠、損害或其他責任,無論是在合約、侵權或其他方面的行為中,由以下原因引起,出於或與軟體或使用或其他交易有關軟體。
|
|
207
|
+
|
|
208
|
+
<br>
|
|
209
|
+
|
|
210
|
+
<img height=6px width="100%" src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/aqua-separator.png">
|
|
211
|
+
|
|
212
|
+
<a href="https://github.com/adamlui/js-utils">**家**</a> /
|
|
213
|
+
<a href="https://github.com/adamlui/js-utils/discussions">討論</a> /
|
|
214
|
+
<a href="#-generate-pw">回到頂部 ↑</a>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h6>
|
|
3
|
+
<picture>
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/white/icon32.svg">
|
|
5
|
+
<img height=14 src="https://raw.githubusercontent.com/adamlui/js-utils/main/docs/images/earth-icon/black/icon32.svg">
|
|
6
|
+
</picture>
|
|
7
|
+
繁體中文 |
|
|
8
|
+
<a href="../SECURITY.md">English</a> |
|
|
9
|
+
<a href="../zh-cn/SECURITY.md">简体中文</a>
|
|
10
|
+
</h6>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
# 🛡️ 安全策略
|
|
14
|
+
|
|
15
|
+
如果您發現漏洞,請打開[安全公告草案](https://github.com/adamlui/js-utils/security/advisories/new)。
|
|
16
|
+
|
|
17
|
+
也歡迎拉取請求,但出於安全原因,請發送電子郵件至 <adam@kudoai.com> 並等待回復後再公開。
|
package/generate-pw.js
CHANGED
|
@@ -29,6 +29,12 @@ function generatePassword(options = {}) {
|
|
|
29
29
|
};
|
|
30
30
|
options = { ...defaultOptions, ...options };
|
|
31
31
|
|
|
32
|
+
// Validate integer args
|
|
33
|
+
for (const numArgType of ['length', 'qty'])
|
|
34
|
+
if (isNaN(options[numArgType]) || options[numArgType] < 1)
|
|
35
|
+
return console.error(
|
|
36
|
+
`ERROR: [${ numArgType }] argument must be 1 or greater.`);
|
|
37
|
+
|
|
32
38
|
if (options.qty > 1) { // return array of [qty] password strings
|
|
33
39
|
const { qty, ...otherOptions } = options;
|
|
34
40
|
return generatePasswords(qty, otherOptions);
|
|
@@ -56,34 +62,10 @@ function generatePassword(options = {}) {
|
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
// Enforce strict mode if enabled
|
|
59
|
-
if (options.strict) {
|
|
65
|
+
if (options.strict) {
|
|
60
66
|
const charTypes = ['number', 'symbol', 'lower', 'upper'],
|
|
61
67
|
requiredCharTypes = charTypes.filter(charType => options[charType + 's'] || options[charType + 'case']);
|
|
62
|
-
|
|
63
|
-
// Init flags
|
|
64
|
-
for (const charType of requiredCharTypes)
|
|
65
|
-
global['has' + charType.charAt(0).toUpperCase() + charType.slice(1)] = false;
|
|
66
|
-
for (let i = 0; i < password.length; i++)
|
|
67
|
-
for (const charType of requiredCharTypes)
|
|
68
|
-
if ((charsets[charType] || charsets[charType + 's']).includes(password.charAt(i)))
|
|
69
|
-
global['has' + charType.charAt(0).toUpperCase() + charType.slice(1)] = true;
|
|
70
|
-
|
|
71
|
-
// Modify password if necessary
|
|
72
|
-
const maxReplacements = Math.min(password.length, requiredCharTypes.length),
|
|
73
|
-
replacedPositions = []; let replacementCnt = 0;
|
|
74
|
-
for (const charType of requiredCharTypes) {
|
|
75
|
-
if (replacementCnt < maxReplacements) {
|
|
76
|
-
if (!global['has' + charType.charAt(0).toUpperCase() + charType.slice(1)]) {
|
|
77
|
-
let replacementPos;
|
|
78
|
-
do replacementPos = randomInt(0, password.length); // pick random pos
|
|
79
|
-
while (replacedPositions.includes(replacementPos)); // check if pos already replaced
|
|
80
|
-
replacedPositions.push(replacementPos); // track new replacement pos
|
|
81
|
-
const replacementCharSet = charsets[charType] || charsets[charType + 's'];
|
|
82
|
-
password = password.substring(0, replacementPos) // perform actual replacement
|
|
83
|
-
+ replacementCharSet.charAt(randomInt(0, replacementCharSet.length))
|
|
84
|
-
+ password.substring(replacementPos + 1);
|
|
85
|
-
replacementCnt++;
|
|
86
|
-
}}}
|
|
68
|
+
password = strictify(password, requiredCharTypes);
|
|
87
69
|
}
|
|
88
70
|
|
|
89
71
|
return password;
|
|
@@ -93,14 +75,76 @@ function generatePassword(options = {}) {
|
|
|
93
75
|
function generatePasswords(qty, options) {
|
|
94
76
|
qty = parseInt(qty);
|
|
95
77
|
if (isNaN(qty)) return console.error(
|
|
96
|
-
'ERROR: First argument
|
|
78
|
+
'ERROR: First argument [qty] of generatePasswords() must be an integer');
|
|
97
79
|
const passwords = [];
|
|
98
80
|
for (let i = 0; i < qty; i++) passwords.push(generatePassword(options));
|
|
99
81
|
return passwords;
|
|
100
82
|
}
|
|
101
83
|
|
|
84
|
+
function strictify(password, requiredCharTypes = ['number', 'symbol', 'lower', 'upper']) {
|
|
85
|
+
|
|
86
|
+
// Init flags
|
|
87
|
+
for (const charType of requiredCharTypes)
|
|
88
|
+
global['has' + charType.charAt(0).toUpperCase() + charType.slice(1)] = false;
|
|
89
|
+
for (let i = 0; i < password.length; i++)
|
|
90
|
+
for (const charType of requiredCharTypes)
|
|
91
|
+
if ((charsets[charType] || charsets[charType + 's']).includes(password.charAt(i)))
|
|
92
|
+
global['has' + charType.charAt(0).toUpperCase() + charType.slice(1)] = true;
|
|
93
|
+
|
|
94
|
+
// Modify password if necessary
|
|
95
|
+
const maxReplacements = Math.min(password.length, requiredCharTypes.length),
|
|
96
|
+
replacedPositions = []; let replacementCnt = 0;
|
|
97
|
+
for (const charType of requiredCharTypes) {
|
|
98
|
+
if (replacementCnt < maxReplacements) {
|
|
99
|
+
if (!global['has' + charType.charAt(0).toUpperCase() + charType.slice(1)]) {
|
|
100
|
+
let replacementPos;
|
|
101
|
+
do replacementPos = randomInt(0, password.length); // pick random pos
|
|
102
|
+
while (replacedPositions.includes(replacementPos)); // check if pos already replaced
|
|
103
|
+
replacedPositions.push(replacementPos); // track new replacement pos
|
|
104
|
+
const replacementCharSet = charsets[charType] || charsets[charType + 's'];
|
|
105
|
+
password = password.substring(0, replacementPos) // perform actual replacement
|
|
106
|
+
+ replacementCharSet.charAt(randomInt(0, replacementCharSet.length))
|
|
107
|
+
+ password.substring(replacementPos + 1);
|
|
108
|
+
replacementCnt++;
|
|
109
|
+
}}}
|
|
110
|
+
|
|
111
|
+
return password;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function validateStrength(password) {
|
|
115
|
+
const strengthCriteria = { minLength: 8, minLower: 1, minUpper: 1, minNumber: 1, minSymbol: 1 };
|
|
116
|
+
|
|
117
|
+
// Count occurrences of each char type
|
|
118
|
+
const charCnts = { 'lower': 0, 'upper': 0, 'number': 0, 'symbol': 0 };
|
|
119
|
+
for (let i = 0; i < password.length; i++) {
|
|
120
|
+
const char = password[i];
|
|
121
|
+
for (const charType of Object.keys(charCnts))
|
|
122
|
+
if ((charsets[charType] || charsets[charType + 's']).includes(char))
|
|
123
|
+
charCnts[charType]++;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Check criteria + add recommendations
|
|
127
|
+
const recommendations = [];
|
|
128
|
+
if (password.length < strengthCriteria.minLength)
|
|
129
|
+
recommendations.push(`Make it at least ${ strengthCriteria.minLength } characters long.`);
|
|
130
|
+
for (const charType of Object.keys(charCnts))
|
|
131
|
+
if (charCnts[charType] < strengthCriteria['min' + charType.charAt(0).toUpperCase() + charType.slice(1)])
|
|
132
|
+
recommendations.push('Include at least one ' + charType
|
|
133
|
+
+ `${ ['upper', 'lower'].includes(charType) ? 'case letter' : '' }.`);
|
|
134
|
+
|
|
135
|
+
// Calculate strength score based on counts and criteria
|
|
136
|
+
let strengthScore = 0;
|
|
137
|
+
strengthScore += ( // +20 for satisfying min length
|
|
138
|
+
password.length >= strengthCriteria.minLength) ? 20 : 0;
|
|
139
|
+
for (const charType of Object.keys(charCnts))
|
|
140
|
+
strengthScore += ( // +20 per char type included
|
|
141
|
+
charCnts[charType] >= strengthCriteria['min' + charType.charAt(0).toUpperCase() + charType.slice(1)]) ? 20 : 0;
|
|
142
|
+
|
|
143
|
+
return { strengthScore, recommendations };
|
|
144
|
+
}
|
|
145
|
+
|
|
102
146
|
// EXPORT functions if script was required
|
|
103
|
-
if (require.main !== module) module.exports = { generatePassword, generatePasswords };
|
|
147
|
+
if (require.main !== module) module.exports = { generatePassword, generatePasswords, strictify, validateStrength };
|
|
104
148
|
|
|
105
149
|
else { // run as CLI tool
|
|
106
150
|
|
|
@@ -111,47 +155,56 @@ else { // run as CLI tool
|
|
|
111
155
|
bw = '\x1b[1;97m'; // bright white
|
|
112
156
|
|
|
113
157
|
// Load settings from ARGS
|
|
114
|
-
const config = {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/^--?(?:
|
|
125
|
-
|
|
158
|
+
const config = {};
|
|
159
|
+
const argRegex = {
|
|
160
|
+
paramOptions: {
|
|
161
|
+
'length': /^--?length/,
|
|
162
|
+
'qty': /^--?qu?a?n?ti?t?y=\d+$/,
|
|
163
|
+
'charset': /^--?chars/,
|
|
164
|
+
'excludeChars': /^--?exclude=/
|
|
165
|
+
},
|
|
166
|
+
flags: {
|
|
167
|
+
'includeNums': /^--?(?:n|(?:include-?)?num(?:ber)?s?=?(?:true|1)?)$/,
|
|
168
|
+
'includeSymbols': /^--?(?:s|(?:include-?)?symbols?=?(?:true|1)?)$/,
|
|
169
|
+
'excludeLowerChars': /^--?(?:L|(?:exclude|disable|no)-?lower-?(?:case)?|lower-?(?:case)?=(?:false|0))$/,
|
|
170
|
+
'excludeUpperChars': /^--?(?:U|(?:exclude|disable|no)-?upper-?(?:case)?|upper-?(?:case)?=(?:false|0))$/,
|
|
171
|
+
'strictMode': /^--?s(?:trict)?(?:-?mode)?$/
|
|
172
|
+
},
|
|
173
|
+
cmds: {
|
|
174
|
+
'help': /^--?h(?:elp)?$/,
|
|
175
|
+
'version': /^--?ve?r?s?i?o?n?$/
|
|
176
|
+
}
|
|
126
177
|
};
|
|
178
|
+
process.argv.forEach(arg => {
|
|
179
|
+
if (!arg.startsWith('-')) return;
|
|
180
|
+
const matchedFlag = Object.keys(argRegex.flags).find(flag => argRegex.flags[flag].test(arg)),
|
|
181
|
+
matchedArgOption = Object.keys(argRegex.paramOptions).find(option => argRegex.paramOptions[option].test(arg)),
|
|
182
|
+
matchedCmd = Object.keys(argRegex.cmds).find(cmd => argRegex.cmds[cmd].test(arg));
|
|
183
|
+
if (matchedFlag) config[matchedFlag] = true;
|
|
184
|
+
else if (matchedArgOption) {
|
|
185
|
+
const value = arg.split('=')[1];
|
|
186
|
+
config[matchedArgOption] = parseInt(value) || value;
|
|
187
|
+
} else if (!matchedCmd) {
|
|
188
|
+
console.error(`\n${br}ERROR: Arg [${ arg }] not recognized.${nc}`);
|
|
189
|
+
console.info(`\n${by}Valid arguments are below.${nc}`);
|
|
190
|
+
printHelpScreen(['paramOptions', 'booelanOptions', 'infoCmds']);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}});
|
|
127
193
|
|
|
128
194
|
// Show HELP screen if -h or --help passed
|
|
129
|
-
if (process.argv.some(arg => /^--?h(?:elp)?$/.test(arg)))
|
|
130
|
-
printHelp(`\n${by}generate-pw [options]${nc}`);
|
|
131
|
-
printHelp('\nArgument options:');
|
|
132
|
-
printHelp(' --length=n Generate password(s) of n length.');
|
|
133
|
-
printHelp(' --qty=n Generate n password(s).');
|
|
134
|
-
printHelp(' --charset=chars Only include chars in password(s).');
|
|
135
|
-
printHelp(' --exclude=chars Exclude chars from password(s).');
|
|
136
|
-
printHelp('\nBoolean options:');
|
|
137
|
-
printHelp(' -n, --include-numbers Allow numbers in password(s).');
|
|
138
|
-
printHelp(' -s, --include-symbols Allow symbols in password(s).');
|
|
139
|
-
printHelp(' -L, --no-lowercase Disallow lowercase letters in password(s).');
|
|
140
|
-
printHelp(' -U, --no-uppercase Disallow uppercase letters in password(s).');
|
|
141
|
-
printHelp('\nInfo commands:');
|
|
142
|
-
printHelp(' -h, --help Display this help screen.');
|
|
143
|
-
printHelp(' -v, --version Show version number.');
|
|
195
|
+
if (process.argv.some(arg => /^--?h(?:elp)?$/.test(arg))) printHelpScreen();
|
|
144
196
|
|
|
145
197
|
// Show VERSION number if -v or --version passed
|
|
146
|
-
|
|
198
|
+
else if (process.argv.some(arg => /^--?ve?r?s?i?o?n?$/.test(arg)))
|
|
147
199
|
console.info('v' + require('./package.json').version);
|
|
148
200
|
|
|
149
|
-
|
|
201
|
+
else { // run MAIN routine
|
|
150
202
|
for (const numArgType of ['length', 'qty'])
|
|
151
|
-
if (config[numArgType] < 1)
|
|
152
|
-
`\n${br}Error:
|
|
203
|
+
if (config[numArgType] && (isNaN(config[numArgType]) || config[numArgType] < 1))
|
|
204
|
+
return console.error(`\n${br}Error: [${ numArgType }] argument must be 1 or greater.${nc}`);
|
|
153
205
|
const funcOptions = {
|
|
154
|
-
length: config.length, qty: config.qty
|
|
206
|
+
length: config.length || 8, qty: config.qty || 1,
|
|
207
|
+
charset: config.charset, exclude: config.excludeChars,
|
|
155
208
|
numbers: config.includeNums, symbols: config.includeSymbols,
|
|
156
209
|
lowercase: !config.excludeLowerChars, uppercase: !config.excludeUpperChars,
|
|
157
210
|
strict: config.strictMode
|
|
@@ -160,7 +213,9 @@ else { // run as CLI tool
|
|
|
160
213
|
console.log('\n' + bw + ( Array.isArray(pwResult) ? pwResult.join('\n') : pwResult ) + nc);
|
|
161
214
|
}
|
|
162
215
|
|
|
163
|
-
|
|
216
|
+
// Define LOGGING functions
|
|
217
|
+
|
|
218
|
+
function printHelpMsg(msg) { // wrap msg + indent 2nd+ lines (for --help screen)
|
|
164
219
|
const terminalWidth = process.stdout.columns || 80,
|
|
165
220
|
indentation = 29, lines = [], words = msg.match(/\S+|\s+/g);
|
|
166
221
|
|
|
@@ -182,4 +237,34 @@ else { // run as CLI tool
|
|
|
182
237
|
: ' '.repeat(indentation) + line // print subsequent lines indented
|
|
183
238
|
));
|
|
184
239
|
}
|
|
240
|
+
|
|
241
|
+
function printHelpScreen(includeSections = ['cmdFormat', 'paramOptions', 'booelanOptions', 'infoCmds']) {
|
|
242
|
+
const sections = {
|
|
243
|
+
'cmdFormat': [
|
|
244
|
+
`\n${by}generate-pw [options|commands]${nc}`
|
|
245
|
+
],
|
|
246
|
+
'paramOptions': [
|
|
247
|
+
'\nParameter options:',
|
|
248
|
+
' --length=n Generate password(s) of n length.',
|
|
249
|
+
' --qty=n Generate n password(s).',
|
|
250
|
+
' --charset=chars Only include chars in password(s).',
|
|
251
|
+
' --charset=chars Only include chars in password(s).',
|
|
252
|
+
' --exclude=chars Exclude chars from password(s).'
|
|
253
|
+
],
|
|
254
|
+
'booelanOptions': [
|
|
255
|
+
'\nBoolean options:',
|
|
256
|
+
' -n, --include-numbers Allow numbers in password(s).',
|
|
257
|
+
' -s, --include-symbols Allow symbols in password(s).',
|
|
258
|
+
' -L, --no-lowercase Disallow lowercase letters in password(s).',
|
|
259
|
+
' -U, --no-uppercase Disallow uppercase letters in password(s).'
|
|
260
|
+
],
|
|
261
|
+
'infoCmds': [
|
|
262
|
+
'\nInfo commands:',
|
|
263
|
+
' -h, --help Display help screen.',
|
|
264
|
+
' -v, --version Show version number.'
|
|
265
|
+
]
|
|
266
|
+
};
|
|
267
|
+
includeSections.forEach(section => { // print valid arg elems
|
|
268
|
+
if (sections[section]) sections[section].forEach(line => printHelpMsg(line)); });
|
|
269
|
+
}
|
|
185
270
|
}
|