@vess-id/ai-identity 0.10.0 → 0.12.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 +0 -16
- package/dist/client.d.ts +0 -14
- package/dist/client.d.ts.map +1 -1
- package/dist/index.d.mts +456 -153
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +172 -206
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -205
- package/dist/index.mjs.map +1 -1
- package/dist/internal-signature/__tests__/canonical.spec.d.ts +2 -0
- package/dist/internal-signature/__tests__/canonical.spec.d.ts.map +1 -0
- package/dist/internal-signature/__tests__/signer-roundtrip.spec.d.ts +2 -0
- package/dist/internal-signature/__tests__/signer-roundtrip.spec.d.ts.map +1 -0
- package/dist/internal-signature/__tests__/signer.spec.d.ts +2 -0
- package/dist/internal-signature/__tests__/signer.spec.d.ts.map +1 -0
- package/dist/internal-signature/canonical.d.ts +80 -0
- package/dist/internal-signature/canonical.d.ts.map +1 -0
- package/dist/internal-signature/index.d.ts +17 -0
- package/dist/internal-signature/index.d.ts.map +1 -0
- package/dist/internal-signature/signer.d.ts +76 -0
- package/dist/internal-signature/signer.d.ts.map +1 -0
- package/dist/registry/action-registry-json.d.ts +114 -0
- package/dist/registry/action-registry-json.d.ts.map +1 -1
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/reauth-constants.d.ts +33 -0
- package/dist/registry/reauth-constants.d.ts.map +1 -0
- package/dist/vp/kb-jwt-builder.d.ts +89 -0
- package/dist/vp/kb-jwt-builder.d.ts.map +1 -0
- package/dist/vp/vp-manager.d.ts.map +1 -1
- package/package.json +20 -26
- package/dist/memory/memory-manager.d.ts +0 -77
- package/dist/memory/memory-manager.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1508,6 +1508,56 @@ var VCManager = class {
|
|
|
1508
1508
|
|
|
1509
1509
|
// src/vp/vp-manager.ts
|
|
1510
1510
|
import { digest as digest2 } from "@sd-jwt/crypto-nodejs";
|
|
1511
|
+
|
|
1512
|
+
// src/vp/kb-jwt-builder.ts
|
|
1513
|
+
var KB_JWT_DEFAULT_LIFETIME_SECONDS = 300;
|
|
1514
|
+
function buildKbJwtPayload(args, deps = {}) {
|
|
1515
|
+
const now = deps.now ?? Date.now;
|
|
1516
|
+
const iatSeconds = Math.floor(now() / 1e3);
|
|
1517
|
+
const kbExpCap = iatSeconds + KB_JWT_DEFAULT_LIFETIME_SECONDS;
|
|
1518
|
+
const vcExp = readVcExpSeconds(args.vcCredential);
|
|
1519
|
+
const expSeconds = vcExp !== void 0 ? Math.min(kbExpCap, vcExp) : kbExpCap;
|
|
1520
|
+
if (expSeconds <= iatSeconds) {
|
|
1521
|
+
throw new Error(
|
|
1522
|
+
`VC has expired: cannot issue KB-JWT (vc.exp=${vcExp}, now=${iatSeconds})`
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
return {
|
|
1526
|
+
iss: args.holderDid,
|
|
1527
|
+
aud: normalizeDomain(args.audience),
|
|
1528
|
+
nonce: args.nonce,
|
|
1529
|
+
iat: iatSeconds,
|
|
1530
|
+
exp: expSeconds
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1533
|
+
function readVcExpSeconds(sdJwtVc) {
|
|
1534
|
+
try {
|
|
1535
|
+
const jwtPart = sdJwtVc.split("~")[0];
|
|
1536
|
+
const payloadB64 = jwtPart.split(".")[1];
|
|
1537
|
+
if (!payloadB64) return void 0;
|
|
1538
|
+
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
1539
|
+
return typeof payload.exp === "number" ? payload.exp : void 0;
|
|
1540
|
+
} catch {
|
|
1541
|
+
return void 0;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
function normalizeDomain(domain) {
|
|
1545
|
+
if (!domain) return domain;
|
|
1546
|
+
let urlStr;
|
|
1547
|
+
if (/^https?:\/\//i.test(domain)) {
|
|
1548
|
+
urlStr = domain;
|
|
1549
|
+
} else {
|
|
1550
|
+
const scheme = /^localhost(:\d+)?$/i.test(domain) ? "http" : "https";
|
|
1551
|
+
urlStr = `${scheme}://${domain}`;
|
|
1552
|
+
}
|
|
1553
|
+
try {
|
|
1554
|
+
return new URL(urlStr).origin;
|
|
1555
|
+
} catch {
|
|
1556
|
+
return domain;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
// src/vp/vp-manager.ts
|
|
1511
1561
|
var VPManager = class {
|
|
1512
1562
|
keyManager;
|
|
1513
1563
|
constructor(keyManager) {
|
|
@@ -1531,12 +1581,12 @@ var VPManager = class {
|
|
|
1531
1581
|
presentableKeys.forEach((key) => {
|
|
1532
1582
|
presentationFrame[key] = true;
|
|
1533
1583
|
});
|
|
1534
|
-
const kbJwtPayload = {
|
|
1535
|
-
|
|
1536
|
-
|
|
1584
|
+
const kbJwtPayload = buildKbJwtPayload({
|
|
1585
|
+
holderDid: options.holderDid,
|
|
1586
|
+
audience: options.domain,
|
|
1537
1587
|
nonce: options.challenge,
|
|
1538
|
-
|
|
1539
|
-
};
|
|
1588
|
+
vcCredential: sdJwtVC
|
|
1589
|
+
});
|
|
1540
1590
|
const presentation = await sdJwtInstance.present(sdJwtVC, presentationFrame, {
|
|
1541
1591
|
kb: { payload: kbJwtPayload }
|
|
1542
1592
|
});
|
|
@@ -1986,172 +2036,6 @@ var ToolManager = class {
|
|
|
1986
2036
|
}
|
|
1987
2037
|
};
|
|
1988
2038
|
|
|
1989
|
-
// src/memory/memory-manager.ts
|
|
1990
|
-
var MemoryManager = class {
|
|
1991
|
-
vpManager;
|
|
1992
|
-
proxyApiUrl;
|
|
1993
|
-
constructor(vpManager) {
|
|
1994
|
-
this.vpManager = vpManager || new VPManager();
|
|
1995
|
-
const config = getConfig();
|
|
1996
|
-
this.proxyApiUrl = config.proxyApi?.baseUrl || "http://localhost:3000";
|
|
1997
|
-
}
|
|
1998
|
-
/**
|
|
1999
|
-
* Write a document to memory
|
|
2000
|
-
*/
|
|
2001
|
-
async write(content, options) {
|
|
2002
|
-
const domain = new URL(this.proxyApiUrl).hostname;
|
|
2003
|
-
const challenge = this.generateChallenge();
|
|
2004
|
-
const vpJwt = await this.vpManager.create(options.vcs, {
|
|
2005
|
-
holderDid: options.holderDid,
|
|
2006
|
-
challenge,
|
|
2007
|
-
domain,
|
|
2008
|
-
purpose: "write"
|
|
2009
|
-
});
|
|
2010
|
-
const response = await fetch(`${this.proxyApiUrl}/api/v1/memory/${options.namespace}/doc`, {
|
|
2011
|
-
method: "POST",
|
|
2012
|
-
headers: {
|
|
2013
|
-
"Content-Type": "application/json",
|
|
2014
|
-
Authorization: `Bearer ${vpJwt}`
|
|
2015
|
-
},
|
|
2016
|
-
body: JSON.stringify({
|
|
2017
|
-
content,
|
|
2018
|
-
metadata: options.metadata,
|
|
2019
|
-
challenge
|
|
2020
|
-
})
|
|
2021
|
-
});
|
|
2022
|
-
if (!response.ok) {
|
|
2023
|
-
const error = await response.text();
|
|
2024
|
-
throw new Error(`Failed to write to memory: ${error}`);
|
|
2025
|
-
}
|
|
2026
|
-
return response.json();
|
|
2027
|
-
}
|
|
2028
|
-
/**
|
|
2029
|
-
* Query memory with vector search
|
|
2030
|
-
*/
|
|
2031
|
-
async query(query, options) {
|
|
2032
|
-
const domain = new URL(this.proxyApiUrl).hostname;
|
|
2033
|
-
const challenge = this.generateChallenge();
|
|
2034
|
-
const vpJwt = await this.vpManager.create(options.vcs, {
|
|
2035
|
-
holderDid: options.holderDid,
|
|
2036
|
-
challenge,
|
|
2037
|
-
domain,
|
|
2038
|
-
purpose: "read"
|
|
2039
|
-
});
|
|
2040
|
-
const queryParams = {
|
|
2041
|
-
query,
|
|
2042
|
-
namespace: options.namespace,
|
|
2043
|
-
limit: options.limit || 10,
|
|
2044
|
-
filter: options.filter
|
|
2045
|
-
};
|
|
2046
|
-
const namespace = options.namespace || "default";
|
|
2047
|
-
const response = await fetch(`${this.proxyApiUrl}/api/v1/memory/${namespace}/query`, {
|
|
2048
|
-
method: "POST",
|
|
2049
|
-
headers: {
|
|
2050
|
-
"Content-Type": "application/json",
|
|
2051
|
-
Authorization: `Bearer ${vpJwt}`
|
|
2052
|
-
},
|
|
2053
|
-
body: JSON.stringify({
|
|
2054
|
-
...queryParams,
|
|
2055
|
-
challenge
|
|
2056
|
-
})
|
|
2057
|
-
});
|
|
2058
|
-
if (!response.ok) {
|
|
2059
|
-
const error = await response.text();
|
|
2060
|
-
throw new Error(`Failed to query memory: ${error}`);
|
|
2061
|
-
}
|
|
2062
|
-
return response.json();
|
|
2063
|
-
}
|
|
2064
|
-
/**
|
|
2065
|
-
* Delete a document from memory
|
|
2066
|
-
*/
|
|
2067
|
-
async delete(documentId, options) {
|
|
2068
|
-
const domain = new URL(this.proxyApiUrl).hostname;
|
|
2069
|
-
const challenge = this.generateChallenge();
|
|
2070
|
-
const vpJwt = await this.vpManager.create(options.vcs, {
|
|
2071
|
-
holderDid: options.holderDid,
|
|
2072
|
-
challenge,
|
|
2073
|
-
domain,
|
|
2074
|
-
purpose: "delete"
|
|
2075
|
-
});
|
|
2076
|
-
const response = await fetch(
|
|
2077
|
-
`${this.proxyApiUrl}/api/v1/memory/${options.namespace}/${documentId}`,
|
|
2078
|
-
{
|
|
2079
|
-
method: "DELETE",
|
|
2080
|
-
headers: {
|
|
2081
|
-
Authorization: `Bearer ${vpJwt}`,
|
|
2082
|
-
"X-Challenge": challenge
|
|
2083
|
-
}
|
|
2084
|
-
}
|
|
2085
|
-
);
|
|
2086
|
-
if (!response.ok) {
|
|
2087
|
-
const error = await response.text();
|
|
2088
|
-
throw new Error(`Failed to delete from memory: ${error}`);
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
/**
|
|
2092
|
-
* List documents in a namespace
|
|
2093
|
-
*/
|
|
2094
|
-
async list(options) {
|
|
2095
|
-
const domain = new URL(this.proxyApiUrl).hostname;
|
|
2096
|
-
const challenge = this.generateChallenge();
|
|
2097
|
-
const vpJwt = await this.vpManager.create(options.vcs, {
|
|
2098
|
-
holderDid: options.holderDid,
|
|
2099
|
-
challenge,
|
|
2100
|
-
domain,
|
|
2101
|
-
purpose: "read"
|
|
2102
|
-
});
|
|
2103
|
-
const params = new URLSearchParams({
|
|
2104
|
-
limit: (options.limit || 100).toString(),
|
|
2105
|
-
offset: (options.offset || 0).toString()
|
|
2106
|
-
});
|
|
2107
|
-
const response = await fetch(
|
|
2108
|
-
`${this.proxyApiUrl}/api/v1/memory/${options.namespace}/list?${params}`,
|
|
2109
|
-
{
|
|
2110
|
-
headers: {
|
|
2111
|
-
Authorization: `Bearer ${vpJwt}`,
|
|
2112
|
-
"X-Challenge": challenge
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
);
|
|
2116
|
-
if (!response.ok) {
|
|
2117
|
-
const error = await response.text();
|
|
2118
|
-
throw new Error(`Failed to list memory documents: ${error}`);
|
|
2119
|
-
}
|
|
2120
|
-
return response.json();
|
|
2121
|
-
}
|
|
2122
|
-
/**
|
|
2123
|
-
* Check if VCs authorize memory access
|
|
2124
|
-
*/
|
|
2125
|
-
async checkAuthorization(vcs, action, resource) {
|
|
2126
|
-
for (const vcJwt of vcs) {
|
|
2127
|
-
try {
|
|
2128
|
-
const parts = vcJwt.split(".");
|
|
2129
|
-
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
2130
|
-
const vcResource = payload.credentialSubject?.resource;
|
|
2131
|
-
const vcActions = payload.credentialSubject?.actions || [];
|
|
2132
|
-
if (this.matchResource(vcResource, resource)) {
|
|
2133
|
-
if (vcActions.includes(action)) {
|
|
2134
|
-
return true;
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
} catch {
|
|
2138
|
-
continue;
|
|
2139
|
-
}
|
|
2140
|
-
}
|
|
2141
|
-
return false;
|
|
2142
|
-
}
|
|
2143
|
-
matchResource(vcResource, requiredResource) {
|
|
2144
|
-
if (vcResource.endsWith("/*")) {
|
|
2145
|
-
const prefix = vcResource.slice(0, -2);
|
|
2146
|
-
return requiredResource.startsWith(prefix);
|
|
2147
|
-
}
|
|
2148
|
-
return vcResource === requiredResource;
|
|
2149
|
-
}
|
|
2150
|
-
generateChallenge() {
|
|
2151
|
-
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
2152
|
-
}
|
|
2153
|
-
};
|
|
2154
|
-
|
|
2155
2039
|
// src/grant/grant-manager.ts
|
|
2156
2040
|
var GrantManager = class {
|
|
2157
2041
|
constructor(_vpManager) {
|
|
@@ -2393,7 +2277,6 @@ var AIdentityClient = class {
|
|
|
2393
2277
|
vc;
|
|
2394
2278
|
vp;
|
|
2395
2279
|
tool;
|
|
2396
|
-
memory;
|
|
2397
2280
|
grant;
|
|
2398
2281
|
keyManager;
|
|
2399
2282
|
currentAgent;
|
|
@@ -2407,7 +2290,6 @@ var AIdentityClient = class {
|
|
|
2407
2290
|
this.vc = new VCManager(this.keyManager, this.agent, this.user);
|
|
2408
2291
|
this.vp = new VPManager(this.keyManager);
|
|
2409
2292
|
this.tool = new ToolManager(this.vp);
|
|
2410
|
-
this.memory = new MemoryManager(this.vp);
|
|
2411
2293
|
this.grant = new GrantManager(this.vp);
|
|
2412
2294
|
}
|
|
2413
2295
|
/**
|
|
@@ -2491,35 +2373,6 @@ var AIdentityClient = class {
|
|
|
2491
2373
|
holderDid
|
|
2492
2374
|
});
|
|
2493
2375
|
}
|
|
2494
|
-
/**
|
|
2495
|
-
* Write to memory with automatic VP creation
|
|
2496
|
-
*/
|
|
2497
|
-
async writeMemory(content, namespace, vcs, metadata) {
|
|
2498
|
-
const holderDid = this.currentAgent?.did;
|
|
2499
|
-
if (!holderDid) {
|
|
2500
|
-
throw new Error("No current agent available");
|
|
2501
|
-
}
|
|
2502
|
-
return this.memory.write(content, {
|
|
2503
|
-
namespace,
|
|
2504
|
-
metadata,
|
|
2505
|
-
vcs,
|
|
2506
|
-
holderDid
|
|
2507
|
-
});
|
|
2508
|
-
}
|
|
2509
|
-
/**
|
|
2510
|
-
* Query memory with automatic VP creation
|
|
2511
|
-
*/
|
|
2512
|
-
async queryMemory(query, vcs, options) {
|
|
2513
|
-
const holderDid = this.currentAgent?.did;
|
|
2514
|
-
if (!holderDid) {
|
|
2515
|
-
throw new Error("No current agent available");
|
|
2516
|
-
}
|
|
2517
|
-
return this.memory.query(query, {
|
|
2518
|
-
...options,
|
|
2519
|
-
vcs,
|
|
2520
|
-
holderDid
|
|
2521
|
-
});
|
|
2522
|
-
}
|
|
2523
2376
|
};
|
|
2524
2377
|
var defaultClient;
|
|
2525
2378
|
function getClient(config, password) {
|
|
@@ -2786,6 +2639,8 @@ var AIdentityError = class extends Error {
|
|
|
2786
2639
|
this.name = this.constructor.name;
|
|
2787
2640
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
2788
2641
|
}
|
|
2642
|
+
code;
|
|
2643
|
+
details;
|
|
2789
2644
|
};
|
|
2790
2645
|
var VCExpiredError = class extends AIdentityError {
|
|
2791
2646
|
constructor(message = "Verifiable Credential has expired", details) {
|
|
@@ -3946,6 +3801,8 @@ var GatewayError = class extends Error {
|
|
|
3946
3801
|
this.responseBody = responseBody;
|
|
3947
3802
|
this.name = "GatewayError";
|
|
3948
3803
|
}
|
|
3804
|
+
statusCode;
|
|
3805
|
+
responseBody;
|
|
3949
3806
|
};
|
|
3950
3807
|
|
|
3951
3808
|
// src/auth/auth-provider.ts
|
|
@@ -4425,6 +4282,7 @@ var SimpleRebac = class {
|
|
|
4425
4282
|
constructor(allowRelations = ["viewer", "editor", "admin", "owner", "act_as"]) {
|
|
4426
4283
|
this.allowRelations = allowRelations;
|
|
4427
4284
|
}
|
|
4285
|
+
allowRelations;
|
|
4428
4286
|
async check(_sub, relations) {
|
|
4429
4287
|
return relations.some((r) => this.allowRelations.includes(r));
|
|
4430
4288
|
}
|
|
@@ -4439,6 +4297,7 @@ var DummyVpVerifier = class {
|
|
|
4439
4297
|
constructor(vc) {
|
|
4440
4298
|
this.vc = vc;
|
|
4441
4299
|
}
|
|
4300
|
+
vc;
|
|
4442
4301
|
async verifyAndExtractClaims() {
|
|
4443
4302
|
return this.vc;
|
|
4444
4303
|
}
|
|
@@ -4800,7 +4659,10 @@ var ACTION_REGISTRY = {
|
|
|
4800
4659
|
subject: { type: "string", minLength: 1 },
|
|
4801
4660
|
body: { type: "string", minLength: 1 },
|
|
4802
4661
|
cc: { type: "string" },
|
|
4803
|
-
bcc: { type: "string" }
|
|
4662
|
+
bcc: { type: "string" },
|
|
4663
|
+
threadId: { type: "string" },
|
|
4664
|
+
inReplyTo: { type: "string" },
|
|
4665
|
+
references: { type: "string" }
|
|
4804
4666
|
},
|
|
4805
4667
|
required: ["to", "subject", "body"],
|
|
4806
4668
|
additionalProperties: false
|
|
@@ -4830,7 +4692,10 @@ var ACTION_REGISTRY = {
|
|
|
4830
4692
|
subject: { type: "string", minLength: 1 },
|
|
4831
4693
|
body: { type: "string", minLength: 1 },
|
|
4832
4694
|
cc: { type: "string" },
|
|
4833
|
-
bcc: { type: "string" }
|
|
4695
|
+
bcc: { type: "string" },
|
|
4696
|
+
threadId: { type: "string" },
|
|
4697
|
+
inReplyTo: { type: "string" },
|
|
4698
|
+
references: { type: "string" }
|
|
4834
4699
|
},
|
|
4835
4700
|
required: ["to", "subject", "body"],
|
|
4836
4701
|
additionalProperties: false
|
|
@@ -5761,6 +5626,17 @@ function normalizeMcpActionName(toolName, actionName) {
|
|
|
5761
5626
|
return actionName;
|
|
5762
5627
|
}
|
|
5763
5628
|
|
|
5629
|
+
// src/registry/reauth-constants.ts
|
|
5630
|
+
var REAUTH_REQUIRED_ACTION = "reauth_required";
|
|
5631
|
+
var GATEWAY_ERROR_CODE = {
|
|
5632
|
+
/** Upstream OAuth token is revoked — the user must re-auth at the SaaS provider. */
|
|
5633
|
+
REAUTH_REQUIRED: "REAUTH_REQUIRED",
|
|
5634
|
+
/** Local VC/VP is invalid (expired, malformed, signature mismatch). Try VC reissuance. */
|
|
5635
|
+
CREDENTIAL_INVALID: "CREDENTIAL_INVALID",
|
|
5636
|
+
/** VC allowed a different resource than the request targeted. Try a new approval. */
|
|
5637
|
+
RESOURCE_MISMATCH: "RESOURCE_MISMATCH"
|
|
5638
|
+
};
|
|
5639
|
+
|
|
5764
5640
|
// src/registry/action-summary.ts
|
|
5765
5641
|
var ACTION_DISPLAY_CONFIGS = {
|
|
5766
5642
|
"slack.message.post": {
|
|
@@ -6015,6 +5891,70 @@ function getTierLimits(tier) {
|
|
|
6015
5891
|
return TIER_LIMITS[resolveUserTier(tier)];
|
|
6016
5892
|
}
|
|
6017
5893
|
|
|
5894
|
+
// src/internal-signature/canonical.ts
|
|
5895
|
+
import { createHash } from "crypto";
|
|
5896
|
+
var SIGNATURE_HEADER = "x-internal-signature";
|
|
5897
|
+
var SIGNATURE_VERSION_PREFIX = "v1=";
|
|
5898
|
+
function sha256Hex(input) {
|
|
5899
|
+
return createHash("sha256").update(input).digest("hex");
|
|
5900
|
+
}
|
|
5901
|
+
function buildCanonicalString(args) {
|
|
5902
|
+
const { method, path: path4, unixSeconds, rawBody } = args;
|
|
5903
|
+
return [method.toUpperCase(), path4, String(unixSeconds), sha256Hex(rawBody)].join("\n");
|
|
5904
|
+
}
|
|
5905
|
+
function parseSignatureHeader(headerValue) {
|
|
5906
|
+
if (typeof headerValue !== "string" || !headerValue.startsWith(SIGNATURE_VERSION_PREFIX)) {
|
|
5907
|
+
return null;
|
|
5908
|
+
}
|
|
5909
|
+
const payload = headerValue.slice(SIGNATURE_VERSION_PREFIX.length);
|
|
5910
|
+
const parts = payload.split(":");
|
|
5911
|
+
if (parts.length !== 3) return null;
|
|
5912
|
+
const [keyId, tsStr, signature] = parts;
|
|
5913
|
+
if (!keyId || !tsStr || !signature) return null;
|
|
5914
|
+
if (!/^[A-Za-z0-9_-]+$/.test(keyId)) return null;
|
|
5915
|
+
if (!/^\d+$/.test(tsStr)) return null;
|
|
5916
|
+
const unixSeconds = Number(tsStr);
|
|
5917
|
+
if (!Number.isFinite(unixSeconds) || unixSeconds < 0) return null;
|
|
5918
|
+
if (!/^[A-Za-z0-9+/]+=*$/.test(signature)) return null;
|
|
5919
|
+
return { keyId, unixSeconds, signature };
|
|
5920
|
+
}
|
|
5921
|
+
function formatSignatureHeader(parsed) {
|
|
5922
|
+
return `${SIGNATURE_VERSION_PREFIX}${parsed.keyId}:${parsed.unixSeconds}:${parsed.signature}`;
|
|
5923
|
+
}
|
|
5924
|
+
|
|
5925
|
+
// src/internal-signature/signer.ts
|
|
5926
|
+
import { createHmac } from "crypto";
|
|
5927
|
+
var MIN_SIGNER_KEY_BYTES = 32;
|
|
5928
|
+
function signRequest(key, args) {
|
|
5929
|
+
assertKeyMaterial(key);
|
|
5930
|
+
const unixSeconds = args.unixSeconds ?? Math.floor(Date.now() / 1e3);
|
|
5931
|
+
const canonical = buildCanonicalString({
|
|
5932
|
+
method: args.method,
|
|
5933
|
+
path: args.path,
|
|
5934
|
+
unixSeconds,
|
|
5935
|
+
rawBody: args.rawBody
|
|
5936
|
+
});
|
|
5937
|
+
const signature = createHmac("sha256", key.secret).update(canonical).digest("base64");
|
|
5938
|
+
const parsed = {
|
|
5939
|
+
keyId: key.keyId,
|
|
5940
|
+
unixSeconds,
|
|
5941
|
+
signature
|
|
5942
|
+
};
|
|
5943
|
+
return formatSignatureHeader(parsed);
|
|
5944
|
+
}
|
|
5945
|
+
function assertKeyMaterial(k) {
|
|
5946
|
+
if (!k.keyId || !/^[A-Za-z0-9_-]+$/.test(k.keyId)) {
|
|
5947
|
+
throw new Error(
|
|
5948
|
+
`internal-signature signer: invalid keyId ${JSON.stringify(k.keyId)} (must match /^[A-Za-z0-9_-]+$/)`
|
|
5949
|
+
);
|
|
5950
|
+
}
|
|
5951
|
+
if (!Buffer.isBuffer(k.secret) || k.secret.length < MIN_SIGNER_KEY_BYTES) {
|
|
5952
|
+
throw new Error(
|
|
5953
|
+
`internal-signature signer: secret too short for keyId=${k.keyId} (${Buffer.isBuffer(k.secret) ? k.secret.length : "not a Buffer"} bytes; minimum ${MIN_SIGNER_KEY_BYTES} required)`
|
|
5954
|
+
);
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
|
|
6018
5958
|
// src/index.ts
|
|
6019
5959
|
var version = "0.0.1";
|
|
6020
5960
|
export {
|
|
@@ -6040,6 +5980,7 @@ export {
|
|
|
6040
5980
|
DummyCreds,
|
|
6041
5981
|
DummyVpVerifier,
|
|
6042
5982
|
FilesystemKeyStorage,
|
|
5983
|
+
GATEWAY_ERROR_CODE,
|
|
6043
5984
|
GatewayClient,
|
|
6044
5985
|
GatewayError,
|
|
6045
5986
|
GrantResourceType,
|
|
@@ -6048,16 +5989,20 @@ export {
|
|
|
6048
5989
|
InvalidVPError,
|
|
6049
5990
|
InvitationStatus,
|
|
6050
5991
|
JsonStateStore,
|
|
5992
|
+
KB_JWT_DEFAULT_LIFETIME_SECONDS,
|
|
6051
5993
|
KeyManager,
|
|
6052
5994
|
LEGACY_RESOURCE_TYPE_MAP,
|
|
5995
|
+
MIN_SIGNER_KEY_BYTES,
|
|
6053
5996
|
MemoryKeyStorage,
|
|
6054
|
-
MemoryManager,
|
|
6055
5997
|
NetworkError,
|
|
6056
5998
|
OAuthProvider,
|
|
6057
5999
|
PROVIDER_ALIASES,
|
|
6000
|
+
REAUTH_REQUIRED_ACTION,
|
|
6058
6001
|
RESOURCE_TYPES,
|
|
6059
6002
|
ReceiptStatus,
|
|
6060
6003
|
SDJwtClient,
|
|
6004
|
+
SIGNATURE_HEADER,
|
|
6005
|
+
SIGNATURE_VERSION_PREFIX,
|
|
6061
6006
|
ScopeUnmatchedError,
|
|
6062
6007
|
SimpleRebac,
|
|
6063
6008
|
StandardActionCategory,
|
|
@@ -6075,7 +6020,9 @@ export {
|
|
|
6075
6020
|
VCType,
|
|
6076
6021
|
VPManager,
|
|
6077
6022
|
WRITE_ACTION_NAMES,
|
|
6023
|
+
buildCanonicalString,
|
|
6078
6024
|
buildGrantIdFields,
|
|
6025
|
+
buildKbJwtPayload,
|
|
6079
6026
|
canonicalizeAction,
|
|
6080
6027
|
checkPermissionWithVP,
|
|
6081
6028
|
configure,
|
|
@@ -6087,6 +6034,7 @@ export {
|
|
|
6087
6034
|
extractProjectKey,
|
|
6088
6035
|
extractPublicKey,
|
|
6089
6036
|
extractPublicKeyFromDid,
|
|
6037
|
+
formatSignatureHeader,
|
|
6090
6038
|
generateActionParamsDisplay,
|
|
6091
6039
|
generateActionSummary,
|
|
6092
6040
|
generateKeyPair,
|
|
@@ -6113,16 +6061,21 @@ export {
|
|
|
6113
6061
|
isWriteAction,
|
|
6114
6062
|
loadActionRegistryFromFile,
|
|
6115
6063
|
loadActionRegistryFromObject,
|
|
6064
|
+
normalizeDomain,
|
|
6116
6065
|
normalizeMcpActionName,
|
|
6117
6066
|
parseGrantAction,
|
|
6118
6067
|
parseGrantResourceType,
|
|
6068
|
+
parseSignatureHeader,
|
|
6119
6069
|
planDelegationForVC,
|
|
6120
6070
|
publicKeysMatch,
|
|
6071
|
+
readVcExpSeconds,
|
|
6121
6072
|
resolveActionsFromSelection,
|
|
6122
6073
|
resolveProvider,
|
|
6123
6074
|
resolveResourceType,
|
|
6124
6075
|
resolveUserTier,
|
|
6076
|
+
sha256Hex,
|
|
6125
6077
|
signJWT,
|
|
6078
|
+
signRequest,
|
|
6126
6079
|
validateRegistryObject,
|
|
6127
6080
|
vcStatusToCredentialStatus,
|
|
6128
6081
|
verifyJWT,
|