@particle-academy/fancy-connector-core 0.8.1 → 0.9.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/CHANGELOG.md +50 -0
- package/dist/index.cjs +39 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -6
- package/dist/index.d.ts +54 -6
- package/dist/index.js +38 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2347,13 +2347,33 @@ type HmacScheme = {
|
|
|
2347
2347
|
/**
|
|
2348
2348
|
* Build the exact string that gets signed. Providers differ here more than
|
|
2349
2349
|
* anywhere else — Stripe signs `${timestamp}.${body}`, Slack signs
|
|
2350
|
-
* `v0:${timestamp}:${body}`, GitHub signs the body alone
|
|
2350
|
+
* `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
|
|
2351
|
+
* `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
|
|
2351
2352
|
*/
|
|
2352
|
-
payload: (raw: string, timestamp?: string) => string;
|
|
2353
|
+
payload: (raw: string, timestamp?: string, id?: string) => string;
|
|
2353
2354
|
/** Seconds a delivery stays acceptable. */
|
|
2354
2355
|
tolerance?: number;
|
|
2355
2356
|
/** Encoding of the signature the provider sends. */
|
|
2356
2357
|
encoding?: "hex" | "base64";
|
|
2358
|
+
/**
|
|
2359
|
+
* How the SECRET is spelled. `utf8` (the default, and every provider before
|
|
2360
|
+
* Svix): the key is the text's bytes. `base64`: the key is the DECODED
|
|
2361
|
+
* bytes — Svix hands out `whsec_<base64>`, and half of the decoded bytes are
|
|
2362
|
+
* not valid UTF-8, so encoding the text would sign with the wrong key and
|
|
2363
|
+
* fail exactly like a wrong secret.
|
|
2364
|
+
*/
|
|
2365
|
+
secretEncoding?: "utf8" | "base64";
|
|
2366
|
+
/** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
|
|
2367
|
+
secretPrefix?: string;
|
|
2368
|
+
};
|
|
2369
|
+
/** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
|
|
2370
|
+
declare function secretKeyBytes(secret: string, options?: {
|
|
2371
|
+
secretEncoding?: "utf8" | "base64";
|
|
2372
|
+
secretPrefix?: string;
|
|
2373
|
+
}): {
|
|
2374
|
+
bytes: Uint8Array;
|
|
2375
|
+
} | {
|
|
2376
|
+
reason: string;
|
|
2357
2377
|
};
|
|
2358
2378
|
/**
|
|
2359
2379
|
* Verify an HMAC-signed delivery.
|
|
@@ -2364,15 +2384,33 @@ type HmacScheme = {
|
|
|
2364
2384
|
*/
|
|
2365
2385
|
declare function verifyHmac(options: {
|
|
2366
2386
|
raw: string;
|
|
2367
|
-
|
|
2387
|
+
/**
|
|
2388
|
+
* The signature(s) the delivery carried. A LIST when the provider sends
|
|
2389
|
+
* several — Stripe signs once per active secret while a secret is rolled
|
|
2390
|
+
* and Svix's header "could be any number of signatures" — and the delivery
|
|
2391
|
+
* is accepted when ANY matches. A first-only rule fails every delivery
|
|
2392
|
+
* whose first signature came from the new secret, for the whole roll, and
|
|
2393
|
+
* it reads exactly like a wrong secret.
|
|
2394
|
+
*/
|
|
2395
|
+
signature: string | string[] | undefined;
|
|
2368
2396
|
secret: string | undefined;
|
|
2369
2397
|
scheme: HmacScheme;
|
|
2370
2398
|
timestamp?: string;
|
|
2399
|
+
/** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
|
|
2400
|
+
id?: string;
|
|
2371
2401
|
/** Seconds since the epoch. Injected so tests are not clock-dependent. */
|
|
2372
2402
|
now?: number;
|
|
2373
2403
|
}): Promise<WebhookVerification>;
|
|
2374
|
-
/**
|
|
2375
|
-
|
|
2404
|
+
/**
|
|
2405
|
+
* HMAC of `payload` under `secret`, hex or base64 encoded. `options` says how
|
|
2406
|
+
* the secret is spelled (see `HmacScheme.secretEncoding`); a secret that
|
|
2407
|
+
* cannot be a key THROWS here — signing has no result to carry a reason in —
|
|
2408
|
+
* while `verifyHmac` names it in its result before ever calling this.
|
|
2409
|
+
*/
|
|
2410
|
+
declare function hmac(secret: string, payload: string, algorithm: HmacScheme["algorithm"], encoding?: "hex" | "base64", options?: {
|
|
2411
|
+
secretEncoding?: "utf8" | "base64";
|
|
2412
|
+
secretPrefix?: string;
|
|
2413
|
+
}): Promise<string>;
|
|
2376
2414
|
/**
|
|
2377
2415
|
* Compare two strings without leaking where they diverge.
|
|
2378
2416
|
*
|
|
@@ -2503,13 +2541,23 @@ type HmacVerificationSpec = {
|
|
|
2503
2541
|
signatureHeader: string;
|
|
2504
2542
|
/** Header carrying the timestamp, when the scheme signs one. */
|
|
2505
2543
|
timestampHeader?: string;
|
|
2544
|
+
/**
|
|
2545
|
+
* Header carrying the delivery's ID, when the scheme signs one — Svix
|
|
2546
|
+
* signs `${svix-id}.${svix-timestamp}.${body}`. A declared id header the
|
|
2547
|
+
* delivery does not carry is a refusal, never a payload with a hole in it.
|
|
2548
|
+
*/
|
|
2549
|
+
idHeader?: string;
|
|
2506
2550
|
scheme: HmacScheme;
|
|
2507
2551
|
/**
|
|
2508
2552
|
* Some schemes pack the timestamp INTO the signature header
|
|
2509
2553
|
* (Stripe: `t=…,v1=…`). Given the raw header value, return the parts.
|
|
2554
|
+
* `signatures` carries EVERY signature the header held (a provider rolling
|
|
2555
|
+
* a secret sends one per active secret); `signature` alone is the 0.8.x
|
|
2556
|
+
* shape and still means one.
|
|
2510
2557
|
*/
|
|
2511
2558
|
parse?: (raw: string) => {
|
|
2512
2559
|
signature?: string;
|
|
2560
|
+
signatures?: string[];
|
|
2513
2561
|
timestamp?: string;
|
|
2514
2562
|
};
|
|
2515
2563
|
/** A challenge the provider makes before it will deliver anything. */
|
|
@@ -2555,4 +2603,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
|
|
|
2555
2603
|
*/
|
|
2556
2604
|
declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
|
|
2557
2605
|
|
|
2558
|
-
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type ByteRange, CANONICAL_METRICS, CONNECTOR_API_VERSION, CONNECTOR_MODES, CREDENTIAL_SCOPES, type CallOptions, type CallResult, type Capabilities, type Catalogue, type ChainLinks, type ChainOutcome, type ChainRef, type ChallengeHandshake, type Citation, type Classified, type ConnectionCredentials, type ConnectionHost, type ConnectionSpec, type Connector, ConnectorAmbiguous, ConnectorApiMismatch, ConnectorAuthError, ConnectorConfigError, ConnectorError, type ConnectorErrorContext, type ConnectorFaker, ConnectorIdempotencyExpiredError, type ConnectorMode, ConnectorModeError, ConnectorRateLimited, type ConnectorRequest, ConnectorRequestError, type ConnectorResult, ConnectorTransient, ConnectorUnreachable, type ContractOperation, type CredentialField, type CredentialScope, DEFAULT_IDEMPOTENCY_WINDOW_SECONDS, DEFAULT_RETRY, type DeliveryDeclaration, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, type FailureKind, type FakeRequest, type FakeValues, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type LeaseAction, type LeaseDeclaration, type LeaseState, MAX_IDEMPOTENCY_KEY_LENGTH, type MetricDescriptor, type MetricSample, type MimeAttachment, type MimeHeader, type MimeMessage, type MimePart, type ModeInputs, NO_IDEMPOTENCY_KEY_WARNING, PROBLEM_SEVERITIES, type PreparedRequest, type ProbeOutcome, type ProbeReport, type ProbeResult, type ProbeSpec, type Problem, type ProviderAdapter, RENDERER_VERSION, REVIEW_STALE_DAYS, type RecordedShape, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SpecSource, type SubscriptionLease, type TextUnit, type Transport, type TransportResponse, type TriggerDescriptor, type VerifyResult, type WebhookVerification, type WebhookVerificationSpec, assertConnectorApi, byteRangeOf, callConnector, capabilityProblems, checkAgainstOpenApi, checkAgainstRecordedShape, classifyError, classifyHttp, classifyStatus, classifyThrown, compareShape, connectionsFor, constantTimeEquals, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
|
|
2606
|
+
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type ByteRange, CANONICAL_METRICS, CONNECTOR_API_VERSION, CONNECTOR_MODES, CREDENTIAL_SCOPES, type CallOptions, type CallResult, type Capabilities, type Catalogue, type ChainLinks, type ChainOutcome, type ChainRef, type ChallengeHandshake, type Citation, type Classified, type ConnectionCredentials, type ConnectionHost, type ConnectionSpec, type Connector, ConnectorAmbiguous, ConnectorApiMismatch, ConnectorAuthError, ConnectorConfigError, ConnectorError, type ConnectorErrorContext, type ConnectorFaker, ConnectorIdempotencyExpiredError, type ConnectorMode, ConnectorModeError, ConnectorRateLimited, type ConnectorRequest, ConnectorRequestError, type ConnectorResult, ConnectorTransient, ConnectorUnreachable, type ContractOperation, type CredentialField, type CredentialScope, DEFAULT_IDEMPOTENCY_WINDOW_SECONDS, DEFAULT_RETRY, type DeliveryDeclaration, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, type FailureKind, type FakeRequest, type FakeValues, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type LeaseAction, type LeaseDeclaration, type LeaseState, MAX_IDEMPOTENCY_KEY_LENGTH, type MetricDescriptor, type MetricSample, type MimeAttachment, type MimeHeader, type MimeMessage, type MimePart, type ModeInputs, NO_IDEMPOTENCY_KEY_WARNING, PROBLEM_SEVERITIES, type PreparedRequest, type ProbeOutcome, type ProbeReport, type ProbeResult, type ProbeSpec, type Problem, type ProviderAdapter, RENDERER_VERSION, REVIEW_STALE_DAYS, type RecordedShape, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SpecSource, type SubscriptionLease, type TextUnit, type Transport, type TransportResponse, type TriggerDescriptor, type VerifyResult, type WebhookVerification, type WebhookVerificationSpec, assertConnectorApi, byteRangeOf, callConnector, capabilityProblems, checkAgainstOpenApi, checkAgainstRecordedShape, classifyError, classifyHttp, classifyStatus, classifyThrown, compareShape, connectionsFor, constantTimeEquals, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, secretKeyBytes, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
|
package/dist/index.d.ts
CHANGED
|
@@ -2347,13 +2347,33 @@ type HmacScheme = {
|
|
|
2347
2347
|
/**
|
|
2348
2348
|
* Build the exact string that gets signed. Providers differ here more than
|
|
2349
2349
|
* anywhere else — Stripe signs `${timestamp}.${body}`, Slack signs
|
|
2350
|
-
* `v0:${timestamp}:${body}`, GitHub signs the body alone
|
|
2350
|
+
* `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
|
|
2351
|
+
* `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
|
|
2351
2352
|
*/
|
|
2352
|
-
payload: (raw: string, timestamp?: string) => string;
|
|
2353
|
+
payload: (raw: string, timestamp?: string, id?: string) => string;
|
|
2353
2354
|
/** Seconds a delivery stays acceptable. */
|
|
2354
2355
|
tolerance?: number;
|
|
2355
2356
|
/** Encoding of the signature the provider sends. */
|
|
2356
2357
|
encoding?: "hex" | "base64";
|
|
2358
|
+
/**
|
|
2359
|
+
* How the SECRET is spelled. `utf8` (the default, and every provider before
|
|
2360
|
+
* Svix): the key is the text's bytes. `base64`: the key is the DECODED
|
|
2361
|
+
* bytes — Svix hands out `whsec_<base64>`, and half of the decoded bytes are
|
|
2362
|
+
* not valid UTF-8, so encoding the text would sign with the wrong key and
|
|
2363
|
+
* fail exactly like a wrong secret.
|
|
2364
|
+
*/
|
|
2365
|
+
secretEncoding?: "utf8" | "base64";
|
|
2366
|
+
/** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
|
|
2367
|
+
secretPrefix?: string;
|
|
2368
|
+
};
|
|
2369
|
+
/** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
|
|
2370
|
+
declare function secretKeyBytes(secret: string, options?: {
|
|
2371
|
+
secretEncoding?: "utf8" | "base64";
|
|
2372
|
+
secretPrefix?: string;
|
|
2373
|
+
}): {
|
|
2374
|
+
bytes: Uint8Array;
|
|
2375
|
+
} | {
|
|
2376
|
+
reason: string;
|
|
2357
2377
|
};
|
|
2358
2378
|
/**
|
|
2359
2379
|
* Verify an HMAC-signed delivery.
|
|
@@ -2364,15 +2384,33 @@ type HmacScheme = {
|
|
|
2364
2384
|
*/
|
|
2365
2385
|
declare function verifyHmac(options: {
|
|
2366
2386
|
raw: string;
|
|
2367
|
-
|
|
2387
|
+
/**
|
|
2388
|
+
* The signature(s) the delivery carried. A LIST when the provider sends
|
|
2389
|
+
* several — Stripe signs once per active secret while a secret is rolled
|
|
2390
|
+
* and Svix's header "could be any number of signatures" — and the delivery
|
|
2391
|
+
* is accepted when ANY matches. A first-only rule fails every delivery
|
|
2392
|
+
* whose first signature came from the new secret, for the whole roll, and
|
|
2393
|
+
* it reads exactly like a wrong secret.
|
|
2394
|
+
*/
|
|
2395
|
+
signature: string | string[] | undefined;
|
|
2368
2396
|
secret: string | undefined;
|
|
2369
2397
|
scheme: HmacScheme;
|
|
2370
2398
|
timestamp?: string;
|
|
2399
|
+
/** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
|
|
2400
|
+
id?: string;
|
|
2371
2401
|
/** Seconds since the epoch. Injected so tests are not clock-dependent. */
|
|
2372
2402
|
now?: number;
|
|
2373
2403
|
}): Promise<WebhookVerification>;
|
|
2374
|
-
/**
|
|
2375
|
-
|
|
2404
|
+
/**
|
|
2405
|
+
* HMAC of `payload` under `secret`, hex or base64 encoded. `options` says how
|
|
2406
|
+
* the secret is spelled (see `HmacScheme.secretEncoding`); a secret that
|
|
2407
|
+
* cannot be a key THROWS here — signing has no result to carry a reason in —
|
|
2408
|
+
* while `verifyHmac` names it in its result before ever calling this.
|
|
2409
|
+
*/
|
|
2410
|
+
declare function hmac(secret: string, payload: string, algorithm: HmacScheme["algorithm"], encoding?: "hex" | "base64", options?: {
|
|
2411
|
+
secretEncoding?: "utf8" | "base64";
|
|
2412
|
+
secretPrefix?: string;
|
|
2413
|
+
}): Promise<string>;
|
|
2376
2414
|
/**
|
|
2377
2415
|
* Compare two strings without leaking where they diverge.
|
|
2378
2416
|
*
|
|
@@ -2503,13 +2541,23 @@ type HmacVerificationSpec = {
|
|
|
2503
2541
|
signatureHeader: string;
|
|
2504
2542
|
/** Header carrying the timestamp, when the scheme signs one. */
|
|
2505
2543
|
timestampHeader?: string;
|
|
2544
|
+
/**
|
|
2545
|
+
* Header carrying the delivery's ID, when the scheme signs one — Svix
|
|
2546
|
+
* signs `${svix-id}.${svix-timestamp}.${body}`. A declared id header the
|
|
2547
|
+
* delivery does not carry is a refusal, never a payload with a hole in it.
|
|
2548
|
+
*/
|
|
2549
|
+
idHeader?: string;
|
|
2506
2550
|
scheme: HmacScheme;
|
|
2507
2551
|
/**
|
|
2508
2552
|
* Some schemes pack the timestamp INTO the signature header
|
|
2509
2553
|
* (Stripe: `t=…,v1=…`). Given the raw header value, return the parts.
|
|
2554
|
+
* `signatures` carries EVERY signature the header held (a provider rolling
|
|
2555
|
+
* a secret sends one per active secret); `signature` alone is the 0.8.x
|
|
2556
|
+
* shape and still means one.
|
|
2510
2557
|
*/
|
|
2511
2558
|
parse?: (raw: string) => {
|
|
2512
2559
|
signature?: string;
|
|
2560
|
+
signatures?: string[];
|
|
2513
2561
|
timestamp?: string;
|
|
2514
2562
|
};
|
|
2515
2563
|
/** A challenge the provider makes before it will deliver anything. */
|
|
@@ -2555,4 +2603,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
|
|
|
2555
2603
|
*/
|
|
2556
2604
|
declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
|
|
2557
2605
|
|
|
2558
|
-
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type ByteRange, CANONICAL_METRICS, CONNECTOR_API_VERSION, CONNECTOR_MODES, CREDENTIAL_SCOPES, type CallOptions, type CallResult, type Capabilities, type Catalogue, type ChainLinks, type ChainOutcome, type ChainRef, type ChallengeHandshake, type Citation, type Classified, type ConnectionCredentials, type ConnectionHost, type ConnectionSpec, type Connector, ConnectorAmbiguous, ConnectorApiMismatch, ConnectorAuthError, ConnectorConfigError, ConnectorError, type ConnectorErrorContext, type ConnectorFaker, ConnectorIdempotencyExpiredError, type ConnectorMode, ConnectorModeError, ConnectorRateLimited, type ConnectorRequest, ConnectorRequestError, type ConnectorResult, ConnectorTransient, ConnectorUnreachable, type ContractOperation, type CredentialField, type CredentialScope, DEFAULT_IDEMPOTENCY_WINDOW_SECONDS, DEFAULT_RETRY, type DeliveryDeclaration, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, type FailureKind, type FakeRequest, type FakeValues, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type LeaseAction, type LeaseDeclaration, type LeaseState, MAX_IDEMPOTENCY_KEY_LENGTH, type MetricDescriptor, type MetricSample, type MimeAttachment, type MimeHeader, type MimeMessage, type MimePart, type ModeInputs, NO_IDEMPOTENCY_KEY_WARNING, PROBLEM_SEVERITIES, type PreparedRequest, type ProbeOutcome, type ProbeReport, type ProbeResult, type ProbeSpec, type Problem, type ProviderAdapter, RENDERER_VERSION, REVIEW_STALE_DAYS, type RecordedShape, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SpecSource, type SubscriptionLease, type TextUnit, type Transport, type TransportResponse, type TriggerDescriptor, type VerifyResult, type WebhookVerification, type WebhookVerificationSpec, assertConnectorApi, byteRangeOf, callConnector, capabilityProblems, checkAgainstOpenApi, checkAgainstRecordedShape, classifyError, classifyHttp, classifyStatus, classifyThrown, compareShape, connectionsFor, constantTimeEquals, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
|
|
2606
|
+
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type ByteRange, CANONICAL_METRICS, CONNECTOR_API_VERSION, CONNECTOR_MODES, CREDENTIAL_SCOPES, type CallOptions, type CallResult, type Capabilities, type Catalogue, type ChainLinks, type ChainOutcome, type ChainRef, type ChallengeHandshake, type Citation, type Classified, type ConnectionCredentials, type ConnectionHost, type ConnectionSpec, type Connector, ConnectorAmbiguous, ConnectorApiMismatch, ConnectorAuthError, ConnectorConfigError, ConnectorError, type ConnectorErrorContext, type ConnectorFaker, ConnectorIdempotencyExpiredError, type ConnectorMode, ConnectorModeError, ConnectorRateLimited, type ConnectorRequest, ConnectorRequestError, type ConnectorResult, ConnectorTransient, ConnectorUnreachable, type ContractOperation, type CredentialField, type CredentialScope, DEFAULT_IDEMPOTENCY_WINDOW_SECONDS, DEFAULT_RETRY, type DeliveryDeclaration, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, type FailureKind, type FakeRequest, type FakeValues, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type LeaseAction, type LeaseDeclaration, type LeaseState, MAX_IDEMPOTENCY_KEY_LENGTH, type MetricDescriptor, type MetricSample, type MimeAttachment, type MimeHeader, type MimeMessage, type MimePart, type ModeInputs, NO_IDEMPOTENCY_KEY_WARNING, PROBLEM_SEVERITIES, type PreparedRequest, type ProbeOutcome, type ProbeReport, type ProbeResult, type ProbeSpec, type Problem, type ProviderAdapter, RENDERER_VERSION, REVIEW_STALE_DAYS, type RecordedShape, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SpecSource, type SubscriptionLease, type TextUnit, type Transport, type TransportResponse, type TriggerDescriptor, type VerifyResult, type WebhookVerification, type WebhookVerificationSpec, assertConnectorApi, byteRangeOf, callConnector, capabilityProblems, checkAgainstOpenApi, checkAgainstRecordedShape, classifyError, classifyHttp, classifyStatus, classifyThrown, compareShape, connectionsFor, constantTimeEquals, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, secretKeyBytes, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
|
package/dist/index.js
CHANGED
|
@@ -1557,12 +1557,35 @@ var PROBLEM_SEVERITIES = ["block", "warn"];
|
|
|
1557
1557
|
var CANONICAL_METRICS = ["like", "share", "reply", "quote", "view"];
|
|
1558
1558
|
|
|
1559
1559
|
// src/webhook.ts
|
|
1560
|
+
function secretKeyBytes(secret, options = {}) {
|
|
1561
|
+
let material = secret;
|
|
1562
|
+
if (options.secretPrefix !== void 0) {
|
|
1563
|
+
if (!material.startsWith(options.secretPrefix)) {
|
|
1564
|
+
return { reason: `signing secret does not start with ${JSON.stringify(options.secretPrefix)}` };
|
|
1565
|
+
}
|
|
1566
|
+
material = material.slice(options.secretPrefix.length);
|
|
1567
|
+
}
|
|
1568
|
+
if ((options.secretEncoding ?? "utf8") === "base64") {
|
|
1569
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(material) || material.length % 4 !== 0) {
|
|
1570
|
+
return { reason: "signing secret is not valid base64" };
|
|
1571
|
+
}
|
|
1572
|
+
try {
|
|
1573
|
+
return { bytes: Uint8Array.from(atob(material), (c) => c.charCodeAt(0)) };
|
|
1574
|
+
} catch {
|
|
1575
|
+
return { reason: "signing secret is not valid base64" };
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
return { bytes: new TextEncoder().encode(material) };
|
|
1579
|
+
}
|
|
1560
1580
|
async function verifyHmac(options) {
|
|
1561
|
-
const { raw,
|
|
1581
|
+
const { raw, secret, scheme, timestamp, id } = options;
|
|
1582
|
+
const signatures = (Array.isArray(options.signature) ? options.signature : [options.signature]).filter(
|
|
1583
|
+
(s) => typeof s === "string" && s !== ""
|
|
1584
|
+
);
|
|
1562
1585
|
if (!secret) {
|
|
1563
1586
|
return { ok: false, reason: "no signing secret configured for this trigger" };
|
|
1564
1587
|
}
|
|
1565
|
-
if (
|
|
1588
|
+
if (signatures.length === 0) return { ok: false, reason: "delivery carried no signature header" };
|
|
1566
1589
|
if (scheme.tolerance !== void 0) {
|
|
1567
1590
|
if (!timestamp) return { ok: false, reason: "delivery carried no timestamp header" };
|
|
1568
1591
|
const sent = Number(timestamp);
|
|
@@ -1572,20 +1595,24 @@ async function verifyHmac(options) {
|
|
|
1572
1595
|
return { ok: false, reason: `delivery is outside the ${scheme.tolerance}s replay window` };
|
|
1573
1596
|
}
|
|
1574
1597
|
}
|
|
1575
|
-
const
|
|
1576
|
-
|
|
1598
|
+
const key = secretKeyBytes(secret, scheme);
|
|
1599
|
+
if ("reason" in key) return { ok: false, reason: key.reason };
|
|
1600
|
+
const expected = await hmac(secret, scheme.payload(raw, timestamp, id), scheme.algorithm, scheme.encoding ?? "hex", scheme);
|
|
1601
|
+
return signatures.some((candidate) => constantTimeEquals(expected, candidate)) ? { ok: true } : { ok: false, reason: "signature did not match" };
|
|
1577
1602
|
}
|
|
1578
|
-
async function hmac(secret, payload, algorithm, encoding = "hex") {
|
|
1603
|
+
async function hmac(secret, payload, algorithm, encoding = "hex", options = {}) {
|
|
1579
1604
|
const subtle = globalThis.crypto?.subtle;
|
|
1580
1605
|
if (!subtle) {
|
|
1581
1606
|
throw new Error(
|
|
1582
1607
|
"WebCrypto is not available in this runtime, so webhook signatures cannot be verified. Refusing to accept deliveries unverified."
|
|
1583
1608
|
);
|
|
1584
1609
|
}
|
|
1610
|
+
const material = secretKeyBytes(secret, options);
|
|
1611
|
+
if ("reason" in material) throw new Error(material.reason);
|
|
1585
1612
|
const encoder2 = new TextEncoder();
|
|
1586
1613
|
const key = await subtle.importKey(
|
|
1587
1614
|
"raw",
|
|
1588
|
-
|
|
1615
|
+
material.bytes,
|
|
1589
1616
|
{ name: "HMAC", hash: algorithm },
|
|
1590
1617
|
false,
|
|
1591
1618
|
["sign"]
|
|
@@ -1686,12 +1713,15 @@ async function verifyDelivery(trigger, delivery, secret, now) {
|
|
|
1686
1713
|
const rawHeader = header2(delivery.headers, spec.signatureHeader);
|
|
1687
1714
|
const parsed = spec.parse && rawHeader ? spec.parse(rawHeader) : { signature: rawHeader };
|
|
1688
1715
|
const timestamp = parsed.timestamp ?? (spec.timestampHeader ? header2(delivery.headers, spec.timestampHeader) : void 0);
|
|
1716
|
+
const id = spec.idHeader ? header2(delivery.headers, spec.idHeader) : void 0;
|
|
1717
|
+
if (spec.idHeader && !id) return { ok: false, reason: "delivery carried no id header" };
|
|
1689
1718
|
return verifyHmac({
|
|
1690
1719
|
raw: delivery.raw,
|
|
1691
|
-
signature: parsed.signature,
|
|
1720
|
+
signature: parsed.signatures ?? parsed.signature,
|
|
1692
1721
|
secret,
|
|
1693
1722
|
scheme: spec.scheme,
|
|
1694
1723
|
timestamp,
|
|
1724
|
+
id,
|
|
1695
1725
|
...now === void 0 ? {} : { now }
|
|
1696
1726
|
});
|
|
1697
1727
|
}
|
|
@@ -1795,6 +1825,7 @@ export {
|
|
|
1795
1825
|
sandboxIsSelectable,
|
|
1796
1826
|
sandboxRefusal,
|
|
1797
1827
|
satisfiesMinimum,
|
|
1828
|
+
secretKeyBytes,
|
|
1798
1829
|
seedFrom,
|
|
1799
1830
|
shapeOf,
|
|
1800
1831
|
shouldRetry,
|