@every-app/sdk 0.3.0-rc.2 → 0.3.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +1 -1
- package/dist/cloudflare/sentinel.d.ts +57 -2
- package/dist/cloudflare/sentinel.d.ts.map +1 -1
- package/dist/cloudflare/sentinel.js +27 -2
- package/dist/cloudflare/worker.d.ts +297 -5
- package/dist/cloudflare/worker.d.ts.map +1 -1
- package/dist/cloudflare/worker.js +279 -12
- package/dist/dev/index.d.ts +1 -1
- package/dist/dev/index.d.ts.map +1 -1
- package/dist/dev/index.js +1 -1
- package/dist/dev/keypair.d.ts +2 -0
- package/dist/dev/keypair.d.ts.map +1 -1
- package/dist/dev/keypair.js +2 -0
- package/dist/internal/aiDefault.d.ts +141 -0
- package/dist/internal/aiDefault.d.ts.map +1 -0
- package/dist/internal/aiDefault.js +204 -0
- package/dist/internal/aiProviders.d.ts +4 -1
- package/dist/internal/aiProviders.d.ts.map +1 -1
- package/dist/internal/aiProviders.js +5 -1
- package/dist/internal/appSettings.d.ts +20 -2
- package/dist/internal/appSettings.d.ts.map +1 -1
- package/dist/internal/appSettings.js +53 -7
- package/dist/internal/audit.d.ts +108 -0
- package/dist/internal/audit.d.ts.map +1 -0
- package/dist/internal/audit.js +235 -0
- package/dist/internal/capabilities.d.ts +276 -7
- package/dist/internal/capabilities.d.ts.map +1 -1
- package/dist/internal/capabilities.js +111 -0
- package/dist/internal/catalog/index.d.ts +39 -2
- package/dist/internal/catalog/index.d.ts.map +1 -1
- package/dist/internal/catalog/inference.d.ts +39 -2
- package/dist/internal/catalog/inference.d.ts.map +1 -1
- package/dist/internal/catalog/inference.js +36 -4
- package/dist/internal/devProviders.d.ts +2 -2
- package/dist/internal/devProviders.d.ts.map +1 -1
- package/dist/internal/devProviders.js +19 -1
- package/dist/internal/events.d.ts +13 -2
- package/dist/internal/events.d.ts.map +1 -1
- package/dist/internal/events.js +42 -4
- package/dist/internal/identity.d.ts +29 -3
- package/dist/internal/identity.d.ts.map +1 -1
- package/dist/internal/identity.js +37 -9
- package/dist/internal/index.d.ts +5 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +5 -1
- package/dist/internal/members.d.ts +3 -2
- package/dist/internal/members.d.ts.map +1 -1
- package/dist/internal/oauthPresets.d.ts +29 -0
- package/dist/internal/oauthPresets.d.ts.map +1 -0
- package/dist/internal/oauthPresets.js +534 -0
- package/dist/internal/oauthScopes.d.ts +56 -1
- package/dist/internal/oauthScopes.d.ts.map +1 -1
- package/dist/internal/oauthScopes.js +98 -4
- package/dist/internal/oauthSpec.d.ts +59 -0
- package/dist/internal/oauthSpec.d.ts.map +1 -0
- package/dist/internal/oauthSpec.js +676 -0
- package/dist/internal/protocol.d.ts +36 -1
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +30 -1
- package/dist/internal/providerRegistry.d.ts +17 -6
- package/dist/internal/providerRegistry.d.ts.map +1 -1
- package/dist/internal/providerRegistry.js +47 -2
- package/dist/internal/providerSpec.d.ts +11 -7
- package/dist/internal/providerSpec.d.ts.map +1 -1
- package/dist/internal/providerSpec.js +134 -37
- package/dist/internal/signInProviders.d.ts.map +1 -1
- package/dist/internal/signInProviders.js +11 -4
- package/dist/server/ai.d.ts +45 -0
- package/dist/server/ai.d.ts.map +1 -0
- package/dist/server/ai.js +40 -0
- package/dist/server/attribution.d.ts +9 -5
- package/dist/server/attribution.d.ts.map +1 -1
- package/dist/server/attribution.js +12 -4
- package/dist/server/connectUrl.d.ts +21 -0
- package/dist/server/connectUrl.d.ts.map +1 -0
- package/dist/server/connectUrl.js +37 -0
- package/dist/server/context.d.ts +68 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +117 -0
- package/dist/server/emit.d.ts +1 -1
- package/dist/server/emit.d.ts.map +1 -1
- package/dist/server/emit.js +4 -4
- package/dist/server/everyApp.d.ts +27 -7
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +106 -5
- package/dist/server/fromMcpTools.d.ts +89 -0
- package/dist/server/fromMcpTools.d.ts.map +1 -0
- package/dist/server/fromMcpTools.js +192 -0
- package/dist/server/gatewayFetch.d.ts +8 -6
- package/dist/server/gatewayFetch.d.ts.map +1 -1
- package/dist/server/gatewayFetch.js +78 -11
- package/dist/server/index.d.ts +7 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +6 -2
- package/dist/server/integrationFetch.d.ts +55 -8
- package/dist/server/integrationFetch.d.ts.map +1 -1
- package/dist/server/integrationFetch.js +198 -18
- package/dist/server/listMembers.d.ts +1 -1
- package/dist/server/listMembers.d.ts.map +1 -1
- package/dist/server/listMembers.js +5 -8
- package/dist/server/sendEmail.d.ts +1 -1
- package/dist/server/sendEmail.d.ts.map +1 -1
- package/dist/server/sendEmail.js +4 -4
- package/dist/server/toolsEndpoint.d.ts.map +1 -1
- package/dist/server/toolsEndpoint.js +11 -5
- package/package.json +13 -14
- package/LICENSE +0 -21
|
@@ -39,6 +39,17 @@ export declare const GATEWAY_ERROR_HEADER = "x-everyapp-error";
|
|
|
39
39
|
* from what browsers send.
|
|
40
40
|
*/
|
|
41
41
|
export declare const ORG_HEADER = "x-everyapp-org";
|
|
42
|
+
/**
|
|
43
|
+
* Which connection an app's call to an OAuth provider uses: the person's
|
|
44
|
+
* (`user`, the default when a person is behind the call) or the
|
|
45
|
+
* organization's (`organization`, the default for background work),
|
|
46
|
+
* docs/design/2026-10-oauth-providers.md section 7. Set by
|
|
47
|
+
* `integrationFetch({ account })`; the gateway reads it on the held-token
|
|
48
|
+
* branch and ignores it elsewhere.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ACCOUNT_HEADER = "x-everyapp-account";
|
|
51
|
+
/** The values {@link ACCOUNT_HEADER} may carry. */
|
|
52
|
+
export type ConnectionAccount = "user" | "organization";
|
|
42
53
|
/** 120-second lifetime — caps revocation staleness while surviving clock skew. */
|
|
43
54
|
export declare const IDENTITY_TTL_SECONDS = 120;
|
|
44
55
|
/** System tokens are minted per call and live at most a minute. */
|
|
@@ -63,6 +74,18 @@ export declare const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
|
|
|
63
74
|
export declare const SHARED_ENV = "EVERYAPP_SHARED";
|
|
64
75
|
/** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
|
|
65
76
|
export declare const DEV_ENV = "EVERYAPP_DEV";
|
|
77
|
+
/**
|
|
78
|
+
* The organization an app's Worker is pinned to (a secret the deploy sends;
|
|
79
|
+
* in development the stub gateway's organization). `everyApp()` refuses an
|
|
80
|
+
* identity for any other organization; absent on a shared app's Workers.
|
|
81
|
+
*/
|
|
82
|
+
export declare const ORG_ID_ENV = "EVERY_APP_ORG_ID";
|
|
83
|
+
/**
|
|
84
|
+
* The organization the dev gateway's seeded user belongs to. The same value
|
|
85
|
+
* as `@every-app/sdk/dev`'s, kept apart like {@link DEV_ISSUER} (the same
|
|
86
|
+
* test pins the two together).
|
|
87
|
+
*/
|
|
88
|
+
export declare const DEV_ORG_ID = "dev-org";
|
|
66
89
|
/** `sub` claim the gateway mints public-route markers with. */
|
|
67
90
|
export declare const PUBLIC_MARKER_SUB = "public";
|
|
68
91
|
/** `sub` claim of gateway system tokens. */
|
|
@@ -81,12 +104,24 @@ export interface IdentitySubject {
|
|
|
81
104
|
orgId: string;
|
|
82
105
|
orgRole: string;
|
|
83
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* A member's role in the organization, as the identity token carries it.
|
|
109
|
+
* Owners and admins manage; anything the Gateway might mint that an app
|
|
110
|
+
* doesn't know is read as `member`.
|
|
111
|
+
*/
|
|
112
|
+
export type OrgRole = "owner" | "admin" | "member";
|
|
113
|
+
/** `role` as an {@link OrgRole}: `owner` and `admin` as they are, anything else `member`. */
|
|
114
|
+
export declare function toOrgRole(role: unknown): OrgRole;
|
|
115
|
+
/** Whether `user` manages the organization: an owner or an admin. */
|
|
116
|
+
export declare function isAdmin(user: {
|
|
117
|
+
orgRole: OrgRole | string;
|
|
118
|
+
}): boolean;
|
|
84
119
|
export interface EveryAppUser {
|
|
85
120
|
/** User id (the `sub` claim). */
|
|
86
121
|
id: string;
|
|
87
122
|
email: string;
|
|
88
123
|
orgId: string;
|
|
89
|
-
orgRole:
|
|
124
|
+
orgRole: OrgRole;
|
|
90
125
|
channel: IdentityChannel;
|
|
91
126
|
/** The acting principal (user, or `mcp:<client>` / agent). */
|
|
92
127
|
actor: IdentityActor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,eAAe,sBAAsB,CAAC;AACnD,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAC3D;;;;GAIG;AACH,eAAO,MAAM,UAAU,kCAAkC,CAAC;AAC1D,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;GAIG;AACH,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AACvD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,mBAAmB,CAAC;AAC3C,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,8CAA8C;AAC9C,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,qEAAqE;AACrE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,mFAAmF;AACnF,eAAO,MAAM,UAAU,6BAA6B,CAAC;AACrD;;;GAGG;AACH,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,qFAAqF;AACrF,eAAO,MAAM,OAAO,iBAAiB,CAAC;AACtC,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAC1C,4CAA4C;AAC5C,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC7D,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,15 @@ export const GATEWAY_ERROR_HEADER = "x-everyapp-error";
|
|
|
38
38
|
* from what browsers send.
|
|
39
39
|
*/
|
|
40
40
|
export const ORG_HEADER = "x-everyapp-org";
|
|
41
|
+
/**
|
|
42
|
+
* Which connection an app's call to an OAuth provider uses: the person's
|
|
43
|
+
* (`user`, the default when a person is behind the call) or the
|
|
44
|
+
* organization's (`organization`, the default for background work),
|
|
45
|
+
* docs/design/2026-10-oauth-providers.md section 7. Set by
|
|
46
|
+
* `integrationFetch({ account })`; the gateway reads it on the held-token
|
|
47
|
+
* branch and ignores it elsewhere.
|
|
48
|
+
*/
|
|
49
|
+
export const ACCOUNT_HEADER = "x-everyapp-account";
|
|
41
50
|
/** 120-second lifetime — caps revocation staleness while surviving clock skew. */
|
|
42
51
|
export const IDENTITY_TTL_SECONDS = 120;
|
|
43
52
|
/** System tokens are minted per call and live at most a minute. */
|
|
@@ -62,10 +71,30 @@ export const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
|
|
|
62
71
|
export const SHARED_ENV = "EVERYAPP_SHARED";
|
|
63
72
|
/** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
|
|
64
73
|
export const DEV_ENV = "EVERYAPP_DEV";
|
|
74
|
+
/**
|
|
75
|
+
* The organization an app's Worker is pinned to (a secret the deploy sends;
|
|
76
|
+
* in development the stub gateway's organization). `everyApp()` refuses an
|
|
77
|
+
* identity for any other organization; absent on a shared app's Workers.
|
|
78
|
+
*/
|
|
79
|
+
export const ORG_ID_ENV = "EVERY_APP_ORG_ID";
|
|
80
|
+
/**
|
|
81
|
+
* The organization the dev gateway's seeded user belongs to. The same value
|
|
82
|
+
* as `@every-app/sdk/dev`'s, kept apart like {@link DEV_ISSUER} (the same
|
|
83
|
+
* test pins the two together).
|
|
84
|
+
*/
|
|
85
|
+
export const DEV_ORG_ID = "dev-org";
|
|
65
86
|
/** `sub` claim the gateway mints public-route markers with. */
|
|
66
87
|
export const PUBLIC_MARKER_SUB = "public";
|
|
67
88
|
/** `sub` claim of gateway system tokens. */
|
|
68
89
|
export const SYSTEM_TOKEN_SUB = "system";
|
|
90
|
+
/** `role` as an {@link OrgRole}: `owner` and `admin` as they are, anything else `member`. */
|
|
91
|
+
export function toOrgRole(role) {
|
|
92
|
+
return role === "owner" || role === "admin" ? role : "member";
|
|
93
|
+
}
|
|
94
|
+
/** Whether `user` manages the organization: an owner or an admin. */
|
|
95
|
+
export function isAdmin(user) {
|
|
96
|
+
return user.orgRole === "owner" || user.orgRole === "admin";
|
|
97
|
+
}
|
|
69
98
|
export class ProtocolClaimsError extends Error {
|
|
70
99
|
constructor(message) {
|
|
71
100
|
super(message);
|
|
@@ -122,7 +151,7 @@ export function identityClaimsToEveryAppUser(payload) {
|
|
|
122
151
|
id: sub,
|
|
123
152
|
email,
|
|
124
153
|
orgId,
|
|
125
|
-
orgRole,
|
|
154
|
+
orgRole: toOrgRole(orgRole),
|
|
126
155
|
channel: chan,
|
|
127
156
|
actor: { sub: act.sub ?? sub },
|
|
128
157
|
scopes,
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
* and not one the gateway serves itself (`refuseHost`, which knows the
|
|
21
21
|
* gateway's own host and `APP_BASE_DOMAIN`).
|
|
22
22
|
*/
|
|
23
|
-
import { type
|
|
23
|
+
import { type Capability, type CapabilityLookup } from "./capabilities.js";
|
|
24
|
+
import { type RegistrableCapability } from "./providerSpec.js";
|
|
24
25
|
/** A `providers` row as the gateway or the CLI read it. */
|
|
25
26
|
export interface ProviderRow {
|
|
26
27
|
id: string;
|
|
@@ -42,13 +43,17 @@ export interface ProviderRow {
|
|
|
42
43
|
* The part of a row a key is set for: its hosts, its host setting and its
|
|
43
44
|
* auth, as one canonical string (sorted keys, sorted hosts), so that
|
|
44
45
|
* replacing a row's hosts or auth changes the key and the value it held
|
|
45
|
-
* is no longer read until the operator sets it again.
|
|
46
|
+
* is no longer read until the operator sets it again. For an OAuth
|
|
47
|
+
* provider the client is bound to its authorize, token and revoke URLs,
|
|
48
|
+
* its API hosts, where the client goes on the token request and its
|
|
49
|
+
* client setting names (`oauth.client-bound-to-endpoints`): an admin who
|
|
50
|
+
* re-points `tokenUrl` has to paste the secret again.
|
|
46
51
|
*/
|
|
47
|
-
export declare function providerBindingKey(capability:
|
|
52
|
+
export declare function providerBindingKey(capability: RegistrableCapability): string;
|
|
48
53
|
/** One registered row as `provider list` and `provider show` report it. */
|
|
49
54
|
export interface RegisteredProvider {
|
|
50
55
|
id: string;
|
|
51
|
-
capability:
|
|
56
|
+
capability: RegistrableCapability;
|
|
52
57
|
/** Whether the row's key was set for the hosts and auth it has now. */
|
|
53
58
|
bound: boolean;
|
|
54
59
|
addedBy: string | null;
|
|
@@ -121,18 +126,24 @@ export declare function rowSecretProblem(id: string, name: string, taken: (name:
|
|
|
121
126
|
* CLI runs it before writing D1, the MCP tool before writing, and the
|
|
122
127
|
* gateway again on every read.
|
|
123
128
|
*/
|
|
124
|
-
export declare function checkProviderRow(id: string, capability:
|
|
129
|
+
export declare function checkProviderRow(id: string, capability: RegistrableCapability, context: {
|
|
125
130
|
/** Settings the other rows hold. */
|
|
126
131
|
rowSettings: ReadonlySet<string>;
|
|
127
132
|
refuseHost?: (host: string) => string | null;
|
|
128
133
|
}): RowRefusal | null;
|
|
134
|
+
/**
|
|
135
|
+
* Every host a row sends a secret to: an API-key provider's `hosts`; an
|
|
136
|
+
* OAuth provider's API hosts (the token), and its authorize, token and
|
|
137
|
+
* revoke hosts (the client). Each passes the row host rules.
|
|
138
|
+
*/
|
|
139
|
+
export declare function registrableHosts(capability: RegistrableCapability): string[];
|
|
129
140
|
/** A row's spec parsed and checked: the capability, or the refusal. */
|
|
130
141
|
export declare function resolveProviderRow(row: ProviderRow, context: {
|
|
131
142
|
rowSettings: ReadonlySet<string>;
|
|
132
143
|
refuseHost?: (host: string) => string | null;
|
|
133
144
|
}): {
|
|
134
145
|
ok: true;
|
|
135
|
-
capability:
|
|
146
|
+
capability: RegistrableCapability;
|
|
136
147
|
} | {
|
|
137
148
|
ok: false;
|
|
138
149
|
refusal: RowRefusal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/providerRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"providerRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/providerRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,IAAI,EAAE,OAAO,CAAC;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uGAAuG;IACvG,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,qBAAqB,GAAG,MAAM,CAgC5E;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,qBAAqB,CAAC;IAClC,uEAAuE;IACvE,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GACtB,uBAAuB,GACvB,kBAAkB,GAClB,uBAAuB,GACvB,uBAAuB,CAAC;AAE5B,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,mFAAmF;IACnF,GAAG,IAAI,SAAS,MAAM,EAAE,CAAC;IACzB,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;IACpD,6EAA6E;IAC7E,YAAY,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC;;;;OAIG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,4EAA4E;IAC5E,eAAe,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,8DAA8D;IAC9D,IAAI,IAAI,SAAS,kBAAkB,EAAE,CAAC;IACtC,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC9C;AAOD,wHAAwH;AACxH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS7D;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAcD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,YAAY,GAClB,MAAM,GAAG,IAAI,CAYf;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAC/B,MAAM,GAAG,IAAI,CAwBf;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE;IACP,oCAAoC;IACpC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC9C,GACA,UAAU,GAAG,IAAI,CAuBnB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAmB5E;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE;IACP,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC9C,GAEC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,qBAAqB,CAAA;CAAE,GAC/C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAyCrC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,GAAE,SAAS,WAAW,EAAO,EACjC,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAqElB;AAED,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB,EAAE,gBAAqC,CAAC"}
|
|
@@ -28,9 +28,25 @@ import { describeSpecProblems, parseProviderSpec, PROVIDER_ID, } from "./provide
|
|
|
28
28
|
* The part of a row a key is set for: its hosts, its host setting and its
|
|
29
29
|
* auth, as one canonical string (sorted keys, sorted hosts), so that
|
|
30
30
|
* replacing a row's hosts or auth changes the key and the value it held
|
|
31
|
-
* is no longer read until the operator sets it again.
|
|
31
|
+
* is no longer read until the operator sets it again. For an OAuth
|
|
32
|
+
* provider the client is bound to its authorize, token and revoke URLs,
|
|
33
|
+
* its API hosts, where the client goes on the token request and its
|
|
34
|
+
* client setting names (`oauth.client-bound-to-endpoints`): an admin who
|
|
35
|
+
* re-points `tokenUrl` has to paste the secret again.
|
|
32
36
|
*/
|
|
33
37
|
export function providerBindingKey(capability) {
|
|
38
|
+
if (capability.mode === "oauth_client") {
|
|
39
|
+
return JSON.stringify({
|
|
40
|
+
kind: "oauth2-user",
|
|
41
|
+
authorizeUrl: capability.authorize.url,
|
|
42
|
+
tokenUrl: capability.flow?.tokenUrl ?? null,
|
|
43
|
+
revokeUrl: capability.flow?.revokeUrl ?? null,
|
|
44
|
+
inject: capability.token[0]?.inject ?? "form",
|
|
45
|
+
clientId: capability.secrets.clientId,
|
|
46
|
+
clientSecret: capability.secrets.clientSecret ?? null,
|
|
47
|
+
hosts: [...capability.api].sort(),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
34
50
|
const auth = Object.fromEntries(Object.entries(capability.auth)
|
|
35
51
|
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
36
52
|
.map(([field, value]) => [
|
|
@@ -147,7 +163,7 @@ export function checkProviderRow(id, capability, context) {
|
|
|
147
163
|
return { id, code: "PROVIDER_SECRET_TAKEN", message: problem };
|
|
148
164
|
}
|
|
149
165
|
}
|
|
150
|
-
for (const host of capability
|
|
166
|
+
for (const host of registrableHosts(capability)) {
|
|
151
167
|
const problem = publicHostProblem(host) ?? context.refuseHost?.(host);
|
|
152
168
|
if (problem) {
|
|
153
169
|
return { id, code: "PROVIDER_HOST_REFUSED", message: problem };
|
|
@@ -155,6 +171,35 @@ export function checkProviderRow(id, capability, context) {
|
|
|
155
171
|
}
|
|
156
172
|
return null;
|
|
157
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Every host a row sends a secret to: an API-key provider's `hosts`; an
|
|
176
|
+
* OAuth provider's API hosts (the token), and its authorize, token and
|
|
177
|
+
* revoke hosts (the client). Each passes the row host rules.
|
|
178
|
+
*/
|
|
179
|
+
export function registrableHosts(capability) {
|
|
180
|
+
if (capability.mode === "api_key")
|
|
181
|
+
return [...capability.hosts];
|
|
182
|
+
const hosts = [...capability.api];
|
|
183
|
+
const urls = [
|
|
184
|
+
capability.authorize.url,
|
|
185
|
+
capability.flow?.tokenUrl,
|
|
186
|
+
capability.flow?.revokeUrl,
|
|
187
|
+
capability.flow?.identity?.url,
|
|
188
|
+
];
|
|
189
|
+
for (const url of urls) {
|
|
190
|
+
if (!url)
|
|
191
|
+
continue;
|
|
192
|
+
try {
|
|
193
|
+
const host = new URL(url).hostname.toLowerCase();
|
|
194
|
+
if (!hosts.includes(host))
|
|
195
|
+
hosts.push(host);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// The parser refused it already.
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return hosts;
|
|
202
|
+
}
|
|
158
203
|
/** A row's spec parsed and checked: the capability, or the refusal. */
|
|
159
204
|
export function resolveProviderRow(row, context) {
|
|
160
205
|
let spec = row.spec;
|
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
* JSON into an {@link ApiKeyCapability} or names every problem; nothing
|
|
7
7
|
* here reads a value: a spec names Gateway settings, never holds one.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* or basic)
|
|
11
|
-
* the
|
|
9
|
+
* Two kinds parse: API-key providers (`auth.kind` bearer, header, query
|
|
10
|
+
* or basic) and OAuth providers (`auth.kind` oauth2-user, the half in
|
|
11
|
+
* ./oauthSpec.ts: the Gateway runs the flow and holds the tokens,
|
|
12
|
+
* docs/design/2026-10-oauth-providers.md). An AI provider is a catalog
|
|
13
|
+
* entry only; the parser says so rather than guessing.
|
|
12
14
|
*
|
|
13
15
|
* The rules that make a row safe on a particular gateway (its secret names
|
|
14
16
|
* are its own, its hosts are public, it shadows no catalog entry) are the
|
|
15
17
|
* registry's (./providerRegistry.ts), run after this parse.
|
|
16
18
|
*/
|
|
17
|
-
import { type ApiKeyCapability } from "./capabilities.js";
|
|
19
|
+
import { type ApiKeyCapability, type OAuthClientCapability } from "./capabilities.js";
|
|
18
20
|
/** A provider id: lowercase, a letter first, 2 to 40 characters. */
|
|
19
21
|
export declare const PROVIDER_ID: RegExp;
|
|
20
22
|
/** A Gateway setting name a provider may hold: upper case, 3 to 64 characters. */
|
|
@@ -26,10 +28,12 @@ export interface ProviderSpecProblem {
|
|
|
26
28
|
path: string;
|
|
27
29
|
message: string;
|
|
28
30
|
}
|
|
31
|
+
/** What a row or a preset may be: an API key, or an OAuth provider with a `flow`. */
|
|
32
|
+
export type RegistrableCapability = ApiKeyCapability | OAuthClientCapability;
|
|
29
33
|
export type ParsedProviderSpec = {
|
|
30
34
|
ok: true;
|
|
31
35
|
id: string;
|
|
32
|
-
capability:
|
|
36
|
+
capability: RegistrableCapability;
|
|
33
37
|
} | {
|
|
34
38
|
ok: false;
|
|
35
39
|
problems: ProviderSpecProblem[];
|
|
@@ -49,7 +53,7 @@ export declare function describeSpecProblems(problems: readonly ProviderSpecProb
|
|
|
49
53
|
* defaults the parser fills in spelled out, so `parseProviderSpec` of it
|
|
50
54
|
* gives the entry back.
|
|
51
55
|
*/
|
|
52
|
-
export declare function providerSpecOf(id: string, capability:
|
|
56
|
+
export declare function providerSpecOf(id: string, capability: RegistrableCapability): Record<string, unknown>;
|
|
53
57
|
/** The methods an app with `access: "write"` may use on `capability` besides its read methods. */
|
|
54
|
-
export declare function writeMethodsOf(capability:
|
|
58
|
+
export declare function writeMethodsOf(capability: RegistrableCapability): readonly string[];
|
|
55
59
|
//# sourceMappingURL=providerSpec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerSpec.d.ts","sourceRoot":"","sources":["../../src/internal/providerSpec.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"providerSpec.d.ts","sourceRoot":"","sources":["../../src/internal/providerSpec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAM3B,MAAM,mBAAmB,CAAC;AAG3B,oEAAoE;AACpE,eAAO,MAAM,WAAW,QAA2B,CAAC;AACpD,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,QAA2B,CAAC;AAC7D,0FAA0F;AAC1F,eAAO,MAAM,aAAa,QACoD,CAAC;AAoF/E,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,qBAAqB,CAAC;AAE7E,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,qBAAqB,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,CAAC;AA+iBnD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAgNpE;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,GACvC,MAAM,CAIR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,qBAAqB,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiDzB;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAC5B,UAAU,EAAE,qBAAqB,GAChC,SAAS,MAAM,EAAE,CAEnB"}
|
|
@@ -6,15 +6,18 @@
|
|
|
6
6
|
* JSON into an {@link ApiKeyCapability} or names every problem; nothing
|
|
7
7
|
* here reads a value: a spec names Gateway settings, never holds one.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* or basic)
|
|
11
|
-
* the
|
|
9
|
+
* Two kinds parse: API-key providers (`auth.kind` bearer, header, query
|
|
10
|
+
* or basic) and OAuth providers (`auth.kind` oauth2-user, the half in
|
|
11
|
+
* ./oauthSpec.ts: the Gateway runs the flow and holds the tokens,
|
|
12
|
+
* docs/design/2026-10-oauth-providers.md). An AI provider is a catalog
|
|
13
|
+
* entry only; the parser says so rather than guessing.
|
|
12
14
|
*
|
|
13
15
|
* The rules that make a row safe on a particular gateway (its secret names
|
|
14
16
|
* are its own, its hosts are public, it shadows no catalog entry) are the
|
|
15
17
|
* registry's (./providerRegistry.ts), run after this parse.
|
|
16
18
|
*/
|
|
17
19
|
import { DEFAULT_WRITE_METHODS, authSettingNames, } from "./capabilities.js";
|
|
20
|
+
import { oauthSpecOf, parseOAuthUserSpec } from "./oauthSpec.js";
|
|
18
21
|
/** A provider id: lowercase, a letter first, 2 to 40 characters. */
|
|
19
22
|
export const PROVIDER_ID = /^[a-z][a-z0-9-]{1,39}$/;
|
|
20
23
|
/** A Gateway setting name a provider may hold: upper case, 3 to 64 characters. */
|
|
@@ -80,7 +83,27 @@ const KNOWN_FIELDS = new Set([
|
|
|
80
83
|
"example",
|
|
81
84
|
"verified",
|
|
82
85
|
"tags",
|
|
86
|
+
// An `oauth2-user` spec's own (./oauthSpec.ts).
|
|
87
|
+
"scopeSets",
|
|
88
|
+
"alwaysRequested",
|
|
89
|
+
"tolerated",
|
|
83
90
|
]);
|
|
91
|
+
/** Fields an API-key spec has that an `oauth2-user` spec does not. */
|
|
92
|
+
const API_KEY_ONLY_FIELDS = [
|
|
93
|
+
"hostSetting",
|
|
94
|
+
"data",
|
|
95
|
+
"secrets",
|
|
96
|
+
"accountWidePaths",
|
|
97
|
+
"smoke",
|
|
98
|
+
"cost",
|
|
99
|
+
"rate",
|
|
100
|
+
"verified",
|
|
101
|
+
];
|
|
102
|
+
const OAUTH_ONLY_FIELDS = [
|
|
103
|
+
"scopeSets",
|
|
104
|
+
"alwaysRequested",
|
|
105
|
+
"tolerated",
|
|
106
|
+
];
|
|
84
107
|
function isRecord(value) {
|
|
85
108
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
86
109
|
}
|
|
@@ -305,7 +328,7 @@ function auth(value, problems) {
|
|
|
305
328
|
default:
|
|
306
329
|
problems.push({
|
|
307
330
|
path: "auth.kind",
|
|
308
|
-
message: "must be bearer, header, query or
|
|
331
|
+
message: "must be bearer, header, query, basic or oauth2-user (an AI provider is a catalog entry, not a spec this gateway takes)",
|
|
309
332
|
});
|
|
310
333
|
return undefined;
|
|
311
334
|
}
|
|
@@ -537,6 +560,43 @@ function verified(value, problems) {
|
|
|
537
560
|
});
|
|
538
561
|
return undefined;
|
|
539
562
|
}
|
|
563
|
+
/** `access`, `readMethods` and `writeMethods`, shared by both kinds. */
|
|
564
|
+
function grants(input, problems) {
|
|
565
|
+
const access = stringList(input["access"], "access", problems, {
|
|
566
|
+
max: 2,
|
|
567
|
+
each: (level, at) => {
|
|
568
|
+
if (level !== "read" && level !== "write") {
|
|
569
|
+
problems.push({ path: at, message: "must be read or write" });
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
});
|
|
573
|
+
if (access && access.length === 0) {
|
|
574
|
+
problems.push({ path: "access", message: "must list read, write or both" });
|
|
575
|
+
}
|
|
576
|
+
const readMethods = methods(input["readMethods"], "readMethods", problems);
|
|
577
|
+
// A write-only provider (a sender, a GraphQL API) reads with nothing:
|
|
578
|
+
// every call needs the write grant. Anything that offers read lists how.
|
|
579
|
+
if (readMethods &&
|
|
580
|
+
readMethods.length === 0 &&
|
|
581
|
+
(!Array.isArray(access) || access.includes("read"))) {
|
|
582
|
+
problems.push({
|
|
583
|
+
path: "readMethods",
|
|
584
|
+
message: "must list a method unless access is write alone",
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
const writeMethods = methods(input["writeMethods"], "writeMethods", problems);
|
|
588
|
+
return { access, readMethods, writeMethods };
|
|
589
|
+
}
|
|
590
|
+
function tagList(value, problems) {
|
|
591
|
+
return stringList(value, "tags", problems, {
|
|
592
|
+
max: 10,
|
|
593
|
+
each: (tag, at) => {
|
|
594
|
+
if (!TAG.test(tag)) {
|
|
595
|
+
problems.push({ path: at, message: "must be a lowercase word" });
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
}
|
|
540
600
|
/**
|
|
541
601
|
* Parse a provider spec. Every problem is reported, with its path, so a
|
|
542
602
|
* person fixes the file once. On success the id and the catalog-shaped
|
|
@@ -563,10 +623,14 @@ export function parseProviderSpec(input) {
|
|
|
563
623
|
message: "must be lowercase letters, digits and hyphens, a letter first, 2 to 40 characters (stripe)",
|
|
564
624
|
});
|
|
565
625
|
}
|
|
566
|
-
|
|
626
|
+
const isOAuth = isRecord(input["auth"]) && input["auth"]["kind"] === "oauth2-user";
|
|
627
|
+
const expectedMode = isOAuth ? "oauth_client" : "api_key";
|
|
628
|
+
if (input["mode"] !== undefined && input["mode"] !== expectedMode) {
|
|
567
629
|
problems.push({
|
|
568
630
|
path: "mode",
|
|
569
|
-
message:
|
|
631
|
+
message: isOAuth
|
|
632
|
+
? "an oauth2-user spec's mode is oauth_client (or left out)"
|
|
633
|
+
: "this gateway registers api_key and oauth_client (auth.kind oauth2-user) providers; an AI provider is a catalog entry",
|
|
570
634
|
});
|
|
571
635
|
}
|
|
572
636
|
const name = text(input["name"], "name", problems, { max: 64 });
|
|
@@ -595,6 +659,61 @@ export function parseProviderSpec(input) {
|
|
|
595
659
|
}
|
|
596
660
|
},
|
|
597
661
|
});
|
|
662
|
+
if (isOAuth) {
|
|
663
|
+
const { access, readMethods, writeMethods } = grants(input, problems);
|
|
664
|
+
const hint = text(input["hint"], "hint", problems, { max: 500 });
|
|
665
|
+
const example = text(input["example"], "example", problems, { max: 200 });
|
|
666
|
+
const tags = tagList(input["tags"], problems);
|
|
667
|
+
// An OAuth provider: its token goes to `hosts` alone, so the API-key
|
|
668
|
+
// fields that shape a key's placement have no meaning here.
|
|
669
|
+
for (const field of API_KEY_ONLY_FIELDS) {
|
|
670
|
+
if (input[field] !== undefined) {
|
|
671
|
+
problems.push({
|
|
672
|
+
path: field,
|
|
673
|
+
message: "not a field of an oauth2-user spec",
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (input["hosts"] === undefined || (hosts && hosts.length === 0)) {
|
|
678
|
+
problems.push({
|
|
679
|
+
path: "hosts",
|
|
680
|
+
message: "required: at least one API host the token is sent to",
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
const parsed = typeof id === "string" &&
|
|
684
|
+
name !== undefined &&
|
|
685
|
+
docs !== undefined &&
|
|
686
|
+
hosts !== undefined
|
|
687
|
+
? parseOAuthUserSpec(input, {
|
|
688
|
+
id,
|
|
689
|
+
name,
|
|
690
|
+
docs,
|
|
691
|
+
hosts,
|
|
692
|
+
...(description === undefined ? {} : { description }),
|
|
693
|
+
...(api === undefined ? {} : { reference: api }),
|
|
694
|
+
...(access === undefined
|
|
695
|
+
? {}
|
|
696
|
+
: { access: access }),
|
|
697
|
+
...(readMethods === undefined ? {} : { readMethods }),
|
|
698
|
+
...(writeMethods === undefined ? {} : { writeMethods }),
|
|
699
|
+
...(hint === undefined ? {} : { hint }),
|
|
700
|
+
...(example === undefined ? {} : { example }),
|
|
701
|
+
...(tags === undefined ? {} : { tags }),
|
|
702
|
+
}, problems)
|
|
703
|
+
: undefined;
|
|
704
|
+
if (problems.length > 0 || !parsed || typeof id !== "string") {
|
|
705
|
+
return { ok: false, problems };
|
|
706
|
+
}
|
|
707
|
+
return { ok: true, id, capability: parsed.capability };
|
|
708
|
+
}
|
|
709
|
+
for (const field of OAUTH_ONLY_FIELDS) {
|
|
710
|
+
if (input[field] !== undefined) {
|
|
711
|
+
problems.push({
|
|
712
|
+
path: field,
|
|
713
|
+
message: "only an oauth2-user spec has it",
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
598
717
|
const hostSetting = input["hostSetting"] === undefined
|
|
599
718
|
? undefined
|
|
600
719
|
: secretName(input["hostSetting"], "hostSetting", problems);
|
|
@@ -628,29 +747,7 @@ export function parseProviderSpec(input) {
|
|
|
628
747
|
...(parsedAuth ? authSettingNames(parsedAuth) : []),
|
|
629
748
|
...(hostSetting === undefined ? [] : [hostSetting]),
|
|
630
749
|
], problems);
|
|
631
|
-
const access =
|
|
632
|
-
max: 2,
|
|
633
|
-
each: (level, at) => {
|
|
634
|
-
if (level !== "read" && level !== "write") {
|
|
635
|
-
problems.push({ path: at, message: "must be read or write" });
|
|
636
|
-
}
|
|
637
|
-
},
|
|
638
|
-
});
|
|
639
|
-
if (access && access.length === 0) {
|
|
640
|
-
problems.push({ path: "access", message: "must list read, write or both" });
|
|
641
|
-
}
|
|
642
|
-
const readMethods = methods(input["readMethods"], "readMethods", problems);
|
|
643
|
-
// A write-only provider (a sender, a GraphQL API) reads with nothing:
|
|
644
|
-
// every call needs the write grant. Anything that offers read lists how.
|
|
645
|
-
if (readMethods &&
|
|
646
|
-
readMethods.length === 0 &&
|
|
647
|
-
(!Array.isArray(access) || access.includes("read"))) {
|
|
648
|
-
problems.push({
|
|
649
|
-
path: "readMethods",
|
|
650
|
-
message: "must list a method unless access is write alone",
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
const writeMethods = methods(input["writeMethods"], "writeMethods", problems);
|
|
750
|
+
const { access, readMethods, writeMethods } = grants(input, problems);
|
|
654
751
|
const paths = accountWidePaths(input["accountWidePaths"], problems);
|
|
655
752
|
const hint = text(input["hint"], "hint", problems, { max: 500 });
|
|
656
753
|
const smokeRequest = smoke(input["smoke"], hosts ?? [], problems);
|
|
@@ -658,14 +755,7 @@ export function parseProviderSpec(input) {
|
|
|
658
755
|
const parsedRate = rate(input["rate"], problems);
|
|
659
756
|
const example = text(input["example"], "example", problems, { max: 200 });
|
|
660
757
|
const parsedVerified = verified(input["verified"], problems);
|
|
661
|
-
const tags =
|
|
662
|
-
max: 10,
|
|
663
|
-
each: (tag, at) => {
|
|
664
|
-
if (!TAG.test(tag)) {
|
|
665
|
-
problems.push({ path: at, message: "must be a lowercase word" });
|
|
666
|
-
}
|
|
667
|
-
},
|
|
668
|
-
});
|
|
758
|
+
const tags = tagList(input["tags"], problems);
|
|
669
759
|
if (problems.length > 0 ||
|
|
670
760
|
typeof id !== "string" ||
|
|
671
761
|
name === undefined ||
|
|
@@ -712,6 +802,13 @@ export function describeSpecProblems(problems) {
|
|
|
712
802
|
* gives the entry back.
|
|
713
803
|
*/
|
|
714
804
|
export function providerSpecOf(id, capability) {
|
|
805
|
+
if (capability.mode === "oauth_client") {
|
|
806
|
+
const spec = oauthSpecOf(id, capability);
|
|
807
|
+
if (!spec) {
|
|
808
|
+
throw new Error(`${id} is a catalog OAuth client without a Gateway-owned flow: it has no spec`);
|
|
809
|
+
}
|
|
810
|
+
return spec;
|
|
811
|
+
}
|
|
715
812
|
return {
|
|
716
813
|
id,
|
|
717
814
|
name: capability.label,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signInProviders.d.ts","sourceRoot":"","sources":["../../src/internal/signInProviders.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"signInProviders.d.ts","sourceRoot":"","sources":["../../src/internal/signInProviders.ts"],"names":[],"mappings":"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"}
|
|
@@ -182,7 +182,7 @@ export const SIGN_IN_PROVIDERS = {
|
|
|
182
182
|
emailClaim: "the ID token's `email` (else the userinfo endpoint's), counted as verified only when `email_verified` is true",
|
|
183
183
|
setup: "setup/signin-oidc.md",
|
|
184
184
|
notes: [
|
|
185
|
-
"Cloudflare Access has its own settings (CLOUDFLARE_ACCESS_OIDC_*, `everyapp access`): use those for Access, this for Okta,
|
|
185
|
+
"Cloudflare Access has its own settings (CLOUDFLARE_ACCESS_OIDC_*, `everyapp access`): use those for Access, this for Okta, Keycloak, Auth0, Authentik, Google Workspace as an OIDC issuer and the like. For Microsoft Entra ID use the `microsoft` provider: Entra's ID tokens carry no `email_verified`, so through this entry every sign-in would be refused as unverified.",
|
|
186
186
|
"ID tokens must be signed with RS256 (every major provider's default).",
|
|
187
187
|
],
|
|
188
188
|
},
|
|
@@ -230,9 +230,16 @@ export function signInProviderState(provider, isSet) {
|
|
|
230
230
|
const set = provider.settings
|
|
231
231
|
.filter((setting) => isSet(setting.name))
|
|
232
232
|
.map((setting) => setting.name);
|
|
233
|
-
const
|
|
233
|
+
const unset = provider.settings
|
|
234
234
|
.filter((setting) => setting.required && !isSet(setting.name))
|
|
235
235
|
.map((setting) => setting.name);
|
|
236
|
-
const status =
|
|
237
|
-
|
|
236
|
+
const status = unset.length === 0 ? "on" : set.length === 0 ? "off" : "incomplete";
|
|
237
|
+
// `missing` names what a half-set provider still needs; a provider nobody
|
|
238
|
+
// started setting up isn't missing anything, it is off.
|
|
239
|
+
return {
|
|
240
|
+
id: provider.id,
|
|
241
|
+
status,
|
|
242
|
+
missing: status === "incomplete" ? unset : [],
|
|
243
|
+
set,
|
|
244
|
+
};
|
|
238
245
|
}
|