@kya-os/mcp-i-core 1.3.23 → 1.3.25
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/dist/identity/user-did-manager.d.ts +1 -1
- package/dist/identity/user-did-manager.js +32 -24
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -2
- package/dist/runtime/base.js +43 -29
- package/dist/services/provider-resolver.d.ts +18 -0
- package/dist/services/provider-resolver.js +36 -2
- package/dist/services/tool-protection.service.d.ts +25 -3
- package/dist/services/tool-protection.service.js +161 -249
- package/dist/types/tool-protection.d.ts +27 -4
- package/dist/utils/base64.js +48 -21
- package/dist/utils/storage-keys.js +6 -6
- package/package.json +2 -2
package/dist/utils/base64.js
CHANGED
|
@@ -18,29 +18,41 @@ exports.base64ToBytes = base64ToBytes;
|
|
|
18
18
|
function base64urlDecodeToString(input) {
|
|
19
19
|
const padded = addPadding(input);
|
|
20
20
|
const base64 = padded.replace(/-/g, "+").replace(/_/g, "/");
|
|
21
|
+
// Prefer Buffer when available (Node.js) as it handles UTF-8 correctly
|
|
22
|
+
if (typeof Buffer !== "undefined") {
|
|
23
|
+
// Buffer.from doesn't throw for invalid base64, so we validate first
|
|
24
|
+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
25
|
+
if (!base64Regex.test(base64)) {
|
|
26
|
+
throw new Error("Invalid base64url string: contains invalid characters");
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const decoded = Buffer.from(base64, "base64").toString("utf-8");
|
|
30
|
+
return decoded;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw new Error(`Invalid base64url string: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
21
36
|
// For platforms that don't have Buffer (e.g., Cloudflare Workers)
|
|
22
37
|
if (typeof atob !== "undefined") {
|
|
23
38
|
try {
|
|
24
|
-
|
|
39
|
+
const binaryString = atob(base64);
|
|
40
|
+
// Decode UTF-8 bytes to string
|
|
41
|
+
if (typeof TextDecoder !== "undefined") {
|
|
42
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
43
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
44
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
45
|
+
}
|
|
46
|
+
return new TextDecoder().decode(bytes);
|
|
47
|
+
}
|
|
48
|
+
// Fallback: return binary string as-is (may not handle UTF-8 correctly)
|
|
49
|
+
return binaryString;
|
|
25
50
|
}
|
|
26
51
|
catch (error) {
|
|
27
52
|
throw new Error(`Invalid base64url string: ${error instanceof Error ? error.message : String(error)}`);
|
|
28
53
|
}
|
|
29
54
|
}
|
|
30
|
-
|
|
31
|
-
// We need to validate by checking if the input contains only valid base64 characters
|
|
32
|
-
// Base64 characters: A-Z, a-z, 0-9, +, /, = (padding)
|
|
33
|
-
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
34
|
-
if (!base64Regex.test(base64)) {
|
|
35
|
-
throw new Error("Invalid base64url string: contains invalid characters");
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
const decoded = Buffer.from(base64, "base64").toString("utf-8");
|
|
39
|
-
return decoded;
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
throw new Error(`Invalid base64url string: ${error instanceof Error ? error.message : String(error)}`);
|
|
43
|
-
}
|
|
55
|
+
throw new Error("Neither Buffer nor atob is available");
|
|
44
56
|
}
|
|
45
57
|
/**
|
|
46
58
|
* Decode base64url string to Uint8Array
|
|
@@ -70,14 +82,29 @@ function base64urlDecodeToBytes(input) {
|
|
|
70
82
|
* Encode string to base64url
|
|
71
83
|
*/
|
|
72
84
|
function base64urlEncodeFromString(input) {
|
|
73
|
-
//
|
|
74
|
-
if (typeof
|
|
75
|
-
const base64 =
|
|
85
|
+
// Prefer Buffer when available (Node.js) as it handles Unicode correctly
|
|
86
|
+
if (typeof Buffer !== "undefined") {
|
|
87
|
+
const base64 = Buffer.from(input, "utf-8").toString("base64");
|
|
76
88
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
77
89
|
}
|
|
78
|
-
// For
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
// For platforms that don't have Buffer (e.g., Cloudflare Workers)
|
|
91
|
+
if (typeof btoa !== "undefined") {
|
|
92
|
+
// btoa doesn't handle Unicode, so we need to encode to UTF-8 bytes first
|
|
93
|
+
try {
|
|
94
|
+
const utf8Bytes = new TextEncoder().encode(input);
|
|
95
|
+
const binaryString = Array.from(utf8Bytes)
|
|
96
|
+
.map((byte) => String.fromCharCode(byte))
|
|
97
|
+
.join("");
|
|
98
|
+
const base64 = btoa(binaryString);
|
|
99
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Fallback: if TextEncoder not available, try direct btoa (may fail for Unicode)
|
|
103
|
+
const base64 = btoa(input);
|
|
104
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error("Neither Buffer nor btoa is available");
|
|
81
108
|
}
|
|
82
109
|
/**
|
|
83
110
|
* Encode Uint8Array to base64url
|
|
@@ -94,9 +94,9 @@ async function migrateDelegationKeys(storage, options = {}) {
|
|
|
94
94
|
};
|
|
95
95
|
try {
|
|
96
96
|
// Find all legacy delegation keys
|
|
97
|
-
const legacyKeys = await storage.list(
|
|
97
|
+
const legacyKeys = await storage.list("agent:");
|
|
98
98
|
const delegationKeys = legacyKeys.filter((key) => key.match(/^agent:[^:]+:delegation$/));
|
|
99
|
-
console.
|
|
99
|
+
console.error(`Found ${delegationKeys.length} legacy delegation keys to migrate`);
|
|
100
100
|
for (const oldKey of delegationKeys) {
|
|
101
101
|
try {
|
|
102
102
|
// Extract agentDid from key: `agent:${agentDid}:delegation`
|
|
@@ -104,7 +104,7 @@ async function migrateDelegationKeys(storage, options = {}) {
|
|
|
104
104
|
if (!match) {
|
|
105
105
|
result.errors.push({
|
|
106
106
|
key: oldKey,
|
|
107
|
-
error:
|
|
107
|
+
error: "Invalid legacy key format",
|
|
108
108
|
});
|
|
109
109
|
result.failed++;
|
|
110
110
|
continue;
|
|
@@ -120,7 +120,7 @@ async function migrateDelegationKeys(storage, options = {}) {
|
|
|
120
120
|
let userDid = null;
|
|
121
121
|
let sessionId = undefined;
|
|
122
122
|
// First, attempt to extract from session data to get both userDid and sessionId
|
|
123
|
-
const sessionKeys = await storage.list(
|
|
123
|
+
const sessionKeys = await storage.list("session:");
|
|
124
124
|
for (const sessionKey of sessionKeys) {
|
|
125
125
|
const sessionData = await storage.get(sessionKey);
|
|
126
126
|
if (sessionData) {
|
|
@@ -153,7 +153,7 @@ async function migrateDelegationKeys(storage, options = {}) {
|
|
|
153
153
|
// Cannot migrate without userDid - skip for now
|
|
154
154
|
result.errors.push({
|
|
155
155
|
key: oldKey,
|
|
156
|
-
error:
|
|
156
|
+
error: "Cannot resolve userDid - skipping migration",
|
|
157
157
|
});
|
|
158
158
|
result.failed++;
|
|
159
159
|
continue;
|
|
@@ -187,7 +187,7 @@ async function migrateDelegationKeys(storage, options = {}) {
|
|
|
187
187
|
}
|
|
188
188
|
catch (error) {
|
|
189
189
|
result.errors.push({
|
|
190
|
-
key:
|
|
190
|
+
key: "migration",
|
|
191
191
|
error: error instanceof Error ? error.message : String(error),
|
|
192
192
|
});
|
|
193
193
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kya-os/mcp-i-core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.25",
|
|
4
4
|
"description": "Core runtime and types for MCP-I framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"prepublishOnly": "npm run build && node ../create-mcpi-app/scripts/validate-no-workspace.js"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@kya-os/contracts": "^1.6.
|
|
31
|
+
"@kya-os/contracts": "^1.6.18",
|
|
32
32
|
"jose": "^5.6.3",
|
|
33
33
|
"json-canonicalize": "^2.0.0",
|
|
34
34
|
"zod": "^3.25.76"
|