@i4ctime/q-ring 0.11.7 → 0.13.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 +45 -10
- package/dist/{chunk-MQM4DLPI.js → chunk-CWV3WTPF.js} +168 -95
- package/dist/chunk-CWV3WTPF.js.map +1 -0
- package/dist/{chunk-A4RZVP3P.js → chunk-SRESNRML.js} +163 -95
- package/dist/chunk-SRESNRML.js.map +1 -0
- package/dist/dashboard-II2ILNXA.js +658 -0
- package/dist/dashboard-II2ILNXA.js.map +1 -0
- package/dist/dashboard-RLMROWIU.js +658 -0
- package/dist/dashboard-RLMROWIU.js.map +1 -0
- package/dist/index.js +712 -145
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +49 -31
- package/dist/mcp.js.map +1 -1
- package/package.json +29 -14
- package/dist/chunk-A4RZVP3P.js.map +0 -1
- package/dist/chunk-MQM4DLPI.js.map +0 -1
- package/dist/dashboard-FSCJDLJX.js +0 -1313
- package/dist/dashboard-FSCJDLJX.js.map +0 -1
- package/dist/dashboard-OXUD62RV.js +0 -1313
- package/dist/dashboard-OXUD62RV.js.map +0 -1
package/dist/mcp.js
CHANGED
|
@@ -32,13 +32,14 @@ import {
|
|
|
32
32
|
registry,
|
|
33
33
|
remember,
|
|
34
34
|
removeHook,
|
|
35
|
+
setPolicyRoot,
|
|
35
36
|
setSecret,
|
|
36
37
|
tunnelCreate,
|
|
37
38
|
tunnelDestroy,
|
|
38
39
|
tunnelList,
|
|
39
40
|
tunnelRead,
|
|
40
41
|
verifyAuditChain
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-CWV3WTPF.js";
|
|
42
43
|
|
|
43
44
|
// src/mcp.ts
|
|
44
45
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -118,24 +119,28 @@ function generateSecret(opts2 = {}) {
|
|
|
118
119
|
}
|
|
119
120
|
case "password": {
|
|
120
121
|
const len = opts2.length ?? 24;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
const classCharsets = [
|
|
123
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
124
|
+
"abcdefghijklmnopqrstuvwxyz",
|
|
125
|
+
"0123456789",
|
|
126
|
+
"!@#$%^&*()-_=+"
|
|
127
|
+
];
|
|
128
|
+
const guaranteed = classCharsets.slice(0, Math.min(classCharsets.length, len)).map((cs) => randomString(cs, 1));
|
|
129
|
+
const remaining = Math.max(0, len - guaranteed.length);
|
|
130
|
+
const chars = [
|
|
131
|
+
...guaranteed,
|
|
132
|
+
...remaining > 0 ? randomString(PASSWORD_CHARS, remaining).split("") : []
|
|
133
|
+
];
|
|
134
|
+
for (let i = chars.length - 1; i > 0; i--) {
|
|
135
|
+
const j = randomInt(i + 1);
|
|
136
|
+
[chars[i], chars[j]] = [chars[j], chars[i]];
|
|
137
|
+
}
|
|
138
|
+
return chars.join("");
|
|
131
139
|
}
|
|
132
140
|
default:
|
|
133
141
|
return randomBytes(32).toString("hex");
|
|
134
142
|
}
|
|
135
143
|
}
|
|
136
|
-
function replaceAt(str, index, char) {
|
|
137
|
-
return str.slice(0, index) + char + str.slice(index + 1);
|
|
138
|
-
}
|
|
139
144
|
function estimateEntropy(secret) {
|
|
140
145
|
const charsets = [
|
|
141
146
|
{ regex: /[a-z]/, size: 26 },
|
|
@@ -173,8 +178,11 @@ function parseDotenv(content) {
|
|
|
173
178
|
'"': '"'
|
|
174
179
|
};
|
|
175
180
|
value = value.replace(/\\([nrt"\\])/g, (_, ch) => escapeMap[ch] ?? ch);
|
|
176
|
-
if (
|
|
177
|
-
|
|
181
|
+
if (!line.includes('"') && !line.includes("'")) {
|
|
182
|
+
const commentMatch = value.match(/\s#/);
|
|
183
|
+
if (commentMatch && commentMatch.index !== void 0) {
|
|
184
|
+
value = value.slice(0, commentMatch.index).trim();
|
|
185
|
+
}
|
|
178
186
|
}
|
|
179
187
|
if (key) result.set(key, value);
|
|
180
188
|
}
|
|
@@ -182,9 +190,14 @@ function parseDotenv(content) {
|
|
|
182
190
|
}
|
|
183
191
|
function importDotenv(filePathOrContent, options = {}) {
|
|
184
192
|
let content;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
const source = options.source ?? "cli";
|
|
194
|
+
if (source === "cli") {
|
|
195
|
+
try {
|
|
196
|
+
content = readFileSync(filePathOrContent, "utf8");
|
|
197
|
+
} catch {
|
|
198
|
+
content = filePathOrContent;
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
188
201
|
content = filePathOrContent;
|
|
189
202
|
}
|
|
190
203
|
const pairs = parseDotenv(content);
|
|
@@ -1329,7 +1342,8 @@ var ALGORITHM = "aes-256-gcm";
|
|
|
1329
1342
|
var KEY_LENGTH = 32;
|
|
1330
1343
|
var IV_LENGTH = 12;
|
|
1331
1344
|
var SALT_LENGTH = 32;
|
|
1332
|
-
var PBKDF2_ITERATIONS =
|
|
1345
|
+
var PBKDF2_ITERATIONS = 21e4;
|
|
1346
|
+
var LEGACY_PBKDF2_ITERATIONS = 1e5;
|
|
1333
1347
|
var TeleportBundleSchema = z4.object({
|
|
1334
1348
|
v: z4.literal(1),
|
|
1335
1349
|
data: z4.string(),
|
|
@@ -1337,7 +1351,8 @@ var TeleportBundleSchema = z4.object({
|
|
|
1337
1351
|
iv: z4.string(),
|
|
1338
1352
|
tag: z4.string(),
|
|
1339
1353
|
createdAt: z4.string(),
|
|
1340
|
-
count: z4.number()
|
|
1354
|
+
count: z4.number(),
|
|
1355
|
+
iter: z4.number().optional()
|
|
1341
1356
|
});
|
|
1342
1357
|
var TeleportPayloadSchema = z4.object({
|
|
1343
1358
|
secrets: z4.array(
|
|
@@ -1350,8 +1365,8 @@ var TeleportPayloadSchema = z4.object({
|
|
|
1350
1365
|
exportedAt: z4.string(),
|
|
1351
1366
|
exportedBy: z4.string().optional()
|
|
1352
1367
|
});
|
|
1353
|
-
function deriveKey(passphrase, salt) {
|
|
1354
|
-
return pbkdf2Sync(passphrase, salt,
|
|
1368
|
+
function deriveKey(passphrase, salt, iterations = PBKDF2_ITERATIONS) {
|
|
1369
|
+
return pbkdf2Sync(passphrase, salt, iterations, KEY_LENGTH, "sha512");
|
|
1355
1370
|
}
|
|
1356
1371
|
function teleportPack(secrets, passphrase) {
|
|
1357
1372
|
const payload = {
|
|
@@ -1361,7 +1376,7 @@ function teleportPack(secrets, passphrase) {
|
|
|
1361
1376
|
const plaintext = JSON.stringify(payload);
|
|
1362
1377
|
const salt = randomBytes2(SALT_LENGTH);
|
|
1363
1378
|
const iv = randomBytes2(IV_LENGTH);
|
|
1364
|
-
const key = deriveKey(passphrase, salt);
|
|
1379
|
+
const key = deriveKey(passphrase, salt, PBKDF2_ITERATIONS);
|
|
1365
1380
|
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
1366
1381
|
const encrypted = Buffer.concat([
|
|
1367
1382
|
cipher.update(plaintext, "utf8"),
|
|
@@ -1375,7 +1390,8 @@ function teleportPack(secrets, passphrase) {
|
|
|
1375
1390
|
iv: iv.toString("base64"),
|
|
1376
1391
|
tag: tag.toString("base64"),
|
|
1377
1392
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1378
|
-
count: secrets.length
|
|
1393
|
+
count: secrets.length,
|
|
1394
|
+
iter: PBKDF2_ITERATIONS
|
|
1379
1395
|
};
|
|
1380
1396
|
return Buffer.from(JSON.stringify(bundle)).toString("base64");
|
|
1381
1397
|
}
|
|
@@ -1403,7 +1419,7 @@ function teleportUnpack(encoded, passphrase) {
|
|
|
1403
1419
|
const iv = Buffer.from(bundle.iv, "base64");
|
|
1404
1420
|
const tag = Buffer.from(bundle.tag, "base64");
|
|
1405
1421
|
const encrypted = Buffer.from(bundle.data, "base64");
|
|
1406
|
-
const key = deriveKey(passphrase, salt);
|
|
1422
|
+
const key = deriveKey(passphrase, salt, bundle.iter ?? LEGACY_PBKDF2_ITERATIONS);
|
|
1407
1423
|
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
1408
1424
|
decipher.setAuthTag(tag);
|
|
1409
1425
|
let decrypted;
|
|
@@ -2172,7 +2188,8 @@ async function execCommand(opts2) {
|
|
|
2172
2188
|
"dig",
|
|
2173
2189
|
"nslookup"
|
|
2174
2190
|
]);
|
|
2175
|
-
|
|
2191
|
+
const commandBase = opts2.command.split(/[\\/]/).pop() ?? opts2.command;
|
|
2192
|
+
if (profile.allowNetwork === false && networkTools.has(commandBase)) {
|
|
2176
2193
|
const msg = `[QRING] Execution blocked: network access is disabled for profile "${profile.name}", command "${opts2.command}" is considered network-related`;
|
|
2177
2194
|
if (opts2.captureOutput) {
|
|
2178
2195
|
return resolve({ code: 126, stdout: "", stderr: msg });
|
|
@@ -2638,14 +2655,14 @@ ${result.stderr}`);
|
|
|
2638
2655
|
if (toolBlock) return toolBlock;
|
|
2639
2656
|
if (dashboardInstance) {
|
|
2640
2657
|
return text(
|
|
2641
|
-
`Dashboard already running at
|
|
2658
|
+
`Dashboard already running at ${dashboardInstance.url}`
|
|
2642
2659
|
);
|
|
2643
2660
|
}
|
|
2644
|
-
const { startDashboardServer } = await import("./dashboard-
|
|
2661
|
+
const { startDashboardServer } = await import("./dashboard-RLMROWIU.js");
|
|
2645
2662
|
dashboardInstance = startDashboardServer({ port: params.port });
|
|
2646
2663
|
return text(
|
|
2647
|
-
`Dashboard started at
|
|
2648
|
-
Open this URL in a browser to see live quantum status.`
|
|
2664
|
+
`Dashboard started at ${dashboardInstance.url}
|
|
2665
|
+
Open this URL in a browser to see live quantum status. The token is required for access.`
|
|
2649
2666
|
);
|
|
2650
2667
|
}
|
|
2651
2668
|
);
|
|
@@ -2834,6 +2851,7 @@ function registerMcpTools(server2) {
|
|
|
2834
2851
|
|
|
2835
2852
|
// src/mcp/server.ts
|
|
2836
2853
|
function createMcpServer() {
|
|
2854
|
+
setPolicyRoot(process.cwd());
|
|
2837
2855
|
const server2 = new McpServer({
|
|
2838
2856
|
name: "q-ring",
|
|
2839
2857
|
version: PACKAGE_VERSION
|