@particle-academy/fancy-connector-core 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/index.cjs +43 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -2
- package/dist/index.d.ts +58 -2
- package/dist/index.js +41 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2468,7 +2468,7 @@ type HmacScheme = {
|
|
|
2468
2468
|
* `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
|
|
2469
2469
|
* `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
|
|
2470
2470
|
*/
|
|
2471
|
-
payload: (raw: string, timestamp?: string, id?: string) => string;
|
|
2471
|
+
payload: (raw: string, timestamp?: string, id?: string, request?: SignedRequestLine) => string;
|
|
2472
2472
|
/** Seconds a delivery stays acceptable. */
|
|
2473
2473
|
tolerance?: number;
|
|
2474
2474
|
/** Encoding of the signature the provider sends. */
|
|
@@ -2483,7 +2483,37 @@ type HmacScheme = {
|
|
|
2483
2483
|
secretEncoding?: "utf8" | "base64";
|
|
2484
2484
|
/** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
|
|
2485
2485
|
secretPrefix?: string;
|
|
2486
|
+
/**
|
|
2487
|
+
* The unit the timestamp header is in. Seconds unless said otherwise:
|
|
2488
|
+
* HubSpot sends MILLISECONDS, and comparing those with a window in seconds
|
|
2489
|
+
* refuses every delivery ever made.
|
|
2490
|
+
*/
|
|
2491
|
+
timestampUnit?: "s" | "ms";
|
|
2492
|
+
/**
|
|
2493
|
+
* The provider signs the REQUEST LINE too (HubSpot v3:
|
|
2494
|
+
* method + uri + body + timestamp). A delivery the host passed without its
|
|
2495
|
+
* method or URL is refused by name, never signed with a gap.
|
|
2496
|
+
*/
|
|
2497
|
+
signsRequestLine?: boolean;
|
|
2498
|
+
/** How the signed URI is spelled from the URL the request was sent to. */
|
|
2499
|
+
uri?: SignedUriRule;
|
|
2500
|
+
};
|
|
2501
|
+
/** The URI rules a provider's signature can follow. Closed: each is a decision. */
|
|
2502
|
+
declare const SIGNED_URI_RULES: readonly ["hubspot-v3"];
|
|
2503
|
+
type SignedUriRule = (typeof SIGNED_URI_RULES)[number];
|
|
2504
|
+
/** The request line as signed: the method, and the URI after the scheme's rule. */
|
|
2505
|
+
type SignedRequestLine = {
|
|
2506
|
+
method: string;
|
|
2507
|
+
uri: string;
|
|
2486
2508
|
};
|
|
2509
|
+
/**
|
|
2510
|
+
* The URI a provider signs, from the URL the request arrived on.
|
|
2511
|
+
*
|
|
2512
|
+
* `hubspot-v3`: only the QUERY portion is percent-decoded, and only for twelve
|
|
2513
|
+
* escapes (case-insensitive); never its leading `?`; any `#fragment` dropped.
|
|
2514
|
+
* Everything else, `%26` and `%3D` included, stays as sent.
|
|
2515
|
+
*/
|
|
2516
|
+
declare function normaliseSignedUri(url: string, rule: SignedUriRule): string;
|
|
2487
2517
|
/** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
|
|
2488
2518
|
declare function secretKeyBytes(secret: string, options?: {
|
|
2489
2519
|
secretEncoding?: "utf8" | "base64";
|
|
@@ -2516,6 +2546,11 @@ declare function verifyHmac(options: {
|
|
|
2516
2546
|
timestamp?: string;
|
|
2517
2547
|
/** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
|
|
2518
2548
|
id?: string;
|
|
2549
|
+
/** The request line as RECEIVED, when the scheme signs it (HubSpot v3). */
|
|
2550
|
+
request?: {
|
|
2551
|
+
method: string;
|
|
2552
|
+
url: string;
|
|
2553
|
+
};
|
|
2519
2554
|
/** Seconds since the epoch. Injected so tests are not clock-dependent. */
|
|
2520
2555
|
now?: number;
|
|
2521
2556
|
}): Promise<WebhookVerification>;
|
|
@@ -2627,6 +2662,11 @@ declare function header(headers: Record<string, string | string[] | undefined>,
|
|
|
2627
2662
|
* SSE, CometD).
|
|
2628
2663
|
*/
|
|
2629
2664
|
type DeliveryMechanism = "webhook" | "subscription" | "poll" | "pubsub" | "stream";
|
|
2665
|
+
/** See `TriggerDescriptor.route`. `path` is dotted; `[]` means every element. */
|
|
2666
|
+
type DeliveryRoute = {
|
|
2667
|
+
by: string;
|
|
2668
|
+
path: string;
|
|
2669
|
+
};
|
|
2630
2670
|
type TriggerDescriptor = {
|
|
2631
2671
|
service: string;
|
|
2632
2672
|
operation: string;
|
|
@@ -2655,6 +2695,15 @@ type TriggerDescriptor = {
|
|
|
2655
2695
|
* it, over the same raw bytes the signature was checked against.
|
|
2656
2696
|
*/
|
|
2657
2697
|
decode?: DeliveryDecode;
|
|
2698
|
+
/**
|
|
2699
|
+
* For a delivery that reaches ONE endpoint on behalf of many tenants
|
|
2700
|
+
* (HubSpot app webhooks, Gmail's Pub/Sub topic): the ONLY key a host may
|
|
2701
|
+
* route by, and where it sits in the verified payload. The rule that goes
|
|
2702
|
+
* with it is fixed, not configurable: route only AFTER verification, only
|
|
2703
|
+
* to a connection or watch the host minted, and drop an unmapped key with a
|
|
2704
|
+
* 2xx and a log line, creating nothing. The package declares; the HOST routes.
|
|
2705
|
+
*/
|
|
2706
|
+
route?: DeliveryRoute;
|
|
2658
2707
|
/** For `poll`: the provider's smallest sane interval, in seconds. */
|
|
2659
2708
|
minPollSeconds?: number;
|
|
2660
2709
|
/** A faked sample event, so the node is runnable before any of the above. */
|
|
@@ -2703,6 +2752,13 @@ type InboundDelivery = {
|
|
|
2703
2752
|
/** The body EXACTLY as received. Not re-serialised. See `webhook.ts`. */
|
|
2704
2753
|
raw: string;
|
|
2705
2754
|
headers: Record<string, string | string[] | undefined>;
|
|
2755
|
+
/**
|
|
2756
|
+
* The request line as RECEIVED, for a provider that signs it (HubSpot v3).
|
|
2757
|
+
* Pass the full URL the provider called, scheme, host, path and query,
|
|
2758
|
+
* exactly as it arrived.
|
|
2759
|
+
*/
|
|
2760
|
+
method?: string;
|
|
2761
|
+
url?: string;
|
|
2706
2762
|
};
|
|
2707
2763
|
/**
|
|
2708
2764
|
* Verify an inbound delivery against a trigger's declared scheme.
|
|
@@ -2728,4 +2784,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
|
|
|
2728
2784
|
*/
|
|
2729
2785
|
declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
|
|
2730
2786
|
|
|
2731
|
-
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type Attendee, 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, DELIVERY_DECODE_KINDS, type DeliveryDeclaration, type DeliveryDecode, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, FORM_FIELD_JSON_REASONS, type FailureKind, type FakeRequest, type FakeValues, FormFieldJsonError, type FormFieldJsonReason, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type Invite, type InviteMethod, type JoinTarget, type JoinTargetKind, 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 RecurrenceRule, 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, decodeDelivery, decodeFormFieldJson, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, joinTargets, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, nextOccurrence, parseInvite, 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 };
|
|
2787
|
+
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type Attendee, 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, DELIVERY_DECODE_KINDS, type DeliveryDeclaration, type DeliveryDecode, type DeliveryMechanism, type DeliveryOutcome, type DeliveryRoute, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, FORM_FIELD_JSON_REASONS, type FailureKind, type FakeRequest, type FakeValues, FormFieldJsonError, type FormFieldJsonReason, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type Invite, type InviteMethod, type JoinTarget, type JoinTargetKind, 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 RecurrenceRule, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SIGNED_URI_RULES, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SignedRequestLine, type SignedUriRule, 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, decodeDelivery, decodeFormFieldJson, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, joinTargets, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, nextOccurrence, normaliseSignedUri, parseInvite, 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
|
@@ -2468,7 +2468,7 @@ type HmacScheme = {
|
|
|
2468
2468
|
* `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
|
|
2469
2469
|
* `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
|
|
2470
2470
|
*/
|
|
2471
|
-
payload: (raw: string, timestamp?: string, id?: string) => string;
|
|
2471
|
+
payload: (raw: string, timestamp?: string, id?: string, request?: SignedRequestLine) => string;
|
|
2472
2472
|
/** Seconds a delivery stays acceptable. */
|
|
2473
2473
|
tolerance?: number;
|
|
2474
2474
|
/** Encoding of the signature the provider sends. */
|
|
@@ -2483,7 +2483,37 @@ type HmacScheme = {
|
|
|
2483
2483
|
secretEncoding?: "utf8" | "base64";
|
|
2484
2484
|
/** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
|
|
2485
2485
|
secretPrefix?: string;
|
|
2486
|
+
/**
|
|
2487
|
+
* The unit the timestamp header is in. Seconds unless said otherwise:
|
|
2488
|
+
* HubSpot sends MILLISECONDS, and comparing those with a window in seconds
|
|
2489
|
+
* refuses every delivery ever made.
|
|
2490
|
+
*/
|
|
2491
|
+
timestampUnit?: "s" | "ms";
|
|
2492
|
+
/**
|
|
2493
|
+
* The provider signs the REQUEST LINE too (HubSpot v3:
|
|
2494
|
+
* method + uri + body + timestamp). A delivery the host passed without its
|
|
2495
|
+
* method or URL is refused by name, never signed with a gap.
|
|
2496
|
+
*/
|
|
2497
|
+
signsRequestLine?: boolean;
|
|
2498
|
+
/** How the signed URI is spelled from the URL the request was sent to. */
|
|
2499
|
+
uri?: SignedUriRule;
|
|
2500
|
+
};
|
|
2501
|
+
/** The URI rules a provider's signature can follow. Closed: each is a decision. */
|
|
2502
|
+
declare const SIGNED_URI_RULES: readonly ["hubspot-v3"];
|
|
2503
|
+
type SignedUriRule = (typeof SIGNED_URI_RULES)[number];
|
|
2504
|
+
/** The request line as signed: the method, and the URI after the scheme's rule. */
|
|
2505
|
+
type SignedRequestLine = {
|
|
2506
|
+
method: string;
|
|
2507
|
+
uri: string;
|
|
2486
2508
|
};
|
|
2509
|
+
/**
|
|
2510
|
+
* The URI a provider signs, from the URL the request arrived on.
|
|
2511
|
+
*
|
|
2512
|
+
* `hubspot-v3`: only the QUERY portion is percent-decoded, and only for twelve
|
|
2513
|
+
* escapes (case-insensitive); never its leading `?`; any `#fragment` dropped.
|
|
2514
|
+
* Everything else, `%26` and `%3D` included, stays as sent.
|
|
2515
|
+
*/
|
|
2516
|
+
declare function normaliseSignedUri(url: string, rule: SignedUriRule): string;
|
|
2487
2517
|
/** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
|
|
2488
2518
|
declare function secretKeyBytes(secret: string, options?: {
|
|
2489
2519
|
secretEncoding?: "utf8" | "base64";
|
|
@@ -2516,6 +2546,11 @@ declare function verifyHmac(options: {
|
|
|
2516
2546
|
timestamp?: string;
|
|
2517
2547
|
/** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
|
|
2518
2548
|
id?: string;
|
|
2549
|
+
/** The request line as RECEIVED, when the scheme signs it (HubSpot v3). */
|
|
2550
|
+
request?: {
|
|
2551
|
+
method: string;
|
|
2552
|
+
url: string;
|
|
2553
|
+
};
|
|
2519
2554
|
/** Seconds since the epoch. Injected so tests are not clock-dependent. */
|
|
2520
2555
|
now?: number;
|
|
2521
2556
|
}): Promise<WebhookVerification>;
|
|
@@ -2627,6 +2662,11 @@ declare function header(headers: Record<string, string | string[] | undefined>,
|
|
|
2627
2662
|
* SSE, CometD).
|
|
2628
2663
|
*/
|
|
2629
2664
|
type DeliveryMechanism = "webhook" | "subscription" | "poll" | "pubsub" | "stream";
|
|
2665
|
+
/** See `TriggerDescriptor.route`. `path` is dotted; `[]` means every element. */
|
|
2666
|
+
type DeliveryRoute = {
|
|
2667
|
+
by: string;
|
|
2668
|
+
path: string;
|
|
2669
|
+
};
|
|
2630
2670
|
type TriggerDescriptor = {
|
|
2631
2671
|
service: string;
|
|
2632
2672
|
operation: string;
|
|
@@ -2655,6 +2695,15 @@ type TriggerDescriptor = {
|
|
|
2655
2695
|
* it, over the same raw bytes the signature was checked against.
|
|
2656
2696
|
*/
|
|
2657
2697
|
decode?: DeliveryDecode;
|
|
2698
|
+
/**
|
|
2699
|
+
* For a delivery that reaches ONE endpoint on behalf of many tenants
|
|
2700
|
+
* (HubSpot app webhooks, Gmail's Pub/Sub topic): the ONLY key a host may
|
|
2701
|
+
* route by, and where it sits in the verified payload. The rule that goes
|
|
2702
|
+
* with it is fixed, not configurable: route only AFTER verification, only
|
|
2703
|
+
* to a connection or watch the host minted, and drop an unmapped key with a
|
|
2704
|
+
* 2xx and a log line, creating nothing. The package declares; the HOST routes.
|
|
2705
|
+
*/
|
|
2706
|
+
route?: DeliveryRoute;
|
|
2658
2707
|
/** For `poll`: the provider's smallest sane interval, in seconds. */
|
|
2659
2708
|
minPollSeconds?: number;
|
|
2660
2709
|
/** A faked sample event, so the node is runnable before any of the above. */
|
|
@@ -2703,6 +2752,13 @@ type InboundDelivery = {
|
|
|
2703
2752
|
/** The body EXACTLY as received. Not re-serialised. See `webhook.ts`. */
|
|
2704
2753
|
raw: string;
|
|
2705
2754
|
headers: Record<string, string | string[] | undefined>;
|
|
2755
|
+
/**
|
|
2756
|
+
* The request line as RECEIVED, for a provider that signs it (HubSpot v3).
|
|
2757
|
+
* Pass the full URL the provider called, scheme, host, path and query,
|
|
2758
|
+
* exactly as it arrived.
|
|
2759
|
+
*/
|
|
2760
|
+
method?: string;
|
|
2761
|
+
url?: string;
|
|
2706
2762
|
};
|
|
2707
2763
|
/**
|
|
2708
2764
|
* Verify an inbound delivery against a trigger's declared scheme.
|
|
@@ -2728,4 +2784,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
|
|
|
2728
2784
|
*/
|
|
2729
2785
|
declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
|
|
2730
2786
|
|
|
2731
|
-
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type Attendee, 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, DELIVERY_DECODE_KINDS, type DeliveryDeclaration, type DeliveryDecode, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, FORM_FIELD_JSON_REASONS, type FailureKind, type FakeRequest, type FakeValues, FormFieldJsonError, type FormFieldJsonReason, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type Invite, type InviteMethod, type JoinTarget, type JoinTargetKind, 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 RecurrenceRule, 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, decodeDelivery, decodeFormFieldJson, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, joinTargets, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, nextOccurrence, parseInvite, 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 };
|
|
2787
|
+
export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type Attendee, 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, DELIVERY_DECODE_KINDS, type DeliveryDeclaration, type DeliveryDecode, type DeliveryMechanism, type DeliveryOutcome, type DeliveryRoute, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, FORM_FIELD_JSON_REASONS, type FailureKind, type FakeRequest, type FakeValues, FormFieldJsonError, type FormFieldJsonReason, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type Invite, type InviteMethod, type JoinTarget, type JoinTargetKind, 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 RecurrenceRule, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SIGNED_URI_RULES, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SignedRequestLine, type SignedUriRule, 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, decodeDelivery, decodeFormFieldJson, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, joinTargets, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, nextOccurrence, normaliseSignedUri, parseInvite, 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
|
@@ -1953,6 +1953,29 @@ var PROBLEM_SEVERITIES = ["block", "warn"];
|
|
|
1953
1953
|
var CANONICAL_METRICS = ["like", "share", "reply", "quote", "view"];
|
|
1954
1954
|
|
|
1955
1955
|
// src/webhook.ts
|
|
1956
|
+
var SIGNED_URI_RULES = ["hubspot-v3"];
|
|
1957
|
+
var HUBSPOT_V3_DECODE = {
|
|
1958
|
+
"%3A": ":",
|
|
1959
|
+
"%2F": "/",
|
|
1960
|
+
"%3F": "?",
|
|
1961
|
+
"%40": "@",
|
|
1962
|
+
"%21": "!",
|
|
1963
|
+
"%24": "$",
|
|
1964
|
+
"%27": "'",
|
|
1965
|
+
"%28": "(",
|
|
1966
|
+
"%29": ")",
|
|
1967
|
+
"%2A": "*",
|
|
1968
|
+
"%2C": ",",
|
|
1969
|
+
"%3B": ";"
|
|
1970
|
+
};
|
|
1971
|
+
function normaliseSignedUri(url, rule) {
|
|
1972
|
+
if (rule !== "hubspot-v3") throw new Error(`unknown signed-uri rule ${JSON.stringify(rule)}`);
|
|
1973
|
+
const withoutFragment = url.split("#", 1)[0] ?? "";
|
|
1974
|
+
const q = withoutFragment.indexOf("?");
|
|
1975
|
+
if (q === -1) return withoutFragment;
|
|
1976
|
+
const query = withoutFragment.slice(q + 1).replace(/%[0-9A-Fa-f]{2}/g, (e) => HUBSPOT_V3_DECODE[e.toUpperCase()] ?? e);
|
|
1977
|
+
return `${withoutFragment.slice(0, q)}?${query}`;
|
|
1978
|
+
}
|
|
1956
1979
|
function secretKeyBytes(secret, options = {}) {
|
|
1957
1980
|
let material = secret;
|
|
1958
1981
|
if (options.secretPrefix !== void 0) {
|
|
@@ -1987,13 +2010,26 @@ async function verifyHmac(options) {
|
|
|
1987
2010
|
const sent = Number(timestamp);
|
|
1988
2011
|
if (!Number.isFinite(sent)) return { ok: false, reason: "timestamp header is not a number" };
|
|
1989
2012
|
const now = options.now ?? Math.floor(Date.now() / 1e3);
|
|
1990
|
-
|
|
2013
|
+
const sentSeconds = scheme.timestampUnit === "ms" ? sent / 1e3 : sent;
|
|
2014
|
+
if (Math.abs(now - sentSeconds) > scheme.tolerance) {
|
|
1991
2015
|
return { ok: false, reason: `delivery is outside the ${scheme.tolerance}s replay window` };
|
|
1992
2016
|
}
|
|
1993
2017
|
}
|
|
1994
2018
|
const key = secretKeyBytes(secret, scheme);
|
|
1995
2019
|
if ("reason" in key) return { ok: false, reason: key.reason };
|
|
1996
|
-
|
|
2020
|
+
let line;
|
|
2021
|
+
if (scheme.signsRequestLine) {
|
|
2022
|
+
const { method, url } = options.request ?? {};
|
|
2023
|
+
if (!method || !url) return { ok: false, reason: "delivery carried no request method or url" };
|
|
2024
|
+
line = { method, uri: scheme.uri ? normaliseSignedUri(url, scheme.uri) : url };
|
|
2025
|
+
}
|
|
2026
|
+
const expected = await hmac(
|
|
2027
|
+
secret,
|
|
2028
|
+
scheme.payload(raw, timestamp, id, line),
|
|
2029
|
+
scheme.algorithm,
|
|
2030
|
+
scheme.encoding ?? "hex",
|
|
2031
|
+
scheme
|
|
2032
|
+
);
|
|
1997
2033
|
return signatures.some((candidate) => constantTimeEquals(expected, candidate)) ? { ok: true } : { ok: false, reason: "signature did not match" };
|
|
1998
2034
|
}
|
|
1999
2035
|
async function hmac(secret, payload, algorithm, encoding = "hex", options = {}) {
|
|
@@ -2118,6 +2154,7 @@ async function verifyDelivery(trigger, delivery, secret, now) {
|
|
|
2118
2154
|
scheme: spec.scheme,
|
|
2119
2155
|
timestamp,
|
|
2120
2156
|
id,
|
|
2157
|
+
...delivery.method === void 0 && delivery.url === void 0 ? {} : { request: { method: delivery.method ?? "", url: delivery.url ?? "" } },
|
|
2121
2158
|
...now === void 0 ? {} : { now }
|
|
2122
2159
|
});
|
|
2123
2160
|
}
|
|
@@ -2169,6 +2206,7 @@ export {
|
|
|
2169
2206
|
RENDERER_VERSION,
|
|
2170
2207
|
REVIEW_STALE_DAYS,
|
|
2171
2208
|
SANDBOX_KINDS,
|
|
2209
|
+
SIGNED_URI_RULES,
|
|
2172
2210
|
SUPPORTED_CONNECTOR_API,
|
|
2173
2211
|
assertConnectorApi,
|
|
2174
2212
|
byteRangeOf,
|
|
@@ -2208,6 +2246,7 @@ export {
|
|
|
2208
2246
|
linkRanges,
|
|
2209
2247
|
measure,
|
|
2210
2248
|
nextOccurrence,
|
|
2249
|
+
normaliseSignedUri,
|
|
2211
2250
|
parseInvite,
|
|
2212
2251
|
parseMime,
|
|
2213
2252
|
payloadHash,
|