@kya-os/mcp-i-core 1.1.13-canary.2 → 1.2.1-canary.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/dist/__tests__/utils/mock-providers.d.ts +5 -3
- package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
- package/dist/__tests__/utils/mock-providers.js +23 -12
- package/dist/__tests__/utils/mock-providers.js.map +1 -1
- package/dist/index.d.ts +33 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/base.d.ts +18 -3
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js +5 -1
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/memory.d.ts +2 -2
- package/dist/providers/memory.d.ts.map +1 -1
- package/dist/providers/memory.js +9 -5
- package/dist/providers/memory.js.map +1 -1
- package/dist/runtime/base.d.ts +40 -1
- package/dist/runtime/base.d.ts.map +1 -1
- package/dist/runtime/base.js +148 -20
- package/dist/runtime/base.js.map +1 -1
- package/dist/services/access-control.service.d.ts +121 -0
- package/dist/services/access-control.service.d.ts.map +1 -0
- package/dist/services/access-control.service.js +458 -0
- package/dist/services/access-control.service.js.map +1 -0
- package/dist/services/crypto.service.d.ts +69 -0
- package/dist/services/crypto.service.d.ts.map +1 -0
- package/dist/services/crypto.service.js +225 -0
- package/dist/services/crypto.service.js.map +1 -0
- package/dist/services/errors.d.ts +49 -0
- package/dist/services/errors.d.ts.map +1 -0
- package/dist/services/errors.js +66 -0
- package/dist/services/errors.js.map +1 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +8 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/proof-verifier.d.ts +98 -0
- package/dist/services/proof-verifier.d.ts.map +1 -0
- package/dist/services/proof-verifier.js +319 -0
- package/dist/services/proof-verifier.js.map +1 -0
- package/dist/services/storage.service.d.ts +116 -0
- package/dist/services/storage.service.d.ts.map +1 -0
- package/dist/services/storage.service.js +405 -0
- package/dist/services/storage.service.js.map +1 -0
- package/dist/utils/base64.d.ts +31 -0
- package/dist/utils/base64.d.ts.map +1 -0
- package/dist/utils/base64.js +138 -0
- package/dist/utils/base64.js.map +1 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/storage-keys.d.ts +120 -0
- package/dist/utils/storage-keys.d.ts.map +1 -0
- package/dist/utils/storage-keys.js +217 -0
- package/dist/utils/storage-keys.js.map +1 -0
- package/package.json +5 -4
- package/dist/compliance/schema-verifier-v2.d.ts +0 -110
- package/dist/compliance/schema-verifier-v2.d.ts.map +0 -1
- package/dist/compliance/schema-verifier-v2.js +0 -510
- package/dist/compliance/schema-verifier-v2.js.map +0 -1
- package/dist/did/resolver.d.ts +0 -92
- package/dist/did/resolver.d.ts.map +0 -1
- package/dist/did/resolver.js +0 -203
- package/dist/did/resolver.js.map +0 -1
- package/dist/proof/proof-engine.d.ts +0 -89
- package/dist/proof/proof-engine.d.ts.map +0 -1
- package/dist/proof/proof-engine.js +0 -249
- package/dist/proof/proof-engine.js.map +0 -1
- package/dist/runtime/base-v2.d.ts +0 -117
- package/dist/runtime/base-v2.d.ts.map +0 -1
- package/dist/runtime/base-v2.js +0 -328
- package/dist/runtime/base-v2.js.map +0 -1
- package/dist/types/providers.d.ts +0 -142
- package/dist/types/providers.d.ts.map +0 -1
- package/dist/types/providers.js +0 -43
- package/dist/types/providers.js.map +0 -1
- package/dist/verification/interfaces.d.ts +0 -125
- package/dist/verification/interfaces.d.ts.map +0 -1
- package/dist/verification/interfaces.js +0 -101
- package/dist/verification/interfaces.js.map +0 -1
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Access Control API Service
|
|
4
|
+
*
|
|
5
|
+
* Brand-neutral service for interacting with access-control APIs
|
|
6
|
+
* (currently AgentShield/bouncer, but designed to be provider-agnostic).
|
|
7
|
+
*
|
|
8
|
+
* This service provides:
|
|
9
|
+
* - Delegation verification
|
|
10
|
+
* - Configuration fetching
|
|
11
|
+
* - Proof submission
|
|
12
|
+
*
|
|
13
|
+
* @package @kya-os/mcp-i-core
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AccessControlApiService = void 0;
|
|
17
|
+
const agentshield_api_1 = require("@kya-os/contracts/agentshield-api");
|
|
18
|
+
const agentshield_api_2 = require("@kya-os/contracts/agentshield-api");
|
|
19
|
+
/**
|
|
20
|
+
* Generate correlation ID for request tracking
|
|
21
|
+
*/
|
|
22
|
+
function generateCorrelationId() {
|
|
23
|
+
// Use crypto.randomUUID() if available (Node.js 14.17+, Cloudflare Workers)
|
|
24
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
25
|
+
return crypto.randomUUID();
|
|
26
|
+
}
|
|
27
|
+
// Fallback for older environments
|
|
28
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Access Control API Service
|
|
32
|
+
*
|
|
33
|
+
* Handles all interactions with the access-control API (AgentShield/bouncer).
|
|
34
|
+
* Designed to be brand-neutral and work with any access-control provider.
|
|
35
|
+
*/
|
|
36
|
+
class AccessControlApiService {
|
|
37
|
+
config;
|
|
38
|
+
metrics;
|
|
39
|
+
constructor(config) {
|
|
40
|
+
const retryConfig = config.retryConfig || {};
|
|
41
|
+
this.config = {
|
|
42
|
+
retryConfig: {
|
|
43
|
+
maxRetries: retryConfig.maxRetries ?? 3,
|
|
44
|
+
initialDelayMs: retryConfig.initialDelayMs ?? 100,
|
|
45
|
+
maxDelayMs: retryConfig.maxDelayMs ?? 5000,
|
|
46
|
+
},
|
|
47
|
+
logger: config.logger || (() => { }),
|
|
48
|
+
baseUrl: config.baseUrl,
|
|
49
|
+
apiKey: config.apiKey,
|
|
50
|
+
fetchProvider: config.fetchProvider,
|
|
51
|
+
sleepProvider: config.sleepProvider ||
|
|
52
|
+
((ms) => new Promise((resolve) => setTimeout(resolve, ms))),
|
|
53
|
+
};
|
|
54
|
+
this.metrics = {
|
|
55
|
+
successCount: 0,
|
|
56
|
+
errorCount: 0,
|
|
57
|
+
retryCount: 0,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fetch tool protection configuration for an agent
|
|
62
|
+
*
|
|
63
|
+
* GET /api/v1/bouncer/config?agent_did={agentDid}
|
|
64
|
+
*/
|
|
65
|
+
async fetchConfig(options) {
|
|
66
|
+
return this.retryWithBackoff(async () => {
|
|
67
|
+
const correlationId = generateCorrelationId();
|
|
68
|
+
const url = `${this.config.baseUrl}/api/v1/bouncer/config?agent_did=${encodeURIComponent(options.agentDid)}`;
|
|
69
|
+
this.config.logger(`[AccessControl] Fetching config for agent: ${options.agentDid}`, {
|
|
70
|
+
correlationId,
|
|
71
|
+
url,
|
|
72
|
+
});
|
|
73
|
+
const response = await this.config.fetchProvider.fetch(url, {
|
|
74
|
+
method: "GET",
|
|
75
|
+
headers: {
|
|
76
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
"X-Request-ID": correlationId,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
const responseText = await response.text();
|
|
82
|
+
const responseData = this.parseResponseJSON(response, responseText);
|
|
83
|
+
// Handle error responses
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
this.handleErrorResponse(response, responseData);
|
|
86
|
+
}
|
|
87
|
+
// Validate and parse success response
|
|
88
|
+
const parsed = agentshield_api_1.toolProtectionConfigAPIResponseSchema.safeParse(responseData);
|
|
89
|
+
if (!parsed.success) {
|
|
90
|
+
throw new agentshield_api_2.AgentShieldAPIError("invalid_response", "Response validation failed", { zodErrors: parsed.error.errors });
|
|
91
|
+
}
|
|
92
|
+
this.config.logger(`[AccessControl] Config fetched successfully`, {
|
|
93
|
+
correlationId,
|
|
94
|
+
agentDid: options.agentDid,
|
|
95
|
+
});
|
|
96
|
+
return parsed.data;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Verify a delegation token
|
|
101
|
+
*
|
|
102
|
+
* POST /api/v1/bouncer/delegations/verify
|
|
103
|
+
*/
|
|
104
|
+
async verifyDelegation(request, context) {
|
|
105
|
+
return this.retryWithBackoff(async () => {
|
|
106
|
+
const correlationId = generateCorrelationId();
|
|
107
|
+
const url = `${this.config.baseUrl}/api/v1/bouncer/delegations/verify`;
|
|
108
|
+
// Build request body dynamically to handle optional fields
|
|
109
|
+
const requestBody = {
|
|
110
|
+
agent_did: request.agent_did,
|
|
111
|
+
};
|
|
112
|
+
// Add optional fields only if they exist
|
|
113
|
+
if (request.scopes !== undefined) {
|
|
114
|
+
requestBody.scopes = request.scopes;
|
|
115
|
+
}
|
|
116
|
+
// Handle credential_jwt: prefer request, fallback to context
|
|
117
|
+
if (request.credential_jwt !== undefined) {
|
|
118
|
+
requestBody.credential_jwt = request.credential_jwt;
|
|
119
|
+
}
|
|
120
|
+
else if (context?.credentialJwt) {
|
|
121
|
+
requestBody.credential_jwt = context.credentialJwt;
|
|
122
|
+
}
|
|
123
|
+
// Handle delegation_token: prefer request, fallback to context
|
|
124
|
+
if (request.delegation_token !== undefined) {
|
|
125
|
+
requestBody.delegation_token = request.delegation_token;
|
|
126
|
+
}
|
|
127
|
+
else if (context?.delegationToken) {
|
|
128
|
+
requestBody.delegation_token = context.delegationToken;
|
|
129
|
+
}
|
|
130
|
+
if (request.timestamp !== undefined) {
|
|
131
|
+
requestBody.timestamp = request.timestamp;
|
|
132
|
+
}
|
|
133
|
+
if (request.client_info) {
|
|
134
|
+
requestBody.client_info = request.client_info;
|
|
135
|
+
}
|
|
136
|
+
// Remove undefined values to ensure Zod validation passes (optional fields should be omitted, not undefined)
|
|
137
|
+
const cleanedRequestBody = Object.fromEntries(Object.entries(requestBody).filter(([_, value]) => value !== undefined));
|
|
138
|
+
// Validate the cleaned request body
|
|
139
|
+
// Note: Workaround for Zod schema issue where .optional() doesn't properly handle omitted fields
|
|
140
|
+
// See AGENTSHIELD_MCPI_COMPLIANCE_REVIEW.md for details
|
|
141
|
+
const validationResult = agentshield_api_1.verifyDelegationRequestSchema.safeParse(cleanedRequestBody);
|
|
142
|
+
if (!validationResult.success) {
|
|
143
|
+
// Check if the error is specifically about scopes being required when it's omitted
|
|
144
|
+
const scopesError = validationResult.error.errors.find((e) => e.path.includes('scopes') && e.message === 'Required');
|
|
145
|
+
if (scopesError && !('scopes' in cleanedRequestBody)) {
|
|
146
|
+
// This is a known Zod schema issue in AgentShield - scopes is optional but Zod treats it as required
|
|
147
|
+
// Skip validation for this case since the field is correctly omitted
|
|
148
|
+
// TODO: Remove this workaround once AgentShield fixes their schema
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.config.logger(`[AccessControl] Validation failed:`, {
|
|
152
|
+
errors: validationResult.error.errors,
|
|
153
|
+
requestBody: requestBody,
|
|
154
|
+
});
|
|
155
|
+
throw new agentshield_api_2.AgentShieldAPIError("validation_error", "Request validation failed", { zodErrors: validationResult.error.errors });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
this.config.logger(`[AccessControl] Verifying delegation for agent: ${request.agent_did}`, {
|
|
159
|
+
correlationId,
|
|
160
|
+
url,
|
|
161
|
+
hasScopes: (request.scopes?.length || 0) > 0,
|
|
162
|
+
});
|
|
163
|
+
const response = await this.config.fetchProvider.fetch(url, {
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers: {
|
|
166
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
167
|
+
"Content-Type": "application/json",
|
|
168
|
+
"X-Request-ID": correlationId,
|
|
169
|
+
},
|
|
170
|
+
// Use cleanedRequestBody directly instead of validated data
|
|
171
|
+
// because Zod seems to strip optional fields in some cases
|
|
172
|
+
body: JSON.stringify(cleanedRequestBody),
|
|
173
|
+
});
|
|
174
|
+
const responseText = await response.text();
|
|
175
|
+
const responseData = this.parseResponseJSON(response, responseText);
|
|
176
|
+
// Handle error responses
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
this.handleErrorResponse(response, responseData);
|
|
179
|
+
}
|
|
180
|
+
// Validate and parse success response
|
|
181
|
+
const parsed = agentshield_api_1.verifyDelegationAPIResponseSchema.safeParse(responseData);
|
|
182
|
+
if (!parsed.success) {
|
|
183
|
+
throw new agentshield_api_2.AgentShieldAPIError("invalid_response", "Response validation failed", { zodErrors: parsed.error.errors });
|
|
184
|
+
}
|
|
185
|
+
this.config.logger(`[AccessControl] Delegation verified`, {
|
|
186
|
+
correlationId,
|
|
187
|
+
agentDid: request.agent_did,
|
|
188
|
+
valid: parsed.data.data.valid,
|
|
189
|
+
});
|
|
190
|
+
return parsed.data;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Submit proofs for audit and verification
|
|
195
|
+
*
|
|
196
|
+
* POST /api/v1/bouncer/proofs
|
|
197
|
+
*/
|
|
198
|
+
async submitProofs(request) {
|
|
199
|
+
return this.retryWithBackoff(async () => {
|
|
200
|
+
// Validate request directly - Zod's .nullish() should handle null/undefined correctly
|
|
201
|
+
const validationResult = agentshield_api_1.proofSubmissionRequestSchema.safeParse(request);
|
|
202
|
+
if (!validationResult.success) {
|
|
203
|
+
// Log validation errors for debugging
|
|
204
|
+
const errorDetails = JSON.stringify(validationResult.error.errors, null, 2);
|
|
205
|
+
this.config.logger(`[AccessControl] Proof submission validation failed:`, {
|
|
206
|
+
errors: validationResult.error.errors,
|
|
207
|
+
request: JSON.stringify(request, null, 2),
|
|
208
|
+
});
|
|
209
|
+
throw new agentshield_api_2.AgentShieldAPIError("validation_error", `Request validation failed: ${errorDetails}`, { zodErrors: validationResult.error.errors });
|
|
210
|
+
}
|
|
211
|
+
// Use validated request for the API call
|
|
212
|
+
const validatedRequest = validationResult.data;
|
|
213
|
+
const correlationId = generateCorrelationId();
|
|
214
|
+
const url = `${this.config.baseUrl}/api/v1/bouncer/proofs`;
|
|
215
|
+
this.config.logger(`[AccessControl] Submitting ${request.proofs.length} proof(s)`, {
|
|
216
|
+
correlationId,
|
|
217
|
+
url,
|
|
218
|
+
sessionId: request.session_id,
|
|
219
|
+
delegationId: request.delegation_id,
|
|
220
|
+
});
|
|
221
|
+
const httpResponse = await this.config.fetchProvider.fetch(url, {
|
|
222
|
+
method: "POST",
|
|
223
|
+
headers: {
|
|
224
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
225
|
+
"Content-Type": "application/json",
|
|
226
|
+
"X-Request-ID": correlationId,
|
|
227
|
+
},
|
|
228
|
+
body: JSON.stringify(validatedRequest),
|
|
229
|
+
});
|
|
230
|
+
const responseText = await httpResponse.text();
|
|
231
|
+
const responseData = this.parseResponseJSON(httpResponse, responseText);
|
|
232
|
+
// Handle error responses
|
|
233
|
+
if (!httpResponse.ok) {
|
|
234
|
+
const errorData = responseData;
|
|
235
|
+
if (errorData.error) {
|
|
236
|
+
const errorCode = errorData.error.code || "api_error";
|
|
237
|
+
// Special handling for all_proofs_rejected - return response instead of throwing
|
|
238
|
+
if (errorCode === "all_proofs_rejected" &&
|
|
239
|
+
httpResponse.status === 400) {
|
|
240
|
+
// Parse the error details to extract accepted/rejected counts
|
|
241
|
+
const errorDetails = errorData.error.details;
|
|
242
|
+
// Create response matching ProofSubmissionResponse interface
|
|
243
|
+
// Validate structure with Zod to ensure type safety
|
|
244
|
+
const errorResponseData = {
|
|
245
|
+
success: false, // ProofSubmissionResponse has a success field
|
|
246
|
+
accepted: 0,
|
|
247
|
+
rejected: errorDetails?.rejected || request.proofs.length,
|
|
248
|
+
outcomes: {
|
|
249
|
+
success: 0,
|
|
250
|
+
failed: 0,
|
|
251
|
+
blocked: 0,
|
|
252
|
+
error: errorDetails?.rejected || request.proofs.length,
|
|
253
|
+
},
|
|
254
|
+
errors: errorDetails?.errors,
|
|
255
|
+
};
|
|
256
|
+
// Validate with Zod schema to ensure type safety
|
|
257
|
+
const validated = agentshield_api_1.proofSubmissionResponseSchema.safeParse(errorResponseData);
|
|
258
|
+
if (validated.success) {
|
|
259
|
+
return validated.data;
|
|
260
|
+
}
|
|
261
|
+
// If validation fails, log and throw error
|
|
262
|
+
throw new agentshield_api_2.AgentShieldAPIError("invalid_response", "Error response validation failed", { zodErrors: validated.error.errors });
|
|
263
|
+
}
|
|
264
|
+
// Ensure error details include status code for retry detection
|
|
265
|
+
const errorDetails = {
|
|
266
|
+
...(errorData.error.details || {}),
|
|
267
|
+
status: httpResponse.status,
|
|
268
|
+
};
|
|
269
|
+
throw new agentshield_api_2.AgentShieldAPIError(errorCode, errorData.error.message || `API error: ${httpResponse.status}`, errorDetails);
|
|
270
|
+
}
|
|
271
|
+
// Map status codes to error codes
|
|
272
|
+
let errorCode = "api_error";
|
|
273
|
+
if (httpResponse.status === 400) {
|
|
274
|
+
errorCode = "validation_error";
|
|
275
|
+
}
|
|
276
|
+
else if (httpResponse.status === 404) {
|
|
277
|
+
errorCode = httpResponse.statusText.includes("delegation")
|
|
278
|
+
? "delegation_not_found"
|
|
279
|
+
: "session_not_found";
|
|
280
|
+
}
|
|
281
|
+
throw new agentshield_api_2.AgentShieldAPIError(errorCode, `API request failed: ${httpResponse.status} ${httpResponse.statusText}`, { status: httpResponse.status, responseData });
|
|
282
|
+
}
|
|
283
|
+
// Try to handle wrapped response format first
|
|
284
|
+
const wrappedResponse = responseData;
|
|
285
|
+
if (wrappedResponse.success !== undefined && wrappedResponse.data) {
|
|
286
|
+
// Response is wrapped in { success, data }
|
|
287
|
+
const dataParsed = agentshield_api_1.proofSubmissionResponseSchema.safeParse(wrappedResponse.data);
|
|
288
|
+
if (dataParsed.success) {
|
|
289
|
+
// const response = dataP sponse;
|
|
290
|
+
this.config.logger(`[AccessControl] Proofs submitted successfully`, {
|
|
291
|
+
correlationId,
|
|
292
|
+
accepted: dataParsed.data.accepted,
|
|
293
|
+
rejected: dataParsed.data.rejected,
|
|
294
|
+
});
|
|
295
|
+
return dataParsed.data;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Try parsing as direct ProofSubmissionResponse
|
|
299
|
+
const parsed = agentshield_api_1.proofSubmissionResponseSchema.safeParse(responseData);
|
|
300
|
+
if (!parsed.success) {
|
|
301
|
+
throw new agentshield_api_2.AgentShieldAPIError("invalid_response", "Response validation failed", { zodErrors: parsed.error.errors, responseData });
|
|
302
|
+
}
|
|
303
|
+
this.config.logger(`[AccessControl] Proofs submitted successfully`, {
|
|
304
|
+
correlationId,
|
|
305
|
+
accepted: parsed.data.accepted,
|
|
306
|
+
rejected: parsed.data.rejected,
|
|
307
|
+
});
|
|
308
|
+
return parsed.data;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get current metrics
|
|
313
|
+
*/
|
|
314
|
+
getMetrics() {
|
|
315
|
+
return { ...this.metrics };
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Reset metrics
|
|
319
|
+
*/
|
|
320
|
+
resetMetrics() {
|
|
321
|
+
this.metrics = {
|
|
322
|
+
successCount: 0,
|
|
323
|
+
errorCount: 0,
|
|
324
|
+
retryCount: 0,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Retry logic with exponential backoff
|
|
329
|
+
*
|
|
330
|
+
* @internal
|
|
331
|
+
*/
|
|
332
|
+
async retryWithBackoff(operation, retryCount = 0) {
|
|
333
|
+
try {
|
|
334
|
+
const result = await operation();
|
|
335
|
+
this.metrics.successCount++;
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
// Check if error is retryable (5xx status codes)
|
|
340
|
+
const isRetryable = this.isRetryableError(error);
|
|
341
|
+
const { maxRetries, initialDelayMs, maxDelayMs } = this.config.retryConfig;
|
|
342
|
+
if (isRetryable && retryCount < maxRetries) {
|
|
343
|
+
const delay = Math.min(initialDelayMs * Math.pow(2, retryCount), maxDelayMs);
|
|
344
|
+
this.metrics.retryCount++;
|
|
345
|
+
this.config.logger(`Retrying after ${delay}ms (attempt ${retryCount + 1}/${maxRetries})`);
|
|
346
|
+
await this.sleep(delay);
|
|
347
|
+
return this.retryWithBackoff(operation, retryCount + 1);
|
|
348
|
+
}
|
|
349
|
+
this.metrics.errorCount++;
|
|
350
|
+
throw error;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Check if an error is retryable (5xx status codes)
|
|
355
|
+
*
|
|
356
|
+
* @internal
|
|
357
|
+
*/
|
|
358
|
+
isRetryableError(error) {
|
|
359
|
+
// Network errors (fetch failures) are retryable
|
|
360
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
// AgentShieldAPIError with 5xx status codes are retryable
|
|
364
|
+
if (error instanceof agentshield_api_2.AgentShieldAPIError) {
|
|
365
|
+
// Check error code for server errors
|
|
366
|
+
if (error.code === "server_error") {
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
// Check if error details contain status code
|
|
370
|
+
const status = error.details?.status;
|
|
371
|
+
if (status && status >= 500 && status < 600) {
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
// Rate limiting (429) is also retryable
|
|
375
|
+
if (status === 429) {
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Check for timeout errors
|
|
380
|
+
if (error instanceof Error) {
|
|
381
|
+
const message = error.message.toLowerCase();
|
|
382
|
+
if (message.includes("timeout") || message.includes("timed out")) {
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Sleep utility for retry delays
|
|
390
|
+
* Uses platform-agnostic sleep provider
|
|
391
|
+
*
|
|
392
|
+
* @internal
|
|
393
|
+
*/
|
|
394
|
+
sleep(ms) {
|
|
395
|
+
return this.config.sleepProvider(ms);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Parse response text to JSON with error handling
|
|
399
|
+
*
|
|
400
|
+
* @internal
|
|
401
|
+
*/
|
|
402
|
+
parseResponseJSON(response, responseText) {
|
|
403
|
+
try {
|
|
404
|
+
return JSON.parse(responseText);
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
// Handle non-JSON error responses (e.g., plain text "Internal Server Error")
|
|
408
|
+
if (!response.ok) {
|
|
409
|
+
const errorCode = this.mapStatusToErrorCode(response.status);
|
|
410
|
+
throw new agentshield_api_2.AgentShieldAPIError(errorCode, `API request failed: ${response.status} ${response.statusText}`, { status: response.status, responseText: responseText.substring(0, 500) });
|
|
411
|
+
}
|
|
412
|
+
// For success responses that aren't JSON, throw invalid_response error
|
|
413
|
+
throw new agentshield_api_2.AgentShieldAPIError("invalid_response", `Failed to parse response: ${error instanceof Error ? error.message : String(error)}`, { responseText: responseText.substring(0, 500) });
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Map HTTP status codes to error codes
|
|
418
|
+
*
|
|
419
|
+
* @internal
|
|
420
|
+
*/
|
|
421
|
+
mapStatusToErrorCode(status, statusText = "") {
|
|
422
|
+
if (status === 400) {
|
|
423
|
+
return "validation_error";
|
|
424
|
+
}
|
|
425
|
+
else if (status === 401 || status === 403) {
|
|
426
|
+
return "authentication_failed";
|
|
427
|
+
}
|
|
428
|
+
else if (status === 404) {
|
|
429
|
+
return "config_not_found";
|
|
430
|
+
}
|
|
431
|
+
else if (status >= 500) {
|
|
432
|
+
return "server_error";
|
|
433
|
+
}
|
|
434
|
+
return "api_error";
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Handle error responses and throw appropriate AgentShieldAPIError
|
|
438
|
+
*
|
|
439
|
+
* @internal
|
|
440
|
+
*/
|
|
441
|
+
handleErrorResponse(response, responseData) {
|
|
442
|
+
const errorData = responseData;
|
|
443
|
+
if (errorData.error) {
|
|
444
|
+
const errorCode = errorData.error.code || "api_error";
|
|
445
|
+
// Ensure error details include status code for retry detection
|
|
446
|
+
const errorDetails = {
|
|
447
|
+
...(errorData.error.details || {}),
|
|
448
|
+
status: response.status,
|
|
449
|
+
};
|
|
450
|
+
throw new agentshield_api_2.AgentShieldAPIError(errorCode, errorData.error.message || `API error: ${response.status}`, errorDetails);
|
|
451
|
+
}
|
|
452
|
+
// Map status codes to error codes
|
|
453
|
+
const errorCode = this.mapStatusToErrorCode(response.status, response.statusText);
|
|
454
|
+
throw new agentshield_api_2.AgentShieldAPIError(errorCode, `API request failed: ${response.status} ${response.statusText}`, { status: response.status, responseData });
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
exports.AccessControlApiService = AccessControlApiService;
|
|
458
|
+
//# sourceMappingURL=access-control.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-control.service.js","sourceRoot":"","sources":["../../src/services/access-control.service.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AASH,uEAM2C;AAC3C,uEAAwE;AAyDxE;;GAEG;AACH,SAAS,qBAAqB;IAC5B,4EAA4E;IAC5E,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IACD,kCAAkC;IAClC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,MAAa,uBAAuB;IAC1B,MAAM,CAAwC;IAC9C,OAAO,CAAiC;IAEhD,YAAY,MAAqC;QAC/C,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG;YACZ,WAAW,EAAE;gBACX,UAAU,EAAE,WAAW,CAAC,UAAU,IAAI,CAAC;gBACvC,cAAc,EAAE,WAAW,CAAC,cAAc,IAAI,GAAG;gBACjD,UAAU,EAAE,WAAW,CAAC,UAAU,IAAI,IAAI;aAC3C;YACD,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;YACnC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,aAAa,EACX,MAAM,CAAC,aAAa;gBACpB,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;SACtE,CAAC;QAEF,IAAI,CAAC,OAAO,GAAG;YACb,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,CAAC;SACd,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,OAEjB;QACC,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,aAAa,GAAG,qBAAqB,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,oCAAoC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAE7G,IAAI,CAAC,MAAM,CAAC,MAAM,CAChB,8CAA8C,OAAO,CAAC,QAAQ,EAAE,EAChE;gBACE,aAAa;gBACb,GAAG;aACJ,CACF,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC1D,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBAC7C,cAAc,EAAE,kBAAkB;oBAClC,cAAc,EAAE,aAAa;iBAC9B;aACF,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAEpE,yBAAyB;YACzB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YACnD,CAAC;YAED,sCAAsC;YACtC,MAAM,MAAM,GACV,uDAAqC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAChE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,4BAA4B,EAC5B,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CACnC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,6CAA6C,EAAE;gBAChE,aAAa;gBACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CACpB,OAAgC,EAChC,OAGC;QAED,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,aAAa,GAAG,qBAAqB,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,oCAAoC,CAAC;YAEvE,2DAA2D;YAC3D,MAAM,WAAW,GAA6D;gBAC5E,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC;YAEF,yCAAyC;YACzC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YACtC,CAAC;YAED,6DAA6D;YAC7D,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBACzC,WAAW,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;YACtD,CAAC;iBAAM,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;gBAClC,WAAW,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;YACrD,CAAC;YAED,iEAAiE;YACjE,IAAI,OAAO,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBAC3C,WAAW,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAC1D,CAAC;iBAAM,IAAI,OAAO,EAAE,eAAe,EAAE,CAAC;gBACpC,WAAW,CAAC,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;YACzD,CAAC;YAED,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACpC,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;YAC5C,CAAC;YAED,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,WAAW,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;YAChD,CAAC;YAED,6GAA6G;YAC7G,MAAM,kBAAkB,GAAG,MAAM,CAAC,WAAW,CAC3C,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CACxE,CAAC;YAEF,oCAAoC;YACpC,iGAAiG;YACjG,wDAAwD;YACxD,MAAM,gBAAgB,GACpB,+CAA6B,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAC9D,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC9B,mFAAmF;gBACnF,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CACpD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU,CAC7D,CAAC;gBACF,IAAI,WAAW,IAAI,CAAC,CAAC,QAAQ,IAAI,kBAAkB,CAAC,EAAE,CAAC;oBACrD,qGAAqG;oBACrG,qEAAqE;oBACrE,mEAAmE;gBACrE,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,oCAAoC,EAAE;wBACvD,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM;wBACrC,WAAW,EAAE,WAAW;qBACzB,CAAC,CAAC;oBACH,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,2BAA2B,EAC3B,EAAE,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAC7C,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAChB,mDAAmD,OAAO,CAAC,SAAS,EAAE,EACtE;gBACE,aAAa;gBACb,GAAG;gBACH,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;aAC7C,CACF,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC1D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBAC7C,cAAc,EAAE,kBAAkB;oBAClC,cAAc,EAAE,aAAa;iBAC9B;gBACD,4DAA4D;gBAC5D,2DAA2D;gBAC3D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC;aACzC,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAEpE,yBAAyB;YACzB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YACnD,CAAC;YAED,sCAAsC;YACtC,MAAM,MAAM,GAAG,mDAAiC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACzE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,4BAA4B,EAC5B,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CACnC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,qCAAqC,EAAE;gBACxD,aAAa;gBACb,QAAQ,EAAE,OAAO,CAAC,SAAS;gBAC3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;aAC9B,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAChB,OAA+B;QAE/B,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACtC,sFAAsF;YACtF,MAAM,gBAAgB,GAAG,8CAA4B,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACzE,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC9B,sCAAsC;gBACtC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC5E,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,qDAAqD,EAAE;oBACxE,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM;oBACrC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC1C,CAAC,CAAC;gBACH,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,8BAA8B,YAAY,EAAE,EAC5C,EAAE,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAC7C,CAAC;YACJ,CAAC;YAED,yCAAyC;YACzC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,IAAI,CAAC;YAE/C,MAAM,aAAa,GAAG,qBAAqB,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC;YAE3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAChB,8BAA8B,OAAO,CAAC,MAAM,CAAC,MAAM,WAAW,EAC9D;gBACE,aAAa;gBACb,GAAG;gBACH,SAAS,EAAE,OAAO,CAAC,UAAU;gBAC7B,YAAY,EAAE,OAAO,CAAC,aAAa;aACpC,CACF,CAAC;YAEF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC9D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBAC7C,cAAc,EAAE,kBAAkB;oBAClC,cAAc,EAAE,aAAa;iBAC9B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACvC,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;YAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YAExE,yBAAyB;YACzB,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,YAGjB,CAAC;gBAEF,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;oBACpB,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC;oBAEtD,iFAAiF;oBACjF,IACE,SAAS,KAAK,qBAAqB;wBACnC,YAAY,CAAC,MAAM,KAAK,GAAG,EAC3B,CAAC;wBACD,8DAA8D;wBAC9D,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,OAExB,CAAC;wBACd,6DAA6D;wBAC7D,oDAAoD;wBACpD,MAAM,iBAAiB,GAAG;4BACxB,OAAO,EAAE,KAAK,EAAE,8CAA8C;4BAC9D,QAAQ,EAAE,CAAC;4BACX,QAAQ,EAAE,YAAY,EAAE,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM;4BACzD,QAAQ,EAAE;gCACR,OAAO,EAAE,CAAC;gCACV,MAAM,EAAE,CAAC;gCACT,OAAO,EAAE,CAAC;gCACV,KAAK,EAAE,YAAY,EAAE,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM;6BACvD;4BACD,MAAM,EAAE,YAAY,EAAE,MAAM;yBAC7B,CAAC;wBAEF,iDAAiD;wBACjD,MAAM,SAAS,GACb,+CAA6B,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;wBAC7D,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;4BACtB,OAAO,SAAS,CAAC,IAAI,CAAC;wBACxB,CAAC;wBAED,2CAA2C;wBAC3C,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,kCAAkC,EAClC,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CACtC,CAAC;oBACJ,CAAC;oBAED,+DAA+D;oBAC/D,MAAM,YAAY,GAAG;wBACnB,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;wBAClC,MAAM,EAAE,YAAY,CAAC,MAAM;qBAC5B,CAAC;oBACF,MAAM,IAAI,qCAAmB,CAC3B,SAAS,EACT,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,cAAc,YAAY,CAAC,MAAM,EAAE,EAC9D,YAAY,CACb,CAAC;gBACJ,CAAC;gBAED,kCAAkC;gBAClC,IAAI,SAAS,GAAG,WAAW,CAAC;gBAC5B,IAAI,YAAY,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAChC,SAAS,GAAG,kBAAkB,CAAC;gBACjC,CAAC;qBAAM,IAAI,YAAY,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACvC,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;wBACxD,CAAC,CAAC,sBAAsB;wBACxB,CAAC,CAAC,mBAAmB,CAAC;gBAC1B,CAAC;gBAED,MAAM,IAAI,qCAAmB,CAC3B,SAAS,EACT,uBAAuB,YAAY,CAAC,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,EACvE,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,CAC9C,CAAC;YACJ,CAAC;YAED,8CAA8C;YAC9C,MAAM,eAAe,GAAG,YAGvB,CAAC;YACF,IAAI,eAAe,CAAC,OAAO,KAAK,SAAS,IAAI,eAAe,CAAC,IAAI,EAAE,CAAC;gBAClE,2CAA2C;gBAC3C,MAAM,UAAU,GAAG,+CAA6B,CAAC,SAAS,CACxD,eAAe,CAAC,IAAI,CACrB,CAAC;gBACF,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;oBACvB,iCAAiC;oBACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,+CAA+C,EAAE;wBAClE,aAAa;wBACb,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ;wBAClC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ;qBACnC,CAAC,CAAC;oBACH,OAAO,UAAU,CAAC,IAAI,CAAC;gBACzB,CAAC;YACH,CAAC;YAED,gDAAgD;YAChD,MAAM,MAAM,GAAG,+CAA6B,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACrE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,4BAA4B,EAC5B,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,CACjD,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,+CAA+C,EAAE;gBAClE,aAAa;gBACb,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ;gBAC9B,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ;aAC/B,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,OAAO,GAAG;YACb,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,CAAC;SACd,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,gBAAgB,CAC5B,SAA2B,EAC3B,UAAU,GAAG,CAAC;QAEd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,iDAAiD;YACjD,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACjD,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,GAC9C,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YAE1B,IAAI,WAAW,IAAI,UAAU,GAAG,UAAU,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,EACxC,UAAU,CACX,CAAC;gBAEF,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,CAChB,kBAAkB,KAAK,eAAe,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,CACtE,CAAC;gBAEF,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;YAC1D,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC1B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,gBAAgB,CAAC,KAAc;QACrC,gDAAgD;QAChD,IAAI,KAAK,YAAY,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,0DAA0D;QAC1D,IAAI,KAAK,YAAY,qCAAmB,EAAE,CAAC;YACzC,qCAAqC;YACrC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC;YACd,CAAC;YAED,6CAA6C;YAC7C,MAAM,MAAM,GAAI,KAAK,CAAC,OAA2C,EAAE,MAAM,CAAC;YAC1E,IAAI,MAAM,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC5C,OAAO,IAAI,CAAC;YACd,CAAC;YACD,wCAAwC;YACxC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACnB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACjE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACK,iBAAiB,CACvB,QAAkB,EAClB,YAAoB;QAEpB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,6EAA6E;YAC7E,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC7D,MAAM,IAAI,qCAAmB,CAC3B,SAAS,EACT,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,EAC/D,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC1E,CAAC;YACJ,CAAC;YACD,uEAAuE;YACvE,MAAM,IAAI,qCAAmB,CAC3B,kBAAkB,EAClB,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACrF,EAAE,YAAY,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACjD,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,oBAAoB,CAAC,MAAc,EAAE,UAAU,GAAG,EAAE;QAC1D,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,kBAAkB,CAAC;QAC5B,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5C,OAAO,uBAAuB,CAAC;QACjC,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,kBAAkB,CAAC;QAC5B,CAAC;aAAM,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACzB,OAAO,cAAc,CAAC;QACxB,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACK,mBAAmB,CACzB,QAAkB,EAClB,YAAqB;QAErB,MAAM,SAAS,GAAG,YAGjB,CAAC;QAEF,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC;YACtD,+DAA+D;YAC/D,MAAM,YAAY,GAAG;gBACnB,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;gBAClC,MAAM,EAAE,QAAQ,CAAC,MAAM;aACxB,CAAC;YACF,MAAM,IAAI,qCAAmB,CAC3B,SAAS,EACT,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,cAAc,QAAQ,CAAC,MAAM,EAAE,EAC1D,YAAY,CACb,CAAC;QACJ,CAAC;QAED,kCAAkC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAClF,MAAM,IAAI,qCAAmB,CAC3B,SAAS,EACT,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,EAC/D,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,CAC1C,CAAC;IACJ,CAAC;CACF;AAlkBD,0DAkkBC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CryptoService
|
|
3
|
+
*
|
|
4
|
+
* Centralized cryptographic operations service that provides consistent
|
|
5
|
+
* signature verification across all platforms (Cloudflare, Node.js, etc.).
|
|
6
|
+
*
|
|
7
|
+
* This service eliminates code duplication and ensures cryptographic operations
|
|
8
|
+
* behave identically everywhere.
|
|
9
|
+
*/
|
|
10
|
+
import { CryptoProvider } from "../providers/base.js";
|
|
11
|
+
/**
|
|
12
|
+
* Minimal JWK interface to avoid external dependencies
|
|
13
|
+
*/
|
|
14
|
+
export interface Ed25519JWK {
|
|
15
|
+
kty: "OKP";
|
|
16
|
+
crv: "Ed25519";
|
|
17
|
+
x: string;
|
|
18
|
+
kid?: string;
|
|
19
|
+
use?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* JWS parsing result
|
|
23
|
+
*/
|
|
24
|
+
export interface ParsedJWS {
|
|
25
|
+
header: Record<string, unknown>;
|
|
26
|
+
payload?: Record<string, unknown>;
|
|
27
|
+
signatureBytes: Uint8Array;
|
|
28
|
+
signingInput: string;
|
|
29
|
+
}
|
|
30
|
+
export declare class CryptoService {
|
|
31
|
+
private cryptoProvider;
|
|
32
|
+
constructor(cryptoProvider: CryptoProvider);
|
|
33
|
+
/**
|
|
34
|
+
* Verify raw Ed25519 signature
|
|
35
|
+
* @param data - Data that was signed
|
|
36
|
+
* @param signature - Signature bytes
|
|
37
|
+
* @param publicKey - Base64 encoded Ed25519 public key (32 bytes)
|
|
38
|
+
*/
|
|
39
|
+
verifyEd25519(data: Uint8Array, signature: Uint8Array, publicKey: string): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Parse JWS into components
|
|
42
|
+
* @param jws - Full compact JWS string (header.payload.signature)
|
|
43
|
+
* @returns Parsed JWS components
|
|
44
|
+
*/
|
|
45
|
+
parseJWS(jws: string): ParsedJWS;
|
|
46
|
+
/**
|
|
47
|
+
* Verify JWS signature (full compact format: header.payload.signature)
|
|
48
|
+
* @param jws - Full compact JWS string (or detached format: header..signature)
|
|
49
|
+
* @param publicKeyJwk - Ed25519 public key in JWK format
|
|
50
|
+
* @param options - Verification options
|
|
51
|
+
* @param options.detachedPayload - Optional detached payload (Uint8Array or string) for detached JWS format
|
|
52
|
+
* @param options.expectedKid - Optional expected key ID to validate
|
|
53
|
+
* @param options.alg - Optional expected algorithm (defaults to 'EdDSA')
|
|
54
|
+
*/
|
|
55
|
+
verifyJWS(jws: string, publicKeyJwk: Ed25519JWK, options?: {
|
|
56
|
+
detachedPayload?: Uint8Array | string;
|
|
57
|
+
expectedKid?: string;
|
|
58
|
+
alg?: "EdDSA";
|
|
59
|
+
}): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Validate Ed25519 JWK format
|
|
62
|
+
*/
|
|
63
|
+
private isValidEd25519JWK;
|
|
64
|
+
/**
|
|
65
|
+
* Convert Ed25519 JWK to base64 encoded public key
|
|
66
|
+
*/
|
|
67
|
+
private jwkToBase64PublicKey;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=crypto.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.service.d.ts","sourceRoot":"","sources":["../../src/services/crypto.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAStD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,SAAS,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,cAAc,EAAE,UAAU,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAElD;;;;;OAKG;IACG,aAAa,CACjB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAgBnB;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IA4DhC;;;;;;;;OAQG;IACG,SAAS,CACb,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,UAAU,EACxB,OAAO,CAAC,EAAE;QACR,eAAe,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;QACtC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,GACA,OAAO,CAAC,OAAO,CAAC;IAoHnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAc7B"}
|