@mybucks.online/core 1.0.12 → 1.1.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/index.js +29 -8
- package/package.json +3 -2
- package/test/index.test.js +70 -0
package/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { ethers } from "ethers";
|
|
|
3
3
|
import scryptJS from "scrypt-js";
|
|
4
4
|
import { nanoid } from "nanoid";
|
|
5
5
|
import { TronWeb } from "tronweb";
|
|
6
|
+
import zxcvbn from "zxcvbn";
|
|
6
7
|
|
|
7
8
|
const { scrypt } = scryptJS;
|
|
8
9
|
const abi = new ethers.AbiCoder();
|
|
@@ -16,17 +17,28 @@ const HASH_OPTIONS = {
|
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* This function computes the scrypt hash using provided passphrase and pin inputs.
|
|
20
|
+
* Passphrase and pin are validated with zxcvbn; weak values are rejected (returns "").
|
|
19
21
|
*
|
|
20
|
-
* @param {*} passphrase
|
|
21
|
-
* @param {*} pin
|
|
22
|
+
* @param {*} passphrase - Must have zxcvbn score >= 3
|
|
23
|
+
* @param {*} pin - Must have zxcvbn score >= 1
|
|
22
24
|
* @param {*} cb a callback function designed to receive the progress updates during the scrypt hashing process.
|
|
23
|
-
* @returns hash result as string format
|
|
25
|
+
* @returns hash result as string format, or "" if passphrase/pin missing or too weak
|
|
24
26
|
*/
|
|
25
27
|
export async function generateHash(passphrase, pin, cb = () => {}) {
|
|
26
28
|
if (!passphrase || !pin) {
|
|
27
29
|
return "";
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
const passphraseResult = zxcvbn(passphrase);
|
|
33
|
+
if (passphraseResult.score < 3) {
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const pinResult = zxcvbn(pin);
|
|
38
|
+
if (pinResult.score < 1) {
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
|
|
30
42
|
const salt = `${passphrase.slice(-4)}${pin}`;
|
|
31
43
|
|
|
32
44
|
const passwordBuffer = Buffer.from(passphrase);
|
|
@@ -87,12 +99,14 @@ const NETWORKS = [
|
|
|
87
99
|
"tron",
|
|
88
100
|
];
|
|
89
101
|
/**
|
|
90
|
-
* This function generates a transfer-link by
|
|
91
|
-
* The transfer-link
|
|
92
|
-
*
|
|
93
|
-
*
|
|
102
|
+
* This function generates a transfer-link token by encoding passphrase and PIN by Base64 and adding random padding.
|
|
103
|
+
* The transfer-link enables users to send their full ownership of a wallet account to another user for gifting or airdropping.
|
|
104
|
+
* Passphrase and PIN are validated with zxcvbn; weak values are rejected (returns null).
|
|
105
|
+
*
|
|
106
|
+
* @param {*} passphrase - Must have zxcvbn score >= 3
|
|
107
|
+
* @param {*} PIN - Must have zxcvbn score >= 1
|
|
94
108
|
* @param {*} network ethereum | polygon | arbitrum | optimism | bsc | avalanche | base | tron
|
|
95
|
-
* @returns A string formatted as a transfer-link token, which can be appended to `https://app.mybucks.online
|
|
109
|
+
* @returns A string formatted as a transfer-link token, which can be appended to `https://app.mybucks.online#wallet=`, or null if invalid/weak
|
|
96
110
|
*/
|
|
97
111
|
export function generateToken(passphrase, pin, network) {
|
|
98
112
|
if (!passphrase || !pin || !network) {
|
|
@@ -102,6 +116,13 @@ export function generateToken(passphrase, pin, network) {
|
|
|
102
116
|
return null;
|
|
103
117
|
}
|
|
104
118
|
|
|
119
|
+
if (zxcvbn(passphrase).score < 3) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
if (zxcvbn(pin).score < 1) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
105
126
|
const merged = Buffer.from(
|
|
106
127
|
passphrase + URL_DELIMITER + pin + URL_DELIMITER + network,
|
|
107
128
|
"utf-8"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mybucks.online/core",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Core module of Mybucks.online Crypto Wallet",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"ethers": "^6.13.5",
|
|
39
39
|
"nanoid": "^5.0.9",
|
|
40
40
|
"scrypt-js": "^3.0.1",
|
|
41
|
-
"tronweb": "^6.0.1"
|
|
41
|
+
"tronweb": "^6.0.1",
|
|
42
|
+
"zxcvbn": "^4.4.2"
|
|
42
43
|
}
|
|
43
44
|
}
|
package/test/index.test.js
CHANGED
|
@@ -29,6 +29,40 @@ describe("generateHash", () => {
|
|
|
29
29
|
assert.strictEqual(hash, "");
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
test("should return empty string for weak passphrase (zxcvbn score < 3)", async () => {
|
|
33
|
+
const weakPassphrases = [
|
|
34
|
+
"password",
|
|
35
|
+
"asdfasdf",
|
|
36
|
+
"123123123",
|
|
37
|
+
"P@ssw0rd",
|
|
38
|
+
"London123",
|
|
39
|
+
"oxford2024",
|
|
40
|
+
"John19821012",
|
|
41
|
+
"asdfASDFaSdf",
|
|
42
|
+
"qwerqwerqwer",
|
|
43
|
+
"1234567890",
|
|
44
|
+
"Julia18921012",
|
|
45
|
+
];
|
|
46
|
+
for (const passphrase of weakPassphrases) {
|
|
47
|
+
const hash = await generateHash(passphrase, DEMO_PIN);
|
|
48
|
+
assert.strictEqual(hash, "");
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("should return empty string for weak pin (zxcvbn score < 1)", async () => {
|
|
53
|
+
const weakPins = [
|
|
54
|
+
"111111",
|
|
55
|
+
"111111111111111",
|
|
56
|
+
"12341234",
|
|
57
|
+
"aaaaaaaaaa",
|
|
58
|
+
"asdfasdf",
|
|
59
|
+
];
|
|
60
|
+
for (const pin of weakPins) {
|
|
61
|
+
const hash = await generateHash(DEMO_PASSPHRASE, pin);
|
|
62
|
+
assert.strictEqual(hash, "", `Expected "" for weak pin "${pin}"`);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
32
66
|
test("should return scrypt hash result", async () => {
|
|
33
67
|
const hash = await generateHash(DEMO_PASSPHRASE, DEMO_PIN);
|
|
34
68
|
assert.strictEqual(hash, DEMO_HASH);
|
|
@@ -71,6 +105,42 @@ describe("generateToken", () => {
|
|
|
71
105
|
assert.strictEqual(generateToken("passphrase", "123456", "invalid"), null);
|
|
72
106
|
});
|
|
73
107
|
|
|
108
|
+
test("should return null for weak passphrase (zxcvbn score < 3)", () => {
|
|
109
|
+
const weakPassphrases = [
|
|
110
|
+
"password",
|
|
111
|
+
"asdfasdf",
|
|
112
|
+
"123123123",
|
|
113
|
+
"P@ssw0rd",
|
|
114
|
+
"London123",
|
|
115
|
+
"oxford2024",
|
|
116
|
+
"asdfASDFaSdf",
|
|
117
|
+
"qwerqwerqwer",
|
|
118
|
+
"1234567890",
|
|
119
|
+
];
|
|
120
|
+
for (const passphrase of weakPassphrases) {
|
|
121
|
+
assert.strictEqual(
|
|
122
|
+
generateToken(passphrase, DEMO_PIN, DEMO_NETWORK),
|
|
123
|
+
null
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("should return null for weak pin (zxcvbn score < 1)", () => {
|
|
129
|
+
const weakPins = [
|
|
130
|
+
"111111",
|
|
131
|
+
"111111111111111",
|
|
132
|
+
"12341234",
|
|
133
|
+
"aaaaaaaaaa",
|
|
134
|
+
"asdfasdf",
|
|
135
|
+
];
|
|
136
|
+
for (const pin of weakPins) {
|
|
137
|
+
assert.strictEqual(
|
|
138
|
+
generateToken(DEMO_PASSPHRASE, pin, DEMO_NETWORK),
|
|
139
|
+
null
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
74
144
|
test("should return valid token", async () => {
|
|
75
145
|
const token = generateToken(DEMO_PASSPHRASE, DEMO_PIN, DEMO_NETWORK);
|
|
76
146
|
|