@alter-ai/alter-sdk 0.2.2 → 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/README.md +93 -51
- package/dist/index.cjs +142 -75
- package/dist/index.d.cts +24 -18
- package/dist/index.d.ts +24 -18
- package/dist/index.js +141 -75
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
* - TokenResponse: Object.freeze(this) prevents mutation after creation
|
|
10
10
|
* - toJSON() and toString() exclude access token from serialization
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Actor types for tracking SDK callers.
|
|
14
|
+
*/
|
|
15
|
+
declare enum ActorType {
|
|
16
|
+
BACKEND_SERVICE = "backend_service",
|
|
17
|
+
AI_AGENT = "ai_agent",
|
|
18
|
+
MCP_SERVER = "mcp_server"
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* OAuth token response from Alter Vault.
|
|
14
22
|
*
|
|
@@ -34,6 +42,12 @@ declare class TokenResponse {
|
|
|
34
42
|
readonly scopes: string[];
|
|
35
43
|
/** Connection ID that provided this token */
|
|
36
44
|
readonly connectionId: string;
|
|
45
|
+
/** Provider ID (google, github, etc.) */
|
|
46
|
+
readonly providerId: string;
|
|
47
|
+
/** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
|
|
48
|
+
readonly injectionHeader: string;
|
|
49
|
+
/** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
|
|
50
|
+
readonly injectionFormat: string;
|
|
37
51
|
constructor(data: {
|
|
38
52
|
access_token: string;
|
|
39
53
|
token_type?: string;
|
|
@@ -41,6 +55,9 @@ declare class TokenResponse {
|
|
|
41
55
|
expires_at?: string | null;
|
|
42
56
|
scopes?: string[];
|
|
43
57
|
connection_id: string;
|
|
58
|
+
provider_id?: string;
|
|
59
|
+
injection_header?: string;
|
|
60
|
+
injection_format?: string;
|
|
44
61
|
});
|
|
45
62
|
/**
|
|
46
63
|
* Parse expires_at from ISO string.
|
|
@@ -80,7 +97,6 @@ declare class TokenResponse {
|
|
|
80
97
|
declare class ConnectionInfo {
|
|
81
98
|
readonly id: string;
|
|
82
99
|
readonly providerId: string;
|
|
83
|
-
readonly attributes: Record<string, unknown>;
|
|
84
100
|
readonly scopes: string[];
|
|
85
101
|
readonly accountIdentifier: string | null;
|
|
86
102
|
readonly accountDisplayName: string | null;
|
|
@@ -91,7 +107,6 @@ declare class ConnectionInfo {
|
|
|
91
107
|
constructor(data: {
|
|
92
108
|
id: string;
|
|
93
109
|
provider_id: string;
|
|
94
|
-
attributes?: Record<string, unknown>;
|
|
95
110
|
scopes?: string[];
|
|
96
111
|
account_identifier?: string | null;
|
|
97
112
|
account_display_name?: string | null;
|
|
@@ -231,8 +246,6 @@ declare enum Provider {
|
|
|
231
246
|
GOOGLE = "google",
|
|
232
247
|
GITHUB = "github",
|
|
233
248
|
SLACK = "slack",
|
|
234
|
-
MICROSOFT = "microsoft",
|
|
235
|
-
SALESFORCE = "salesforce",
|
|
236
249
|
SENTRY = "sentry"
|
|
237
250
|
}
|
|
238
251
|
/**
|
|
@@ -265,14 +278,12 @@ declare enum HttpMethod {
|
|
|
265
278
|
interface AlterVaultOptions {
|
|
266
279
|
/** Alter Vault API key (must start with "alter_key_") */
|
|
267
280
|
apiKey: string;
|
|
268
|
-
/** Base URL for Alter Vault API */
|
|
269
|
-
baseUrl?: string;
|
|
270
281
|
/** HTTP request timeout in milliseconds (default: 30000) */
|
|
271
282
|
timeout?: number;
|
|
272
|
-
/** Actor type (
|
|
273
|
-
actorType
|
|
283
|
+
/** Actor type (use ActorType enum: AI_AGENT, MCP_SERVER, BACKEND_SERVICE) */
|
|
284
|
+
actorType: ActorType | string;
|
|
274
285
|
/** Unique identifier for the actor (e.g., "email-assistant-v2") */
|
|
275
|
-
actorIdentifier
|
|
286
|
+
actorIdentifier: string;
|
|
276
287
|
/** Human-readable name for the actor */
|
|
277
288
|
actorName?: string;
|
|
278
289
|
/** Actor version string (e.g., "1.0.0") */
|
|
@@ -286,8 +297,6 @@ interface AlterVaultOptions {
|
|
|
286
297
|
* Options for the request() method.
|
|
287
298
|
*/
|
|
288
299
|
interface RequestOptions {
|
|
289
|
-
/** User attributes to match connection (e.g., { user_id: "alice" }) */
|
|
290
|
-
user: Record<string, unknown>;
|
|
291
300
|
/** Optional JSON request body */
|
|
292
301
|
json?: Record<string, unknown>;
|
|
293
302
|
/** Optional additional headers */
|
|
@@ -326,8 +335,6 @@ interface CreateConnectSessionOptions {
|
|
|
326
335
|
email?: string;
|
|
327
336
|
name?: string;
|
|
328
337
|
};
|
|
329
|
-
/** User attributes for connection matching */
|
|
330
|
-
attributes?: Record<string, unknown>;
|
|
331
338
|
/** Restrict to specific providers (e.g., ["google", "github"]) */
|
|
332
339
|
allowedProviders?: string[];
|
|
333
340
|
/** URL to redirect after OAuth completion */
|
|
@@ -358,9 +365,8 @@ interface CreateConnectSessionOptions {
|
|
|
358
365
|
*
|
|
359
366
|
* // Make API request (token injected automatically)
|
|
360
367
|
* const response = await vault.request(
|
|
361
|
-
*
|
|
368
|
+
* "connection-uuid-here", HttpMethod.GET,
|
|
362
369
|
* "https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
363
|
-
* { user: { user_id: "alice" } },
|
|
364
370
|
* );
|
|
365
371
|
* const events = await response.json();
|
|
366
372
|
*
|
|
@@ -382,7 +388,7 @@ declare class AlterVault {
|
|
|
382
388
|
* 4. Logs the call for audit (fire-and-forget)
|
|
383
389
|
* 5. Returns the raw response
|
|
384
390
|
*/
|
|
385
|
-
request(
|
|
391
|
+
request(connectionId: string, method: HttpMethod | string, url: string, options?: RequestOptions): Promise<Response>;
|
|
386
392
|
/**
|
|
387
393
|
* List OAuth connections for this app.
|
|
388
394
|
*
|
|
@@ -440,7 +446,7 @@ declare class PolicyViolationError extends TokenRetrievalError {
|
|
|
440
446
|
/**
|
|
441
447
|
* Raised when OAuth connection not found.
|
|
442
448
|
*
|
|
443
|
-
* This indicates no connection exists for the given
|
|
449
|
+
* This indicates no connection exists for the given connection_id.
|
|
444
450
|
*/
|
|
445
451
|
declare class ConnectionNotFoundError extends TokenRetrievalError {
|
|
446
452
|
constructor(message: string, details?: Record<string, unknown>);
|
|
@@ -487,4 +493,4 @@ declare class TimeoutError extends NetworkError {
|
|
|
487
493
|
constructor(message: string, details?: Record<string, unknown>);
|
|
488
494
|
}
|
|
489
495
|
|
|
490
|
-
export { APICallAuditLog, AlterSDKError, AlterVault, type AlterVaultOptions, ConnectSession, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, type RequestOptions, TimeoutError, TokenExpiredError, TokenResponse, TokenRetrievalError };
|
|
496
|
+
export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, ConnectSession, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, type RequestOptions, TimeoutError, TokenExpiredError, TokenResponse, TokenRetrievalError };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { createHash, createHmac, randomUUID } from "crypto";
|
|
3
|
+
|
|
1
4
|
// src/exceptions.ts
|
|
2
5
|
var AlterSDKError = class extends Error {
|
|
3
6
|
details;
|
|
@@ -66,6 +69,12 @@ var TimeoutError = class extends NetworkError {
|
|
|
66
69
|
};
|
|
67
70
|
|
|
68
71
|
// src/models.ts
|
|
72
|
+
var ActorType = /* @__PURE__ */ ((ActorType2) => {
|
|
73
|
+
ActorType2["BACKEND_SERVICE"] = "backend_service";
|
|
74
|
+
ActorType2["AI_AGENT"] = "ai_agent";
|
|
75
|
+
ActorType2["MCP_SERVER"] = "mcp_server";
|
|
76
|
+
return ActorType2;
|
|
77
|
+
})(ActorType || {});
|
|
69
78
|
var TokenResponse = class _TokenResponse {
|
|
70
79
|
/** Token type (usually "Bearer") */
|
|
71
80
|
tokenType;
|
|
@@ -77,12 +86,21 @@ var TokenResponse = class _TokenResponse {
|
|
|
77
86
|
scopes;
|
|
78
87
|
/** Connection ID that provided this token */
|
|
79
88
|
connectionId;
|
|
89
|
+
/** Provider ID (google, github, etc.) */
|
|
90
|
+
providerId;
|
|
91
|
+
/** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
|
|
92
|
+
injectionHeader;
|
|
93
|
+
/** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
|
|
94
|
+
injectionFormat;
|
|
80
95
|
constructor(data) {
|
|
81
96
|
this.tokenType = data.token_type ?? "Bearer";
|
|
82
97
|
this.expiresIn = data.expires_in ?? null;
|
|
83
98
|
this.expiresAt = data.expires_at ? _TokenResponse.parseExpiresAt(data.expires_at) : null;
|
|
84
99
|
this.scopes = data.scopes ?? [];
|
|
85
100
|
this.connectionId = data.connection_id;
|
|
101
|
+
this.providerId = data.provider_id ?? "";
|
|
102
|
+
this.injectionHeader = data.injection_header ?? "Authorization";
|
|
103
|
+
this.injectionFormat = data.injection_format ?? "Bearer {token}";
|
|
86
104
|
Object.freeze(this);
|
|
87
105
|
}
|
|
88
106
|
/**
|
|
@@ -147,7 +165,6 @@ var TokenResponse = class _TokenResponse {
|
|
|
147
165
|
var ConnectionInfo = class {
|
|
148
166
|
id;
|
|
149
167
|
providerId;
|
|
150
|
-
attributes;
|
|
151
168
|
scopes;
|
|
152
169
|
accountIdentifier;
|
|
153
170
|
accountDisplayName;
|
|
@@ -158,7 +175,6 @@ var ConnectionInfo = class {
|
|
|
158
175
|
constructor(data) {
|
|
159
176
|
this.id = data.id;
|
|
160
177
|
this.providerId = data.provider_id;
|
|
161
|
-
this.attributes = data.attributes ?? {};
|
|
162
178
|
this.scopes = data.scopes ?? [];
|
|
163
179
|
this.accountIdentifier = data.account_identifier ?? null;
|
|
164
180
|
this.accountDisplayName = data.account_display_name ?? null;
|
|
@@ -172,7 +188,6 @@ var ConnectionInfo = class {
|
|
|
172
188
|
return {
|
|
173
189
|
id: this.id,
|
|
174
190
|
provider_id: this.providerId,
|
|
175
|
-
attributes: this.attributes,
|
|
176
191
|
scopes: this.scopes,
|
|
177
192
|
account_identifier: this.accountIdentifier,
|
|
178
193
|
account_display_name: this.accountDisplayName,
|
|
@@ -319,9 +334,8 @@ function _extractAccessToken(token) {
|
|
|
319
334
|
return value;
|
|
320
335
|
}
|
|
321
336
|
var _fetch;
|
|
322
|
-
var SDK_VERSION = "0.
|
|
337
|
+
var SDK_VERSION = "0.3.0";
|
|
323
338
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
324
|
-
var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
|
|
325
339
|
var HTTP_FORBIDDEN = 403;
|
|
326
340
|
var HTTP_NOT_FOUND = 404;
|
|
327
341
|
var HTTP_BAD_REQUEST = 400;
|
|
@@ -401,6 +415,8 @@ var AlterVault = class _AlterVault {
|
|
|
401
415
|
// SECURITY LAYER 4: ES2022 private fields — truly private at runtime.
|
|
402
416
|
// These are NOT accessible via (obj as any), Object.keys(), or prototype.
|
|
403
417
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
418
|
+
/** HMAC signing key (derived from API key using AWS SigV4 pattern, raw bytes) */
|
|
419
|
+
#hmacKey;
|
|
404
420
|
/** HTTP Client for Alter Backend (has x-api-key) */
|
|
405
421
|
#alterClient;
|
|
406
422
|
/** HTTP Client for External Provider APIs (NO x-api-key) */
|
|
@@ -438,10 +454,8 @@ var AlterVault = class _AlterVault {
|
|
|
438
454
|
for (const [name, value] of actorStrings) {
|
|
439
455
|
_AlterVault.#validateActorString(value, name);
|
|
440
456
|
}
|
|
441
|
-
this
|
|
442
|
-
|
|
443
|
-
""
|
|
444
|
-
);
|
|
457
|
+
this.#hmacKey = createHmac("sha256", options.apiKey).update("alter-signing-v1").digest();
|
|
458
|
+
this.baseUrl = (process.env.ALTER_BASE_URL ?? "https://backend.alterai.dev").replace(/\/+$/, "");
|
|
445
459
|
const timeoutMs = options.timeout ?? 3e4;
|
|
446
460
|
this.#actorType = options.actorType;
|
|
447
461
|
this.#actorIdentifier = options.actorIdentifier;
|
|
@@ -494,14 +508,20 @@ var AlterVault = class _AlterVault {
|
|
|
494
508
|
if (!apiKey.startsWith("alter_key_")) {
|
|
495
509
|
throw new AlterSDKError("api_key must start with 'alter_key_'");
|
|
496
510
|
}
|
|
497
|
-
if (
|
|
498
|
-
throw new AlterSDKError(
|
|
511
|
+
if (!actorType) {
|
|
512
|
+
throw new AlterSDKError(
|
|
513
|
+
"actor_type is required (use ActorType.AI_AGENT, ActorType.MCP_SERVER, or ActorType.BACKEND_SERVICE)"
|
|
514
|
+
);
|
|
499
515
|
}
|
|
500
|
-
|
|
516
|
+
const validValues = Object.values(ActorType);
|
|
517
|
+
if (!validValues.includes(String(actorType))) {
|
|
501
518
|
throw new AlterSDKError(
|
|
502
|
-
|
|
519
|
+
`actor_type must be one of ${JSON.stringify(validValues.sort())}, got '${String(actorType)}'`
|
|
503
520
|
);
|
|
504
521
|
}
|
|
522
|
+
if (!actorIdentifier) {
|
|
523
|
+
throw new AlterSDKError("actor_identifier is required");
|
|
524
|
+
}
|
|
505
525
|
}
|
|
506
526
|
/**
|
|
507
527
|
* Build default headers for the Alter backend HTTP client.
|
|
@@ -528,6 +548,28 @@ var AlterVault = class _AlterVault {
|
|
|
528
548
|
}
|
|
529
549
|
return headers;
|
|
530
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* Compute HMAC-SHA256 signature headers for an Alter backend request.
|
|
553
|
+
*
|
|
554
|
+
* String-to-sign format: METHOD\nPATH_WITH_SORTED_QUERY\nTIMESTAMP\nCONTENT_HASH
|
|
555
|
+
*
|
|
556
|
+
* The path should include sorted query parameters if present (e.g. "/sdk/endpoint?a=1&b=2").
|
|
557
|
+
* Currently all SDK→backend calls are POSTs without query params, so the path is clean.
|
|
558
|
+
*/
|
|
559
|
+
#computeHmacHeaders(method, path, body) {
|
|
560
|
+
const timestamp = String(Math.floor(Date.now() / 1e3));
|
|
561
|
+
const contentHash = createHash("sha256").update(body ?? "").digest("hex");
|
|
562
|
+
const stringToSign = `${method.toUpperCase()}
|
|
563
|
+
${path}
|
|
564
|
+
${timestamp}
|
|
565
|
+
${contentHash}`;
|
|
566
|
+
const signature = createHmac("sha256", this.#hmacKey).update(stringToSign).digest("hex");
|
|
567
|
+
return {
|
|
568
|
+
"X-Alter-Timestamp": timestamp,
|
|
569
|
+
"X-Alter-Content-SHA256": contentHash,
|
|
570
|
+
"X-Alter-Signature": signature
|
|
571
|
+
};
|
|
572
|
+
}
|
|
531
573
|
/**
|
|
532
574
|
* Build per-request actor headers for instance tracking.
|
|
533
575
|
*/
|
|
@@ -624,7 +666,7 @@ var AlterVault = class _AlterVault {
|
|
|
624
666
|
if (response.status === HTTP_NOT_FOUND) {
|
|
625
667
|
const errorData = await _AlterVault.#safeParseJson(response);
|
|
626
668
|
throw new ConnectionNotFoundError(
|
|
627
|
-
errorData.message ?? "OAuth connection not found for
|
|
669
|
+
errorData.message ?? "OAuth connection not found for the given connection_id",
|
|
628
670
|
errorData
|
|
629
671
|
);
|
|
630
672
|
}
|
|
@@ -670,22 +712,24 @@ var AlterVault = class _AlterVault {
|
|
|
670
712
|
* This is a private method. Tokens are NEVER exposed to developers.
|
|
671
713
|
* Use request() instead, which handles tokens internally.
|
|
672
714
|
*/
|
|
673
|
-
async #getToken(
|
|
715
|
+
async #getToken(connectionId, reason, requestMetadata, runId, threadId, toolCallId) {
|
|
674
716
|
const actorHeaders = this.#getActorRequestHeaders(
|
|
675
717
|
runId,
|
|
676
718
|
threadId,
|
|
677
719
|
toolCallId
|
|
678
720
|
);
|
|
679
721
|
let response;
|
|
722
|
+
const tokenBody = {
|
|
723
|
+
connection_id: connectionId,
|
|
724
|
+
reason: reason ?? null,
|
|
725
|
+
request: requestMetadata ?? null
|
|
726
|
+
};
|
|
727
|
+
const tokenPath = "/sdk/token";
|
|
728
|
+
const hmacHeaders = this.#computeHmacHeaders("POST", tokenPath, JSON.stringify(tokenBody));
|
|
680
729
|
try {
|
|
681
|
-
response = await this.#alterClient.post(
|
|
682
|
-
json:
|
|
683
|
-
|
|
684
|
-
attributes,
|
|
685
|
-
reason: reason ?? null,
|
|
686
|
-
request: requestMetadata ?? null
|
|
687
|
-
},
|
|
688
|
-
headers: actorHeaders
|
|
730
|
+
response = await this.#alterClient.post(tokenPath, {
|
|
731
|
+
json: tokenBody,
|
|
732
|
+
headers: { ...actorHeaders, ...hmacHeaders }
|
|
689
733
|
});
|
|
690
734
|
} catch (error) {
|
|
691
735
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -702,7 +746,7 @@ var AlterVault = class _AlterVault {
|
|
|
702
746
|
}
|
|
703
747
|
throw new TokenRetrievalError(
|
|
704
748
|
`Failed to retrieve token: ${error instanceof Error ? error.message : String(error)}`,
|
|
705
|
-
{
|
|
749
|
+
{ connection_id: connectionId, error: String(error) }
|
|
706
750
|
);
|
|
707
751
|
}
|
|
708
752
|
this.#cacheActorIdFromResponse(response);
|
|
@@ -710,6 +754,18 @@ var AlterVault = class _AlterVault {
|
|
|
710
754
|
const tokenData = await response.json();
|
|
711
755
|
const typedData = tokenData;
|
|
712
756
|
const tokenResponse = new TokenResponse(typedData);
|
|
757
|
+
if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(tokenResponse.injectionHeader)) {
|
|
758
|
+
throw new TokenRetrievalError(
|
|
759
|
+
`Backend returned invalid injection_header: ${tokenResponse.injectionHeader}`,
|
|
760
|
+
{ connectionId: String(connectionId) }
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
if (/[\r\n\x00]/.test(tokenResponse.injectionFormat)) {
|
|
764
|
+
throw new TokenRetrievalError(
|
|
765
|
+
`Backend returned invalid injection_format (contains control characters)`,
|
|
766
|
+
{ connectionId: String(connectionId) }
|
|
767
|
+
);
|
|
768
|
+
}
|
|
713
769
|
_storeAccessToken(tokenResponse, typedData.access_token);
|
|
714
770
|
return tokenResponse;
|
|
715
771
|
}
|
|
@@ -738,10 +794,13 @@ var AlterVault = class _AlterVault {
|
|
|
738
794
|
toolCallId: params.toolCallId
|
|
739
795
|
});
|
|
740
796
|
const sanitized = auditLog.sanitize();
|
|
741
|
-
const actorHeaders = this.#getActorRequestHeaders();
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
|
|
797
|
+
const actorHeaders = this.#getActorRequestHeaders(params.runId);
|
|
798
|
+
const auditPath = "/sdk/oauth/audit/api-call";
|
|
799
|
+
const auditBody = sanitized;
|
|
800
|
+
const auditHmac = this.#computeHmacHeaders("POST", auditPath, JSON.stringify(auditBody));
|
|
801
|
+
const response = await this.#alterClient.post(auditPath, {
|
|
802
|
+
json: auditBody,
|
|
803
|
+
headers: { ...actorHeaders, ...auditHmac }
|
|
745
804
|
});
|
|
746
805
|
this.#cacheActorIdFromResponse(response);
|
|
747
806
|
if (!response.ok) {
|
|
@@ -807,13 +866,13 @@ var AlterVault = class _AlterVault {
|
|
|
807
866
|
* 4. Logs the call for audit (fire-and-forget)
|
|
808
867
|
* 5. Returns the raw response
|
|
809
868
|
*/
|
|
810
|
-
async request(
|
|
869
|
+
async request(connectionId, method, url, options) {
|
|
811
870
|
if (this.#closed) {
|
|
812
871
|
throw new AlterSDKError(
|
|
813
872
|
"SDK instance has been closed. Create a new AlterVault instance to make requests."
|
|
814
873
|
);
|
|
815
874
|
}
|
|
816
|
-
const
|
|
875
|
+
const runId = options?.runId ?? randomUUID();
|
|
817
876
|
const methodStr = String(method).toUpperCase();
|
|
818
877
|
const urlLower = url.toLowerCase();
|
|
819
878
|
if (!ALLOWED_URL_SCHEMES.some((scheme) => urlLower.startsWith(scheme))) {
|
|
@@ -821,7 +880,7 @@ var AlterVault = class _AlterVault {
|
|
|
821
880
|
`URL must start with https:// or http://, got: ${url.slice(0, 50)}`
|
|
822
881
|
);
|
|
823
882
|
}
|
|
824
|
-
if (options
|
|
883
|
+
if (options?.pathParams && Object.keys(options.pathParams).length > 0) {
|
|
825
884
|
const encodedParams = {};
|
|
826
885
|
for (const [key, value] of Object.entries(options.pathParams)) {
|
|
827
886
|
encodedParams[key] = encodeURIComponent(String(value));
|
|
@@ -851,22 +910,25 @@ var AlterVault = class _AlterVault {
|
|
|
851
910
|
);
|
|
852
911
|
}
|
|
853
912
|
}
|
|
854
|
-
if (options.extraHeaders && "Authorization" in options.extraHeaders) {
|
|
855
|
-
console.warn(
|
|
856
|
-
"extraHeaders contains 'Authorization' which will be overwritten with the auto-injected Bearer token"
|
|
857
|
-
);
|
|
858
|
-
}
|
|
859
913
|
const tokenResponse = await this.#getToken(
|
|
860
|
-
|
|
861
|
-
options
|
|
862
|
-
options.reason,
|
|
914
|
+
connectionId,
|
|
915
|
+
options?.reason,
|
|
863
916
|
{ method: methodStr, url },
|
|
864
|
-
|
|
865
|
-
options
|
|
866
|
-
options
|
|
917
|
+
runId,
|
|
918
|
+
options?.threadId,
|
|
919
|
+
options?.toolCallId
|
|
867
920
|
);
|
|
868
|
-
const
|
|
869
|
-
|
|
921
|
+
const injectionHeaderLower = tokenResponse.injectionHeader.toLowerCase();
|
|
922
|
+
if (options?.extraHeaders && Object.keys(options.extraHeaders).some(
|
|
923
|
+
(k) => k.toLowerCase() === injectionHeaderLower
|
|
924
|
+
)) {
|
|
925
|
+
console.warn(
|
|
926
|
+
`extraHeaders contains '${tokenResponse.injectionHeader}' which will be overwritten with the auto-injected credential`
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
const requestHeaders = options?.extraHeaders ? { ...options.extraHeaders } : {};
|
|
930
|
+
const accessToken = _extractAccessToken(tokenResponse);
|
|
931
|
+
requestHeaders[tokenResponse.injectionHeader] = tokenResponse.injectionFormat.replace("{token}", accessToken);
|
|
870
932
|
if (!requestHeaders["User-Agent"]) {
|
|
871
933
|
requestHeaders["User-Agent"] = SDK_USER_AGENT;
|
|
872
934
|
}
|
|
@@ -874,16 +936,16 @@ var AlterVault = class _AlterVault {
|
|
|
874
936
|
let response;
|
|
875
937
|
try {
|
|
876
938
|
response = await this.#providerClient.request(methodStr, url, {
|
|
877
|
-
json: options
|
|
939
|
+
json: options?.json,
|
|
878
940
|
headers: requestHeaders,
|
|
879
|
-
params: options
|
|
941
|
+
params: options?.queryParams
|
|
880
942
|
});
|
|
881
943
|
} catch (error) {
|
|
882
944
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
883
945
|
throw new TimeoutError(
|
|
884
946
|
`Provider API request timed out: ${error instanceof Error ? error.message : String(error)}`,
|
|
885
947
|
{
|
|
886
|
-
|
|
948
|
+
connection_id: connectionId,
|
|
887
949
|
method: methodStr,
|
|
888
950
|
url
|
|
889
951
|
}
|
|
@@ -892,7 +954,7 @@ var AlterVault = class _AlterVault {
|
|
|
892
954
|
throw new NetworkError(
|
|
893
955
|
`Failed to call provider API: ${error instanceof Error ? error.message : String(error)}`,
|
|
894
956
|
{
|
|
895
|
-
|
|
957
|
+
connection_id: connectionId,
|
|
896
958
|
method: methodStr,
|
|
897
959
|
url,
|
|
898
960
|
error: String(error)
|
|
@@ -902,7 +964,7 @@ var AlterVault = class _AlterVault {
|
|
|
902
964
|
const latencyMs = Date.now() - startTime;
|
|
903
965
|
const auditHeaders = {};
|
|
904
966
|
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
905
|
-
if (key.toLowerCase() !==
|
|
967
|
+
if (key.toLowerCase() !== injectionHeaderLower) {
|
|
906
968
|
auditHeaders[key] = value;
|
|
907
969
|
}
|
|
908
970
|
}
|
|
@@ -913,19 +975,19 @@ var AlterVault = class _AlterVault {
|
|
|
913
975
|
});
|
|
914
976
|
this.#scheduleAuditLog({
|
|
915
977
|
connectionId: tokenResponse.connectionId,
|
|
916
|
-
providerId:
|
|
978
|
+
providerId: tokenResponse.providerId || connectionId,
|
|
917
979
|
method: methodStr,
|
|
918
980
|
url,
|
|
919
981
|
requestHeaders: auditHeaders,
|
|
920
|
-
requestBody: options
|
|
982
|
+
requestBody: options?.json ?? null,
|
|
921
983
|
responseStatus: response.status,
|
|
922
984
|
responseHeaders,
|
|
923
985
|
responseBody,
|
|
924
986
|
latencyMs,
|
|
925
|
-
reason: options
|
|
926
|
-
runId
|
|
927
|
-
threadId: options
|
|
928
|
-
toolCallId: options
|
|
987
|
+
reason: options?.reason ?? null,
|
|
988
|
+
runId,
|
|
989
|
+
threadId: options?.threadId ?? null,
|
|
990
|
+
toolCallId: options?.toolCallId ?? null
|
|
929
991
|
});
|
|
930
992
|
if (response.status >= HTTP_CLIENT_ERROR_START) {
|
|
931
993
|
throw new ProviderAPIError(
|
|
@@ -933,7 +995,7 @@ var AlterVault = class _AlterVault {
|
|
|
933
995
|
response.status,
|
|
934
996
|
responseBody,
|
|
935
997
|
{
|
|
936
|
-
|
|
998
|
+
connection_id: connectionId,
|
|
937
999
|
method: methodStr,
|
|
938
1000
|
url
|
|
939
1001
|
}
|
|
@@ -955,14 +1017,17 @@ var AlterVault = class _AlterVault {
|
|
|
955
1017
|
}
|
|
956
1018
|
const actorHeaders = this.#getActorRequestHeaders();
|
|
957
1019
|
let response;
|
|
1020
|
+
const listBody = {
|
|
1021
|
+
provider_id: options?.providerId ?? null,
|
|
1022
|
+
limit: options?.limit ?? 100,
|
|
1023
|
+
offset: options?.offset ?? 0
|
|
1024
|
+
};
|
|
1025
|
+
const listPath = "/sdk/oauth/connections/list";
|
|
1026
|
+
const listHmac = this.#computeHmacHeaders("POST", listPath, JSON.stringify(listBody));
|
|
958
1027
|
try {
|
|
959
|
-
response = await this.#alterClient.post(
|
|
960
|
-
json:
|
|
961
|
-
|
|
962
|
-
limit: options?.limit ?? 100,
|
|
963
|
-
offset: options?.offset ?? 0
|
|
964
|
-
},
|
|
965
|
-
headers: actorHeaders
|
|
1028
|
+
response = await this.#alterClient.post(listPath, {
|
|
1029
|
+
json: listBody,
|
|
1030
|
+
headers: { ...actorHeaders, ...listHmac }
|
|
966
1031
|
});
|
|
967
1032
|
} catch (error) {
|
|
968
1033
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -1013,17 +1078,19 @@ var AlterVault = class _AlterVault {
|
|
|
1013
1078
|
}
|
|
1014
1079
|
const actorHeaders = this.#getActorRequestHeaders();
|
|
1015
1080
|
let response;
|
|
1081
|
+
const sessionBody = {
|
|
1082
|
+
end_user: options.endUser,
|
|
1083
|
+
allowed_providers: options.allowedProviders ?? null,
|
|
1084
|
+
return_url: options.returnUrl ?? null,
|
|
1085
|
+
allowed_origin: options.allowedOrigin ?? null,
|
|
1086
|
+
metadata: options.metadata ?? null
|
|
1087
|
+
};
|
|
1088
|
+
const sessionPath = "/sdk/oauth/connect/session";
|
|
1089
|
+
const sessionHmac = this.#computeHmacHeaders("POST", sessionPath, JSON.stringify(sessionBody));
|
|
1016
1090
|
try {
|
|
1017
|
-
response = await this.#alterClient.post(
|
|
1018
|
-
json:
|
|
1019
|
-
|
|
1020
|
-
attributes: options.attributes ?? null,
|
|
1021
|
-
allowed_providers: options.allowedProviders ?? null,
|
|
1022
|
-
return_url: options.returnUrl ?? null,
|
|
1023
|
-
allowed_origin: options.allowedOrigin ?? null,
|
|
1024
|
-
metadata: options.metadata ?? null
|
|
1025
|
-
},
|
|
1026
|
-
headers: actorHeaders
|
|
1091
|
+
response = await this.#alterClient.post(sessionPath, {
|
|
1092
|
+
json: sessionBody,
|
|
1093
|
+
headers: { ...actorHeaders, ...sessionHmac }
|
|
1027
1094
|
});
|
|
1028
1095
|
} catch (error) {
|
|
1029
1096
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -1075,8 +1142,6 @@ var Provider = /* @__PURE__ */ ((Provider2) => {
|
|
|
1075
1142
|
Provider2["GOOGLE"] = "google";
|
|
1076
1143
|
Provider2["GITHUB"] = "github";
|
|
1077
1144
|
Provider2["SLACK"] = "slack";
|
|
1078
|
-
Provider2["MICROSOFT"] = "microsoft";
|
|
1079
|
-
Provider2["SALESFORCE"] = "salesforce";
|
|
1080
1145
|
Provider2["SENTRY"] = "sentry";
|
|
1081
1146
|
return Provider2;
|
|
1082
1147
|
})(Provider || {});
|
|
@@ -1092,6 +1157,7 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
|
|
|
1092
1157
|
})(HttpMethod || {});
|
|
1093
1158
|
export {
|
|
1094
1159
|
APICallAuditLog,
|
|
1160
|
+
ActorType,
|
|
1095
1161
|
AlterSDKError,
|
|
1096
1162
|
AlterVault,
|
|
1097
1163
|
ConnectSession,
|