@wildo-ai/external-connectors-models 1.1.11 → 1.1.13
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/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/companion-exports.js.map +1 -1
- package/dist/esm/core/commons.external-connectors-models.schemas.d.ts +10 -0
- package/dist/esm/core/commons.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/commons.external-connectors-models.schemas.js +10 -0
- package/dist/esm/core/commons.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/core/oauth2.enums.d.ts.map +1 -1
- package/dist/esm/core/oauth2.enums.js.map +1 -1
- package/dist/esm/core/operation-classification.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/operation-classification.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/core/operations.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/operations.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/core/security.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/security.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.d.ts +20 -46
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.js +34 -5
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/billing.standard-interface.schemas.d.ts +56 -3
- package/dist/esm/protocols/billing.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/billing.standard-interface.schemas.js +15 -2
- package/dist/esm/protocols/billing.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/content-safety.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/content-safety.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/document-extraction.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/document-extraction.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.d.ts +157 -0
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.js +134 -0
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.d.ts +85 -0
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.js +46 -2
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/email.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/email.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/email.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/email.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.d.ts +49 -6
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.js +89 -6
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/file-storage.standard-interface.d.ts +9 -2
- package/dist/esm/protocols/file-storage.standard-interface.d.ts.map +1 -1
- package/dist/esm/protocols/file-storage.standard-interface.js +6 -0
- package/dist/esm/protocols/file-storage.standard-interface.js.map +1 -1
- package/dist/esm/protocols/frontend.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/frontend.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.d.ts +254 -0
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.js +480 -0
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/hooks-capability.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/hooks-capability.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.d.ts +95 -1
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.js +110 -0
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/image.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/image.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/llm.external-connectors-models.schemas.d.ts +95 -3
- package/dist/esm/protocols/llm.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/llm.external-connectors-models.schemas.js +147 -15
- package/dist/esm/protocols/llm.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.definitions.d.ts.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.definitions.js.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.schemas.js.map +1 -1
- package/dist/esm/protocols/oauth2.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/oauth2.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.d.ts +52 -0
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.js +132 -0
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.d.ts +111 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.d.ts.map +1 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.js +203 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.js.map +1 -0
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.d.ts +6 -0
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.d.ts.map +1 -1
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.js +13 -7
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.js.map +1 -1
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.d.ts +50 -0
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.d.ts.map +1 -0
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.js +30 -0
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.js.map +1 -0
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.d.ts +730 -17
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.js +822 -20
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.d.ts +73 -0
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.js +82 -0
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/sms.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/sms.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/sms.standard-interface.schemas.d.ts +79 -1
- package/dist/esm/protocols/sms.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/sms.standard-interface.schemas.js +93 -0
- package/dist/esm/protocols/sms.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/subject-erasure-effect.standard-interface.d.ts.map +1 -1
- package/dist/esm/protocols/subject-erasure-effect.standard-interface.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/dist/esm/.native.tsbuildinfo +0 -1
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
import { z } from 'zod';
|
|
47
47
|
import { API_HttpMethod } from '../core/commons.external-connectors-models.schemas';
|
|
48
48
|
import { ExternalOperation_Classification } from '../core/operation-classification.external-connectors-models.schemas';
|
|
49
|
-
import type
|
|
49
|
+
import { ExternalProvider_Connection_OwnerScope, type ExternalProvider_ConnectionTarget } from '../core/security.external-connectors-models.schemas';
|
|
50
|
+
import type { ProviderRestOperationGraphql } from './graphql-operations.external-connectors-models.schemas';
|
|
50
51
|
/** @wildo_source:part:start external-connectors.models.rest-operation-contract facet:layer:shared facet:family:provider facet:audience:app-developer */
|
|
51
52
|
/** Where a declared parameter rides on the wire. */
|
|
52
53
|
export declare enum ProviderRestParameterLocation {
|
|
@@ -140,6 +141,19 @@ export interface ProviderRestOperationParameter {
|
|
|
140
141
|
* above it; the origin itself cannot move, as for every path value.
|
|
141
142
|
*/
|
|
142
143
|
readonly multiSegment?: true;
|
|
144
|
+
/**
|
|
145
|
+
* PATH only (#3397): the value is the CONNECTION's vendor-reported fact of this name, never the caller's input. Every
|
|
146
|
+
* QuickBooks path is `/v3/company/{realmId}/…`, and the company is the one the person connected, so asking each caller
|
|
147
|
+
* for it would let a call name a company its connection was not made for and leave every application re-typing it.
|
|
148
|
+
*
|
|
149
|
+
* The fact must be declared on the connection's OAuth2 contract with a
|
|
150
|
+
* {@link ProviderOAuth2ReportedAccountFact.pathSegmentPattern}; the access resolver re-admits the stored value on every
|
|
151
|
+
* call and hands it to the request compiler, which fills nothing else from it. A caller value under the same input
|
|
152
|
+
* name is refused rather than ignored, and the operation's `inputSchema` must not declare one
|
|
153
|
+
* ({@link describeProviderRestOperationConnectionFactDefects}). Exclusive with `from`, `constantValue` and
|
|
154
|
+
* `multiSegment`.
|
|
155
|
+
*/
|
|
156
|
+
readonly connectionFact?: string;
|
|
143
157
|
readonly description?: string;
|
|
144
158
|
}
|
|
145
159
|
/** How the request body is built from the operation's input. */
|
|
@@ -208,12 +222,50 @@ export interface ProviderRestOperationInputOptions {
|
|
|
208
222
|
/** Dot-path, inside each listed item, to the text a person reads (`name`). Vendor content, never derived from the value. */
|
|
209
223
|
readonly labelPath: string;
|
|
210
224
|
/**
|
|
211
|
-
* Inputs the options depend on: `{ <options-operation input field>: <this operation's input field> }`.
|
|
225
|
+
* Inputs the options depend on: `{ <options-operation input field>: <this operation's input field PATH> }`.
|
|
226
|
+
* The value side is a dot path into this operation's input, like the `inputOptions` key (#3399): Jira's issue
|
|
227
|
+
* types depend on `project.key`. The key side is a top-level field of the options operation's own input.
|
|
212
228
|
* A choice that is not yet made is REFUSED by name rather than listed as empty — "no projects" and
|
|
213
229
|
* "choose a workspace first" are different answers, and only one of them is true.
|
|
214
230
|
*/
|
|
215
231
|
readonly dependsOn?: Readonly<Record<string, string>>;
|
|
232
|
+
/**
|
|
233
|
+
* Fixed values the options operation is called with, beside what `dependsOn` forwards (#3399): Jira lists only the
|
|
234
|
+
* projects a person may create in (`action: 'create'`), Box lists the root folder (`folder_id: '0'`). A field may
|
|
235
|
+
* not be both fixed and forwarded.
|
|
236
|
+
*/
|
|
237
|
+
readonly input?: Readonly<Record<string, string | number | boolean>>;
|
|
238
|
+
/**
|
|
239
|
+
* Dot path, inside the options operation's output, to the listed items, when that output is an object rather than the
|
|
240
|
+
* list itself (#3399): QuickBooks answers a query as `{ Customer: [...] }`, Box a folder as `{ entries: [...] }`. An
|
|
241
|
+
* object without that path lists nothing, which is how QuickBooks answers a query with no rows; anything else at the
|
|
242
|
+
* path that is not a list is an unreadable answer. Absent, the output itself must be the list.
|
|
243
|
+
*/
|
|
244
|
+
readonly itemsPath?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Keeps only the listed items whose value at each dot path equals the given text (#3399): a folder's items are files,
|
|
247
|
+
* folders and web links, and only a folder can be a parent (`{ type: 'folder' }`). Absent, every item is a choice.
|
|
248
|
+
*/
|
|
249
|
+
readonly itemWhere?: Readonly<Record<string, string>>;
|
|
216
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Why an operation's `inputOptions` cannot be honoured, or an empty list (#3399). Each key, and each `dependsOn` value,
|
|
253
|
+
* is a dot path into the operation's input (`project.key`, `CustomerRef.value`; a top-level field is a one-segment
|
|
254
|
+
* path), and must name a field the operation's `inputSchema` declares. Checked where a catalogue loads (the operation
|
|
255
|
+
* executor, an augmentation or supplement merge) and at publish, so a mistyped path is refused once, by name, instead of
|
|
256
|
+
* offering a picker that fills nothing. An operation without an `inputSchema` passes its input through unvalidated and
|
|
257
|
+
* declares no fields, so there is nothing to check its paths against; only their shape is.
|
|
258
|
+
*/
|
|
259
|
+
export declare function describeProviderRestOperationInputOptionsDefects(operation: Pick<ProviderRestOperation, 'operationId' | 'inputSchema' | 'inputOptions'>): string[];
|
|
260
|
+
/**
|
|
261
|
+
* Why an operation's {@link ProviderRestOperationParameter.connectionFact} parameters cannot be honoured, or an empty
|
|
262
|
+
* list (#3397). Each must be a PATH parameter the path template uses, fed by nothing else (no `from`, `constantValue` or
|
|
263
|
+
* `multiSegment`), and the operation's `inputSchema` must not declare a field of its name: a caller is never asked for a
|
|
264
|
+
* value the connection supplies, and one it sends anyway is refused at the call. With `reportedAccountFacts` (the
|
|
265
|
+
* connection's OAuth2 declaration), each named fact must also be declared there with a `pathSegmentPattern`; without
|
|
266
|
+
* it the request compiler refuses the call, so a module walk passes them to catch it before any call.
|
|
267
|
+
*/
|
|
268
|
+
export declare function describeProviderRestOperationConnectionFactDefects(operation: Pick<ProviderRestOperation, 'operationId' | 'pathTemplate' | 'parameters' | 'inputSchema'>, reportedAccountFacts?: Readonly<Record<string, ProviderOAuth2ReportedAccountFact>>): string[];
|
|
217
269
|
/**
|
|
218
270
|
* A provider operation, hand-authored. The unit an application addresses:
|
|
219
271
|
* `executeProviderOperation({ providerRef: 'slack', operationId: 'conversations.list', input })`.
|
|
@@ -315,10 +367,19 @@ export interface ProviderRestOperation {
|
|
|
315
367
|
/** Narrows the provider's semantics for this one operation (a slow export, a tight endpoint). */
|
|
316
368
|
readonly remoteCallSemantics?: Partial<ProviderRestCallSemantics>;
|
|
317
369
|
/**
|
|
318
|
-
* Where each input's choices come from, keyed by
|
|
319
|
-
*
|
|
370
|
+
* Where each input's choices come from, keyed by a dot PATH into the input (#3399): `workspace` for a top-level
|
|
371
|
+
* field, `project.key` or `CustomerRef.value` for the value a vendor nests inside a reference object. Absent for an
|
|
372
|
+
* input a caller types. Every path must name a field of `inputSchema`
|
|
373
|
+
* ({@link describeProviderRestOperationInputOptionsDefects}). See {@link ProviderRestOperationInputOptions}.
|
|
320
374
|
*/
|
|
321
375
|
readonly inputOptions?: Readonly<Record<string, ProviderRestOperationInputOptions>>;
|
|
376
|
+
/**
|
|
377
|
+
* Present for a GraphQL operation (#3392): the provider-owned document the call sends to `pathTemplate` (the vendor's
|
|
378
|
+
* GraphQL endpoint), with the operation's input as its variables. A 2xx answer carrying `errors` fails the call; the
|
|
379
|
+
* output is read from the answer's `data`. See {@link ProviderRestOperationGraphql} for what such an operation may and
|
|
380
|
+
* may not declare beside it.
|
|
381
|
+
*/
|
|
382
|
+
readonly graphql?: ProviderRestOperationGraphql;
|
|
322
383
|
/** Set when the vendor has deprecated it; the executor logs once per operation, never refuses. */
|
|
323
384
|
readonly deprecated?: {
|
|
324
385
|
readonly reason: string;
|
|
@@ -420,6 +481,22 @@ export declare function describeProviderRestApplicationOutcomeDefects(outcome: P
|
|
|
420
481
|
export declare const PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER = "{tenant}";
|
|
421
482
|
/** A tenant value the token URL admits: a GUID or a DNS name. Nothing that can leave the URL's path segment. */
|
|
422
483
|
export declare const PROVIDER_CLIENT_CREDENTIALS_TENANT_SHAPE: RegExp;
|
|
484
|
+
/**
|
|
485
|
+
* The placeholder that BEGINS a client-credentials token URL whose token endpoint is on the deployment's own vendor
|
|
486
|
+
* instance (#3402): `{deploymentOrigin}/oauth2/v1/token`. Filled with the ORIGIN of the base URL the engine resolved for
|
|
487
|
+
* the REST contract (from `baseUrlHostEnvVarName` or `baseUrlEnvVarName`), never from a connection or a request.
|
|
488
|
+
*
|
|
489
|
+
* Okta is the case: every org has its own host (`<org>.okta.com`, or a custom domain), and its org authorization server's
|
|
490
|
+
* token endpoint is on that host. A fixed {@link ProviderRestClientCredentials.tokenHosts} list cannot admit a host only
|
|
491
|
+
* the operator knows, and a `{tenant}` value would be a second, separately typed copy of the host the operations already
|
|
492
|
+
* go to, which could disagree with it. Filling the token endpoint from the SAME resolved origin keeps them one value: the
|
|
493
|
+
* client's assertion is sent to the host the operator named, and to nothing a person connecting could choose.
|
|
494
|
+
*
|
|
495
|
+
* spec-cite: Okta Developer, "Implement OAuth for Okta with a service app"
|
|
496
|
+
* (https://developer.okta.com/docs/guides/implement-oauth-for-okta-serviceapp/main/, fetched 2026-11-10) — the token
|
|
497
|
+
* request is `POST https://{yourOktaDomain}/oauth2/v1/token`, and the assertion's `aud` is that URL.
|
|
498
|
+
*/
|
|
499
|
+
export declare const PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER = "{deploymentOrigin}";
|
|
423
500
|
/** What a {@link ProviderClientCredentialsVerifiedFact} records: a value the person typed and the vendor accepted. */
|
|
424
501
|
export declare enum ProviderClientCredentialsFactSource {
|
|
425
502
|
/** The client id the token endpoint issued a token for: Microsoft's bot App ID. */
|
|
@@ -451,9 +528,14 @@ export interface ProviderClientCredentialsVerifiedFact {
|
|
|
451
528
|
* secret the connection holds (#2663). The Bot Framework is the first: a Teams bot's App ID and secret, and for a
|
|
452
529
|
* single-tenant bot the tenant it is registered in, mint a token for `https://api.botframework.com/.default`.
|
|
453
530
|
*
|
|
531
|
+
* Declared beside `oauth2` (#3398), it is the APPLICATION's own connection: Box's client-credentials grant and Zoom's
|
|
532
|
+
* server-to-server OAuth renew the application's token while people and organizations connect through the exchange.
|
|
533
|
+
* {@link providerClientCredentialsServesOwnerScope} says which door a connection takes.
|
|
534
|
+
*
|
|
454
535
|
* The token is minted per call when no unexpired one is cached, never stored, and attached where
|
|
455
|
-
* {@link ProviderProtocolRuntimeContract}'s `apiKey` says, so `apiKey.secretRef` names the
|
|
456
|
-
*
|
|
536
|
+
* {@link ProviderProtocolRuntimeContract}'s `apiKey` says, so (with no `oauth2` beside it) `apiKey.secretRef` names the
|
|
537
|
+
* client's credential, its SECRET or its private key (#3402), the slot whose absence means "not configured". The
|
|
538
|
+
* client id, credential and tenant are read from the connection: the
|
|
457
539
|
* application's own environment for an APPLICATION connection, the organization's typed credential for an
|
|
458
540
|
* ORGANIZATION one.
|
|
459
541
|
*
|
|
@@ -468,16 +550,62 @@ export interface ProviderClientCredentialsVerifiedFact {
|
|
|
468
550
|
* `https://api.botframework.com/.default`, fetched 2026-10-06.
|
|
469
551
|
*/
|
|
470
552
|
export interface ProviderRestClientCredentials {
|
|
471
|
-
/**
|
|
553
|
+
/**
|
|
554
|
+
* The https token endpoint. May carry {@link PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}, or BEGIN with
|
|
555
|
+
* {@link PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER} when the token endpoint is on the deployment's own
|
|
556
|
+
* vendor instance (Okta's org, #3402).
|
|
557
|
+
*/
|
|
472
558
|
readonly tokenUrl: string;
|
|
473
|
-
/**
|
|
559
|
+
/**
|
|
560
|
+
* The hosts the token endpoint may be on once filled. The client secret is sent nowhere else. EMPTY exactly when the
|
|
561
|
+
* token URL begins with {@link PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}: its host is the one the
|
|
562
|
+
* operator named for the operations, and no fixed list can name it.
|
|
563
|
+
*/
|
|
474
564
|
readonly tokenHosts: readonly string[];
|
|
475
|
-
/**
|
|
476
|
-
|
|
565
|
+
/**
|
|
566
|
+
* The `scope` parameter, sent as written. Omitted, no `scope` is sent: RFC 6749 makes it optional, and Box, Zoom and
|
|
567
|
+
* Salesforce grant the scopes configured on the app instead (#3398).
|
|
568
|
+
* spec-cite: RFC 6749 §4.4.2 — `scope`: "OPTIONAL. The scope of the access request as described by Section 3.3."
|
|
569
|
+
* Fetched 2026-10-06.
|
|
570
|
+
*/
|
|
571
|
+
readonly scope?: string;
|
|
572
|
+
/**
|
|
573
|
+
* The `grant_type` sent. Omitted, `client_credentials` (RFC 6749 §4.4). See {@link ProviderClientCredentialsGrantType}.
|
|
574
|
+
*/
|
|
575
|
+
readonly grantType?: ProviderClientCredentialsGrantType;
|
|
576
|
+
/**
|
|
577
|
+
* Further parameters of the token request a vendor requires, by name: a fixed value, or one read from a slot of the
|
|
578
|
+
* connection (#3398). Box's client-credentials grant names the subject it authenticates as (`box_subject_type`,
|
|
579
|
+
* `box_subject_id`); Zoom's server-to-server grant names the account (`account_id`). A parameter the grant itself
|
|
580
|
+
* defines (`grant_type`, `client_id`, `client_secret`, `scope`, the client assertion) is refused here: each has its own
|
|
581
|
+
* field. See {@link ProviderClientCredentialsTokenRequestParameter}.
|
|
582
|
+
*/
|
|
583
|
+
readonly tokenRequestParameters?: Readonly<Record<string, ProviderClientCredentialsTokenRequestParameter>>;
|
|
584
|
+
/**
|
|
585
|
+
* How the client authenticates to the token endpoint. Omitted,
|
|
586
|
+
* {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_POST} with a client secret: the id and secret in the
|
|
587
|
+
* body, as Microsoft's identity platform documents. {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC}
|
|
588
|
+
* sends them in the Basic header only (Zoom's server-to-server OAuth documents nothing else). With
|
|
589
|
+
* {@link privateKeyJwt} the method is {@link ProviderOAuth2ClientAuthenticationMethod.PRIVATE_KEY_JWT}, implied when
|
|
590
|
+
* omitted (#3402).
|
|
591
|
+
*/
|
|
592
|
+
readonly tokenEndpointAuthMethod?: ProviderOAuth2ClientAuthenticationMethod;
|
|
477
593
|
/** The slot holding the client id. */
|
|
478
594
|
readonly clientIdSecretRef: string;
|
|
479
|
-
/**
|
|
480
|
-
|
|
595
|
+
/**
|
|
596
|
+
* The slot holding the client secret. Exactly one of this and {@link privateKeyJwt} (#3402): a client authenticates
|
|
597
|
+
* with a shared secret or with a key it alone holds, never both. The client's CREDENTIAL slot (this one, or the
|
|
598
|
+
* private key's) equals the contract's `apiKey.secretRef` when the contract declares no `oauth2` (the slot whose
|
|
599
|
+
* absence means "not configured"); beside `oauth2`, `apiKey.secretRef` is the slot of the people's and organizations'
|
|
600
|
+
* minted tokens and this one serves the application alone.
|
|
601
|
+
*/
|
|
602
|
+
readonly clientSecretSecretRef?: string;
|
|
603
|
+
/**
|
|
604
|
+
* The client authenticates with a JWT it signs with its own private key (`private_key_jwt`, #3402) instead of a
|
|
605
|
+
* secret: Okta's OAuth service apps accept nothing else for the Management API. See
|
|
606
|
+
* {@link ProviderClientCredentialsPrivateKeyJwt}.
|
|
607
|
+
*/
|
|
608
|
+
readonly privateKeyJwt?: ProviderClientCredentialsPrivateKeyJwt;
|
|
481
609
|
/** The slot filling {@link PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}. Required exactly when the token URL carries it. */
|
|
482
610
|
readonly tenantSecretRef?: string;
|
|
483
611
|
/** Facts an ORGANIZATION connection records once the vendor accepted its credential, keyed by fact name. */
|
|
@@ -485,12 +613,171 @@ export interface ProviderRestClientCredentials {
|
|
|
485
613
|
/** Seconds a token is kept when the answer states no `expires_in`. Omitted, it is not cached. */
|
|
486
614
|
readonly tokenLifetimeFallbackSeconds?: number;
|
|
487
615
|
}
|
|
616
|
+
/**
|
|
617
|
+
* The `grant_type` a client-credentials token request sends. Narrower than `OAuth2_GrantType` on purpose: these are the
|
|
618
|
+
* grants the client-credentials minter performs, each with nothing but the client's own credential and the declared
|
|
619
|
+
* parameters, and a member joins in the change that implements it.
|
|
620
|
+
*/
|
|
621
|
+
export declare enum ProviderClientCredentialsGrantType {
|
|
622
|
+
/**
|
|
623
|
+
* The OAuth 2.0 client-credentials grant: the default.
|
|
624
|
+
* spec-cite: RFC 6749 §4.4.2 — `grant_type`: "REQUIRED. Value MUST be set to "client_credentials"." Fetched 2026-10-06.
|
|
625
|
+
*/
|
|
626
|
+
CLIENT_CREDENTIALS = "client_credentials",
|
|
627
|
+
/**
|
|
628
|
+
* Zoom's server-to-server OAuth: the same exchange (a client authenticated with Basic, one token back, no refresh
|
|
629
|
+
* token) under Zoom's own grant name, with the account named in `account_id`.
|
|
630
|
+
* spec-cite: https://developers.zoom.us/docs/internal-apps/s2s-oauth/ — "Use the `account_credentials` grant type to
|
|
631
|
+
* generate an access token."; "Set up the body of the access token request using the `account_credentials`
|
|
632
|
+
* `grant_type` and your `account_id`." Fetched 2026-11-09.
|
|
633
|
+
*/
|
|
634
|
+
ACCOUNT_CREDENTIALS = "account_credentials"
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* One further parameter of a client-credentials token request ({@link ProviderRestClientCredentials.tokenRequestParameters}):
|
|
638
|
+
* a fixed `value` the module states (`box_subject_type: enterprise`), or a `secretRef` naming the connection slot that
|
|
639
|
+
* holds it (Box's enterprise id, Zoom's account id), read like the client id: from the application's environment for
|
|
640
|
+
* the application's connection, from the organization's credential for an organization's.
|
|
641
|
+
*/
|
|
642
|
+
export type ProviderClientCredentialsTokenRequestParameter = {
|
|
643
|
+
readonly value: string;
|
|
644
|
+
readonly secretRef?: never;
|
|
645
|
+
} | {
|
|
646
|
+
readonly secretRef: string;
|
|
647
|
+
readonly value?: never;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* The algorithms a client assertion is signed with (#3402). The JWS names (RFC 7518 §3.1) of the two asymmetric
|
|
651
|
+
* families every vendor measured accepts: Okta lists "RS256, RS384, RS512, ES256, ES384, and ES512" for a service app's
|
|
652
|
+
* key. A member joins when a vendor needs it.
|
|
653
|
+
* spec-cite: RFC 7518 §3.1 — "RS256 | RSASSA-PKCS1-v1_5 using SHA-256" and "ES256 | ECDSA using P-256 and SHA-256";
|
|
654
|
+
* https://developer.okta.com/docs/guides/implement-oauth-for-okta-serviceapp/main/ — the supported algorithms. Both
|
|
655
|
+
* fetched 2026-11-09.
|
|
656
|
+
*/
|
|
657
|
+
export declare enum ProviderClientAssertionSigningAlgorithm {
|
|
658
|
+
/** ECDSA on P-256 with SHA-256: a short key and signature, and the default to choose for a new key. */
|
|
659
|
+
ES256 = "ES256",
|
|
660
|
+
/** RSASSA-PKCS1-v1_5 with SHA-256, for a vendor or key store that issues RSA keys. */
|
|
661
|
+
RS256 = "RS256"
|
|
662
|
+
}
|
|
663
|
+
/** The longest a client assertion may live: Okta refuses one whose `exp` is more than an hour away. */
|
|
664
|
+
export declare const PROVIDER_CLIENT_ASSERTION_MAXIMUM_LIFETIME_SECONDS = 3600;
|
|
665
|
+
/** How long a client assertion lives when the declaration says nothing: long enough for one request, and no more. */
|
|
666
|
+
export declare const PROVIDER_CLIENT_ASSERTION_DEFAULT_LIFETIME_SECONDS = 300;
|
|
667
|
+
/**
|
|
668
|
+
* `private_key_jwt` client authentication for a client-credentials token request (#3402). The client signs, per token
|
|
669
|
+
* request, a JWT whose `iss` and `sub` are its client id, whose `aud` is the token endpoint it is sent to, with a short
|
|
670
|
+
* `exp` and a fresh `jti`, and sends it as `client_assertion`.
|
|
671
|
+
*
|
|
672
|
+
* The private key is read from a slot of the connection, as an unencrypted PEM (PKCS#8, or an RSA PKCS#1 / EC key the
|
|
673
|
+
* signer re-wraps), like a secret: the application's configured provider secrets for its own connection, an organization's sealed
|
|
674
|
+
* credential row for an organization's.
|
|
675
|
+
*
|
|
676
|
+
* ## Why the platform keyring does not hold this key (decided 2026-11-10, #3402)
|
|
677
|
+
*
|
|
678
|
+
* The key layer (#2916) holds keys by PURPOSE, each signing the platform's own claims under its own `typ` and verified
|
|
679
|
+
* from public halves the platform publishes. A client key is the opposite: its public half is REGISTERED BY THE OPERATOR
|
|
680
|
+
* at the vendor (Okta's app, a Google service account), the vendor is its only verifier, and the vendor fixes the
|
|
681
|
+
* algorithm (Okta's console and Google's uploaded keys are RSA, while the keyring signs ES256 only). A keyring rotation
|
|
682
|
+
* would also silently break every connection whose vendor still holds the old public half. So custody signing for vendor
|
|
683
|
+
* clients is a key purpose of its own (RS256 across the keyring providers, a public half handed to the operator, rotation
|
|
684
|
+
* coordinated with the vendor registration), recorded on #2916, and not a missing step of this declaration.
|
|
685
|
+
*
|
|
686
|
+
* spec-cite: RFC 7523 §2.2 — "The value of the "client_assertion_type" is
|
|
687
|
+
* "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"."; §3 — the JWT "MUST contain an "iss" (issuer) claim", for
|
|
688
|
+
* client authentication "the subject MUST be the "client_id" of the OAuth client", an "aud" (audience) claim "containing
|
|
689
|
+
* a value that identifies the authorization server", and an "exp" (expiration time) claim; OpenID Connect Core 1.0 §9,
|
|
690
|
+
* `private_key_jwt` — `iss` and `sub` "MUST contain the client_id of the OAuth Client", "The Audience SHOULD be the URL
|
|
691
|
+
* of the Authorization Server's Token Endpoint", `jti` REQUIRED: "These tokens MUST only be used once". Fetched
|
|
692
|
+
* 2026-11-09 from https://www.rfc-editor.org/rfc/rfc7523 and https://openid.net/specs/openid-connect-core-1_0.html.
|
|
693
|
+
*/
|
|
694
|
+
export interface ProviderClientCredentialsPrivateKeyJwt {
|
|
695
|
+
/** The slot holding the client's private key: an unencrypted PEM, PKCS#8 (`-----BEGIN PRIVATE KEY-----`) or PKCS#1 / EC. */
|
|
696
|
+
readonly privateKeySecretRef: string;
|
|
697
|
+
/** The JWS algorithm the key signs with. Must match the key: an EC P-256 key for ES256, an RSA key for RS256. */
|
|
698
|
+
readonly algorithm: ProviderClientAssertionSigningAlgorithm;
|
|
699
|
+
/**
|
|
700
|
+
* The slot holding the key id sent as the assertion's `kid` header, when the vendor locates the key by it (Okta
|
|
701
|
+
* requires a `kid` on every key registered with the app). Omitted, no `kid` is sent.
|
|
702
|
+
*/
|
|
703
|
+
readonly keyIdSecretRef?: string;
|
|
704
|
+
/** Seconds until the assertion's `exp`. Omitted, {@link PROVIDER_CLIENT_ASSERTION_DEFAULT_LIFETIME_SECONDS}. */
|
|
705
|
+
readonly assertionLifetimeSeconds?: number;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* The slot of a client-credentials declaration's own CREDENTIAL: the client secret, or the private key (#3402).
|
|
709
|
+
* `undefined` only for a declaration {@link describeProviderRestClientCredentialsDefects} refuses.
|
|
710
|
+
*/
|
|
711
|
+
export declare function providerClientCredentialsCredentialSlot(credentials: ProviderRestClientCredentials): string | undefined;
|
|
712
|
+
/**
|
|
713
|
+
* The parameter names {@link ProviderRestClientCredentials.tokenRequestParameters} may not declare: each is written by
|
|
714
|
+
* the grant itself (the grant type, the client's credential, the scope, a client assertion), so a second value would
|
|
715
|
+
* either be ignored or override the declared one.
|
|
716
|
+
*/
|
|
717
|
+
export declare const PROVIDER_CLIENT_CREDENTIALS_RESERVED_PARAMETER_NAMES: readonly string[];
|
|
718
|
+
/**
|
|
719
|
+
* Whether the client-credentials door of a REST contract serves a connection of this owner scope (#3398).
|
|
720
|
+
*
|
|
721
|
+
* Alone, it serves every admitted connection: the application's own (from its environment) and an organization's (from
|
|
722
|
+
* the credential the organization typed, as a Teams bot). Beside `oauth2`, a person or an organization connects through
|
|
723
|
+
* the authorization-code exchange, and the client-credentials grant serves the APPLICATION's own account only, so that
|
|
724
|
+
* account renews itself instead of resting on a pasted token that expires within the hour.
|
|
725
|
+
*/
|
|
726
|
+
export declare function providerClientCredentialsServesOwnerScope(contract: {
|
|
727
|
+
readonly clientCredentials?: ProviderRestClientCredentials;
|
|
728
|
+
readonly oauth2?: unknown;
|
|
729
|
+
}, ownerScope: ExternalProvider_Connection_OwnerScope): boolean;
|
|
730
|
+
/**
|
|
731
|
+
* The slot a connection of this owner scope AUTHENTICATES with, as the engine's REST access resolver reads it: the
|
|
732
|
+
* client-credentials grant's own credential (its client secret or private key) when that door serves the owner scope
|
|
733
|
+
* ({@link providerClientCredentialsServesOwnerScope}), else `apiKey.secretRef`, the stored or pasted token itself.
|
|
734
|
+
*
|
|
735
|
+
* For a contract declaring `clientCredentials` beside `oauth2` (Box, Zoom, #3398) the two differ by owner: the
|
|
736
|
+
* application's own account mints from the server app's secret, while a person's connection reads its exchanged token
|
|
737
|
+
* from `apiKey.secretRef`. A tool standing in for one connection (`wildo providers probe`, `connect`, the doctor's
|
|
738
|
+
* configuration checks, all APPLICATION-owned) asks this instead of reading `apiKey.secretRef`, so it reads the slot the
|
|
739
|
+
* engine would. `undefined` when the contract names neither.
|
|
740
|
+
*/
|
|
741
|
+
export declare function providerRestConnectionCredentialSlot(contract: {
|
|
742
|
+
readonly clientCredentials?: ProviderRestClientCredentials;
|
|
743
|
+
readonly oauth2?: unknown;
|
|
744
|
+
readonly apiKey?: {
|
|
745
|
+
readonly secretRef?: string;
|
|
746
|
+
};
|
|
747
|
+
}, ownerScope: ExternalProvider_Connection_OwnerScope): string | undefined;
|
|
488
748
|
/**
|
|
489
749
|
* Why a client-credentials declaration cannot be honoured, or an empty list. Checked where a provider is composed:
|
|
490
750
|
* a token URL that is not https, a token host that is not a DNS name or that the URL is not on, a tenant placeholder
|
|
491
751
|
* with no tenant slot (or the reverse), or any other placeholder in the URL.
|
|
492
752
|
*/
|
|
493
753
|
export declare function describeProviderRestClientCredentialsDefects(credentials: ProviderRestClientCredentials): string[];
|
|
754
|
+
/**
|
|
755
|
+
* Why a REST contract's `clientCredentials` sits wrongly beside the contract's other authentication fields, or an empty
|
|
756
|
+
* list (#2663, #3398). Checked where a provider is composed, beside {@link describeProviderRestClientCredentialsDefects}.
|
|
757
|
+
*
|
|
758
|
+
* - beside `requestSigning`: two ways to authenticate one call;
|
|
759
|
+
* - alone, `apiKey.secretRef` must be the client secret's slot, the one whose absence means "not configured";
|
|
760
|
+
* - beside `oauth2` the grant serves the APPLICATION's own account only ({@link providerClientCredentialsServesOwnerScope}),
|
|
761
|
+
* so the module must admit that connection; `apiKey.secretRef` names the exchanged tokens' slot and may not be the
|
|
762
|
+
* client secret's (a person's token would be read from it); and `verifiedAccountFacts`, which only an organization's
|
|
763
|
+
* connection records, would record nothing.
|
|
764
|
+
* - a token URL on {@link PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER} (#3402) needs a base URL the
|
|
765
|
+
* DEPLOYMENT names (`baseUrlHostEnvVarName` or `baseUrlEnvVarName`), and may serve the APPLICATION's connection only:
|
|
766
|
+
* the deployment's instance is the application's own (its Okta org), so an organization minting there would
|
|
767
|
+
* authenticate against the application's vendor tenant, never its own.
|
|
768
|
+
*/
|
|
769
|
+
export declare function describeProviderRestClientCredentialsPlacementDefects(contract: {
|
|
770
|
+
readonly clientCredentials?: ProviderRestClientCredentials;
|
|
771
|
+
readonly oauth2?: unknown;
|
|
772
|
+
readonly requestSigning?: unknown;
|
|
773
|
+
readonly apiKey: {
|
|
774
|
+
readonly secretRef: string;
|
|
775
|
+
};
|
|
776
|
+
readonly baseUrlHostEnvVarName?: string;
|
|
777
|
+
readonly baseUrlEnvVarName?: string;
|
|
778
|
+
}, admitsApplicationConnection: boolean,
|
|
779
|
+
/** Whether the module admits an ORGANIZATION or USER connection. Omitted, `false`. */
|
|
780
|
+
admitsNonApplicationConnection?: boolean): string[];
|
|
494
781
|
/**
|
|
495
782
|
* The vendor's error code at `errorCodePath` in a parsed answer, when it is code-shaped. Used for a refused 2xx and for
|
|
496
783
|
* a non-2xx answer alike: a vendor that states its code in the body states it in the same place whatever the status.
|
|
@@ -702,8 +989,108 @@ export interface ProviderRestOAuth2 {
|
|
|
702
989
|
*
|
|
703
990
|
* Absent — not empty — when no revocation is declared, so "this vendor cannot be told" stays
|
|
704
991
|
* distinguishable from "nobody has looked".
|
|
992
|
+
*
|
|
993
|
+
* The client authenticates here exactly as it does at the token endpoint ({@link tokenEndpointAuthMethod}), and the
|
|
994
|
+
* body is form-encoded unless {@link revocationRequestBodyEncoding} says otherwise: a vendor that takes RFC 7009's
|
|
995
|
+
* `token` parameter and answers its 200, but wants Basic or a JSON body, is still declared here.
|
|
705
996
|
*/
|
|
706
997
|
readonly rfc7009RevocationUrl?: string;
|
|
998
|
+
/**
|
|
999
|
+
* The vendor's USERINFO endpoint (#3397): a GET carrying the access token the authorization just minted as a Bearer
|
|
1000
|
+
* credential, whose JSON answer is read by every fact declared with
|
|
1001
|
+
* {@link ProviderOAuth2ReportedFactSource.USERINFO_RESPONSE}. DocuSign names the connected account and its API host
|
|
1002
|
+
* nowhere else: `GET https://account(-d).docusign.com/oauth/userinfo` lists the person's `accounts`, each with its
|
|
1003
|
+
* `account_id` and `base_uri`.
|
|
1004
|
+
*
|
|
1005
|
+
* Called ONCE, at the authorization-code exchange that makes (or remakes) the connection, and only when some fact
|
|
1006
|
+
* reads it; never at a refresh. The vendor's own guidance is to call it at setup and store the answer, and DocuSign
|
|
1007
|
+
* enforces an hourly limit on these requests per user and per integration key, so a call per refresh would spend that
|
|
1008
|
+
* limit to restate facts that change "very infrequently".
|
|
1009
|
+
* spec-cite: DocuSign, "UserInfo" (https://developers.docusign.com/platform/auth/reference/user-info/, fetched
|
|
1010
|
+
* 2026-11-09) — "Your integration should call this method to get the information needed to begin making API calls
|
|
1011
|
+
* during setup, then store it for use in future calls" and "Docusign enforces hourly limits on the number of
|
|
1012
|
+
* `/oauth/userinfo` requests per user ID and per integration key".
|
|
1013
|
+
*
|
|
1014
|
+
* Resolved like {@link tokenUrl}, through the same {@link endpointHostAllowances} and deployment values, because it
|
|
1015
|
+
* receives a credential too (the person's access token). It belongs to the same authorization server, so it may carry
|
|
1016
|
+
* only the host-forming placeholders the token endpoint carries, each in the same position
|
|
1017
|
+
* ({@link describeProviderOAuth2ReportedFactUseDefects}); every reader of "which placeholders does this client have"
|
|
1018
|
+
* therefore stays complete reading the authorize and token endpoints alone. A redirect is refused, never followed.
|
|
1019
|
+
*/
|
|
1020
|
+
readonly userInfoUrl?: string;
|
|
1021
|
+
/**
|
|
1022
|
+
* How the client authenticates to the vendor's token endpoint: at the code exchange, at every refresh (and every
|
|
1023
|
+
* per-audience mint, which is a refresh), and at the revocation endpoint. Named after the client metadata field
|
|
1024
|
+
* `token_endpoint_auth_method`, whose values it uses. See {@link ProviderOAuth2ClientAuthenticationMethod}.
|
|
1025
|
+
*
|
|
1026
|
+
* Absent means {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_POST}: `client_id` and `client_secret` in
|
|
1027
|
+
* the body, the engine's behaviour before this field existed, so no existing provider sends a different byte. Declare
|
|
1028
|
+
* {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC} for a vendor that documents the Basic header
|
|
1029
|
+
* (Zoom, Notion, Intuit). With Basic the body carries neither `client_id` nor `client_secret`: the header identifies
|
|
1030
|
+
* the client, and a credential is sent on one channel only.
|
|
1031
|
+
* spec-cite: RFC 6749 §4.1.3 — `client_id` is "REQUIRED, if the client is not authenticating with the authorization
|
|
1032
|
+
* server" as Section 3.2.1 describes. Fetched 2026-11-06.
|
|
1033
|
+
*
|
|
1034
|
+
* ## Why the revocation endpoint does not get a method of its own
|
|
1035
|
+
*
|
|
1036
|
+
* RFC 7009 sends the client's credentials at the revocation endpoint "as described in Section 2.3. of [RFC6749]", the
|
|
1037
|
+
* same section as the token endpoint, and every vendor measured on 2026-11-06 (Zoom, Notion, Intuit) authenticates
|
|
1038
|
+
* both endpoints the same way. A separate member would be a choice no vendor has needed; it is added when one does.
|
|
1039
|
+
* spec-cite: RFC 7009 §2.1 — "The client also includes its authentication credentials as described in Section 2.3.
|
|
1040
|
+
* of [RFC6749]." Fetched 2026-11-06.
|
|
1041
|
+
*/
|
|
1042
|
+
readonly tokenEndpointAuthMethod?: ProviderOAuth2ClientAuthenticationMethod;
|
|
1043
|
+
/**
|
|
1044
|
+
* How the token request's parameters are written (exchange, refresh, per-audience mint). Absent means
|
|
1045
|
+
* {@link ProviderOAuth2RequestBodyEncoding.FORM}, as RFC 6749 specifies. Notion's token endpoint takes JSON only.
|
|
1046
|
+
*/
|
|
1047
|
+
readonly tokenRequestBodyEncoding?: ProviderOAuth2RequestBodyEncoding;
|
|
1048
|
+
/**
|
|
1049
|
+
* Extra parameters the AUTHORIZATION-CODE exchange carries beside the specification's own (follow-up to #3392), each a
|
|
1050
|
+
* fixed value the provider module owns: a vendor that issues a different kind of token when asked in the exchange.
|
|
1051
|
+
* Shopify issues an expiring offline token (an hour, with a refresh token) only when the exchange carries `expiring=1`,
|
|
1052
|
+
* and a non-expiring one otherwise; a public app on non-expiring tokens is refused from April 2027.
|
|
1053
|
+
* spec-cite: https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens — the `expiring` row: "Set
|
|
1054
|
+
* to `1` for an expiring offline token, or `0` (default) for a non-expiring one.", fetched 2026-11-10.
|
|
1055
|
+
*
|
|
1056
|
+
* Sent at the code exchange only: a refresh renews the grant the exchange made and Shopify's refresh request carries no
|
|
1057
|
+
* such parameter. A name the engine writes itself (`grant_type`, `code`, `redirect_uri`, `code_verifier`, the client's
|
|
1058
|
+
* credentials, `refresh_token`, `scope`) is refused, so a declaration cannot change what the exchange is
|
|
1059
|
+
* ({@link describeProviderOAuth2TokenRequestDefects}).
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* codeExchangeParameters: { expiring: '1' }
|
|
1063
|
+
*/
|
|
1064
|
+
readonly codeExchangeParameters?: Readonly<Record<string, string>>;
|
|
1065
|
+
/**
|
|
1066
|
+
* The refusals of a REFRESH that the vendor documents as a dead refresh token, beside the specification's
|
|
1067
|
+
* `invalid_grant` (follow-up to #3392). A refresh refused with one of them retires the stored connection the way
|
|
1068
|
+
* `invalid_grant` does, rather than being retried at every call. Shopify answers a refresh token that can no longer be
|
|
1069
|
+
* used with `invalid_request` and a fixed description, and says to treat it as final.
|
|
1070
|
+
* spec-cite: https://shopify.dev/docs/api/usage/response-codes — "A refresh token that can no longer be used returns this
|
|
1071
|
+
* status with the error code `invalid_request` and the description `This request requires an active refresh_token`.
|
|
1072
|
+
* Treat it as final rather than retrying.", fetched 2026-11-10.
|
|
1073
|
+
*
|
|
1074
|
+
* `error` is the OAuth2 `error` code. `errorDescription`, when given, must equal the answer's `error_description`
|
|
1075
|
+
* exactly: `invalid_request` alone also names a malformed request, which says nothing about the person's grant, so a
|
|
1076
|
+
* vendor that reuses a generic code is matched on its description too. Read at a refresh only, never at the exchange.
|
|
1077
|
+
* `invalid_client` is refused: it names the APPLICATION's registration, and retiring every connection over it would
|
|
1078
|
+
* blame the people who connected (see `providerOAuth2GrantWasPermanentlyRejected`).
|
|
1079
|
+
*
|
|
1080
|
+
* @example
|
|
1081
|
+
* refreshRefusals: [{ error: 'invalid_request', errorDescription: 'This request requires an active refresh_token' }]
|
|
1082
|
+
*/
|
|
1083
|
+
readonly refreshRefusals?: readonly ProviderOAuth2RefreshRefusal[];
|
|
1084
|
+
/**
|
|
1085
|
+
* How the revocation request's parameters are written. Absent means {@link ProviderOAuth2RequestBodyEncoding.FORM}, as
|
|
1086
|
+
* RFC 7009 specifies, whatever {@link tokenRequestBodyEncoding} says: the two encodings are declared separately because
|
|
1087
|
+
* a vendor can differ between its two endpoints. Intuit's own client library form-encodes the token request and sends
|
|
1088
|
+
* the revocation request as JSON.
|
|
1089
|
+
* spec-cite: intuit/oauth-jsclient `OAuthClient.prototype.revoke` and `_tokenRequestHeaders`
|
|
1090
|
+
* (https://raw.githubusercontent.com/intuit/oauth-jsclient/e65c49b0fd1c5356ba24ddbbe910b8bc71b6f75f/src/OAuthClient.js,
|
|
1091
|
+
* fetched 2026-11-06).
|
|
1092
|
+
*/
|
|
1093
|
+
readonly revocationRequestBodyEncoding?: ProviderOAuth2RequestBodyEncoding;
|
|
707
1094
|
/**
|
|
708
1095
|
* Scopes the vendor's own catalogue entry asked for. An application may request FEWER (a subset of
|
|
709
1096
|
* these, once resolved), and an operation's `requiredScopes` is the finer statement. Kept because
|
|
@@ -829,7 +1216,8 @@ export interface ProviderRestOAuth2 {
|
|
|
829
1216
|
*
|
|
830
1217
|
* ## Why this exists: the token endpoint receives the application's client secret
|
|
831
1218
|
*
|
|
832
|
-
* The exchange
|
|
1219
|
+
* The exchange sends `client_id` and the APPLICATION's `client_secret` to the resolved `tokenUrl`, in the body or in a
|
|
1220
|
+
* Basic header ({@link ProviderRestOAuth2.tokenEndpointAuthMethod}); either way the host receives the secret.
|
|
833
1221
|
* Until 2026-09-12 every placeholder was answered from the connect-start request body, so where a
|
|
834
1222
|
* placeholder formed the HOST — Microsoft's `https://{cloud}/…/token`, Salesforce's
|
|
835
1223
|
* `https://{environment}/…`, Zoho's `https://accounts.{location}/…` — any user allowed to start a
|
|
@@ -980,6 +1368,12 @@ export interface ProviderRestOAuth2Audience {
|
|
|
980
1368
|
readonly hosts: {
|
|
981
1369
|
readonly values: readonly string[];
|
|
982
1370
|
readonly hostSuffixes?: readonly string[];
|
|
1371
|
+
/**
|
|
1372
|
+
* The most DNS labels a host may carry before one of `hostSuffixes`; absent, any number (#3640). The same bound,
|
|
1373
|
+
* with the same meaning, as a host allowance's `hostSuffixMaxLabels`: declare it where the vendor documents its
|
|
1374
|
+
* hosts as one shape (`<store>.myshopify.com`), so a token is never sent to a deeper name under the suffix.
|
|
1375
|
+
*/
|
|
1376
|
+
readonly hostSuffixMaxLabels?: number;
|
|
983
1377
|
};
|
|
984
1378
|
/**
|
|
985
1379
|
* The scopes that mint a token for this audience, all of ONE resource. An entry may begin with
|
|
@@ -999,7 +1393,10 @@ export interface ProviderOAuth2AudienceSelection {
|
|
|
999
1393
|
readonly audience: ProviderRestOAuth2Audience;
|
|
1000
1394
|
readonly primary: boolean;
|
|
1001
1395
|
}
|
|
1002
|
-
/**
|
|
1396
|
+
/**
|
|
1397
|
+
* Whether `host` is admitted by one audience's hosts: an exact value, or `<labels><suffix>` for a declared suffix, with
|
|
1398
|
+
* no more labels than `hostSuffixMaxLabels` allows (#3640).
|
|
1399
|
+
*/
|
|
1003
1400
|
export declare function providerOAuth2AudienceAdmitsHost(audience: ProviderRestOAuth2Audience, host: string): boolean;
|
|
1004
1401
|
/**
|
|
1005
1402
|
* The ONE audience whose hosts admit `host`, or `undefined` when none does. The declaration guarantees at most one
|
|
@@ -1096,6 +1493,74 @@ export declare enum ProviderOAuth2PkceSupport {
|
|
|
1096
1493
|
/** The vendor refuses PKCE from a confidential client (Slack): neither is sent. */
|
|
1097
1494
|
NOT_ACCEPTED = "NOT_ACCEPTED"
|
|
1098
1495
|
}
|
|
1496
|
+
/**
|
|
1497
|
+
* How this application's client authenticates to a vendor's token and revocation endpoints. See
|
|
1498
|
+
* {@link ProviderRestOAuth2.tokenEndpointAuthMethod}.
|
|
1499
|
+
*
|
|
1500
|
+
* The values are the names the "OAuth Token Endpoint Authentication Methods" registry gives these two methods, which
|
|
1501
|
+
* is what OpenID Connect and dynamic client registration call `token_endpoint_auth_method`, so a vendor's discovery
|
|
1502
|
+
* document (`token_endpoint_auth_methods_supported`) can be compared with a declaration by eye.
|
|
1503
|
+
* spec-cite: RFC 7591 §2 — `token_endpoint_auth_method`: "client_secret_post": "The client uses the HTTP POST parameters
|
|
1504
|
+
* as defined in OAuth 2.0, Section 2.3.1."; "client_secret_basic": "The client uses HTTP Basic as defined in OAuth 2.0,
|
|
1505
|
+
* Section 2.3.1." Fetched 2026-11-06.
|
|
1506
|
+
*
|
|
1507
|
+
* Narrower than `OAuth2_TokenEndpoint_AuthMethod` on purpose: that vocabulary also names `client_secret_jwt` and
|
|
1508
|
+
* `none`, which nothing here performs. `private_key_jwt` joined with #3402, performed by the client-credentials grant
|
|
1509
|
+
* only; the connected-account exchange refuses it at startup. A member nothing honours would
|
|
1510
|
+
* be a declaration that looks like a client-authentication choice and changes nothing, so each method joins this
|
|
1511
|
+
* vocabulary in the change that implements it.
|
|
1512
|
+
*/
|
|
1513
|
+
export declare enum ProviderOAuth2ClientAuthenticationMethod {
|
|
1514
|
+
/**
|
|
1515
|
+
* `client_id` and `client_secret` as parameters of the request body: the engine's behaviour when nothing is declared,
|
|
1516
|
+
* and what most vendors' own documentation shows. RFC 6749 calls it "NOT RECOMMENDED", which is why a vendor that
|
|
1517
|
+
* documents Basic declares {@link CLIENT_SECRET_BASIC} rather than being met with this.
|
|
1518
|
+
* spec-cite: RFC 6749 §2.3.1 — sending the two parameters in the body "is NOT RECOMMENDED and SHOULD be limited to
|
|
1519
|
+
* clients unable to directly utilize the HTTP Basic authentication scheme". Fetched 2026-11-06.
|
|
1520
|
+
*/
|
|
1521
|
+
CLIENT_SECRET_POST = "client_secret_post",
|
|
1522
|
+
/**
|
|
1523
|
+
* `Authorization: Basic base64(client_id ":" client_secret)`, each half form-urlencoded BEFORE base64, and neither in
|
|
1524
|
+
* the body: one credential on one channel. Every authorization server must accept it (Zoom, Notion and Intuit document
|
|
1525
|
+
* it as their client authentication).
|
|
1526
|
+
* spec-cite: RFC 6749 §2.3.1 — "The client identifier is encoded using the "application/x-www-form-urlencoded"
|
|
1527
|
+
* encoding algorithm per Appendix B", and so is the password, before both become the Basic user-id and password; "The
|
|
1528
|
+
* authorization server MUST support the HTTP Basic authentication scheme". Appendix B encodes UTF-8 first, so `£` is
|
|
1529
|
+
* `%C2%A3` and a space is `+`. Fetched 2026-11-06.
|
|
1530
|
+
*/
|
|
1531
|
+
CLIENT_SECRET_BASIC = "client_secret_basic",
|
|
1532
|
+
/**
|
|
1533
|
+
* A JWT the client signs with its own private key, sent as `client_assertion` (#3402). Performed by the
|
|
1534
|
+
* client-credentials grant only ({@link ProviderRestClientCredentials.privateKeyJwt}); the connected-account exchange
|
|
1535
|
+
* does not sign assertions, so `oauth2.tokenEndpointAuthMethod` refuses it at startup.
|
|
1536
|
+
* spec-cite: OpenID Connect Core 1.0 §9 — `private_key_jwt`: "Clients that have registered a public key sign a JWT
|
|
1537
|
+
* using that key." Fetched 2026-11-09 from https://openid.net/specs/openid-connect-core-1_0.html.
|
|
1538
|
+
*/
|
|
1539
|
+
PRIVATE_KEY_JWT = "private_key_jwt"
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* How the parameters of a request to a vendor's token or revocation endpoint are written in its body. See
|
|
1543
|
+
* {@link ProviderRestOAuth2.tokenRequestBodyEncoding} and {@link ProviderRestOAuth2.revocationRequestBodyEncoding}.
|
|
1544
|
+
*
|
|
1545
|
+
* The parameters are the same in both encodings (`grant_type`, `code`, `refresh_token`, `token`, …); only their
|
|
1546
|
+
* serialization and the `Content-Type` change.
|
|
1547
|
+
*/
|
|
1548
|
+
export declare enum ProviderOAuth2RequestBodyEncoding {
|
|
1549
|
+
/**
|
|
1550
|
+
* `application/x-www-form-urlencoded`, which RFC 6749 and RFC 7009 specify: the default for both requests.
|
|
1551
|
+
* spec-cite: RFC 6749 §4.1.3 (the client makes the token request "by sending the following parameters using the
|
|
1552
|
+
* "application/x-www-form-urlencoded" format"; §6 does the same for a refresh), and RFC 7009 §2.1 (the revocation
|
|
1553
|
+
* request uses "the "application/x-www-form-urlencoded" format in the HTTP request entity-body"). Fetched 2026-11-06.
|
|
1554
|
+
*/
|
|
1555
|
+
FORM = "FORM",
|
|
1556
|
+
/**
|
|
1557
|
+
* `application/json`, an object whose members are the same parameters as string values. A deviation some vendors
|
|
1558
|
+
* document: Notion's token endpoint takes only JSON, and Intuit's own client library revokes with a JSON body.
|
|
1559
|
+
* spec-cite: https://developers.notion.com/docs/authorization — the token request's `Content-Type: application/json`,
|
|
1560
|
+
* fetched 2026-11-06.
|
|
1561
|
+
*/
|
|
1562
|
+
JSON = "JSON"
|
|
1563
|
+
}
|
|
1099
1564
|
/**
|
|
1100
1565
|
* A `scope` list encoding that deviates from RFC 6749's space-delimited list, in either direction: the token answer
|
|
1101
1566
|
* ({@link ProviderRestOAuth2.grantedScopesDelimiter}) or the authorize request ({@link ProviderRestOAuth2.authorizeScopesDelimiter}).
|
|
@@ -1112,6 +1577,40 @@ export declare enum ProviderOAuth2ScopeListDelimiter {
|
|
|
1112
1577
|
*/
|
|
1113
1578
|
COMMA = "COMMA"
|
|
1114
1579
|
}
|
|
1580
|
+
/**
|
|
1581
|
+
* What makes a client-authentication declaration unusable (see {@link ProviderRestOAuth2.tokenEndpointAuthMethod}):
|
|
1582
|
+
*
|
|
1583
|
+
* - a method or an encoding outside its vocabulary. The request builder tests for the declared member, so an unknown
|
|
1584
|
+
* value (a misspelling in a module written without types) would silently fall back to the default and send the
|
|
1585
|
+
* secret the way the vendor said not to;
|
|
1586
|
+
* - a revocation encoding with no revocation URL, a setting that changes nothing.
|
|
1587
|
+
*/
|
|
1588
|
+
export declare function describeProviderOAuth2ClientAuthenticationDefects(oauth2: Pick<ProviderRestOAuth2, 'tokenEndpointAuthMethod' | 'tokenRequestBodyEncoding' | 'revocationRequestBodyEncoding' | 'rfc7009RevocationUrl'>): string[];
|
|
1589
|
+
/** A refresh refusal the vendor documents as a dead refresh token. See {@link ProviderRestOAuth2.refreshRefusals}. */
|
|
1590
|
+
export interface ProviderOAuth2RefreshRefusal {
|
|
1591
|
+
/** The OAuth2 `error` code of the refusal. */
|
|
1592
|
+
readonly error: string;
|
|
1593
|
+
/** The `error_description` the refusal must carry, exactly, when the code alone is not specific to a dead token. */
|
|
1594
|
+
readonly errorDescription?: string;
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* What makes a token-request declaration unusable (follow-up to #3392), checked where the provider registry composes:
|
|
1598
|
+
*
|
|
1599
|
+
* - a {@link ProviderRestOAuth2.codeExchangeParameters} name that is not a plain identifier, that names a parameter the
|
|
1600
|
+
* engine writes itself, or whose value is empty;
|
|
1601
|
+
* - a {@link ProviderRestOAuth2.refreshRefusals} entry whose code is not code-shaped (it would never match), is
|
|
1602
|
+
* `invalid_grant` (already a refusal, so the entry says nothing) or `invalid_client` (the application's registration,
|
|
1603
|
+
* never one person's grant), or whose description is empty.
|
|
1604
|
+
*/
|
|
1605
|
+
export declare function describeProviderOAuth2TokenRequestDefects(oauth2: Pick<ProviderRestOAuth2, 'codeExchangeParameters' | 'refreshRefusals'>): string[];
|
|
1606
|
+
/**
|
|
1607
|
+
* Whether a refresh's refusal is one the provider declares as a dead refresh token ({@link ProviderRestOAuth2.refreshRefusals}).
|
|
1608
|
+
* The one reading, shared by the refresh and its tests.
|
|
1609
|
+
*/
|
|
1610
|
+
export declare function providerOAuth2RefreshRefusalIsDeclared(oauth2: Pick<ProviderRestOAuth2, 'refreshRefusals'>, answer: {
|
|
1611
|
+
readonly error: string;
|
|
1612
|
+
readonly errorDescription?: string;
|
|
1613
|
+
}): boolean;
|
|
1115
1614
|
/**
|
|
1116
1615
|
* The granted scopes a token answer's `scope` string names, read with the vendor's declared delimiter: whitespace (RFC
|
|
1117
1616
|
* 6749 §5.1) when none is declared, a comma for {@link ProviderOAuth2ScopeListDelimiter.COMMA}.
|
|
@@ -1161,13 +1660,104 @@ export declare enum ProviderOAuth2ReportedFactSource {
|
|
|
1161
1660
|
* answer names the account only inside the ID token (#2660).
|
|
1162
1661
|
* spec-cite: OpenID Connect Core 1.0 §3.1.3.7, item 6.
|
|
1163
1662
|
*/
|
|
1164
|
-
ID_TOKEN_CLAIMS = "id_token_claims"
|
|
1663
|
+
ID_TOKEN_CLAIMS = "id_token_claims",
|
|
1664
|
+
/**
|
|
1665
|
+
* A query parameter of the AUTHORIZATION REDIRECT that brings the person back with the code (#3397): Intuit's
|
|
1666
|
+
* `realmId`, the QuickBooks company the person chose on the consent screen. `responsePath` is the parameter's name,
|
|
1667
|
+
* one segment. Read by the callback leg, kept with the attempt until the completion leg redeems the code, and recorded
|
|
1668
|
+
* only from that exchange: a refresh has no redirect, so it never restates such a fact and the stored value stands.
|
|
1669
|
+
*
|
|
1670
|
+
* The weakest of the three sources, and restricted for it. The redirect reaches this application through the
|
|
1671
|
+
* browser of the person who authorized, so that person could change the value before it arrives, exactly as they
|
|
1672
|
+
* could type an answer. Such a fact is therefore admitted only where a wrong value harms nobody but the person who
|
|
1673
|
+
* forged it: as a PATH value ({@link ProviderOAuth2ReportedAccountFact.pathSegmentPattern}) of a vendor that checks it
|
|
1674
|
+
* against the token on every call (Intuit answers a realm the token was not granted for with an authorization fault).
|
|
1675
|
+
* It may never be an `origin`, fill a base URL host, or route inbound deliveries, since each of those decides where a
|
|
1676
|
+
* credential goes or which organization receives a message; `describeProviderOAuth2ReportedFactUseDefects` refuses it.
|
|
1677
|
+
*/
|
|
1678
|
+
AUTHORIZATION_REDIRECT_QUERY = "authorization_redirect_query",
|
|
1679
|
+
/**
|
|
1680
|
+
* The JSON answer of the vendor's USERINFO endpoint ({@link ProviderRestOAuth2.userInfoUrl}, #3397), fetched with the
|
|
1681
|
+
* access token the authorization just minted: DocuSign's `accounts[…].account_id` and `base_uri`. As trustworthy as
|
|
1682
|
+
* the token answer (the vendor answers over TLS, to a request the person's own token authorized), so it may be placed
|
|
1683
|
+
* wherever a token fact may. Read at the authorization-code exchange only: a refresh does not call the endpoint, so it
|
|
1684
|
+
* never restates such a fact and the stored value stands until the person connects again.
|
|
1685
|
+
*/
|
|
1686
|
+
USERINFO_RESPONSE = "userinfo_response"
|
|
1687
|
+
}
|
|
1688
|
+
/** What reading a {@link ProviderOAuth2ReportedAccountFact.responsePath} out of a vendor's answer found (#3397). */
|
|
1689
|
+
export declare enum ProviderReportedFactReadOutcome {
|
|
1690
|
+
/** A non-empty string or a finite number stood at the path; `value` is its text. */
|
|
1691
|
+
FOUND = "FOUND",
|
|
1692
|
+
/** Nothing usable stood at the path: a missing key, a `null`, an object, an empty string. The fact is not reported. */
|
|
1693
|
+
ABSENT = "ABSENT",
|
|
1694
|
+
/**
|
|
1695
|
+
* A selection segment (`accounts[is_default=true]`) met an array in which NOT EXACTLY ONE element matched. The vendor's
|
|
1696
|
+
* answer does not name one element, so no fact is read from it: guessing the first would address a request to an
|
|
1697
|
+
* account nobody chose. `matched` is how many did.
|
|
1698
|
+
*/
|
|
1699
|
+
SELECTION_NOT_SINGLE = "SELECTION_NOT_SINGLE"
|
|
1700
|
+
}
|
|
1701
|
+
/** The result of {@link readProviderReportedFactValue}. */
|
|
1702
|
+
export type ProviderReportedFactRead = {
|
|
1703
|
+
readonly outcome: ProviderReportedFactReadOutcome.FOUND;
|
|
1704
|
+
readonly value: string;
|
|
1705
|
+
} | {
|
|
1706
|
+
readonly outcome: ProviderReportedFactReadOutcome.ABSENT;
|
|
1707
|
+
} | {
|
|
1708
|
+
readonly outcome: ProviderReportedFactReadOutcome.SELECTION_NOT_SINGLE;
|
|
1709
|
+
readonly segment: string;
|
|
1710
|
+
readonly matched: number;
|
|
1711
|
+
};
|
|
1712
|
+
/** One step of a parsed {@link ProviderOAuth2ReportedAccountFact.responsePath}. */
|
|
1713
|
+
export interface ProviderReportedFactPathSegment {
|
|
1714
|
+
/** The own property read at this step. */
|
|
1715
|
+
readonly key: string;
|
|
1716
|
+
/** Present on a SELECTION step: the property is an array, and the one element whose `field` reads as `equals` is kept. */
|
|
1717
|
+
readonly select?: {
|
|
1718
|
+
readonly field: string;
|
|
1719
|
+
readonly equals: string;
|
|
1720
|
+
};
|
|
1165
1721
|
}
|
|
1722
|
+
/**
|
|
1723
|
+
* The steps of a reported fact's `responsePath`, or `undefined` when it is not one (#3397). A path is dot-separated;
|
|
1724
|
+
* each step is an own property name, optionally followed by ONE selection `[field=value]` that picks, out of the array
|
|
1725
|
+
* at that property, the single element whose `field` reads as `value`: `accounts[is_default=true].account_id`.
|
|
1726
|
+
*
|
|
1727
|
+
* Names, fields and values may not contain `.`, `[`, `]` or `=`; a value may be empty. Kept this small on purpose: it
|
|
1728
|
+
* addresses one element by one stated condition, which is what a vendor documenting "the default account" means, and
|
|
1729
|
+
* nothing that would need a query language.
|
|
1730
|
+
*/
|
|
1731
|
+
export declare function parseProviderReportedFactPath(path: string): readonly ProviderReportedFactPathSegment[] | undefined;
|
|
1732
|
+
/**
|
|
1733
|
+
* The value at a reported fact's `responsePath` inside a vendor's JSON answer (#3397): a token answer, the claims of
|
|
1734
|
+
* its ID token, or a userinfo answer. Own properties only (the answer is a vendor's JSON, and `constructor` is not a
|
|
1735
|
+
* fact). A FOUND value is a non-empty string or a finite number's decimal text.
|
|
1736
|
+
*
|
|
1737
|
+
* A selection step keeps the ONE array element whose field reads as the stated value (a string as itself, a number as
|
|
1738
|
+
* its decimal text, a boolean as `true` / `false`, so DocuSign's `is_default: true` matches `[is_default=true]` whether
|
|
1739
|
+
* it is sent as a boolean or a string). Zero or several matches is {@link ProviderReportedFactReadOutcome.SELECTION_NOT_SINGLE}:
|
|
1740
|
+
* two facts selected with the same condition (`accounts[is_default=true].account_id` and `….base_uri`) are therefore
|
|
1741
|
+
* read from the same element or not at all. Anything else that does not lead to a scalar (a missing key, a property
|
|
1742
|
+
* that is not an array where a selection is written, an unparsable path) is ABSENT.
|
|
1743
|
+
*/
|
|
1744
|
+
export declare function readProviderReportedFactValue(payload: unknown, path: string): ProviderReportedFactRead;
|
|
1745
|
+
/**
|
|
1746
|
+
* The query parameters an authorization redirect carries for the OAuth protocol itself, never as an account fact: a
|
|
1747
|
+
* redirect-sourced fact named like one would read the code, the state or the error as the account.
|
|
1748
|
+
* spec-cite: RFC 6749 §4.1.2 (`code`, `state`) and §4.1.2.1 (`error`, `error_description`, `error_uri`); RFC 9207 §2
|
|
1749
|
+
* (`iss`).
|
|
1750
|
+
* semantic-literal-boundary: the OAuth protocol's own redirect parameter names, compared with a module's declaration.
|
|
1751
|
+
*/
|
|
1752
|
+
export declare const PROVIDER_OAUTH2_REDIRECT_PROTOCOL_PARAMETERS: readonly string[];
|
|
1166
1753
|
/** One vendor-reported account fact. See {@link ProviderRestOAuth2.reportedAccountFacts}. */
|
|
1167
1754
|
export interface ProviderOAuth2ReportedAccountFact {
|
|
1168
1755
|
/**
|
|
1169
|
-
* Dot-path inside the fact's {@link source}: the token endpoint's JSON answer by default,
|
|
1170
|
-
* `id_token
|
|
1756
|
+
* Dot-path inside the fact's {@link source}: the token endpoint's JSON answer by default, the claims of its
|
|
1757
|
+
* `id_token`, or the userinfo endpoint's JSON answer. A string or finite number there is the value. A step may select
|
|
1758
|
+
* ONE element of an array by a stated condition, `accounts[is_default=true].account_id` (#3397); zero or several
|
|
1759
|
+
* matching elements report nothing and refuse the connect ({@link readProviderReportedFactValue}). For
|
|
1760
|
+
* {@link ProviderOAuth2ReportedFactSource.AUTHORIZATION_REDIRECT_QUERY}, the redirect's query parameter name.
|
|
1171
1761
|
*/
|
|
1172
1762
|
readonly responsePath: string;
|
|
1173
1763
|
/** Where {@link responsePath} is read. Omitted, the token endpoint's JSON answer. */
|
|
@@ -1179,6 +1769,27 @@ export interface ProviderOAuth2ReportedAccountFact {
|
|
|
1179
1769
|
readonly origin?: Extract<ProviderOAuth2EndpointHostAllowance, {
|
|
1180
1770
|
readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DECLARED_VALUES;
|
|
1181
1771
|
}>;
|
|
1772
|
+
/**
|
|
1773
|
+
* Present when operations may place the value as ONE PATH SEGMENT (#3397): QuickBooks' `/v3/company/{realmId}/…`. An
|
|
1774
|
+
* operation names the fact on a PATH parameter ({@link ProviderRestOperationParameter.connectionFact}) and the caller
|
|
1775
|
+
* never supplies it. A JavaScript regular expression the WHOLE value must match (it is anchored for you), checked when
|
|
1776
|
+
* the connection is made (a value that does not match, or no value, refuses the connect) and again on every call, as
|
|
1777
|
+
* an origin is. A value that matches is still refused when it is `.` or `..` or holds a `/`, so it can never move the
|
|
1778
|
+
* request to another path. Keep it as narrow as the vendor documents: `\d+` for a QuickBooks company id.
|
|
1779
|
+
*
|
|
1780
|
+
* Without this a vendor-reported fact fills nothing: what the vendor reported is not an answer the person gave, and
|
|
1781
|
+
* only a declared shape keeps a value that would otherwise go unexamined out of a URL.
|
|
1782
|
+
*/
|
|
1783
|
+
readonly pathSegmentPattern?: string;
|
|
1784
|
+
/**
|
|
1785
|
+
* `true` when the value may fill the base URL's `{<this fact's name>}` HOST placeholder (#3397), admitted against the
|
|
1786
|
+
* REST contract's `baseUrlHostAllowances` entry for that name on every call: the same allowance, and the same
|
|
1787
|
+
* resolver, that admit a host a person typed at connect. Needs a `DECLARED_VALUES` allowance under the fact's name.
|
|
1788
|
+
* Never filled into an OAuth2 endpoint (authorize, token, revocation): those carry the client secret, and only the
|
|
1789
|
+
* person's answers or the deployment fill them. An `origin` is the other way to address the account; a fact is one
|
|
1790
|
+
* or the other.
|
|
1791
|
+
*/
|
|
1792
|
+
readonly fillsBaseUrlHost?: true;
|
|
1182
1793
|
/**
|
|
1183
1794
|
* `true` when the inbound receiver routes the vendor's deliveries to an organization by this fact: Slack's
|
|
1184
1795
|
* `team.id`, the workspace an event comes from (#2660). Such a fact may name ONE organization only, so an
|
|
@@ -1252,6 +1863,37 @@ export declare function providerOAuth2IdTokenRequirementHolds(requirement: Provi
|
|
|
1252
1863
|
* the behavior is entirely unspecified").
|
|
1253
1864
|
*/
|
|
1254
1865
|
export declare function describeProviderOAuth2IdTokenRequirementDefects(oauth2: Pick<ProviderRestOAuth2, 'idTokenRequirements' | 'scopes' | 'reportedAccountFacts' | 'idTokenIssuer'>): string[];
|
|
1866
|
+
/**
|
|
1867
|
+
* Whether a vendor-reported value may stand as one path segment under its fact's declared
|
|
1868
|
+
* {@link ProviderOAuth2ReportedAccountFact.pathSegmentPattern} (#3397): the WHOLE value matches the pattern, and it is
|
|
1869
|
+
* not empty, not a dot-segment and holds no `/`, whatever the pattern admits. The one admission, applied where the value
|
|
1870
|
+
* is captured (the authorization) and where it is spent (every call). A pattern that does not compile admits nothing.
|
|
1871
|
+
*/
|
|
1872
|
+
export declare function providerReportedPathSegmentAdmits(pattern: string, value: string): boolean;
|
|
1873
|
+
/** The REST-contract slice {@link describeProviderOAuth2ReportedFactUseDefects} reads. */
|
|
1874
|
+
export interface ProviderReportedFactUseContract {
|
|
1875
|
+
readonly baseUrl?: string;
|
|
1876
|
+
readonly baseUrlConnectionFact?: string;
|
|
1877
|
+
readonly baseUrlHostAllowances?: Readonly<Record<string, ProviderOAuth2EndpointHostAllowance>>;
|
|
1878
|
+
readonly oauth2?: Pick<ProviderRestOAuth2, 'reportedAccountFacts' | 'connectionParameters'> & Partial<Pick<ProviderRestOAuth2, 'tokenUrl' | 'userInfoUrl'>>;
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* What makes the declared USES of a connection's vendor-reported facts unsafe or unusable (#3397), checked at boot with
|
|
1882
|
+
* the contract's other declarations:
|
|
1883
|
+
*
|
|
1884
|
+
* - a fact read from the authorization redirect is something the person who authorized could change, so it may not be
|
|
1885
|
+
* an `origin`, fill a base URL host, or route inbound deliveries, and its name must be one query parameter that is
|
|
1886
|
+
* not the OAuth protocol's own (`code`, `state`, …);
|
|
1887
|
+
* - a `pathSegmentPattern` must compile, admit no empty value, and not sit beside an `origin`;
|
|
1888
|
+
* - a `fillsBaseUrlHost` fact must name a `{placeholder}` of the base URL that a `DECLARED_VALUES` allowance governs,
|
|
1889
|
+
* must not also be an `origin` or something the person is asked at connect, and cannot share a contract with
|
|
1890
|
+
* `baseUrlConnectionFact`, which already decides where calls go;
|
|
1891
|
+
* - every other `responsePath` must parse ({@link parseProviderReportedFactPath});
|
|
1892
|
+
* - a fact read from the userinfo answer needs a `userInfoUrl`, a `userInfoUrl` needs a fact that reads it (a request
|
|
1893
|
+
* carrying the person's token that nothing uses is not made), and the userinfo endpoint may carry only the
|
|
1894
|
+
* host-forming placeholders the token endpoint carries, in the same position (it is the same authorization server).
|
|
1895
|
+
*/
|
|
1896
|
+
export declare function describeProviderOAuth2ReportedFactUseDefects(contract: ProviderReportedFactUseContract): string[];
|
|
1255
1897
|
/** The values a whole-scope placeholder admits. See {@link ProviderRestOAuth2.scopeValueAllowances}. */
|
|
1256
1898
|
export interface ProviderOAuth2ScopeValueAllowance {
|
|
1257
1899
|
readonly values: readonly string[];
|
|
@@ -1421,6 +2063,24 @@ export type ProviderOAuth2EndpointHostAllowance = {
|
|
|
1421
2063
|
* so `evilmy.salesforce.com` never matches `.my.salesforce.com`.
|
|
1422
2064
|
*/
|
|
1423
2065
|
readonly hostSuffixes?: readonly string[];
|
|
2066
|
+
/**
|
|
2067
|
+
* The MOST DNS labels an admitted host may carry before its suffix (#3640); absent, any number. Applies to every
|
|
2068
|
+
* entry of `hostSuffixes`, and only to them (an exact `values` entry is admitted as written).
|
|
2069
|
+
*
|
|
2070
|
+
* Declared only where the VENDOR documents the shape. Shopify does: a store host is exactly one label under
|
|
2071
|
+
* `.myshopify.com` ("Confirm the `shop` parameter matches `^[a-zA-Z0-9][a-zA-Z0-9\-]*\.myshopify\.com$`"), so it
|
|
2072
|
+
* declares `1`. Without the bound, a person answering `shop` with the full domain they see, `acme.myshopify.com`,
|
|
2073
|
+
* composed `acme.myshopify.com.myshopify.com`: a host under the suffix that does not exist, which failed every
|
|
2074
|
+
* request on DNS. (That answer is now also stripped to its handle, see `stripProviderHostAnswerTemplateSuffix`; the
|
|
2075
|
+
* bound is what refuses `acme.evil.myshopify.com`, naming the expected form.)
|
|
2076
|
+
* spec-cite: https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant —
|
|
2077
|
+
* the `shop` parameter check, as quoted in the Shopify module's header (fetched 2026-11-10).
|
|
2078
|
+
*
|
|
2079
|
+
* Every place a suffix admits a host reads it, through `providerHostIsUnderSuffix`: the answer filled into an endpoint
|
|
2080
|
+
* or base URL, the token-endpoint host description, the declined-value check. A positive integer, with at least one
|
|
2081
|
+
* suffix (`describeProviderOAuth2EndpointHostAllowanceDefects`).
|
|
2082
|
+
*/
|
|
2083
|
+
readonly hostSuffixMaxLabels?: number;
|
|
1424
2084
|
/**
|
|
1425
2085
|
* ORIGIN only: an admitted value must ALSO have the same origin as the deployment's configured base
|
|
1426
2086
|
* URL (the REST contract's `baseUrl` / `baseUrlEnvVarName`) (#991 review F4).
|
|
@@ -1526,6 +2186,59 @@ export declare enum ProviderOAuth2EndpointTemplateDefect {
|
|
|
1526
2186
|
* hyphen; 63 octets per label).
|
|
1527
2187
|
*/
|
|
1528
2188
|
export declare const PROVIDER_OAUTH2_DNS_NAME_PATTERN: RegExp;
|
|
2189
|
+
/**
|
|
2190
|
+
* Whether `host` is `<labels><suffix>`: it ends with the dotted `suffix`, what precedes the suffix is a DNS name (never
|
|
2191
|
+
* empty, so the bare suffix is not admitted), and that DNS name carries at most `maxLabels` labels (#3640).
|
|
2192
|
+
*
|
|
2193
|
+
* THE one suffix test. Every place a declared host suffix admits a host — an answer filled into an endpoint or a base URL,
|
|
2194
|
+
* an audience selecting a request host, the token-endpoint host description, a declined value a suffix would still admit —
|
|
2195
|
+
* asks this function, so a label bound declared once holds at all of them. `maxLabels` absent means unbounded, which is
|
|
2196
|
+
* what every suffix meant before the bound existed. A bound that is not a positive integer admits nothing (fail closed):
|
|
2197
|
+
* the declaration checks refuse it where a person is reading a diff, and this keeps the runtime closed regardless.
|
|
2198
|
+
*
|
|
2199
|
+
* Case-insensitive; the caller need not lower-case.
|
|
2200
|
+
*/
|
|
2201
|
+
export declare function providerHostIsUnderSuffix(host: string, suffix: string, maxLabels?: number): boolean;
|
|
2202
|
+
/** One declared host suffix with its label bound, as {@link providerHostSuffixesOverlap} compares them. */
|
|
2203
|
+
export interface ProviderHostSuffixBound {
|
|
2204
|
+
readonly suffix: string;
|
|
2205
|
+
/** At most this many DNS labels before the suffix; absent, unbounded. See {@link providerHostIsUnderSuffix}. */
|
|
2206
|
+
readonly maxLabels?: number;
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Whether some host is admitted under BOTH suffixes (#3640). Two suffixes can only share a host when one ends with the
|
|
2210
|
+
* other (`.a.b` and `.b`): a host under the longer one carries the extra labels (`.a`) before the shorter one, so the
|
|
2211
|
+
* shorter one's bound must leave room for one label of its own plus those. Equal suffixes always share a host.
|
|
2212
|
+
*/
|
|
2213
|
+
export declare function providerHostSuffixesOverlap(left: ProviderHostSuffixBound, right: ProviderHostSuffixBound): boolean;
|
|
2214
|
+
/**
|
|
2215
|
+
* The bare answer for a placeholder that OPENS a host, when the person typed the whole host (#3640).
|
|
2216
|
+
*
|
|
2217
|
+
* `https://{shop}.myshopify.com` asks for the store's handle, and the person connecting sees `acme.myshopify.com` in the
|
|
2218
|
+
* vendor's own screens. Filled verbatim, that answer dials `acme.myshopify.com.myshopify.com`: a host the suffix admits
|
|
2219
|
+
* (it ends in `.myshopify.com`) that does not exist, so every request fails on DNS naming a host rather than the answer.
|
|
2220
|
+
* The literal text the template writes after the placeholder (`literalHostSuffix`) is therefore stripped ONCE from an
|
|
2221
|
+
* answer that ends with it: `acme.myshopify.com` → `acme`. Nothing else is rewritten; the result is then admitted like
|
|
2222
|
+
* any other answer, so an answer with too many labels left (`acme.evil.myshopify.com` → `acme.evil` under a one-label
|
|
2223
|
+
* bound) is still refused.
|
|
2224
|
+
*
|
|
2225
|
+
* Generic rather than per vendor, because it is a property of the TEMPLATE: every provider whose host opens with a
|
|
2226
|
+
* placeholder (Shopify, Zendesk) asks for the part before a literal the vendor shows people with it attached. Done where
|
|
2227
|
+
* the template is filled, not in a connect prompt, so the OAuth start, the stored-answer re-admission and every
|
|
2228
|
+
* operation's base URL read the same answer the same way, whichever screen or flag supplied it. A host that literally
|
|
2229
|
+
* repeated its suffix is never a real vendor host, so nothing a person could mean is lost.
|
|
2230
|
+
*/
|
|
2231
|
+
export declare function stripProviderHostAnswerTemplateSuffix(value: string, literalHostSuffix: string | undefined): string;
|
|
2232
|
+
/**
|
|
2233
|
+
* The words a refusal uses for the answer a bounded suffix expects (#3640): `a single DNS label before .myshopify.com
|
|
2234
|
+
* (the 'acme' of acme.myshopify.com)`. Shared so every refusal names the same form.
|
|
2235
|
+
*/
|
|
2236
|
+
export declare function describeProviderHostSuffixExpectedForm(suffix: string, maxLabels: number | undefined, answerExcludesSuffix: boolean): string;
|
|
2237
|
+
/**
|
|
2238
|
+
* Why a declared label bound on host suffixes cannot be honoured (#3640): it is not a positive integer, or there is no
|
|
2239
|
+
* suffix for it to bound. Shared by the endpoint allowances and the audiences, so both refuse the same shapes.
|
|
2240
|
+
*/
|
|
2241
|
+
export declare function describeProviderHostSuffixMaxLabelsDefects(maxLabels: number | undefined, hostSuffixes: readonly string[] | undefined): string[];
|
|
1529
2242
|
/**
|
|
1530
2243
|
* Why a DECLARED host allowance cannot be applied where its placeholder sits — the position rules the
|
|
1531
2244
|
* transposer enforces at GENERATION time, so a broken declaration refuses the batch instead of being
|