@wener/common 1.0.3 → 1.0.5
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/lib/cn/DivisionCode.js.map +1 -1
- package/lib/cn/Mod11Checksum.js.map +1 -1
- package/lib/cn/Mod31Checksum.js.map +1 -1
- package/lib/cn/ResidentIdentityCardNumber.js.map +1 -1
- package/lib/cn/UnifiedSocialCreditCode.js.map +1 -1
- package/lib/cn/formatDate.js.map +1 -1
- package/lib/cn/parseSex.js.map +1 -1
- package/lib/cn/types.d.js.map +1 -1
- package/lib/consola/createStandardConsolaReporter.js +18 -0
- package/lib/consola/createStandardConsolaReporter.js.map +1 -0
- package/lib/consola/formatLogObject.js +125 -0
- package/lib/consola/formatLogObject.js.map +1 -0
- package/lib/consola/index.js +3 -0
- package/lib/consola/index.js.map +1 -0
- package/lib/data/formatSort.js +15 -0
- package/lib/data/formatSort.js.map +1 -0
- package/lib/data/index.js +4 -0
- package/lib/data/index.js.map +1 -0
- package/lib/data/maybeNumber.js +22 -0
- package/lib/data/maybeNumber.js.map +1 -0
- package/lib/data/parseSort.js +95 -0
- package/lib/data/parseSort.js.map +1 -0
- package/lib/data/resolvePagination.js +36 -0
- package/lib/data/resolvePagination.js.map +1 -0
- package/lib/data/types.d.js +3 -0
- package/lib/data/types.d.js.map +1 -0
- package/lib/index.js +6 -2
- package/lib/index.js.map +1 -1
- package/lib/jsonschema/JsonSchema.js +6 -6
- package/lib/jsonschema/JsonSchema.js.map +1 -1
- package/lib/jsonschema/types.d.js.map +1 -1
- package/lib/meta/defineFileType.js.map +1 -1
- package/lib/meta/defineInit.js.map +1 -1
- package/lib/meta/defineMetadata.js.map +1 -1
- package/lib/password/PHC.js +8 -8
- package/lib/password/PHC.js.map +1 -1
- package/lib/password/Password.js.map +1 -1
- package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
- package/lib/search/AdvanceSearch.js.map +1 -1
- package/lib/search/formatAdvanceSearch.js.map +1 -1
- package/lib/search/optimizeAdvanceSearch.js.map +1 -1
- package/lib/search/parseAdvanceSearch.js.map +1 -1
- package/lib/search/parser.d.js.map +1 -1
- package/lib/search/types.d.js.map +1 -1
- package/lib/tools/generateSchema.js +43 -0
- package/lib/tools/generateSchema.js.map +1 -0
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -1
- package/package.json +19 -5
- package/src/cn/DivisionCode.test.ts +38 -45
- package/src/cn/DivisionCode.ts +140 -184
- package/src/cn/Mod11Checksum.ts +17 -17
- package/src/cn/Mod31Checksum.ts +25 -25
- package/src/cn/ResidentIdentityCardNumber.test.ts +12 -16
- package/src/cn/ResidentIdentityCardNumber.ts +82 -82
- package/src/cn/UnifiedSocialCreditCode.test.ts +11 -11
- package/src/cn/UnifiedSocialCreditCode.ts +115 -120
- package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +1 -1
- package/src/cn/formatDate.ts +10 -10
- package/src/cn/parseSex.ts +11 -25
- package/src/cn/types.d.ts +43 -43
- package/src/consola/createStandardConsolaReporter.ts +31 -0
- package/src/consola/formatLogObject.ts +171 -0
- package/src/consola/index.ts +2 -0
- package/src/data/formatSort.test.ts +13 -0
- package/src/data/formatSort.ts +18 -0
- package/src/data/index.ts +5 -0
- package/src/data/maybeNumber.ts +23 -0
- package/src/data/parseSort.test.ts +67 -0
- package/src/data/parseSort.ts +108 -0
- package/src/data/resolvePagination.test.ts +58 -0
- package/src/data/resolvePagination.ts +60 -0
- package/src/data/types.d.ts +33 -0
- package/src/index.ts +8 -2
- package/src/jsonschema/JsonSchema.test.ts +13 -22
- package/src/jsonschema/JsonSchema.ts +146 -178
- package/src/jsonschema/types.d.ts +151 -161
- package/src/meta/defineFileType.tsx +54 -54
- package/src/meta/defineInit.ts +32 -53
- package/src/meta/defineMetadata.test.ts +5 -7
- package/src/meta/defineMetadata.ts +28 -46
- package/src/password/PHC.test.ts +186 -277
- package/src/password/PHC.ts +243 -243
- package/src/password/Password.test.ts +38 -50
- package/src/password/Password.ts +73 -95
- package/src/password/createArgon2PasswordAlgorithm.ts +65 -69
- package/src/password/createBase64PasswordAlgorithm.ts +9 -9
- package/src/password/createBcryptPasswordAlgorithm.ts +20 -22
- package/src/password/createPBKDF2PasswordAlgorithm.ts +49 -61
- package/src/password/createScryptPasswordAlgorithm.ts +48 -59
- package/src/search/AdvanceSearch.test.ts +136 -143
- package/src/search/AdvanceSearch.ts +6 -6
- package/src/search/formatAdvanceSearch.ts +44 -53
- package/src/search/optimizeAdvanceSearch.ts +70 -83
- package/src/search/parseAdvanceSearch.ts +16 -19
- package/src/search/parser.d.ts +3 -3
- package/src/search/types.d.ts +28 -54
- package/src/tools/generateSchema.ts +39 -0
- package/src/tools/renderJsonSchemaToMarkdownDoc.ts +69 -69
- package/lib/normalizePagination.js +0 -14
- package/lib/normalizePagination.js.map +0 -1
- package/lib/parseSort.js +0 -106
- package/lib/parseSort.js.map +0 -1
- package/src/normalizePagination.ts +0 -25
- package/src/parseSort.test.ts +0 -42
- package/src/parseSort.ts +0 -133
package/src/password/PHC.ts
CHANGED
|
@@ -1,247 +1,247 @@
|
|
|
1
1
|
import { ArrayBuffers } from '@wener/utils';
|
|
2
2
|
|
|
3
3
|
export namespace PHC {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
4
|
+
// https://github.com/simonepri/phc-format/blob/master/index.js
|
|
5
|
+
|
|
6
|
+
const idRegex = /^[a-z0-9-]{1,32}$/;
|
|
7
|
+
const nameRegex = /^[a-z0-9-]{1,32}$/;
|
|
8
|
+
const valueRegex = /^[a-zA-Z0-9/+.-]+$/;
|
|
9
|
+
const b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
|
|
10
|
+
const decimalRegex = /^((-)?[1-9]\d*|0)$/;
|
|
11
|
+
const versionRegex = /^v=(\d+)$/;
|
|
12
|
+
|
|
13
|
+
const fromBase64 = ArrayBuffers.fromBase64;
|
|
14
|
+
const toBase64 = ArrayBuffers.toBase64;
|
|
15
|
+
const isBuffer = (v: any): v is Uint8Array => {
|
|
16
|
+
return v instanceof Uint8Array;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function objToKeyVal(obj: Record<string, any>): string {
|
|
20
|
+
return objectKeys(obj)
|
|
21
|
+
.map((k) => [k, obj[k]].join('='))
|
|
22
|
+
.join(',');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function keyValtoObj(str: string): Record<string, string> {
|
|
26
|
+
const obj: Record<string, string> = {};
|
|
27
|
+
str.split(',').forEach((ps) => {
|
|
28
|
+
const pss = ps.split('=');
|
|
29
|
+
if (pss.length < 2) {
|
|
30
|
+
throw new TypeError(`params must be in the format name=value`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const key = pss.shift();
|
|
34
|
+
if (key !== undefined) {
|
|
35
|
+
obj[key] = pss.join('=');
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return obj;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function objectKeys<T extends object>(object: T): Array<keyof T> {
|
|
42
|
+
return Object.keys(object) as Array<keyof T>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function objectValues<T extends object>(object: T): Array<T[keyof T]> {
|
|
46
|
+
if (typeof Object.values === 'function') return Object.values(object);
|
|
47
|
+
return objectKeys(object).map((k) => object[k]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface SerializeOptions {
|
|
51
|
+
id: string;
|
|
52
|
+
version?: number;
|
|
53
|
+
params?: Record<string, string | number | Uint8Array>;
|
|
54
|
+
salt?: Uint8Array;
|
|
55
|
+
hash?: Uint8Array;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generates a PHC string using the data provided.
|
|
60
|
+
* @param {SerializeOptions} opts Object that holds the data needed to generate the PHC string.
|
|
61
|
+
* @return {string} The hash string adhering to the PHC format.
|
|
62
|
+
*/
|
|
63
|
+
export function serialize(opts: SerializeOptions): string {
|
|
64
|
+
const fields: string[] = [''];
|
|
65
|
+
|
|
66
|
+
if (typeof opts !== 'object' || opts === null) {
|
|
67
|
+
throw new TypeError('opts must be an object');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Identifier Validation
|
|
71
|
+
if (typeof opts.id !== 'string') {
|
|
72
|
+
throw new TypeError('id must be a string');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!idRegex.test(opts.id)) {
|
|
76
|
+
throw new TypeError(`id must satisfy ${idRegex}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fields.push(opts.id);
|
|
80
|
+
|
|
81
|
+
if (typeof opts.version !== 'undefined') {
|
|
82
|
+
if (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {
|
|
83
|
+
throw new TypeError('version must be a positive integer number');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
fields.push(`v=${opts.version}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Parameters Validation
|
|
90
|
+
if (typeof opts.params !== 'undefined') {
|
|
91
|
+
if (typeof opts.params !== 'object' || opts.params === null) {
|
|
92
|
+
throw new TypeError('params must be an object');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const pk = objectKeys(opts.params);
|
|
96
|
+
if (!pk.every((p) => nameRegex.test(p.toString()))) {
|
|
97
|
+
throw new TypeError(`params names must satisfy ${nameRegex}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.
|
|
101
|
+
pk.forEach((k) => {
|
|
102
|
+
const value = opts.params![k];
|
|
103
|
+
if (typeof value === 'number') {
|
|
104
|
+
opts.params![k] = value.toString();
|
|
105
|
+
} else if (value instanceof Uint8Array) {
|
|
106
|
+
opts.params![k] = toBase64(value).split('=')[0];
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
const pv = objectValues(opts.params);
|
|
110
|
+
if (!pv.every((v) => typeof v === 'string')) {
|
|
111
|
+
throw new TypeError('params values must be strings');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!pv.every((v) => valueRegex.test(v))) {
|
|
115
|
+
throw new TypeError(`params values must satisfy ${valueRegex}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const strpar = objToKeyVal(opts.params as Record<string, string>);
|
|
119
|
+
fields.push(strpar);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (typeof opts.salt !== 'undefined') {
|
|
123
|
+
// Salt Validation
|
|
124
|
+
if (!isBuffer(opts.salt)) {
|
|
125
|
+
throw new TypeError('salt must be a Buffer');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fields.push(toBase64(opts.salt).split('=')[0]);
|
|
129
|
+
|
|
130
|
+
if (typeof opts.hash !== 'undefined') {
|
|
131
|
+
// Hash Validation
|
|
132
|
+
if (!isBuffer(opts.hash)) {
|
|
133
|
+
throw new TypeError('hash must be a Buffer');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fields.push(toBase64(opts.hash).split('=')[0]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Create the PHC formatted string
|
|
141
|
+
const phcstr = fields.join('$');
|
|
142
|
+
|
|
143
|
+
return phcstr;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface DeserializeResult {
|
|
147
|
+
id: string;
|
|
148
|
+
version?: number;
|
|
149
|
+
params?: Record<string, string | number>;
|
|
150
|
+
salt?: Uint8Array;
|
|
151
|
+
hash?: Uint8Array;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Parses data from a PHC string.
|
|
156
|
+
* @param {string} phcstr A PHC string to parse.
|
|
157
|
+
* @return {DeserializeResult} The object containing the data parsed from the PHC string.
|
|
158
|
+
*/
|
|
159
|
+
export function deserialize(phcstr: string): DeserializeResult {
|
|
160
|
+
if (typeof phcstr !== 'string' || phcstr === '') {
|
|
161
|
+
throw new TypeError('pchstr must be a non-empty string');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (phcstr[0] !== '$') {
|
|
165
|
+
throw new TypeError('pchstr must contain a $ as first char');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const fields = phcstr.split('$');
|
|
169
|
+
// Remove first empty $
|
|
170
|
+
fields.shift();
|
|
171
|
+
|
|
172
|
+
// Parse Fields
|
|
173
|
+
let maxf = 5;
|
|
174
|
+
if (!versionRegex.test(fields[1])) maxf--;
|
|
175
|
+
if (fields.length > maxf) {
|
|
176
|
+
throw new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Parse Identifier
|
|
180
|
+
const id = fields.shift();
|
|
181
|
+
if (!id || !idRegex.test(id)) {
|
|
182
|
+
throw new TypeError(`id must satisfy ${idRegex}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
let version: number | undefined;
|
|
186
|
+
// Parse Version
|
|
187
|
+
if (fields[0] && versionRegex.test(fields[0])) {
|
|
188
|
+
const versionMatch = fields.shift()?.match(versionRegex);
|
|
189
|
+
version = versionMatch ? parseInt(versionMatch[1], 10) : undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let hash: Uint8Array | undefined;
|
|
193
|
+
let salt: Uint8Array | undefined;
|
|
194
|
+
if (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {
|
|
195
|
+
if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
|
|
196
|
+
// Parse Hash
|
|
197
|
+
const hashStr = fields.pop();
|
|
198
|
+
if (hashStr) hash = fromBase64(hashStr);
|
|
199
|
+
// Parse Salt
|
|
200
|
+
const saltStr = fields.pop();
|
|
201
|
+
if (saltStr !== undefined) salt = fromBase64(saltStr);
|
|
202
|
+
} else {
|
|
203
|
+
// Parse Salt
|
|
204
|
+
const saltStr = fields.pop();
|
|
205
|
+
if (saltStr !== undefined) salt = fromBase64(saltStr);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Parse Parameters
|
|
210
|
+
let params: Record<string, string | number> | undefined;
|
|
211
|
+
if (fields.length > 0) {
|
|
212
|
+
const parstr = fields.pop();
|
|
213
|
+
if (parstr) {
|
|
214
|
+
params = keyValtoObj(parstr);
|
|
215
|
+
if (!Object.keys(params).every((p) => nameRegex.test(p))) {
|
|
216
|
+
throw new TypeError(`params names must satisfy ${nameRegex}}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const pv = Object.values(params);
|
|
220
|
+
if (!pv.every((v) => valueRegex.test(String(v)))) {
|
|
221
|
+
throw new TypeError(`params values must satisfy ${valueRegex}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Convert Decimal Strings into Numbers
|
|
225
|
+
Object.keys(params).forEach((k) => {
|
|
226
|
+
const value = params![k];
|
|
227
|
+
if (typeof value === 'string' && decimalRegex.test(value)) {
|
|
228
|
+
params![k] = parseInt(value, 10);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (fields.length > 0) {
|
|
235
|
+
throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Build the output object
|
|
239
|
+
const phcobj: DeserializeResult = { id };
|
|
240
|
+
if (version !== undefined) phcobj.version = version;
|
|
241
|
+
if (params) phcobj.params = params;
|
|
242
|
+
if (salt) phcobj.salt = salt;
|
|
243
|
+
if (hash) phcobj.hash = hash;
|
|
244
|
+
|
|
245
|
+
return phcobj;
|
|
246
|
+
}
|
|
247
247
|
}
|
|
@@ -5,54 +5,42 @@ import { createBcryptPasswordAlgorithm } from './createBcryptPasswordAlgorithm';
|
|
|
5
5
|
import { Password } from './Password';
|
|
6
6
|
|
|
7
7
|
describe('Password', () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
hash: string;
|
|
47
|
-
}> = [
|
|
48
|
-
{ hash: '$2y$10$MQ057tMbDG6/lVkGFWrNwOR9kh/5rzbkhBPrwNPTPuZ5wBpGNbWLa' },
|
|
49
|
-
{ hash: '$argon2i$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$76L95nAjG4SjjdoR0YZyFw' },
|
|
50
|
-
{ hash: '$argon2d$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$+cB2R45sauVlfxbGslAmOw' },
|
|
51
|
-
{ hash: '$argon2id$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$iP9HYuSDXgG2lW7KARBuQQ' },
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
for (const { password = '1', hash } of tests) {
|
|
55
|
-
expect(await Password.verify(password, hash)).toBe(true);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
8
|
+
const check = async ({ password = '1', ...rest }: Password.PasswordHashOptions & { password?: string }) => {
|
|
9
|
+
let out = await Password.hash(password, rest);
|
|
10
|
+
console.log(`${rest.algorithm || 'default'}: hash ${out}`);
|
|
11
|
+
let result = await Password.verify(password, out);
|
|
12
|
+
expect(result).toBe(true);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
Password.addAlgorithm(createBcryptPasswordAlgorithm());
|
|
16
|
+
Password.addAlgorithm(createBase64PasswordAlgorithm());
|
|
17
|
+
Password.addAlgorithm(createArgon2PasswordAlgorithm({ provide: import('argon2') }));
|
|
18
|
+
// Password.addAlgorithm(createScryptPasswordAlgorithm());
|
|
19
|
+
|
|
20
|
+
test('base', async () => {
|
|
21
|
+
await check({});
|
|
22
|
+
|
|
23
|
+
await check({ algorithm: 'bcrypt' });
|
|
24
|
+
|
|
25
|
+
await check({ algorithm: 'base64' });
|
|
26
|
+
// invalid base 64
|
|
27
|
+
await check({ algorithm: 'base64', password: '你好' });
|
|
28
|
+
|
|
29
|
+
await check({ algorithm: '5' });
|
|
30
|
+
await check({ algorithm: '6' });
|
|
31
|
+
await check({ algorithm: '7' });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('should verify manual created hash', async () => {
|
|
35
|
+
const tests: Array<{ password?: string; hash: string }> = [
|
|
36
|
+
{ hash: '$2y$10$MQ057tMbDG6/lVkGFWrNwOR9kh/5rzbkhBPrwNPTPuZ5wBpGNbWLa' },
|
|
37
|
+
{ hash: '$argon2i$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$76L95nAjG4SjjdoR0YZyFw' },
|
|
38
|
+
{ hash: '$argon2d$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$+cB2R45sauVlfxbGslAmOw' },
|
|
39
|
+
{ hash: '$argon2id$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$iP9HYuSDXgG2lW7KARBuQQ' },
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
for (const { password = '1', hash } of tests) {
|
|
43
|
+
expect(await Password.verify(password, hash)).toBe(true);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
58
46
|
});
|