@every-app/sdk 0.3.0-rc.1 → 0.3.0-rc.11
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/LICENSE +21 -0
- package/README.md +62 -64
- package/dist/cloudflare/catalogSettings.generated.d.ts +84 -0
- package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
- package/dist/cloudflare/catalogSettings.generated.js +175 -0
- package/dist/cloudflare/index.d.ts +3 -2
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +4 -1
- package/dist/cloudflare/sentinel.d.ts +60 -2
- package/dist/cloudflare/sentinel.d.ts.map +1 -1
- package/dist/cloudflare/sentinel.js +37 -2
- package/dist/cloudflare/worker.d.ts +391 -63
- package/dist/cloudflare/worker.d.ts.map +1 -1
- package/dist/cloudflare/worker.js +394 -108
- 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/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/internal/aiDefault.d.ts +205 -0
- package/dist/internal/aiDefault.d.ts.map +1 -0
- package/dist/internal/aiDefault.js +335 -0
- package/dist/internal/aiProviders.d.ts +7 -2
- package/dist/internal/aiProviders.d.ts.map +1 -1
- package/dist/internal/aiProviders.js +19 -6
- package/dist/internal/appSettings.d.ts +82 -4
- package/dist/internal/appSettings.d.ts.map +1 -1
- package/dist/internal/appSettings.js +204 -29
- 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 +2261 -815
- package/dist/internal/capabilities.d.ts.map +1 -1
- package/dist/internal/capabilities.js +122 -1034
- package/dist/internal/catalog/commerce.d.ts +394 -0
- package/dist/internal/catalog/commerce.d.ts.map +1 -0
- package/dist/internal/catalog/commerce.js +477 -0
- package/dist/internal/catalog/comms.d.ts +375 -0
- package/dist/internal/catalog/comms.d.ts.map +1 -0
- package/dist/internal/catalog/comms.js +520 -0
- package/dist/internal/catalog/index.d.ts +2008 -0
- package/dist/internal/catalog/index.d.ts.map +1 -0
- package/dist/internal/catalog/index.js +19 -0
- package/dist/internal/catalog/inference.d.ts +393 -0
- package/dist/internal/catalog/inference.d.ts.map +1 -0
- package/dist/internal/catalog/inference.js +460 -0
- package/dist/internal/catalog/infra.d.ts +458 -0
- package/dist/internal/catalog/infra.d.ts.map +1 -0
- package/dist/internal/catalog/infra.js +608 -0
- package/dist/internal/catalog/search.d.ts +400 -0
- package/dist/internal/catalog/search.d.ts.map +1 -0
- package/dist/internal/catalog/search.js +463 -0
- 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 +65 -3
- package/dist/internal/events.d.ts.map +1 -1
- package/dist/internal/events.js +110 -5
- package/dist/internal/gatewaySettings.d.ts +3 -2
- package/dist/internal/gatewaySettings.d.ts.map +1 -1
- package/dist/internal/gatewaySettings.js +12 -6
- package/dist/internal/identity.d.ts +41 -4
- package/dist/internal/identity.d.ts.map +1 -1
- package/dist/internal/identity.js +48 -10
- package/dist/internal/index.d.ts +6 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +6 -1
- package/dist/internal/members.d.ts +3 -2
- package/dist/internal/members.d.ts.map +1 -1
- package/dist/internal/oauthBuiltIns.d.ts +101 -0
- package/dist/internal/oauthBuiltIns.d.ts.map +1 -0
- package/dist/internal/oauthBuiltIns.js +122 -0
- package/dist/internal/oauthClient.d.ts +8 -50
- package/dist/internal/oauthClient.d.ts.map +1 -1
- package/dist/internal/oauthClient.js +2 -177
- package/dist/internal/oauthPresets.d.ts +32 -0
- package/dist/internal/oauthPresets.d.ts.map +1 -0
- package/dist/internal/oauthPresets.js +253 -0
- package/dist/internal/oauthScopes.d.ts +43 -100
- package/dist/internal/oauthScopes.d.ts.map +1 -1
- package/dist/internal/oauthScopes.js +83 -382
- package/dist/internal/oauthSpec.d.ts +103 -0
- package/dist/internal/oauthSpec.d.ts.map +1 -0
- package/dist/internal/oauthSpec.js +520 -0
- package/dist/internal/protocol.d.ts +97 -5
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +89 -1
- package/dist/internal/providerRegistry.d.ts +17 -6
- package/dist/internal/providerRegistry.d.ts.map +1 -1
- package/dist/internal/providerRegistry.js +71 -8
- package/dist/internal/providerSpec.d.ts +18 -7
- package/dist/internal/providerSpec.d.ts.map +1 -1
- package/dist/internal/providerSpec.js +420 -34
- package/dist/internal/remoteMcp.d.ts.map +1 -1
- package/dist/internal/remoteMcp.js +1 -5
- package/dist/internal/signInProviders.d.ts +104 -0
- package/dist/internal/signInProviders.d.ts.map +1 -0
- package/dist/internal/signInProviders.js +245 -0
- package/dist/internal/tools.d.ts +5 -4
- package/dist/internal/tools.d.ts.map +1 -1
- package/dist/internal/tools.js +4 -3
- package/dist/manifest.d.ts +267 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +30 -0
- package/dist/server/ai.d.ts +111 -0
- package/dist/server/ai.d.ts.map +1 -0
- package/dist/server/ai.js +145 -0
- package/dist/server/aiBinding.d.ts +68 -0
- package/dist/server/aiBinding.d.ts.map +1 -0
- package/dist/server/aiBinding.js +294 -0
- package/dist/server/attribution.d.ts +18 -5
- package/dist/server/attribution.d.ts.map +1 -1
- package/dist/server/attribution.js +19 -5
- package/dist/server/connectUrl.d.ts +16 -0
- package/dist/server/connectUrl.d.ts.map +1 -0
- package/dist/server/connectUrl.js +40 -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/emailBinding.d.ts +72 -0
- package/dist/server/emailBinding.d.ts.map +1 -0
- package/dist/server/emailBinding.js +124 -0
- package/dist/server/emit.d.ts +1 -1
- package/dist/server/emit.d.ts.map +1 -1
- package/dist/server/emit.js +7 -7
- package/dist/server/env.d.ts +44 -0
- package/dist/server/env.d.ts.map +1 -0
- package/dist/server/env.js +1 -0
- package/dist/server/eventsEndpoint.d.ts +48 -0
- package/dist/server/eventsEndpoint.d.ts.map +1 -0
- package/dist/server/eventsEndpoint.js +145 -0
- package/dist/server/everyApp.d.ts +40 -11
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +116 -6
- 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 +42 -18
- package/dist/server/gatewayFetch.d.ts.map +1 -1
- package/dist/server/gatewayFetch.js +138 -19
- package/dist/server/gatewayUrl.d.ts +13 -0
- package/dist/server/gatewayUrl.d.ts.map +1 -0
- package/dist/server/gatewayUrl.js +34 -0
- package/dist/server/index.d.ts +16 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +13 -3
- package/dist/server/integrationFetch.d.ts +92 -73
- package/dist/server/integrationFetch.d.ts.map +1 -1
- package/dist/server/integrationFetch.js +206 -319
- package/dist/server/listMembers.d.ts +1 -1
- package/dist/server/listMembers.d.ts.map +1 -1
- package/dist/server/listMembers.js +8 -11
- package/dist/server/refusal.d.ts +55 -0
- package/dist/server/refusal.d.ts.map +1 -0
- package/dist/server/refusal.js +193 -0
- package/dist/server/sendEmail.d.ts +1 -1
- package/dist/server/sendEmail.d.ts.map +1 -1
- package/dist/server/sendEmail.js +7 -7
- package/dist/server/tools.d.ts +7 -2
- package/dist/server/tools.d.ts.map +1 -1
- package/dist/server/tools.js +2 -1
- package/dist/server/toolsEndpoint.d.ts +3 -1
- package/dist/server/toolsEndpoint.d.ts.map +1 -1
- package/dist/server/toolsEndpoint.js +19 -7
- package/dist/server/webhooks.d.ts +56 -0
- package/dist/server/webhooks.d.ts.map +1 -0
- package/dist/server/webhooks.js +205 -0
- package/dist/tanstack-start/index.d.ts +9 -0
- package/dist/tanstack-start/index.d.ts.map +1 -0
- package/dist/tanstack-start/index.js +29 -0
- package/dist/testing/index.d.ts +93 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +156 -0
- package/package.json +35 -14
- package/dist/server/authorizeUrl.d.ts +0 -43
- package/dist/server/authorizeUrl.d.ts.map +0 -1
- package/dist/server/authorizeUrl.js +0 -110
package/dist/internal/events.js
CHANGED
|
@@ -24,29 +24,58 @@ export const EVENT_TYPES = [
|
|
|
24
24
|
entry("member", "member.reactivated", "A member was reactivated"),
|
|
25
25
|
entry("member", "member.removed", "A member was removed"),
|
|
26
26
|
entry("member", "member.password_reset", "A member reset their password"),
|
|
27
|
+
entry("member", "member.invitation_cancelled", "A pending invitation was cancelled"),
|
|
28
|
+
entry("organization", "organization.renamed", "The workspace was renamed"),
|
|
29
|
+
entry("organization", "organization.linked_dev_changed", "Linked dev (everyapp dev against this Gateway) was turned on or off"),
|
|
27
30
|
entry("app", "app.installed", "An app was installed on the Gateway"),
|
|
28
31
|
entry("app", "app.updated", "An app was redeployed"),
|
|
32
|
+
entry("app", "app.live", "An app went live on the Gateway"),
|
|
29
33
|
entry("app", "app.removed", "An app was removed from the Gateway"),
|
|
30
34
|
entry("app", "app.needs_setup", "An app needs a setting before it opens"),
|
|
31
35
|
entry("app", "app.ready", "An app has every setting it needs"),
|
|
32
36
|
entry("app", "app.paused_cap", "An app is paused: its monthly cap is reached"),
|
|
33
37
|
entry("app", "app.tools_changed", "An app's AI tools changed"),
|
|
38
|
+
entry("app", "app.renamed", "An app's name or description changed"),
|
|
39
|
+
entry("app", "app.settings_changed", "An app's settings were set or unset (names only)"),
|
|
40
|
+
entry("app", "app.access_changed", "Who can open an app changed"),
|
|
41
|
+
entry("app", "app.email_changed", "An app's email senders or inbound changed"),
|
|
34
42
|
entry("cap", "cap.warning", "An app is at 80% of its monthly cap"),
|
|
35
43
|
entry("cap", "cap.reached", "An app reached its monthly cap"),
|
|
36
44
|
entry("cap", "cap.raised", "An app's monthly cap, or the workspace default, was raised or removed"),
|
|
45
|
+
entry("cap", "cap.changed", "An app's monthly cap, or the workspace default, was set or lowered"),
|
|
46
|
+
entry("group", "group.created", "A group was created"),
|
|
47
|
+
entry("group", "group.updated", "A group was renamed or described"),
|
|
48
|
+
entry("group", "group.removed", "A group was removed"),
|
|
49
|
+
entry("group", "group.members_changed", "A group's members changed"),
|
|
50
|
+
entry("group", "group.apps_changed", "The apps a group opens changed"),
|
|
37
51
|
entry("tool", "tool.blocked", "An AI client's tool call was blocked"),
|
|
38
52
|
entry("tool", "tool.error", "An AI client's tool call failed"),
|
|
39
53
|
entry("connection", "connection.created", "An AI app was connected"),
|
|
40
54
|
entry("connection", "connection.revoked", "An AI app connection was revoked"),
|
|
55
|
+
entry("connection", "connection.used", "Linked dev used the Gateway's services, or an app used a member's OAuth connection (first call of the day)"),
|
|
41
56
|
entry("token", "token.created", "A personal access token was created"),
|
|
42
57
|
entry("token", "token.revoked", "A personal access token was revoked"),
|
|
43
58
|
entry("access", "access.changed", "Cloudflare Access was turned on or off"),
|
|
59
|
+
entry("signin_provider", "signin_provider.added", "A sign-in provider (Continue with Google, …) was turned on"),
|
|
60
|
+
entry("signin_provider", "signin_provider.removed", "A sign-in provider was turned off"),
|
|
44
61
|
entry("mcp_app", "mcp_app.added", "An MCP app was added"),
|
|
45
62
|
entry("mcp_app", "mcp_app.removed", "An MCP app was removed"),
|
|
46
63
|
entry("mcp_app", "mcp_app.enabled", "An MCP app is being served again"),
|
|
47
64
|
entry("mcp_app", "mcp_app.disabled", "An MCP app stopped being served"),
|
|
48
|
-
entry("
|
|
49
|
-
entry("
|
|
65
|
+
entry("mcp_app", "mcp_app.updated", "An MCP app's risk default, name or description changed"),
|
|
66
|
+
entry("mcp_app", "mcp_app.tool_changed", "One tool of an MCP app was overridden: its risk, or on/off"),
|
|
67
|
+
entry("provider", "provider.added", "A provider was registered"),
|
|
68
|
+
entry("provider", "provider.removed", "A provider was removed"),
|
|
69
|
+
entry("provider", "provider.updated", "A provider's spec or OAuth client was replaced"),
|
|
70
|
+
entry("provider", "provider.connected", "Someone connected an account at an OAuth provider in an app"),
|
|
71
|
+
entry("provider", "provider.disconnected", "An OAuth provider account was disconnected"),
|
|
72
|
+
entry("provider", "provider.connection_expired", "An OAuth provider refused to refresh a connection; it needs reconnecting"),
|
|
73
|
+
entry("subscription", "subscription.created", "An event subscription was added"),
|
|
74
|
+
entry("subscription", "subscription.updated", "An event subscription was changed, paused or resumed"),
|
|
75
|
+
entry("subscription", "subscription.removed", "An event subscription was removed"),
|
|
76
|
+
entry("subscription", "subscription.redelivered", "A delivery was queued again by hand"),
|
|
77
|
+
entry("ai", "ai.default_changed", "The default model provider changed"),
|
|
78
|
+
entry("ai", "ai.model_changed", "A provider's default model changed"),
|
|
50
79
|
entry("ping", "ping", "A test event, sent to one subscription on request"),
|
|
51
80
|
];
|
|
52
81
|
const typesByName = new Map(EVENT_TYPES.map((info) => [info.type, info]));
|
|
@@ -99,8 +128,19 @@ export const EVENT_SUBSCRIPTIONS_MAX = 25;
|
|
|
99
128
|
/** A webhook signing secret's length. */
|
|
100
129
|
export const EVENT_SECRET_MIN_LENGTH = 16;
|
|
101
130
|
export const EVENT_SECRET_MAX_LENGTH = 128;
|
|
102
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Deliveries (the queue and its log) are kept this long. Events themselves
|
|
133
|
+
* are the audit log and live longer ({@link AUDIT_RETENTION_DAYS}).
|
|
134
|
+
*/
|
|
103
135
|
export const EVENT_RETENTION_DAYS = 30;
|
|
136
|
+
/**
|
|
137
|
+
* Events are kept this long: Admin → Activity → Audit, `everyapp workspace
|
|
138
|
+
* audit` and `everyapp_workspace_audit` read them back. A constant, not a
|
|
139
|
+
* setting.
|
|
140
|
+
*/
|
|
141
|
+
export const AUDIT_RETENTION_DAYS = 90;
|
|
142
|
+
/** The most audit rows one page carries, on every surface. */
|
|
143
|
+
export const AUDIT_PAGE_MAX = 200;
|
|
104
144
|
/** A subscription's URL. */
|
|
105
145
|
export const EVENT_URL_MAX_LENGTH = 2048;
|
|
106
146
|
/** A subscription's name. */
|
|
@@ -163,17 +203,82 @@ export function isPrivateEventTargetName(host) {
|
|
|
163
203
|
return EVENT_PRIVATE_NAME_SUFFIXES.some((suffix) => host === suffix || host.endsWith(`.${suffix}`));
|
|
164
204
|
}
|
|
165
205
|
/** The sinks a subscription delivers to. */
|
|
166
|
-
export const EVENT_SINKS = ["webhook", "email"];
|
|
206
|
+
export const EVENT_SINKS = ["webhook", "email", "app"];
|
|
167
207
|
/** Whom the email sink mails: the organization's owners, or owners and admins. */
|
|
168
208
|
export const EVENT_EMAIL_RECIPIENTS = ["owners", "admins"];
|
|
209
|
+
/**
|
|
210
|
+
* The `app` sink (docs/design/2026-11-birds-decisions/app-event-sink.md):
|
|
211
|
+
* an app declares `events: { subscribe, why }` in its manifest, the deploy
|
|
212
|
+
* makes the subscription for the app's own organization, and the Gateway
|
|
213
|
+
* delivers over the app's service binding to {@link APP_EVENTS_PATH} with a
|
|
214
|
+
* system token of purpose `events.deliver`.
|
|
215
|
+
*
|
|
216
|
+
* Which events may reach an app is an **allowlist** of families, not a
|
|
217
|
+
* deny-list: a family added to the catalogue later reaches no app until it
|
|
218
|
+
* is added here on purpose. `token.*`, `subscription.*`, `provider.*`,
|
|
219
|
+
* `signin_provider.*`, `cap.*`, `ai.*`, `access.*` and `organization.*` are
|
|
220
|
+
* not on it, and `member.password_reset` is left out of `member.*`.
|
|
221
|
+
*/
|
|
222
|
+
export const APP_EVENTS_PATH = "/__everyapp/events";
|
|
223
|
+
export const APP_SINK_EVENT_FAMILIES = [
|
|
224
|
+
"member",
|
|
225
|
+
"group",
|
|
226
|
+
"app",
|
|
227
|
+
"mcp_app",
|
|
228
|
+
"connection",
|
|
229
|
+
"tool",
|
|
230
|
+
];
|
|
231
|
+
/** Types of an allowed family that still never reach an app. */
|
|
232
|
+
export const APP_SINK_EXCLUDED_TYPES = [
|
|
233
|
+
"member.password_reset",
|
|
234
|
+
];
|
|
235
|
+
/** The most patterns one app's `events.subscribe` may list. */
|
|
236
|
+
export const APP_SINK_PATTERNS_MAX = 25;
|
|
237
|
+
/** The family a type or pattern belongs to: its first segment. */
|
|
238
|
+
function familyOf(typeOrPattern) {
|
|
239
|
+
const dot = typeOrPattern.indexOf(".");
|
|
240
|
+
return dot === -1 ? typeOrPattern : typeOrPattern.slice(0, dot);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Whether an event of this type may be delivered to an app at all: its
|
|
244
|
+
* family is on the allowlist and the type isn't excluded. Checked when the
|
|
245
|
+
* bus queues a delivery and again before each attempt, whatever the
|
|
246
|
+
* subscription's stored patterns say.
|
|
247
|
+
*/
|
|
248
|
+
export function appSinkTypeAllowed(type) {
|
|
249
|
+
if (APP_SINK_EXCLUDED_TYPES.includes(type))
|
|
250
|
+
return false;
|
|
251
|
+
return APP_SINK_EVENT_FAMILIES.includes(familyOf(type));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* What is wrong with a pattern an app's manifest subscribes to, or null: a
|
|
255
|
+
* well-formed pattern ({@link eventPatternProblem}) inside an allowed
|
|
256
|
+
* family. `*` and any pattern outside the families are refused at deploy.
|
|
257
|
+
*/
|
|
258
|
+
export function appSinkPatternProblem(pattern) {
|
|
259
|
+
const problem = eventPatternProblem(pattern);
|
|
260
|
+
if (problem)
|
|
261
|
+
return problem;
|
|
262
|
+
if (APP_SINK_EXCLUDED_TYPES.includes(pattern)) {
|
|
263
|
+
return `"${pattern}" never reaches an app`;
|
|
264
|
+
}
|
|
265
|
+
if (pattern === "*" ||
|
|
266
|
+
!APP_SINK_EVENT_FAMILIES.includes(familyOf(pattern))) {
|
|
267
|
+
return `"${pattern}" can't reach an app: an app subscribes to ${APP_SINK_EVENT_FAMILIES.map((family) => `${family}.*`).join(", ")} (member.password_reset excepted)`;
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
169
271
|
/**
|
|
170
272
|
* A subscription pattern: `*` (everything but ping), an exact type, or a
|
|
171
273
|
* prefix with `.*` (`member.*`, `app.*`, `app.crm.*`). `app.*` matches the
|
|
172
274
|
* gateway's app events and every app's own.
|
|
173
275
|
*/
|
|
174
276
|
export function eventPatternMatches(pattern, type) {
|
|
277
|
+
// Everything but a test ping and the bus's own housekeeping: a webhook
|
|
278
|
+
// hears about subscriptions only when it names `subscription.*`, so a
|
|
279
|
+
// catch-all's first delivery is the event it was made for, not itself.
|
|
175
280
|
if (pattern === "*")
|
|
176
|
-
return type !== "ping";
|
|
281
|
+
return type !== "ping" && !type.startsWith("subscription.");
|
|
177
282
|
if (pattern.endsWith(".*")) {
|
|
178
283
|
return type.startsWith(pattern.slice(0, -1));
|
|
179
284
|
}
|
|
@@ -24,7 +24,8 @@ export declare const GATEWAY_OWN_SETTINGS: readonly ["AI_PROXY_EXTRA_ROUTES", "E
|
|
|
24
24
|
export type SettableGatewaySetting = Exclude<CapabilitySecret, (typeof INSTALL_OWNED_GATEWAY_SETTINGS)[number]> | (typeof GATEWAY_OWN_SETTINGS)[number];
|
|
25
25
|
/**
|
|
26
26
|
* The Gateway's optional settings `everyapp secret set` changes: every
|
|
27
|
-
* setting a catalog provider reads,
|
|
27
|
+
* setting a catalog provider reads, the Gateway's own, then the sign-in
|
|
28
|
+
* providers' (`<ID>_SIGNIN_<FIELD>`, ./signInProviders.ts).
|
|
28
29
|
*/
|
|
29
30
|
export declare const SETTABLE_GATEWAY_SETTINGS: readonly SettableGatewaySetting[];
|
|
30
31
|
/**
|
|
@@ -51,7 +52,7 @@ export declare function isSettableGatewaySetting(name: string): boolean;
|
|
|
51
52
|
* are typed and check their shape; anything else is a credential and
|
|
52
53
|
* stays hidden.
|
|
53
54
|
*/
|
|
54
|
-
export declare const PLAIN_GATEWAY_SETTINGS: readonly ["EMAIL_FROM", "EMAIL_FROM_NAME", "EMAIL_PROVIDER", "EMAIL_PASSWORD_SIGN_IN", "
|
|
55
|
+
export declare const PLAIN_GATEWAY_SETTINGS: readonly ["EMAIL_FROM", "EMAIL_FROM_NAME", "EMAIL_PROVIDER", "EMAIL_PASSWORD_SIGN_IN", "AI_PROXY_EXTRA_ROUTES", "MCP_OAUTH_ENABLED", "MCP_DCR_ENABLED", "MCP_ALLOWED_ORIGINS", "MCP_AUDIT_RETENTION_DAYS", "CLOUDFLARE_ACCESS_OIDC_ISSUER", "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID", "CLOUDFLARE_ACCESS_OIDC_LABEL", "CLOUDFLARE_ACCESS_TEAM_DOMAIN", "CLOUDFLARE_ACCESS_AUD", "CLOUDFLARE_ACCESS_APPS_AUD", "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS", "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN", "HOSTED_OPEN_SIGNUP", "BROWSER_APP_INSTALLS", "DISPATCH_NAMESPACE", "THIRD_PARTY_DOMAIN", "EVENTS_ALLOW_PRIVATE_TARGETS"];
|
|
55
56
|
/** Whether a settable Gateway setting's value is a plain value, not a credential. */
|
|
56
57
|
export declare function isPlainGatewaySetting(name: string): boolean;
|
|
57
58
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gatewaySettings.d.ts","sourceRoot":"","sources":["../../src/internal/gatewaySettings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"gatewaySettings.d.ts","sourceRoot":"","sources":["../../src/internal/gatewaySettings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAM3B;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,mLASjC,CAAC;AAMX,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElE;AAmBD,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,yrBAkCvB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,EAAE,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC,GAC1E,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,sBAAsB,EAItE,CAAC;AAIF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAgC,CAAC;AAEvE,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,olBAuBmB,CAAC;AASvD,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,6EAIa,CAAC;AAIvD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,iGAAiG;AACjG,eAAO,MAAM,yBAAyB,yDAI5B,CAAC;AAEX,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAmBD,iDAAiD;AACjD,eAAO,MAAM,8BAA8B,sFAC0C,CAAC;AAEtF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAQ5E"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* declaring every settable one.
|
|
12
12
|
*/
|
|
13
13
|
import { CAPABILITIES, CAPABILITY_IDS, capabilitySettings, } from "./capabilities.js";
|
|
14
|
+
import { PLAIN_SIGN_IN_SETTINGS, SIGN_IN_GATEWAY_SETTINGS, } from "./signInProviders.js";
|
|
14
15
|
/**
|
|
15
16
|
* The Gateway's own settings: the install writes them once (`everyapp
|
|
16
17
|
* setup`), or an operator by hand (THIRD_PARTY_DEPLOYS), and `everyapp
|
|
@@ -33,8 +34,7 @@ export function isInstallOwnedGatewaySetting(name) {
|
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
36
|
* The settings the catalog's providers read (the AI providers' keys, the
|
|
36
|
-
* API-key providers' keys, the OAuth clients
|
|
37
|
-
* URL), in catalog order, the install's own left out: what `everyapp
|
|
37
|
+
* API-key providers' keys and hosts, the OAuth clients), in catalog order, the install's own left out: what `everyapp
|
|
38
38
|
* secret set` accepts because a provider reads it. A gateway's registered
|
|
39
39
|
* rows add theirs at run time (providerRegistry.settingNames()).
|
|
40
40
|
*/
|
|
@@ -75,7 +75,7 @@ export const GATEWAY_OWN_SETTINGS = [
|
|
|
75
75
|
// gate, THIRD_PARTY_DEPLOYS, is never set from here: it is opened by
|
|
76
76
|
// hand once the launch checks pass (docs/runbooks/hosted-install.md).
|
|
77
77
|
"CF_DEPLOY_TOKEN",
|
|
78
|
-
// Self-hosted
|
|
78
|
+
// Self-hosted Gateway app installs: off unless exactly "on" (everyapp deploy-token add).
|
|
79
79
|
"BROWSER_APP_INSTALLS",
|
|
80
80
|
"DISPATCH_NAMESPACE",
|
|
81
81
|
"THIRD_PARTY_DOMAIN",
|
|
@@ -84,11 +84,13 @@ export const GATEWAY_OWN_SETTINGS = [
|
|
|
84
84
|
];
|
|
85
85
|
/**
|
|
86
86
|
* The Gateway's optional settings `everyapp secret set` changes: every
|
|
87
|
-
* setting a catalog provider reads,
|
|
87
|
+
* setting a catalog provider reads, the Gateway's own, then the sign-in
|
|
88
|
+
* providers' (`<ID>_SIGNIN_<FIELD>`, ./signInProviders.ts).
|
|
88
89
|
*/
|
|
89
90
|
export const SETTABLE_GATEWAY_SETTINGS = [
|
|
90
91
|
...PROVIDER_GATEWAY_SETTINGS,
|
|
91
92
|
...GATEWAY_OWN_SETTINGS,
|
|
93
|
+
...SIGN_IN_GATEWAY_SETTINGS,
|
|
92
94
|
];
|
|
93
95
|
const SETTABLE = new Set(SETTABLE_GATEWAY_SETTINGS);
|
|
94
96
|
/**
|
|
@@ -124,7 +126,6 @@ export const PLAIN_GATEWAY_SETTINGS = [
|
|
|
124
126
|
"EMAIL_FROM_NAME",
|
|
125
127
|
"EMAIL_PROVIDER",
|
|
126
128
|
"EMAIL_PASSWORD_SIGN_IN",
|
|
127
|
-
"MASTODON_URL",
|
|
128
129
|
"AI_PROXY_EXTRA_ROUTES",
|
|
129
130
|
"MCP_OAUTH_ENABLED",
|
|
130
131
|
"MCP_DCR_ENABLED",
|
|
@@ -144,7 +145,12 @@ export const PLAIN_GATEWAY_SETTINGS = [
|
|
|
144
145
|
"THIRD_PARTY_DOMAIN",
|
|
145
146
|
"EVENTS_ALLOW_PRIVATE_TARGETS",
|
|
146
147
|
];
|
|
147
|
-
const PLAIN = new Set(
|
|
148
|
+
const PLAIN = new Set([
|
|
149
|
+
...PLAIN_GATEWAY_SETTINGS,
|
|
150
|
+
// The sign-in providers' ids, issuer, label and tenant; their client
|
|
151
|
+
// secrets are credentials.
|
|
152
|
+
...PLAIN_SIGN_IN_SETTINGS,
|
|
153
|
+
]);
|
|
148
154
|
/** Whether a settable Gateway setting's value is a plain value, not a credential. */
|
|
149
155
|
export function isPlainGatewaySetting(name) {
|
|
150
156
|
return PLAIN.has(name);
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, type SystemClaims, type SystemTokenPurpose } from "./protocol.js";
|
|
2
|
-
export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, };
|
|
1
|
+
import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, type SystemClaims, type SystemTokenPurpose } from "./protocol.js";
|
|
2
|
+
export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, };
|
|
3
3
|
export declare class IdentityError extends Error {
|
|
4
4
|
readonly status = 401;
|
|
5
5
|
constructor(message: string);
|
|
6
6
|
}
|
|
7
7
|
export declare class ConfigurationError extends Error {
|
|
8
8
|
readonly status = 500;
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* The Gateway refusal code the same gap gets once deployed
|
|
11
|
+
* (`ai_provider_not_configured`, `ai_default_not_configured`), when the
|
|
12
|
+
* error is "not set up" rather than a mistake in the code.
|
|
13
|
+
*/
|
|
14
|
+
readonly code: string | undefined;
|
|
15
|
+
/** The settings that would close the gap (`.dev.vars` names in local dev). */
|
|
16
|
+
readonly settings: readonly string[];
|
|
17
|
+
constructor(message: string, setup?: {
|
|
18
|
+
code: string;
|
|
19
|
+
settings?: readonly string[];
|
|
20
|
+
});
|
|
10
21
|
}
|
|
11
22
|
/**
|
|
12
23
|
* Parse the public key set from an env var value. Accepts a JSON array of PEM
|
|
@@ -35,6 +46,25 @@ export interface VerifyOptions {
|
|
|
35
46
|
* claims).
|
|
36
47
|
*/
|
|
37
48
|
export declare function verifyIdentityJwt(token: string, options: VerifyOptions): Promise<EveryAppUser>;
|
|
49
|
+
/** A verified identity, with when it stops being one. */
|
|
50
|
+
export interface VerifiedIdentity {
|
|
51
|
+
user: EveryAppUser;
|
|
52
|
+
/** The token's `exp`, in epoch milliseconds. */
|
|
53
|
+
expiresAt: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* {@link verifyIdentityJwt}, keeping the token's expiry: the SDK's request
|
|
57
|
+
* context stops forwarding an identity shortly before it, and goes on as
|
|
58
|
+
* the organization's background work.
|
|
59
|
+
*/
|
|
60
|
+
export declare function verifyIdentity(token: string, options: VerifyOptions): Promise<VerifiedIdentity>;
|
|
61
|
+
/**
|
|
62
|
+
* The organization pin: a deployed Worker serves one organization
|
|
63
|
+
* (`EVERY_APP_ORG_ID`), and an identity for any other is refused, whatever
|
|
64
|
+
* its audience says. Throws {@link IdentityError} on a mismatch; a Worker
|
|
65
|
+
* with no pin (a shared app's) accepts every organization.
|
|
66
|
+
*/
|
|
67
|
+
export declare function assertOrganizationPin(user: EveryAppUser, organizationId: string | undefined): void;
|
|
38
68
|
/**
|
|
39
69
|
* Verify the gateway's system token (the value of `x-everyapp-system`)
|
|
40
70
|
* fail-closed, for exactly one purpose. A user identity or public marker is
|
|
@@ -56,9 +86,16 @@ export interface IdentityResult {
|
|
|
56
86
|
user: EveryAppUser | null;
|
|
57
87
|
/** True when the gateway marked this request as a public route. */
|
|
58
88
|
isPublic: boolean;
|
|
89
|
+
/** When the identity expires (epoch ms); null on a public route. */
|
|
90
|
+
expiresAt: number | null;
|
|
59
91
|
}
|
|
60
92
|
export interface RequestIdentityOptions {
|
|
61
93
|
audience: string;
|
|
94
|
+
/**
|
|
95
|
+
* The organization this Worker is pinned to ({@link ORG_ID_ENV}): an
|
|
96
|
+
* identity for another is refused. Undefined accepts every organization.
|
|
97
|
+
*/
|
|
98
|
+
organizationId?: string;
|
|
62
99
|
/** Provide keys directly, or let {@link getIdentityFromRequest} read env. */
|
|
63
100
|
publicKeys?: string[];
|
|
64
101
|
/** Env bag to read {@link PUBLIC_KEYS_ENV} / {@link DEV_ENV} from. */
|
|
@@ -84,5 +121,5 @@ export declare function resolveVerifyOptions(options: RequestIdentityOptions): V
|
|
|
84
121
|
* problem — including a bare/forged public header — so a re-exposed worker
|
|
85
122
|
* fails closed.
|
|
86
123
|
*/
|
|
87
|
-
export declare function getIdentityFromRequest(request: Request, options: RequestIdentityOptions): Promise<IdentityResult>;
|
|
124
|
+
export declare function getIdentityFromRequest(request: Request | Headers, options: RequestIdentityOptions): Promise<IdentityResult>;
|
|
88
125
|
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/internal/identity.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,UAAU,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EAKjB,KAAK,YAAY,EACjB,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,OAAO;
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/internal/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* survives verification produces a user.
|
|
10
10
|
*/
|
|
11
11
|
import { importSPKI, jwtVerify, decodeProtectedHeader, } from "jose";
|
|
12
|
-
import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, assertPublicMarkerClaims, assertSystemClaims, identityClaimsToEveryAppUser, ProtocolClaimsError, } from "./protocol.js";
|
|
13
|
-
export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, };
|
|
12
|
+
import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, assertPublicMarkerClaims, assertSystemClaims, identityClaimsToEveryAppUser, ProtocolClaimsError, } from "./protocol.js";
|
|
13
|
+
export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, };
|
|
14
14
|
export class IdentityError extends Error {
|
|
15
15
|
status = 401;
|
|
16
16
|
constructor(message) {
|
|
@@ -20,9 +20,19 @@ export class IdentityError extends Error {
|
|
|
20
20
|
}
|
|
21
21
|
export class ConfigurationError extends Error {
|
|
22
22
|
status = 500;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* The Gateway refusal code the same gap gets once deployed
|
|
25
|
+
* (`ai_provider_not_configured`, `ai_default_not_configured`), when the
|
|
26
|
+
* error is "not set up" rather than a mistake in the code.
|
|
27
|
+
*/
|
|
28
|
+
code;
|
|
29
|
+
/** The settings that would close the gap (`.dev.vars` names in local dev). */
|
|
30
|
+
settings;
|
|
31
|
+
constructor(message, setup) {
|
|
24
32
|
super(message);
|
|
25
33
|
this.name = "ConfigurationError";
|
|
34
|
+
this.code = setup?.code;
|
|
35
|
+
this.settings = setup?.settings ?? [];
|
|
26
36
|
}
|
|
27
37
|
}
|
|
28
38
|
/**
|
|
@@ -81,9 +91,19 @@ function assertDevIssuer(options) {
|
|
|
81
91
|
* claims).
|
|
82
92
|
*/
|
|
83
93
|
export async function verifyIdentityJwt(token, options) {
|
|
94
|
+
return (await verifyIdentity(token, options)).user;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* {@link verifyIdentityJwt}, keeping the token's expiry: the SDK's request
|
|
98
|
+
* context stops forwarding an identity shortly before it, and goes on as
|
|
99
|
+
* the organization's background work.
|
|
100
|
+
*/
|
|
101
|
+
export async function verifyIdentity(token, options) {
|
|
84
102
|
const payload = await verifyPinnedJwt(token, options, "user");
|
|
85
103
|
try {
|
|
86
|
-
|
|
104
|
+
const user = identityClaimsToEveryAppUser(payload);
|
|
105
|
+
// `exp` is a required claim (verifyPinnedJwt); jose checked it.
|
|
106
|
+
return { user, expiresAt: payload.exp * 1000 };
|
|
87
107
|
}
|
|
88
108
|
catch (error) {
|
|
89
109
|
if (error instanceof ProtocolClaimsError) {
|
|
@@ -92,6 +112,17 @@ export async function verifyIdentityJwt(token, options) {
|
|
|
92
112
|
throw error;
|
|
93
113
|
}
|
|
94
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The organization pin: a deployed Worker serves one organization
|
|
117
|
+
* (`EVERY_APP_ORG_ID`), and an identity for any other is refused, whatever
|
|
118
|
+
* its audience says. Throws {@link IdentityError} on a mismatch; a Worker
|
|
119
|
+
* with no pin (a shared app's) accepts every organization.
|
|
120
|
+
*/
|
|
121
|
+
export function assertOrganizationPin(user, organizationId) {
|
|
122
|
+
if (organizationId && user.orgId !== organizationId) {
|
|
123
|
+
throw new IdentityError(`identity is for organization "${user.orgId}", and this Worker serves organization "${organizationId}" (${ORG_ID_ENV})`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
95
126
|
/**
|
|
96
127
|
* Verify the gateway's system token (the value of `x-everyapp-system`)
|
|
97
128
|
* fail-closed, for exactly one purpose. A user identity or public marker is
|
|
@@ -137,7 +168,7 @@ async function verifyPinnedJwt(token, options, expectedTyp) {
|
|
|
137
168
|
throw new IdentityError(`unexpected kid "${header.kid}"`);
|
|
138
169
|
}
|
|
139
170
|
if (expectedTyp !== "public" && !options.issuer) {
|
|
140
|
-
throw new IdentityError(`${ISSUER_ENV} not configured — deploy with the
|
|
171
|
+
throw new IdentityError(`${ISSUER_ENV} not configured — deploy with the EveryApp CLI or provide an explicit issuer.`);
|
|
141
172
|
}
|
|
142
173
|
const verifyOpts = {
|
|
143
174
|
algorithms: [IDENTITY_ALG],
|
|
@@ -217,15 +248,22 @@ export function resolveVerifyOptions(options) {
|
|
|
217
248
|
*/
|
|
218
249
|
export async function getIdentityFromRequest(request, options) {
|
|
219
250
|
const verifyOptions = resolveVerifyOptions(options);
|
|
220
|
-
const
|
|
251
|
+
const headers = isRequestLike(request) ? request.headers : request;
|
|
252
|
+
const publicMarker = headers.get(PUBLIC_HEADER);
|
|
221
253
|
if (publicMarker) {
|
|
222
254
|
await verifyPublicMarkerJwt(publicMarker, verifyOptions);
|
|
223
|
-
return { user: null, isPublic: true };
|
|
255
|
+
return { user: null, isPublic: true, expiresAt: null };
|
|
224
256
|
}
|
|
225
|
-
const token =
|
|
257
|
+
const token = headers.get(IDENTITY_HEADER);
|
|
226
258
|
if (!token) {
|
|
227
259
|
throw new IdentityError("request reached the app without an identity token (not proxied through the gateway?)");
|
|
228
260
|
}
|
|
229
|
-
const user = await
|
|
230
|
-
|
|
261
|
+
const { user, expiresAt } = await verifyIdentity(token, verifyOptions);
|
|
262
|
+
assertOrganizationPin(user, options.organizationId);
|
|
263
|
+
return { user, isPublic: false, expiresAt };
|
|
264
|
+
}
|
|
265
|
+
// Duck-typed: a Request from another realm (a test runner, a polyfill) still
|
|
266
|
+
// carries its headers the same way.
|
|
267
|
+
function isRequestLike(value) {
|
|
268
|
+
return "headers" in value && typeof value.headers?.get === "function";
|
|
231
269
|
}
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./protocol.js";
|
|
|
2
2
|
export * from "./tools.js";
|
|
3
3
|
export * from "./capabilities.js";
|
|
4
4
|
export * from "./aiProviders.js";
|
|
5
|
+
export * from "./aiDefault.js";
|
|
5
6
|
export * from "./gatewaySettings.js";
|
|
6
7
|
export * from "./appSettings.js";
|
|
7
8
|
export * from "./email.js";
|
|
@@ -9,11 +10,15 @@ export * from "./members.js";
|
|
|
9
10
|
export * from "./organizationName.js";
|
|
10
11
|
export * from "./oauthClient.js";
|
|
11
12
|
export * from "./oauthScopes.js";
|
|
13
|
+
export * from "./oauthSpec.js";
|
|
14
|
+
export * from "./oauthPresets.js";
|
|
12
15
|
export * from "./providerApps.js";
|
|
13
16
|
export * from "./events.js";
|
|
17
|
+
export * from "./audit.js";
|
|
14
18
|
export * from "./providerSpec.js";
|
|
15
19
|
export * from "./providerRegistry.js";
|
|
16
20
|
export * from "./remoteMcp.js";
|
|
21
|
+
export * from "./signInProviders.js";
|
|
17
22
|
export * from "./devProviders.js";
|
|
18
|
-
export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, type IdentityResult, type RequestIdentityOptions, type VerifyOptions, } from "./identity.js";
|
|
23
|
+
export { ConfigurationError, IdentityError, assertOrganizationPin, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentity, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, type IdentityResult, type RequestIdentityOptions, type VerifiedIdentity, type VerifyOptions, } from "./identity.js";
|
|
19
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
|
package/dist/internal/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./protocol.js";
|
|
|
2
2
|
export * from "./tools.js";
|
|
3
3
|
export * from "./capabilities.js";
|
|
4
4
|
export * from "./aiProviders.js";
|
|
5
|
+
export * from "./aiDefault.js";
|
|
5
6
|
export * from "./gatewaySettings.js";
|
|
6
7
|
export * from "./appSettings.js";
|
|
7
8
|
export * from "./email.js";
|
|
@@ -9,10 +10,14 @@ export * from "./members.js";
|
|
|
9
10
|
export * from "./organizationName.js";
|
|
10
11
|
export * from "./oauthClient.js";
|
|
11
12
|
export * from "./oauthScopes.js";
|
|
13
|
+
export * from "./oauthSpec.js";
|
|
14
|
+
export * from "./oauthPresets.js";
|
|
12
15
|
export * from "./providerApps.js";
|
|
13
16
|
export * from "./events.js";
|
|
17
|
+
export * from "./audit.js";
|
|
14
18
|
export * from "./providerSpec.js";
|
|
15
19
|
export * from "./providerRegistry.js";
|
|
16
20
|
export * from "./remoteMcp.js";
|
|
21
|
+
export * from "./signInProviders.js";
|
|
17
22
|
export * from "./devProviders.js";
|
|
18
|
-
export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, } from "./identity.js";
|
|
23
|
+
export { ConfigurationError, IdentityError, assertOrganizationPin, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentity, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, } from "./identity.js";
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* gateway builds it, the SDK's `listMembers()` returns it, and its local-dev
|
|
5
5
|
* fallback answers in the same shape. Types only.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import type { OrgRole } from "./protocol.js";
|
|
8
|
+
/** A member's role in the organization: the identity token's {@link OrgRole}. */
|
|
9
|
+
export type OrganizationMemberRole = OrgRole;
|
|
9
10
|
/**
|
|
10
11
|
* One member of the organization who can open the app: not deactivated,
|
|
11
12
|
* and, for an organization's own app, granted it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../src/internal/members.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,
|
|
1
|
+
{"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../src/internal/members.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,iFAAiF;AACjF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,sBAAsB,CAAC;CAC9B;AAED,2BAA2B;AAC3B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,SAAS,CAAC;IACtB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,UAAU,EAAE,IAAI,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OAuth providers every Gateway has built in, as `oauth2-user` specs:
|
|
3
|
+
* the same JSON shape as the presets (./oauthPresets.ts) and a registered
|
|
4
|
+
* row (`everyapp provider add`). What differs between Google, Microsoft
|
|
5
|
+
* and Slack is here as data: the endpoints, the API hosts, how scopes are
|
|
6
|
+
* separated and prefixed, the extra authorize parameters, how the account
|
|
7
|
+
* is named, and the scopes a token may carry beyond what the app asked.
|
|
8
|
+
* No code anywhere reads a provider id to decide anything.
|
|
9
|
+
*
|
|
10
|
+
* Pure data with no imports, so the catalog (./capabilities.ts) can build
|
|
11
|
+
* its entries from it without an import cycle. Each spec parses with
|
|
12
|
+
* `parseProviderSpec` and round-trips through `oauthSpecOf`
|
|
13
|
+
* (oauthBuiltIns.test.ts).
|
|
14
|
+
*/
|
|
15
|
+
export declare const BUILT_IN_OAUTH_SPECS: {
|
|
16
|
+
readonly "google-workspace": {
|
|
17
|
+
readonly id: "google-workspace";
|
|
18
|
+
readonly name: "Google";
|
|
19
|
+
readonly description: "Gmail, Calendar, Drive, Search Console, Analytics and the other Google APIs, as the person who connects.";
|
|
20
|
+
readonly docs: "https://console.cloud.google.com/apis/credentials";
|
|
21
|
+
readonly api: "https://developers.google.com/identity/protocols/oauth2/scopes";
|
|
22
|
+
readonly hosts: readonly ["gmail.googleapis.com", "www.googleapis.com", "searchconsole.googleapis.com", "analyticsdata.googleapis.com", "analyticsadmin.googleapis.com", "openidconnect.googleapis.com"];
|
|
23
|
+
readonly auth: {
|
|
24
|
+
readonly kind: "oauth2-user";
|
|
25
|
+
readonly authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth";
|
|
26
|
+
readonly tokenUrl: "https://oauth2.googleapis.com/token";
|
|
27
|
+
readonly clientId: "GOOGLE_WORKSPACE_CLIENT_ID";
|
|
28
|
+
readonly clientSecret: "GOOGLE_WORKSPACE_CLIENT_SECRET";
|
|
29
|
+
readonly inject: "form";
|
|
30
|
+
readonly pkce: true;
|
|
31
|
+
readonly scopeSeparator: "space";
|
|
32
|
+
readonly scopePrefix: "https://www.googleapis.com/auth/";
|
|
33
|
+
readonly authorizeParams: {
|
|
34
|
+
readonly access_type: "offline";
|
|
35
|
+
readonly prompt: "consent";
|
|
36
|
+
};
|
|
37
|
+
readonly identity: {
|
|
38
|
+
readonly url: "https://openidconnect.googleapis.com/v1/userinfo";
|
|
39
|
+
readonly label: "email";
|
|
40
|
+
readonly id: "sub";
|
|
41
|
+
readonly scopes: readonly ["openid", "email"];
|
|
42
|
+
};
|
|
43
|
+
readonly tolerated: readonly ["profile", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"];
|
|
44
|
+
};
|
|
45
|
+
readonly hint: "A Web application OAuth client in Google Cloud, with the Gateway's callback as its redirect URI and the scopes your apps list on its consent screen.";
|
|
46
|
+
};
|
|
47
|
+
readonly "microsoft-365": {
|
|
48
|
+
readonly id: "microsoft-365";
|
|
49
|
+
readonly name: "Microsoft 365";
|
|
50
|
+
readonly description: "Outlook mail and calendar, OneDrive and the rest of Microsoft Graph, as the person who connects.";
|
|
51
|
+
readonly docs: "https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade";
|
|
52
|
+
readonly api: "https://learn.microsoft.com/graph/permissions-reference";
|
|
53
|
+
readonly hosts: readonly ["graph.microsoft.com"];
|
|
54
|
+
readonly auth: {
|
|
55
|
+
readonly kind: "oauth2-user";
|
|
56
|
+
readonly authorizeUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
|
|
57
|
+
readonly tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token";
|
|
58
|
+
readonly clientId: "MICROSOFT_365_CLIENT_ID";
|
|
59
|
+
readonly clientSecret: "MICROSOFT_365_CLIENT_SECRET";
|
|
60
|
+
readonly inject: "form";
|
|
61
|
+
readonly pkce: true;
|
|
62
|
+
readonly scopeSeparator: "space";
|
|
63
|
+
readonly scopePrefix: "https://graph.microsoft.com/";
|
|
64
|
+
readonly identity: {
|
|
65
|
+
readonly url: "https://graph.microsoft.com/v1.0/me";
|
|
66
|
+
readonly label: "userPrincipalName";
|
|
67
|
+
readonly id: "id";
|
|
68
|
+
readonly scopes: readonly ["User.Read", "offline_access"];
|
|
69
|
+
};
|
|
70
|
+
readonly tolerated: readonly ["openid", "profile", "email"];
|
|
71
|
+
};
|
|
72
|
+
readonly hint: "An app registration in Entra for accounts in any organization and personal accounts, with the Gateway's callback as a Web redirect URI. If two apps share this client with different scopes, Microsoft may hand back both apps' scopes and the Gateway refuses the token: give each app its own client.";
|
|
73
|
+
};
|
|
74
|
+
readonly slack: {
|
|
75
|
+
readonly id: "slack";
|
|
76
|
+
readonly name: "Slack";
|
|
77
|
+
readonly description: "Channels, members and messages, as the Slack app.";
|
|
78
|
+
readonly docs: "https://api.slack.com/apps";
|
|
79
|
+
readonly api: "https://api.slack.com/scopes";
|
|
80
|
+
readonly hosts: readonly ["slack.com"];
|
|
81
|
+
readonly auth: {
|
|
82
|
+
readonly kind: "oauth2-user";
|
|
83
|
+
readonly authorizeUrl: "https://slack.com/oauth/v2/authorize";
|
|
84
|
+
readonly tokenUrl: "https://slack.com/api/oauth.v2.access";
|
|
85
|
+
readonly revokeUrl: "https://slack.com/api/auth.revoke";
|
|
86
|
+
readonly clientId: "SLACK_CLIENT_ID";
|
|
87
|
+
readonly clientSecret: "SLACK_CLIENT_SECRET";
|
|
88
|
+
readonly inject: "form";
|
|
89
|
+
readonly pkce: false;
|
|
90
|
+
readonly scopeSeparator: "comma";
|
|
91
|
+
readonly identity: {
|
|
92
|
+
readonly url: "https://slack.com/api/auth.test";
|
|
93
|
+
readonly label: "team";
|
|
94
|
+
readonly id: "team_id";
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
readonly hint: "A Slack app with the Gateway's callback as its redirect URL and the bot scopes your apps list.";
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
export type BuiltInOAuthId = keyof typeof BUILT_IN_OAUTH_SPECS;
|
|
101
|
+
//# sourceMappingURL=oauthBuiltIns.d.ts.map
|