@vess-id/ai-identity 0.2.0 → 0.3.1
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/agent/agent-did-manager.d.ts +50 -0
- package/dist/agent/agent-did-manager.d.ts.map +1 -0
- package/dist/auth/auth-provider.d.ts +51 -0
- package/dist/auth/auth-provider.d.ts.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/client.d.ts +80 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/config/index.d.ts +30 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/constraint/__tests__/fixtures/constraint.fixtures.d.ts +56 -0
- package/dist/constraint/__tests__/fixtures/constraint.fixtures.d.ts.map +1 -0
- package/dist/constraint/constraint-evaluator.d.ts +72 -0
- package/dist/constraint/constraint-evaluator.d.ts.map +1 -0
- package/dist/constraint/index.d.ts +5 -0
- package/dist/constraint/index.d.ts.map +1 -0
- package/dist/did/agent.d.ts +52 -0
- package/dist/did/agent.d.ts.map +1 -0
- package/dist/did/did-utils.d.ts +75 -0
- package/dist/did/did-utils.d.ts.map +1 -0
- package/dist/did/key-manager.d.ts +19 -0
- package/dist/did/key-manager.d.ts.map +1 -0
- package/dist/gateway/gateway-client.d.ts +103 -0
- package/dist/gateway/gateway-client.d.ts.map +1 -0
- package/dist/gateway/index.d.ts +2 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/grant/grant-manager.d.ts +140 -0
- package/dist/grant/grant-manager.d.ts.map +1 -0
- package/dist/grant/index.d.ts +2 -0
- package/dist/grant/index.d.ts.map +1 -0
- package/dist/identity/device-enroll-manager.d.ts +111 -0
- package/dist/identity/device-enroll-manager.d.ts.map +1 -0
- package/dist/identity/user-identity-manager.d.ts +69 -0
- package/dist/identity/user-identity-manager.d.ts.map +1 -0
- package/dist/identity/user-key-pair-manager.d.ts +22 -0
- package/dist/identity/user-key-pair-manager.d.ts.map +1 -0
- package/dist/index.d.ts +32 -3013
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +483 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +482 -49
- package/dist/index.mjs.map +1 -1
- package/dist/memory/memory-manager.d.ts +71 -0
- package/dist/memory/memory-manager.d.ts.map +1 -0
- package/dist/monitoring/metrics-manager.d.ts +74 -0
- package/dist/monitoring/metrics-manager.d.ts.map +1 -0
- package/dist/organization/disclosure-config-manager.d.ts +61 -0
- package/dist/organization/disclosure-config-manager.d.ts.map +1 -0
- package/dist/organization/key-rotation-manager.d.ts +63 -0
- package/dist/organization/key-rotation-manager.d.ts.map +1 -0
- package/dist/organization/organization-manager.d.ts +38 -0
- package/dist/organization/organization-manager.d.ts.map +1 -0
- package/dist/registry/access-orchestrator.d.ts +183 -0
- package/dist/registry/access-orchestrator.d.ts.map +1 -0
- package/dist/registry/action-registry-json.d.ts +1363 -0
- package/dist/registry/action-registry-json.d.ts.map +1 -0
- package/dist/registry/action-registry.d.ts +65 -0
- package/dist/registry/action-registry.d.ts.map +1 -0
- package/dist/registry/index.d.ts +4 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/revocation/revocation-manager.d.ts +98 -0
- package/dist/revocation/revocation-manager.d.ts.map +1 -0
- package/dist/state/index.d.ts +3 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/json-state-store.d.ts +24 -0
- package/dist/state/json-state-store.d.ts.map +1 -0
- package/dist/state/state-store.interface.d.ts +37 -0
- package/dist/state/state-store.interface.d.ts.map +1 -0
- package/dist/storage/filesystem-key-storage.d.ts +16 -0
- package/dist/storage/filesystem-key-storage.d.ts.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/key-storage.interface.d.ts +42 -0
- package/dist/storage/key-storage.interface.d.ts.map +1 -0
- package/dist/storage/memory-key-storage.d.ts +17 -0
- package/dist/storage/memory-key-storage.d.ts.map +1 -0
- package/dist/tool/tool-manager.d.ts +44 -0
- package/dist/tool/tool-manager.d.ts.map +1 -0
- package/dist/utils/crypto.d.ts +22 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/sdjwt-client.d.ts +168 -0
- package/dist/utils/sdjwt-client.d.ts.map +1 -0
- package/dist/vc/api-vc-manager.d.ts +40 -0
- package/dist/vc/api-vc-manager.d.ts.map +1 -0
- package/dist/vc/vc-manager.d.ts +55 -0
- package/dist/vc/vc-manager.d.ts.map +1 -0
- package/dist/vp/vp-manager.d.ts +40 -0
- package/dist/vp/vp-manager.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/index.d.mts +0 -3014
package/dist/index.mjs
CHANGED
|
@@ -32,26 +32,26 @@ function configure(config) {
|
|
|
32
32
|
function getConfig() {
|
|
33
33
|
return globalConfig;
|
|
34
34
|
}
|
|
35
|
-
function getDidApiUrl(
|
|
35
|
+
function getDidApiUrl(path4) {
|
|
36
36
|
const baseUrl = globalConfig.didApi?.baseUrl || process.env.DID_API_BASE_URL;
|
|
37
37
|
if (!baseUrl) {
|
|
38
38
|
throw new Error("DID API base URL not configured");
|
|
39
39
|
}
|
|
40
|
-
return `${baseUrl}${
|
|
40
|
+
return `${baseUrl}${path4}`;
|
|
41
41
|
}
|
|
42
|
-
function getIssuerApiUrl(
|
|
42
|
+
function getIssuerApiUrl(path4) {
|
|
43
43
|
const baseUrl = globalConfig.issuerApi?.baseUrl || process.env.ISSUER_API_BASE_URL;
|
|
44
44
|
if (!baseUrl) {
|
|
45
45
|
throw new Error("Issuer API base URL not configured");
|
|
46
46
|
}
|
|
47
|
-
return `${baseUrl}${
|
|
47
|
+
return `${baseUrl}${path4}`;
|
|
48
48
|
}
|
|
49
|
-
function getVerifierApiUrl(
|
|
49
|
+
function getVerifierApiUrl(path4) {
|
|
50
50
|
const baseUrl = globalConfig.verifierApi?.baseUrl || process.env.VERIFIER_API_BASE_URL;
|
|
51
51
|
if (!baseUrl) {
|
|
52
52
|
throw new Error("Verifier API base URL not configured");
|
|
53
53
|
}
|
|
54
|
-
return `${baseUrl}${
|
|
54
|
+
return `${baseUrl}${path4}`;
|
|
55
55
|
}
|
|
56
56
|
function getApiHeaders(apiType) {
|
|
57
57
|
const headers = {
|
|
@@ -898,12 +898,12 @@ var AgentDIDManager = class {
|
|
|
898
898
|
* List all agent DIDs
|
|
899
899
|
*/
|
|
900
900
|
async listAgentDIDs() {
|
|
901
|
-
const
|
|
902
|
-
const
|
|
903
|
-
const
|
|
904
|
-
const mappingDir =
|
|
901
|
+
const fs4 = await import("fs/promises");
|
|
902
|
+
const path4 = await import("path");
|
|
903
|
+
const os3 = await import("os");
|
|
904
|
+
const mappingDir = path4.join(os3.homedir(), ".vess-aidentity", "agent-dids");
|
|
905
905
|
try {
|
|
906
|
-
const files = await
|
|
906
|
+
const files = await fs4.readdir(mappingDir);
|
|
907
907
|
const results = [];
|
|
908
908
|
for (const file of files) {
|
|
909
909
|
if (file.endsWith(".did")) {
|
|
@@ -924,24 +924,24 @@ var AgentDIDManager = class {
|
|
|
924
924
|
* Save agent ID -> DID mapping to persistent storage
|
|
925
925
|
*/
|
|
926
926
|
async saveAgentDIDMapping(agentId, did) {
|
|
927
|
-
const
|
|
928
|
-
const
|
|
929
|
-
const
|
|
930
|
-
const mappingDir =
|
|
931
|
-
await
|
|
932
|
-
const mappingFile =
|
|
933
|
-
await
|
|
927
|
+
const fs4 = await import("fs/promises");
|
|
928
|
+
const path4 = await import("path");
|
|
929
|
+
const os3 = await import("os");
|
|
930
|
+
const mappingDir = path4.join(os3.homedir(), ".vess-aidentity", "agent-dids");
|
|
931
|
+
await fs4.mkdir(mappingDir, { recursive: true });
|
|
932
|
+
const mappingFile = path4.join(mappingDir, `${agentId}.did`);
|
|
933
|
+
await fs4.writeFile(mappingFile, did, "utf-8");
|
|
934
934
|
}
|
|
935
935
|
/**
|
|
936
936
|
* Load agent ID -> DID mapping from persistent storage
|
|
937
937
|
*/
|
|
938
938
|
async loadAgentDIDMapping(agentId) {
|
|
939
|
-
const
|
|
940
|
-
const
|
|
941
|
-
const
|
|
942
|
-
const mappingFile =
|
|
939
|
+
const fs4 = await import("fs/promises");
|
|
940
|
+
const path4 = await import("path");
|
|
941
|
+
const os3 = await import("os");
|
|
942
|
+
const mappingFile = path4.join(os3.homedir(), ".vess", "agent-dids", `${agentId}.did`);
|
|
943
943
|
try {
|
|
944
|
-
return await
|
|
944
|
+
return await fs4.readFile(mappingFile, "utf-8");
|
|
945
945
|
} catch {
|
|
946
946
|
return null;
|
|
947
947
|
}
|
|
@@ -950,12 +950,12 @@ var AgentDIDManager = class {
|
|
|
950
950
|
* Delete agent ID -> DID mapping from persistent storage
|
|
951
951
|
*/
|
|
952
952
|
async deleteAgentDIDMapping(agentId) {
|
|
953
|
-
const
|
|
954
|
-
const
|
|
955
|
-
const
|
|
956
|
-
const mappingFile =
|
|
953
|
+
const fs4 = await import("fs/promises");
|
|
954
|
+
const path4 = await import("path");
|
|
955
|
+
const os3 = await import("os");
|
|
956
|
+
const mappingFile = path4.join(os3.homedir(), ".vess", "agent-dids", `${agentId}.did`);
|
|
957
957
|
try {
|
|
958
|
-
await
|
|
958
|
+
await fs4.unlink(mappingFile);
|
|
959
959
|
} catch {
|
|
960
960
|
}
|
|
961
961
|
}
|
|
@@ -1227,24 +1227,24 @@ var UserIdentityManager = class {
|
|
|
1227
1227
|
* Save current user DID to persistent storage
|
|
1228
1228
|
*/
|
|
1229
1229
|
async saveUserDID(did) {
|
|
1230
|
-
const
|
|
1231
|
-
const
|
|
1232
|
-
const
|
|
1233
|
-
const configDir =
|
|
1234
|
-
await
|
|
1235
|
-
const userDIDFile =
|
|
1236
|
-
await
|
|
1230
|
+
const fs4 = await import("fs/promises");
|
|
1231
|
+
const path4 = await import("path");
|
|
1232
|
+
const os3 = await import("os");
|
|
1233
|
+
const configDir = path4.join(os3.homedir(), ".vess-aidentity");
|
|
1234
|
+
await fs4.mkdir(configDir, { recursive: true });
|
|
1235
|
+
const userDIDFile = path4.join(configDir, "user-did.txt");
|
|
1236
|
+
await fs4.writeFile(userDIDFile, did, "utf-8");
|
|
1237
1237
|
}
|
|
1238
1238
|
/**
|
|
1239
1239
|
* Load current user DID from persistent storage
|
|
1240
1240
|
*/
|
|
1241
1241
|
async loadUserDID() {
|
|
1242
|
-
const
|
|
1243
|
-
const
|
|
1244
|
-
const
|
|
1245
|
-
const userDIDFile =
|
|
1242
|
+
const fs4 = await import("fs/promises");
|
|
1243
|
+
const path4 = await import("path");
|
|
1244
|
+
const os3 = await import("os");
|
|
1245
|
+
const userDIDFile = path4.join(os3.homedir(), ".vess-aidentity", "user-did.txt");
|
|
1246
1246
|
try {
|
|
1247
|
-
return await
|
|
1247
|
+
return await fs4.readFile(userDIDFile, "utf-8");
|
|
1248
1248
|
} catch {
|
|
1249
1249
|
return null;
|
|
1250
1250
|
}
|
|
@@ -1253,12 +1253,12 @@ var UserIdentityManager = class {
|
|
|
1253
1253
|
* Clear saved user DID
|
|
1254
1254
|
*/
|
|
1255
1255
|
async clearUserDID() {
|
|
1256
|
-
const
|
|
1257
|
-
const
|
|
1258
|
-
const
|
|
1259
|
-
const userDIDFile =
|
|
1256
|
+
const fs4 = await import("fs/promises");
|
|
1257
|
+
const path4 = await import("path");
|
|
1258
|
+
const os3 = await import("os");
|
|
1259
|
+
const userDIDFile = path4.join(os3.homedir(), ".vess-aidentity", "user-did.txt");
|
|
1260
1260
|
try {
|
|
1261
|
-
await
|
|
1261
|
+
await fs4.unlink(userDIDFile);
|
|
1262
1262
|
} catch {
|
|
1263
1263
|
}
|
|
1264
1264
|
}
|
|
@@ -2772,6 +2772,137 @@ var UserKeyPairManager = class {
|
|
|
2772
2772
|
}
|
|
2773
2773
|
};
|
|
2774
2774
|
|
|
2775
|
+
// src/identity/device-enroll-manager.ts
|
|
2776
|
+
var DeviceEnrollManager = class {
|
|
2777
|
+
baseUrl;
|
|
2778
|
+
constructor(baseUrl) {
|
|
2779
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
2780
|
+
}
|
|
2781
|
+
/**
|
|
2782
|
+
* Start the device enrollment flow.
|
|
2783
|
+
* Sends the root DID public key to the Gateway and gets a user code.
|
|
2784
|
+
*
|
|
2785
|
+
* @param params - Root DID public info and client metadata
|
|
2786
|
+
* @returns Request ID, user code, and verification URL
|
|
2787
|
+
*/
|
|
2788
|
+
async startDeviceEnrollment(params) {
|
|
2789
|
+
const response = await fetch(`${this.baseUrl}/api/v1/device/start`, {
|
|
2790
|
+
method: "POST",
|
|
2791
|
+
headers: { "Content-Type": "application/json" },
|
|
2792
|
+
body: JSON.stringify({
|
|
2793
|
+
rootDid: params.rootDid,
|
|
2794
|
+
publicKeyJwk: params.publicKeyJwk,
|
|
2795
|
+
clientInfo: params.clientInfo,
|
|
2796
|
+
purpose: params.purpose || "root_did_enrollment"
|
|
2797
|
+
})
|
|
2798
|
+
});
|
|
2799
|
+
if (!response.ok) {
|
|
2800
|
+
const errorBody = await response.text();
|
|
2801
|
+
throw new Error(
|
|
2802
|
+
`Failed to start device enrollment: ${response.status} - ${errorBody}`
|
|
2803
|
+
);
|
|
2804
|
+
}
|
|
2805
|
+
const body = await response.json();
|
|
2806
|
+
if (!body.success) {
|
|
2807
|
+
throw new Error(`Failed to start device enrollment: ${JSON.stringify(body)}`);
|
|
2808
|
+
}
|
|
2809
|
+
return body.data;
|
|
2810
|
+
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Start the device enrollment flow with server-side DID generation.
|
|
2813
|
+
* The server generates the real key pair on approval (not at start time).
|
|
2814
|
+
* Use this for remote/cloud-managed mode.
|
|
2815
|
+
*
|
|
2816
|
+
* @param params - Client metadata (no DID or key needed)
|
|
2817
|
+
* @returns Request ID, user code, and verification URL
|
|
2818
|
+
*/
|
|
2819
|
+
async startServerSideEnrollment(params) {
|
|
2820
|
+
const response = await fetch(`${this.baseUrl}/api/v1/device/start`, {
|
|
2821
|
+
method: "POST",
|
|
2822
|
+
headers: { "Content-Type": "application/json" },
|
|
2823
|
+
body: JSON.stringify({
|
|
2824
|
+
generateServerSide: true,
|
|
2825
|
+
clientInfo: params.clientInfo,
|
|
2826
|
+
purpose: params.purpose || "root_did_enrollment"
|
|
2827
|
+
})
|
|
2828
|
+
});
|
|
2829
|
+
if (!response.ok) {
|
|
2830
|
+
const errorBody = await response.text();
|
|
2831
|
+
throw new Error(
|
|
2832
|
+
`Failed to start device enrollment: ${response.status} - ${errorBody}`
|
|
2833
|
+
);
|
|
2834
|
+
}
|
|
2835
|
+
const body = await response.json();
|
|
2836
|
+
if (!body.success) {
|
|
2837
|
+
throw new Error(`Failed to start device enrollment: ${JSON.stringify(body)}`);
|
|
2838
|
+
}
|
|
2839
|
+
return body.data;
|
|
2840
|
+
}
|
|
2841
|
+
/**
|
|
2842
|
+
* Poll for enrollment status.
|
|
2843
|
+
* Call this periodically after startDeviceEnrollment() to check if
|
|
2844
|
+
* the user has approved the enrollment in the web UI.
|
|
2845
|
+
*
|
|
2846
|
+
* @param requestId - The request ID from startDeviceEnrollment()
|
|
2847
|
+
* @returns Current status and token if approved
|
|
2848
|
+
*/
|
|
2849
|
+
async pollDeviceEnrollment(requestId) {
|
|
2850
|
+
const response = await fetch(`${this.baseUrl}/api/v1/device/poll`, {
|
|
2851
|
+
method: "POST",
|
|
2852
|
+
headers: { "Content-Type": "application/json" },
|
|
2853
|
+
body: JSON.stringify({ requestId })
|
|
2854
|
+
});
|
|
2855
|
+
if (!response.ok) {
|
|
2856
|
+
const errorBody = await response.text();
|
|
2857
|
+
throw new Error(
|
|
2858
|
+
`Failed to poll device enrollment: ${response.status} - ${errorBody}`
|
|
2859
|
+
);
|
|
2860
|
+
}
|
|
2861
|
+
const body = await response.json();
|
|
2862
|
+
if (!body.success) {
|
|
2863
|
+
throw new Error(`Failed to poll device enrollment: ${JSON.stringify(body)}`);
|
|
2864
|
+
}
|
|
2865
|
+
return body.data;
|
|
2866
|
+
}
|
|
2867
|
+
/**
|
|
2868
|
+
* Convenience method: Start enrollment and poll until completion.
|
|
2869
|
+
* Returns the final result (approved, expired, or denied).
|
|
2870
|
+
*
|
|
2871
|
+
* @param params - Enrollment parameters (client-generated mode)
|
|
2872
|
+
* @param onUserCode - Callback when user code is available (present to user)
|
|
2873
|
+
* @param pollIntervalMs - Polling interval in ms (default: 3000)
|
|
2874
|
+
* @param maxPolls - Maximum number of poll attempts (default: 120)
|
|
2875
|
+
*/
|
|
2876
|
+
async enrollAndWait(params, onUserCode, pollIntervalMs = 3e3, maxPolls = 120) {
|
|
2877
|
+
const startResult = await this.startDeviceEnrollment(params);
|
|
2878
|
+
return this.pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls);
|
|
2879
|
+
}
|
|
2880
|
+
/**
|
|
2881
|
+
* Convenience method: Start server-side enrollment and poll until completion.
|
|
2882
|
+
* Returns the final result including the server-generated rootDid on approval.
|
|
2883
|
+
*
|
|
2884
|
+
* @param params - Client metadata (server-generated mode)
|
|
2885
|
+
* @param onUserCode - Callback when user code is available (present to user)
|
|
2886
|
+
* @param pollIntervalMs - Polling interval in ms (default: 3000)
|
|
2887
|
+
* @param maxPolls - Maximum number of poll attempts (default: 120)
|
|
2888
|
+
*/
|
|
2889
|
+
async enrollServerSideAndWait(params, onUserCode, pollIntervalMs = 3e3, maxPolls = 120) {
|
|
2890
|
+
const startResult = await this.startServerSideEnrollment(params);
|
|
2891
|
+
return this.pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls);
|
|
2892
|
+
}
|
|
2893
|
+
async pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls) {
|
|
2894
|
+
onUserCode(startResult);
|
|
2895
|
+
for (let i = 0; i < maxPolls; i++) {
|
|
2896
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
2897
|
+
const pollResult = await this.pollDeviceEnrollment(startResult.requestId);
|
|
2898
|
+
if (pollResult.status !== "pending") {
|
|
2899
|
+
return pollResult;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
return { status: "expired" };
|
|
2903
|
+
}
|
|
2904
|
+
};
|
|
2905
|
+
|
|
2775
2906
|
// src/vc/api-vc-manager.ts
|
|
2776
2907
|
import {
|
|
2777
2908
|
CredentialType as CredentialType2
|
|
@@ -3831,11 +3962,308 @@ function evaluateConstraints(constraints, context, currentInvocations, expiresAt
|
|
|
3831
3962
|
return defaultConstraintEvaluator.evaluate(constraints, context, currentInvocations, expiresAt);
|
|
3832
3963
|
}
|
|
3833
3964
|
|
|
3965
|
+
// src/state/json-state-store.ts
|
|
3966
|
+
import * as fs2 from "fs/promises";
|
|
3967
|
+
import * as path2 from "path";
|
|
3968
|
+
import * as os2 from "os";
|
|
3969
|
+
var JsonStateStore = class {
|
|
3970
|
+
filePath;
|
|
3971
|
+
data = null;
|
|
3972
|
+
constructor(filePath) {
|
|
3973
|
+
this.filePath = filePath || path2.join(os2.homedir(), ".vess", "state.json");
|
|
3974
|
+
}
|
|
3975
|
+
async get(key) {
|
|
3976
|
+
const data = await this.load();
|
|
3977
|
+
return getNestedValue(data, key);
|
|
3978
|
+
}
|
|
3979
|
+
async set(key, value) {
|
|
3980
|
+
const data = await this.load();
|
|
3981
|
+
setNestedValue(data, key, value);
|
|
3982
|
+
await this.save(data);
|
|
3983
|
+
}
|
|
3984
|
+
async delete(key) {
|
|
3985
|
+
const data = await this.load();
|
|
3986
|
+
const existed = getNestedValue(data, key) !== void 0;
|
|
3987
|
+
if (existed) {
|
|
3988
|
+
deleteNestedValue(data, key);
|
|
3989
|
+
await this.save(data);
|
|
3990
|
+
}
|
|
3991
|
+
return existed;
|
|
3992
|
+
}
|
|
3993
|
+
async has(key) {
|
|
3994
|
+
const data = await this.load();
|
|
3995
|
+
return getNestedValue(data, key) !== void 0;
|
|
3996
|
+
}
|
|
3997
|
+
async getAll() {
|
|
3998
|
+
return { ...await this.load() };
|
|
3999
|
+
}
|
|
4000
|
+
async clear() {
|
|
4001
|
+
this.data = {};
|
|
4002
|
+
await this.save(this.data);
|
|
4003
|
+
}
|
|
4004
|
+
/**
|
|
4005
|
+
* Get the file path used by this store (useful for diagnostics)
|
|
4006
|
+
*/
|
|
4007
|
+
getFilePath() {
|
|
4008
|
+
return this.filePath;
|
|
4009
|
+
}
|
|
4010
|
+
async load() {
|
|
4011
|
+
if (this.data !== null) {
|
|
4012
|
+
return this.data;
|
|
4013
|
+
}
|
|
4014
|
+
try {
|
|
4015
|
+
const raw = await fs2.readFile(this.filePath, "utf-8");
|
|
4016
|
+
this.data = JSON.parse(raw);
|
|
4017
|
+
} catch (err) {
|
|
4018
|
+
if (err.code === "ENOENT") {
|
|
4019
|
+
this.data = {};
|
|
4020
|
+
} else if (err instanceof SyntaxError) {
|
|
4021
|
+
this.data = {};
|
|
4022
|
+
} else {
|
|
4023
|
+
throw err;
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
return this.data;
|
|
4027
|
+
}
|
|
4028
|
+
async save(data) {
|
|
4029
|
+
this.data = data;
|
|
4030
|
+
const dir = path2.dirname(this.filePath);
|
|
4031
|
+
await fs2.mkdir(dir, { recursive: true, mode: 448 });
|
|
4032
|
+
const tmpPath = this.filePath + ".tmp";
|
|
4033
|
+
await fs2.writeFile(tmpPath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
|
|
4034
|
+
await fs2.rename(tmpPath, this.filePath);
|
|
4035
|
+
}
|
|
4036
|
+
};
|
|
4037
|
+
function getNestedValue(obj, key) {
|
|
4038
|
+
const parts = key.split(".");
|
|
4039
|
+
let current = obj;
|
|
4040
|
+
for (const part of parts) {
|
|
4041
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
4042
|
+
return void 0;
|
|
4043
|
+
}
|
|
4044
|
+
current = current[part];
|
|
4045
|
+
}
|
|
4046
|
+
return current;
|
|
4047
|
+
}
|
|
4048
|
+
function setNestedValue(obj, key, value) {
|
|
4049
|
+
const parts = key.split(".");
|
|
4050
|
+
let current = obj;
|
|
4051
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
4052
|
+
const part = parts[i];
|
|
4053
|
+
if (current[part] === void 0 || current[part] === null || typeof current[part] !== "object") {
|
|
4054
|
+
current[part] = {};
|
|
4055
|
+
}
|
|
4056
|
+
current = current[part];
|
|
4057
|
+
}
|
|
4058
|
+
current[parts[parts.length - 1]] = value;
|
|
4059
|
+
}
|
|
4060
|
+
function deleteNestedValue(obj, key) {
|
|
4061
|
+
const parts = key.split(".");
|
|
4062
|
+
let current = obj;
|
|
4063
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
4064
|
+
const part = parts[i];
|
|
4065
|
+
if (current[part] === void 0 || typeof current[part] !== "object") {
|
|
4066
|
+
return;
|
|
4067
|
+
}
|
|
4068
|
+
current = current[part];
|
|
4069
|
+
}
|
|
4070
|
+
delete current[parts[parts.length - 1]];
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
// src/gateway/gateway-client.ts
|
|
4074
|
+
var GatewayClient = class {
|
|
4075
|
+
baseUrl;
|
|
4076
|
+
stateStore;
|
|
4077
|
+
apiKey;
|
|
4078
|
+
sessionToken;
|
|
4079
|
+
constructor(options) {
|
|
4080
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
4081
|
+
this.stateStore = options.stateStore;
|
|
4082
|
+
this.apiKey = options.apiKey;
|
|
4083
|
+
this.sessionToken = options.sessionToken;
|
|
4084
|
+
}
|
|
4085
|
+
/**
|
|
4086
|
+
* Set session token for authenticated requests
|
|
4087
|
+
*/
|
|
4088
|
+
setSessionToken(token) {
|
|
4089
|
+
this.sessionToken = token;
|
|
4090
|
+
}
|
|
4091
|
+
/**
|
|
4092
|
+
* Fetch events from the Gateway.
|
|
4093
|
+
* If cursor is not provided, attempts to load it from StateStore.
|
|
4094
|
+
*
|
|
4095
|
+
* NOTE: The /events long-poll endpoint may not be implemented on the API server yet.
|
|
4096
|
+
* This client is designed to work once the endpoint is available.
|
|
4097
|
+
*/
|
|
4098
|
+
async getEvents(options = {}) {
|
|
4099
|
+
let cursor = options.cursor;
|
|
4100
|
+
if (!cursor && this.stateStore) {
|
|
4101
|
+
cursor = await this.stateStore.get("events.cursor");
|
|
4102
|
+
}
|
|
4103
|
+
const params = new URLSearchParams();
|
|
4104
|
+
if (cursor) params.set("cursor", cursor);
|
|
4105
|
+
if (options.limit) params.set("limit", String(options.limit));
|
|
4106
|
+
if (options.waitSeconds !== void 0) params.set("wait", String(options.waitSeconds));
|
|
4107
|
+
const url = `${this.baseUrl}/api/v1/events?${params.toString()}`;
|
|
4108
|
+
const response = await fetch(url, {
|
|
4109
|
+
method: "GET",
|
|
4110
|
+
headers: this.buildHeaders()
|
|
4111
|
+
});
|
|
4112
|
+
if (!response.ok) {
|
|
4113
|
+
const body = await response.text().catch(() => "");
|
|
4114
|
+
throw new GatewayError(
|
|
4115
|
+
`getEvents failed: ${response.status} ${response.statusText}`,
|
|
4116
|
+
response.status,
|
|
4117
|
+
body
|
|
4118
|
+
);
|
|
4119
|
+
}
|
|
4120
|
+
const result = await response.json();
|
|
4121
|
+
if (result.cursor && this.stateStore) {
|
|
4122
|
+
await this.stateStore.set("events.cursor", result.cursor);
|
|
4123
|
+
}
|
|
4124
|
+
return result;
|
|
4125
|
+
}
|
|
4126
|
+
/**
|
|
4127
|
+
* Acknowledge an event (mark as processed).
|
|
4128
|
+
*
|
|
4129
|
+
* NOTE: The /events/:id/ack endpoint may not be implemented on the API server yet.
|
|
4130
|
+
*/
|
|
4131
|
+
async ackEvent(eventId) {
|
|
4132
|
+
const url = `${this.baseUrl}/api/v1/events/${encodeURIComponent(eventId)}/ack`;
|
|
4133
|
+
const response = await fetch(url, {
|
|
4134
|
+
method: "POST",
|
|
4135
|
+
headers: this.buildHeaders()
|
|
4136
|
+
});
|
|
4137
|
+
if (!response.ok) {
|
|
4138
|
+
const body = await response.text().catch(() => "");
|
|
4139
|
+
throw new GatewayError(
|
|
4140
|
+
`ackEvent failed: ${response.status} ${response.statusText}`,
|
|
4141
|
+
response.status,
|
|
4142
|
+
body
|
|
4143
|
+
);
|
|
4144
|
+
}
|
|
4145
|
+
return await response.json();
|
|
4146
|
+
}
|
|
4147
|
+
/**
|
|
4148
|
+
* Validate an API key against the Gateway.
|
|
4149
|
+
*
|
|
4150
|
+
* @param apiKey API key to validate
|
|
4151
|
+
* @param projectId Optional project scope
|
|
4152
|
+
* @param requiredScopes Scopes the caller needs — callers should pass the
|
|
4153
|
+
* scopes relevant to their context (e.g. MCP passes
|
|
4154
|
+
* ['mcp:tools:*', 'mcp:memory:*']).
|
|
4155
|
+
*/
|
|
4156
|
+
async validateApiKey(apiKey, projectId, requiredScopes) {
|
|
4157
|
+
const url = `${this.baseUrl}/api/mcp/api-keys/validate`;
|
|
4158
|
+
const body = { projectId };
|
|
4159
|
+
if (requiredScopes && requiredScopes.length > 0) {
|
|
4160
|
+
body.requiredScopes = requiredScopes;
|
|
4161
|
+
}
|
|
4162
|
+
const response = await fetch(url, {
|
|
4163
|
+
method: "POST",
|
|
4164
|
+
headers: {
|
|
4165
|
+
"Content-Type": "application/json",
|
|
4166
|
+
"X-API-Key": apiKey
|
|
4167
|
+
},
|
|
4168
|
+
body: JSON.stringify(body)
|
|
4169
|
+
});
|
|
4170
|
+
if (!response.ok) {
|
|
4171
|
+
return { valid: false };
|
|
4172
|
+
}
|
|
4173
|
+
return await response.json();
|
|
4174
|
+
}
|
|
4175
|
+
buildHeaders() {
|
|
4176
|
+
const headers = {
|
|
4177
|
+
"Content-Type": "application/json"
|
|
4178
|
+
};
|
|
4179
|
+
if (this.apiKey) {
|
|
4180
|
+
headers["X-API-Key"] = this.apiKey;
|
|
4181
|
+
}
|
|
4182
|
+
if (this.sessionToken) {
|
|
4183
|
+
headers["Authorization"] = `Bearer ${this.sessionToken}`;
|
|
4184
|
+
}
|
|
4185
|
+
return headers;
|
|
4186
|
+
}
|
|
4187
|
+
};
|
|
4188
|
+
var GatewayError = class extends Error {
|
|
4189
|
+
constructor(message, statusCode, responseBody) {
|
|
4190
|
+
super(message);
|
|
4191
|
+
this.statusCode = statusCode;
|
|
4192
|
+
this.responseBody = responseBody;
|
|
4193
|
+
this.name = "GatewayError";
|
|
4194
|
+
}
|
|
4195
|
+
};
|
|
4196
|
+
|
|
4197
|
+
// src/auth/auth-provider.ts
|
|
4198
|
+
var AuthProvider = class {
|
|
4199
|
+
stateStore;
|
|
4200
|
+
gatewayClient;
|
|
4201
|
+
constructor(stateStore, gatewayClient) {
|
|
4202
|
+
this.stateStore = stateStore;
|
|
4203
|
+
this.gatewayClient = gatewayClient;
|
|
4204
|
+
}
|
|
4205
|
+
/**
|
|
4206
|
+
* Authenticate with an API key. Validates against the Gateway and
|
|
4207
|
+
* persists the result in the StateStore.
|
|
4208
|
+
*
|
|
4209
|
+
* @returns The validation result
|
|
4210
|
+
*/
|
|
4211
|
+
async login(apiKey, apiUrl, projectId) {
|
|
4212
|
+
const result = await this.gatewayClient.validateApiKey(apiKey, projectId);
|
|
4213
|
+
if (result.valid) {
|
|
4214
|
+
const authState = {
|
|
4215
|
+
apiKey,
|
|
4216
|
+
apiUrl,
|
|
4217
|
+
userId: result.userId,
|
|
4218
|
+
projectId: result.projectId || projectId,
|
|
4219
|
+
scopes: result.scopes,
|
|
4220
|
+
authenticatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4221
|
+
};
|
|
4222
|
+
await this.stateStore.set("auth", authState);
|
|
4223
|
+
}
|
|
4224
|
+
return result;
|
|
4225
|
+
}
|
|
4226
|
+
/**
|
|
4227
|
+
* Get the current auth state from the StateStore.
|
|
4228
|
+
* Returns undefined if not authenticated.
|
|
4229
|
+
*/
|
|
4230
|
+
async getAuthState() {
|
|
4231
|
+
return this.stateStore.get("auth");
|
|
4232
|
+
}
|
|
4233
|
+
/**
|
|
4234
|
+
* Check if we have stored auth credentials
|
|
4235
|
+
*/
|
|
4236
|
+
async isAuthenticated() {
|
|
4237
|
+
const auth = await this.getAuthState();
|
|
4238
|
+
return auth !== void 0 && auth.apiKey !== void 0;
|
|
4239
|
+
}
|
|
4240
|
+
/**
|
|
4241
|
+
* Clear auth state (logout)
|
|
4242
|
+
*/
|
|
4243
|
+
async logout() {
|
|
4244
|
+
await this.stateStore.delete("auth");
|
|
4245
|
+
}
|
|
4246
|
+
/**
|
|
4247
|
+
* Get the stored API key, or undefined if not authenticated
|
|
4248
|
+
*/
|
|
4249
|
+
async getApiKey() {
|
|
4250
|
+
const auth = await this.getAuthState();
|
|
4251
|
+
return auth?.apiKey;
|
|
4252
|
+
}
|
|
4253
|
+
/**
|
|
4254
|
+
* Get the stored API URL, or undefined if not authenticated
|
|
4255
|
+
*/
|
|
4256
|
+
async getApiUrl() {
|
|
4257
|
+
const auth = await this.getAuthState();
|
|
4258
|
+
return auth?.apiUrl;
|
|
4259
|
+
}
|
|
4260
|
+
};
|
|
4261
|
+
|
|
3834
4262
|
// src/registry/action-registry.ts
|
|
3835
4263
|
import Ajv from "ajv";
|
|
3836
4264
|
import addFormats from "ajv-formats";
|
|
3837
|
-
import
|
|
3838
|
-
import
|
|
4265
|
+
import fs3 from "fs/promises";
|
|
4266
|
+
import path3 from "path";
|
|
3839
4267
|
var actionMetaSchema = {
|
|
3840
4268
|
$id: "https://vess.ai/schemas/action-meta.json",
|
|
3841
4269
|
type: "object",
|
|
@@ -3980,8 +4408,8 @@ function formatAjvErrors(errors) {
|
|
|
3980
4408
|
});
|
|
3981
4409
|
}
|
|
3982
4410
|
async function loadActionRegistryFromFile(filePath) {
|
|
3983
|
-
const abs =
|
|
3984
|
-
const raw = await
|
|
4411
|
+
const abs = path3.resolve(filePath);
|
|
4412
|
+
const raw = await fs3.readFile(abs, "utf8");
|
|
3985
4413
|
const json = JSON.parse(raw);
|
|
3986
4414
|
const result = validateRegistryObject(json);
|
|
3987
4415
|
if (!result.ok) {
|
|
@@ -4700,11 +5128,16 @@ export {
|
|
|
4700
5128
|
AgentDIDManager,
|
|
4701
5129
|
AgentManager,
|
|
4702
5130
|
AllowAllAbac,
|
|
5131
|
+
AuthProvider,
|
|
4703
5132
|
ConstraintEvaluator,
|
|
5133
|
+
DeviceEnrollManager,
|
|
4704
5134
|
DisclosureConfigManager,
|
|
4705
5135
|
DummyCreds,
|
|
4706
5136
|
DummyVpVerifier,
|
|
4707
5137
|
FilesystemKeyStorage,
|
|
5138
|
+
GatewayClient,
|
|
5139
|
+
GatewayError,
|
|
5140
|
+
JsonStateStore,
|
|
4708
5141
|
KeyManager,
|
|
4709
5142
|
KeyRotationManager,
|
|
4710
5143
|
MemoryKeyStorage,
|