@bike4mind/cli 0.18.3 → 0.18.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/LICENSE +16 -2
- package/README.md +9 -9
- package/bin/bike4mind-cli.mjs +1 -1
- package/dist/{BackgroundAgentManager-H_MnlEXz.mjs → BackgroundAgentManager-D-xsWd3C.mjs} +641 -5421
- package/dist/{ConfigStore-DL7p3ZiY.mjs → ConfigStore-D39UqFnY.mjs} +261 -33
- package/dist/commands/apiCommand.mjs +1 -1
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/envCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +2 -2
- package/dist/commands/mcpCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/index.mjs +4 -4
- package/dist/{package-B-ONmxJ7.mjs → package-I_v_WFUn.mjs} +1 -1
- package/dist/{utils-fqhJmuB8.mjs → utils-Cdktpk_k.mjs} +21 -9
- package/dist/utils-DEizxshI.mjs +3 -0
- package/package.json +9 -9
- package/dist/utils-CLjLKvqQ.mjs +0 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { timingSafeEqual } from "crypto";
|
|
2
|
+
import { createHash, timingSafeEqual } from "crypto";
|
|
3
3
|
import speakeasy from "speakeasy";
|
|
4
4
|
import QRCode from "qrcode";
|
|
5
5
|
//#region ../../b4m-core/auth/dist/mfaService/utils.mjs
|
|
@@ -35,8 +35,18 @@ function verifyTOTPToken(secret, token, window = 1) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* Hash a backup code for at-rest storage.
|
|
39
|
+
* Codes are high-entropy random strings (speakeasy base32, ~50 bits), so a
|
|
40
|
+
* fast SHA-256 is appropriate — no dictionary attack risk, and the migration
|
|
41
|
+
* backfill over thousands of users stays instantaneous.
|
|
42
|
+
*/
|
|
43
|
+
function hashBackupCode(code) {
|
|
44
|
+
return createHash("sha256").update(code.trim().toUpperCase()).digest("hex");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Generate cryptographically secure backup codes for MFA.
|
|
48
|
+
* Returns plaintext codes for display to the user; callers are responsible for
|
|
49
|
+
* hashing them (via hashBackupCode) before storing in the database.
|
|
40
50
|
*/
|
|
41
51
|
function generateBackupCodes(count = 10) {
|
|
42
52
|
return Array.from({ length: count }, () => {
|
|
@@ -44,15 +54,17 @@ function generateBackupCodes(count = 10) {
|
|
|
44
54
|
});
|
|
45
55
|
}
|
|
46
56
|
/**
|
|
47
|
-
* Verify a backup code against
|
|
57
|
+
* Verify a backup code against stored hashes.
|
|
58
|
+
* Hashes the provided code and compares against stored SHA-256 hashes using
|
|
59
|
+
* constant-time comparison to prevent timing attacks.
|
|
48
60
|
*/
|
|
49
61
|
function verifyBackupCode(userBackupCodes, providedCode) {
|
|
50
62
|
if (!userBackupCodes || !providedCode) return { isValid: false };
|
|
51
|
-
const
|
|
52
|
-
const providedBuf = Buffer.from(
|
|
63
|
+
const providedHash = hashBackupCode(providedCode);
|
|
64
|
+
const providedBuf = Buffer.from(providedHash, "utf8");
|
|
53
65
|
let matchIdx = -1;
|
|
54
66
|
for (let i = 0; i < userBackupCodes.length; i++) {
|
|
55
|
-
const storedBuf = Buffer.from(userBackupCodes[i]
|
|
67
|
+
const storedBuf = Buffer.from(userBackupCodes[i], "utf8");
|
|
56
68
|
if (storedBuf.length === providedBuf.length && timingSafeEqual(storedBuf, providedBuf)) {
|
|
57
69
|
matchIdx = i;
|
|
58
70
|
break;
|
|
@@ -75,7 +87,7 @@ function userRequiresMFA(user, enforceMFASetting) {
|
|
|
75
87
|
* Check if a user has MFA configured
|
|
76
88
|
*/
|
|
77
89
|
function userHasMFAConfigured(user) {
|
|
78
|
-
return !!(user.mfa && user.mfa.totpEnabled
|
|
90
|
+
return !!(user.mfa && user.mfa.totpEnabled);
|
|
79
91
|
}
|
|
80
92
|
/**
|
|
81
93
|
* Server-side attempt tracking to prevent bypass via refresh/cancel
|
|
@@ -143,4 +155,4 @@ function userCanDisableMFA(user, enforceMFASetting) {
|
|
|
143
155
|
return !enforceMFASetting;
|
|
144
156
|
}
|
|
145
157
|
//#endregion
|
|
146
|
-
export {
|
|
158
|
+
export { hashBackupCode as a, shouldResetFailedAttempts as c, userHasMFAConfigured as d, userRequiresMFA as f, getLockoutTimeRemaining as i, userCanDisableMFA as l, verifyTOTPToken as m, generateBackupCodes as n, isUserLockedOut as o, verifyBackupCode as p, generateTOTPSetup as r, recordFailedAttempt as s, clearFailedAttempts as t, userEligibleForMFA as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"tree-sitter-wasms": "^0.1.13",
|
|
97
97
|
"turndown": "^7.2.4",
|
|
98
98
|
"undici": "^7.28.0",
|
|
99
|
-
"unpdf": "^
|
|
99
|
+
"unpdf": "^1.6.2",
|
|
100
100
|
"uuid": "^13.0.2",
|
|
101
101
|
"voyageai": "^0.4.0",
|
|
102
102
|
"web-tree-sitter": "0.25.10",
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"zod": "^4.4.3",
|
|
108
108
|
"zod-validation-error": "^5.0.0",
|
|
109
109
|
"zustand": "^5.0.13",
|
|
110
|
-
"@bike4mind/fab-pipeline": "0.
|
|
111
|
-
"@bike4mind/llm-adapters": "0.
|
|
110
|
+
"@bike4mind/fab-pipeline": "0.5.0",
|
|
111
|
+
"@bike4mind/llm-adapters": "0.9.1",
|
|
112
112
|
"@bike4mind/observability": "0.2.0"
|
|
113
113
|
},
|
|
114
114
|
"devDependencies": {
|
|
@@ -124,11 +124,11 @@
|
|
|
124
124
|
"tsx": "^4.22.3",
|
|
125
125
|
"typescript": "^5.9.3",
|
|
126
126
|
"vitest": "^4.1.9",
|
|
127
|
-
"@bike4mind/
|
|
128
|
-
"@bike4mind/
|
|
129
|
-
"@bike4mind/mcp": "1.40.
|
|
130
|
-
"@bike4mind/services": "2.
|
|
131
|
-
"@bike4mind/utils": "2.
|
|
127
|
+
"@bike4mind/common": "2.120.0",
|
|
128
|
+
"@bike4mind/agents": "0.18.3",
|
|
129
|
+
"@bike4mind/mcp": "1.40.3",
|
|
130
|
+
"@bike4mind/services": "2.104.0",
|
|
131
|
+
"@bike4mind/utils": "2.28.0"
|
|
132
132
|
},
|
|
133
133
|
"optionalDependencies": {
|
|
134
134
|
"@vscode/ripgrep": "^1.18.0"
|
package/dist/utils-CLjLKvqQ.mjs
DELETED