@every-app/sdk 0.3.0-rc.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -74
- package/dist/cloudflare/catalogSettings.generated.d.ts +20 -6
- package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -1
- package/dist/cloudflare/catalogSettings.generated.js +45 -14
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/sentinel.d.ts +3 -0
- package/dist/cloudflare/sentinel.d.ts.map +1 -1
- package/dist/cloudflare/sentinel.js +10 -0
- package/dist/cloudflare/worker.d.ts +67 -23
- package/dist/cloudflare/worker.d.ts.map +1 -1
- package/dist/cloudflare/worker.js +68 -32
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/aiDefault.d.ts +36 -79
- package/dist/internal/aiDefault.d.ts.map +1 -1
- package/dist/internal/aiDefault.js +47 -149
- package/dist/internal/aiProviders.d.ts +1 -1
- package/dist/internal/aiProviders.d.ts.map +1 -1
- package/dist/internal/aiProviders.js +2 -2
- package/dist/internal/appSettings.d.ts +140 -89
- package/dist/internal/appSettings.d.ts.map +1 -1
- package/dist/internal/appSettings.js +264 -156
- package/dist/internal/capabilities.d.ts +145 -503
- package/dist/internal/capabilities.d.ts.map +1 -1
- package/dist/internal/capabilities.js +29 -550
- package/dist/internal/catalog/commerce.js +1 -1
- package/dist/internal/catalog/comms.d.ts +37 -0
- package/dist/internal/catalog/comms.d.ts.map +1 -1
- package/dist/internal/catalog/comms.js +43 -0
- package/dist/internal/catalog/index.d.ts +72 -0
- package/dist/internal/catalog/index.d.ts.map +1 -1
- package/dist/internal/catalog/infra.d.ts +35 -0
- package/dist/internal/catalog/infra.d.ts.map +1 -1
- package/dist/internal/catalog/infra.js +65 -0
- package/dist/internal/devProviders.d.ts +1 -19
- package/dist/internal/devProviders.d.ts.map +1 -1
- package/dist/internal/devProviders.js +7 -1
- package/dist/internal/events.d.ts +52 -1
- package/dist/internal/events.d.ts.map +1 -1
- package/dist/internal/events.js +66 -2
- package/dist/internal/gatewaySettings.d.ts +6 -16
- package/dist/internal/gatewaySettings.d.ts.map +1 -1
- package/dist/internal/gatewaySettings.js +6 -24
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/mcpOAuth.d.ts +210 -0
- package/dist/internal/mcpOAuth.d.ts.map +1 -0
- package/dist/internal/mcpOAuth.js +735 -0
- package/dist/internal/oauthClient.d.ts +7 -47
- package/dist/internal/oauthClient.d.ts.map +1 -1
- package/dist/internal/oauthClient.js +1 -115
- package/dist/internal/oauthPresets.d.ts +356 -20
- package/dist/internal/oauthPresets.d.ts.map +1 -1
- package/dist/internal/oauthPresets.js +183 -861
- package/dist/internal/oauthScopes.d.ts +43 -155
- package/dist/internal/oauthScopes.d.ts.map +1 -1
- package/dist/internal/oauthScopes.js +82 -475
- package/dist/internal/oauthSpec.d.ts +28 -71
- package/dist/internal/oauthSpec.d.ts.map +1 -1
- package/dist/internal/oauthSpec.js +172 -448
- package/dist/internal/protocol.d.ts +39 -15
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +40 -7
- package/dist/internal/providerApps.d.ts +2 -2
- package/dist/internal/providerApps.js +2 -2
- package/dist/internal/providerRegistry.d.ts +5 -64
- package/dist/internal/providerRegistry.d.ts.map +1 -1
- package/dist/internal/providerRegistry.js +19 -118
- package/dist/internal/providerSpec.d.ts.map +1 -1
- package/dist/internal/providerSpec.js +14 -36
- package/dist/internal/remoteMcp.d.ts +191 -47
- package/dist/internal/remoteMcp.d.ts.map +1 -1
- package/dist/internal/remoteMcp.js +338 -133
- package/dist/internal/signInProviders.d.ts +1 -1
- package/dist/internal/signInProviders.d.ts.map +1 -1
- package/dist/internal/tools.d.ts +15 -8
- package/dist/internal/tools.d.ts.map +1 -1
- package/dist/internal/tools.js +9 -8
- package/dist/manifest.d.ts +96 -28
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +1 -1
- package/dist/server/ai.d.ts +1 -93
- package/dist/server/ai.d.ts.map +1 -1
- package/dist/server/ai.js +17 -111
- package/dist/server/attribution.d.ts +10 -1
- package/dist/server/attribution.d.ts.map +1 -1
- package/dist/server/attribution.js +7 -1
- package/dist/server/connectUrl.d.ts +4 -9
- package/dist/server/connectUrl.d.ts.map +1 -1
- package/dist/server/connectUrl.js +17 -14
- package/dist/server/context.d.ts +12 -14
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +23 -25
- package/dist/server/emit.d.ts.map +1 -1
- package/dist/server/emit.js +2 -2
- package/dist/server/env.d.ts +3 -0
- package/dist/server/env.d.ts.map +1 -1
- 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 +16 -26
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +22 -46
- package/dist/server/gatewayFetch.d.ts +19 -1
- package/dist/server/gatewayFetch.d.ts.map +1 -1
- package/dist/server/gatewayFetch.js +45 -3
- package/dist/server/index.d.ts +6 -9
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -8
- package/dist/server/integrationFetch.d.ts +60 -72
- package/dist/server/integrationFetch.d.ts.map +1 -1
- package/dist/server/integrationFetch.js +124 -397
- package/dist/server/listMembers.d.ts.map +1 -1
- package/dist/server/listMembers.js +2 -2
- package/dist/server/refusal.d.ts +0 -9
- package/dist/server/refusal.d.ts.map +1 -1
- package/dist/server/refusal.js +0 -22
- package/dist/server/sendEmail.d.ts.map +1 -1
- package/dist/server/sendEmail.js +2 -2
- package/dist/server/tools.d.ts +17 -6
- package/dist/server/tools.d.ts.map +1 -1
- package/dist/server/tools.js +14 -4
- package/dist/server/toolsEndpoint.d.ts +2 -1
- package/dist/server/toolsEndpoint.d.ts.map +1 -1
- package/dist/server/toolsEndpoint.js +4 -3
- 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/testing/index.d.ts +2 -3
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -6
- package/package.json +6 -1
- package/dist/server/aiBinding.d.ts +0 -68
- package/dist/server/aiBinding.d.ts.map +0 -1
- package/dist/server/aiBinding.js +0 -294
- package/dist/server/authorizeUrl.d.ts +0 -43
- package/dist/server/authorizeUrl.d.ts.map +0 -1
- package/dist/server/authorizeUrl.js +0 -106
- package/dist/server/emailBinding.d.ts +0 -72
- package/dist/server/emailBinding.d.ts.map +0 -1
- package/dist/server/emailBinding.js +0 -124
- package/dist/server/fromMcpTools.d.ts +0 -89
- package/dist/server/fromMcpTools.d.ts.map +0 -1
- package/dist/server/fromMcpTools.js +0 -192
|
@@ -16,18 +16,15 @@
|
|
|
16
16
|
* proxy's rules: inference routes only, the model allowlist, the usage
|
|
17
17
|
* tap. Never a capability: its key would reach the account's credits
|
|
18
18
|
* and keys on the same host.
|
|
19
|
-
* - `oauth_client`:
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* the
|
|
25
|
-
*
|
|
26
|
-
* (./
|
|
27
|
-
*
|
|
28
|
-
* lists in its manifest entry's `scopes`, which ./oauthScopes.ts turns
|
|
29
|
-
* into what the app may ask the provider for and what a token it is
|
|
30
|
-
* handed may carry.
|
|
19
|
+
* - `oauth_client`: an OAuth provider whose client the gateway holds and
|
|
20
|
+
* whose flow it runs. None is in the catalog: each is a registered row,
|
|
21
|
+
* written from a preset (./oauthPresets.ts: Google, Microsoft, Slack,
|
|
22
|
+
* GitHub and the rest) or an operator's spec. A person connects in an app,
|
|
23
|
+
* for exactly the provider scopes the app's manifest entry lists
|
|
24
|
+
* (`scopes`); the gateway keeps the tokens and puts the person's token
|
|
25
|
+
* on the app's calls to the provider's `api` hosts. Each provider is a
|
|
26
|
+
* spec (./oauthSpec.ts), its differences data; ./oauthScopes.ts holds
|
|
27
|
+
* the one set of scope rules.
|
|
31
28
|
* - `service`: something the gateway does itself, with no upstream host
|
|
32
29
|
* an app names (sending email, listing the organization's members). An
|
|
33
30
|
* app lists it the same way and calls its routes,
|
|
@@ -70,8 +67,8 @@ export const CAPABILITIES = {
|
|
|
70
67
|
"/v1/images/variations",
|
|
71
68
|
],
|
|
72
69
|
unstoredRoutes: ["/v1/responses", "/v1/chat/completions"],
|
|
73
|
-
// More than inference needs
|
|
74
|
-
//
|
|
70
|
+
// More than inference needs the app's manifest (`ai.routes`): OpenAI
|
|
71
|
+
// paths only.
|
|
75
72
|
extraRoutes: true,
|
|
76
73
|
// Tool calling on chat completions needs `reasoning_effort: "none"`
|
|
77
74
|
// on the GPT-6 family (the responses route takes tools as it is).
|
|
@@ -296,518 +293,6 @@ export const CAPABILITIES = {
|
|
|
296
293
|
settings: [],
|
|
297
294
|
optionalSettings: [],
|
|
298
295
|
},
|
|
299
|
-
slack: {
|
|
300
|
-
mode: "oauth_client",
|
|
301
|
-
label: "Slack",
|
|
302
|
-
secrets: {
|
|
303
|
-
clientId: "SLACK_CLIENT_ID",
|
|
304
|
-
clientSecret: "SLACK_CLIENT_SECRET",
|
|
305
|
-
},
|
|
306
|
-
token: [
|
|
307
|
-
{
|
|
308
|
-
host: "slack.com",
|
|
309
|
-
path: "/api/oauth.v2.access",
|
|
310
|
-
methods: ["POST"],
|
|
311
|
-
inject: "form",
|
|
312
|
-
},
|
|
313
|
-
],
|
|
314
|
-
access: ["write"],
|
|
315
|
-
console: "https://api.slack.com/apps",
|
|
316
|
-
setup: "setup/slack.md",
|
|
317
|
-
authorize: {
|
|
318
|
-
url: "https://slack.com/oauth/v2/authorize",
|
|
319
|
-
// The sets' union: the bot scopes in set order, then the one user
|
|
320
|
-
// scope no bot set carries. Postiz lists `channels.read`,
|
|
321
|
-
// `users.read`, `messages.write`, `channels.join` and `files.write`
|
|
322
|
-
// (it posts to channels it joins and uploads images); Open CRM adds
|
|
323
|
-
// `users.email`, `channels.manage` and `user-channels.manage` (its
|
|
324
|
-
// team agents match members to Slack users by email, create and
|
|
325
|
-
// manage the channels they post to, open DMs, and the installing
|
|
326
|
-
// person invites the bot to private channels).
|
|
327
|
-
scopes: [
|
|
328
|
-
"channels:read",
|
|
329
|
-
"groups:read",
|
|
330
|
-
"users:read",
|
|
331
|
-
"users:read.email",
|
|
332
|
-
"chat:write",
|
|
333
|
-
"chat:write.public",
|
|
334
|
-
"chat:write.customize",
|
|
335
|
-
"channels:join",
|
|
336
|
-
"channels:manage",
|
|
337
|
-
"groups:write",
|
|
338
|
-
"channels:write.invites",
|
|
339
|
-
"groups:write.invites",
|
|
340
|
-
"im:write",
|
|
341
|
-
"files:write",
|
|
342
|
-
"channels:write",
|
|
343
|
-
],
|
|
344
|
-
},
|
|
345
|
-
scopePolicy: {
|
|
346
|
-
dialect: "slack",
|
|
347
|
-
// `oauth.v2.access` takes `code` with no `grant_type`; an app that
|
|
348
|
-
// opts into token rotation refreshes with `refresh_token`.
|
|
349
|
-
grantTypes: [null, "refresh_token"],
|
|
350
|
-
// Slack reads no `scope` on the token leg (the installation's scopes
|
|
351
|
-
// were fixed on the authorize URL), so the request goes as sent.
|
|
352
|
-
requestScope: "keep",
|
|
353
|
-
alwaysRequested: [],
|
|
354
|
-
tolerated: [],
|
|
355
|
-
deniedSegments: [],
|
|
356
|
-
// Slack authorizes by method name, not verb, and every method is one
|
|
357
|
-
// exact `/api/<method>` path on the host that also serves the token
|
|
358
|
-
// endpoint (which no set lists). A read set names its methods in
|
|
359
|
-
// `paths` (GET) and `posts` (POST) alike; a write set in `posts`
|
|
360
|
-
// only, with the one listing among them in `paths` too.
|
|
361
|
-
sets: {
|
|
362
|
-
"channels.read": {
|
|
363
|
-
label: "Channels (read-only)",
|
|
364
|
-
access: "read",
|
|
365
|
-
scopes: ["channels:read", "groups:read"],
|
|
366
|
-
routes: [
|
|
367
|
-
{
|
|
368
|
-
host: "slack.com",
|
|
369
|
-
paths: [
|
|
370
|
-
"/api/conversations.list",
|
|
371
|
-
"/api/conversations.info",
|
|
372
|
-
"/api/conversations.members",
|
|
373
|
-
"/api/users.conversations",
|
|
374
|
-
],
|
|
375
|
-
posts: [
|
|
376
|
-
/^\/api\/conversations\.(list|info|members)$/,
|
|
377
|
-
/^\/api\/users\.conversations$/,
|
|
378
|
-
],
|
|
379
|
-
},
|
|
380
|
-
],
|
|
381
|
-
},
|
|
382
|
-
"users.read": {
|
|
383
|
-
label: "Members (read-only)",
|
|
384
|
-
access: "read",
|
|
385
|
-
scopes: ["users:read"],
|
|
386
|
-
routes: [
|
|
387
|
-
{
|
|
388
|
-
host: "slack.com",
|
|
389
|
-
paths: [
|
|
390
|
-
"/api/users.list",
|
|
391
|
-
"/api/users.info",
|
|
392
|
-
"/api/users.getPresence",
|
|
393
|
-
"/api/bots.info",
|
|
394
|
-
],
|
|
395
|
-
posts: [
|
|
396
|
-
/^\/api\/users\.(list|info|getPresence)$/,
|
|
397
|
-
/^\/api\/bots\.info$/,
|
|
398
|
-
],
|
|
399
|
-
},
|
|
400
|
-
],
|
|
401
|
-
},
|
|
402
|
-
"users.email": {
|
|
403
|
-
// Slack grants it only beside `users:read`: declare both sets.
|
|
404
|
-
label: "Members' email addresses (read-only)",
|
|
405
|
-
access: "read",
|
|
406
|
-
scopes: ["users:read.email"],
|
|
407
|
-
routes: [
|
|
408
|
-
{
|
|
409
|
-
host: "slack.com",
|
|
410
|
-
paths: ["/api/users.lookupByEmail"],
|
|
411
|
-
posts: [/^\/api\/users\.lookupByEmail$/],
|
|
412
|
-
},
|
|
413
|
-
],
|
|
414
|
-
},
|
|
415
|
-
"messages.write": {
|
|
416
|
-
label: "Messages (post as the app)",
|
|
417
|
-
access: "write",
|
|
418
|
-
scopes: ["chat:write", "chat:write.public", "chat:write.customize"],
|
|
419
|
-
routes: [
|
|
420
|
-
{
|
|
421
|
-
host: "slack.com",
|
|
422
|
-
// The scheduled-messages listing is the one read among them.
|
|
423
|
-
paths: ["/api/chat.scheduledMessages.list"],
|
|
424
|
-
posts: [
|
|
425
|
-
/^\/api\/chat\.(postMessage|postEphemeral|update|delete|scheduleMessage|deleteScheduledMessage|scheduledMessages\.list)$/,
|
|
426
|
-
],
|
|
427
|
-
},
|
|
428
|
-
],
|
|
429
|
-
},
|
|
430
|
-
"channels.join": {
|
|
431
|
-
label: "Channels (join public ones)",
|
|
432
|
-
access: "write",
|
|
433
|
-
scopes: ["channels:join"],
|
|
434
|
-
routes: [
|
|
435
|
-
{
|
|
436
|
-
host: "slack.com",
|
|
437
|
-
paths: [],
|
|
438
|
-
posts: [/^\/api\/conversations\.join$/],
|
|
439
|
-
},
|
|
440
|
-
],
|
|
441
|
-
},
|
|
442
|
-
"channels.manage": {
|
|
443
|
-
label: "Channels (create, manage and invite to; open DMs)",
|
|
444
|
-
access: "write",
|
|
445
|
-
scopes: [
|
|
446
|
-
"channels:manage",
|
|
447
|
-
"groups:write",
|
|
448
|
-
"channels:write.invites",
|
|
449
|
-
"groups:write.invites",
|
|
450
|
-
"im:write",
|
|
451
|
-
],
|
|
452
|
-
routes: [
|
|
453
|
-
{
|
|
454
|
-
host: "slack.com",
|
|
455
|
-
paths: [],
|
|
456
|
-
posts: [
|
|
457
|
-
/^\/api\/conversations\.(create|rename|archive|unarchive|invite|open|kick|leave|setTopic|setPurpose|mark)$/,
|
|
458
|
-
],
|
|
459
|
-
},
|
|
460
|
-
],
|
|
461
|
-
},
|
|
462
|
-
"files.write": {
|
|
463
|
-
label: "Files (upload)",
|
|
464
|
-
access: "write",
|
|
465
|
-
scopes: ["files:write"],
|
|
466
|
-
routes: [
|
|
467
|
-
{
|
|
468
|
-
host: "slack.com",
|
|
469
|
-
paths: [],
|
|
470
|
-
// The external upload flow; the retired `files.upload` stays off.
|
|
471
|
-
posts: [
|
|
472
|
-
/^\/api\/files\.(getUploadURLExternal|completeUploadExternal)$/,
|
|
473
|
-
],
|
|
474
|
-
},
|
|
475
|
-
],
|
|
476
|
-
},
|
|
477
|
-
"user-channels.manage": {
|
|
478
|
-
label: "Channels (as the installing person: read, manage, invite to)",
|
|
479
|
-
access: "write",
|
|
480
|
-
scopes: [],
|
|
481
|
-
// Slack's `user_scope`: issued to the person's own token, which
|
|
482
|
-
// Open CRM uses to invite the bot to private channels.
|
|
483
|
-
userScopes: [
|
|
484
|
-
"channels:read",
|
|
485
|
-
"channels:write",
|
|
486
|
-
"groups:read",
|
|
487
|
-
"groups:write",
|
|
488
|
-
],
|
|
489
|
-
routes: [
|
|
490
|
-
{
|
|
491
|
-
host: "slack.com",
|
|
492
|
-
paths: [
|
|
493
|
-
"/api/conversations.list",
|
|
494
|
-
"/api/conversations.info",
|
|
495
|
-
"/api/conversations.members",
|
|
496
|
-
"/api/users.conversations",
|
|
497
|
-
],
|
|
498
|
-
posts: [
|
|
499
|
-
/^\/api\/conversations\.(list|info|members|create|rename|archive|unarchive|invite|kick|leave|setTopic|setPurpose|mark)$/,
|
|
500
|
-
/^\/api\/users\.conversations$/,
|
|
501
|
-
],
|
|
502
|
-
},
|
|
503
|
-
],
|
|
504
|
-
},
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
api: ["slack.com"],
|
|
508
|
-
// Slack refuses `code_challenge`; `auth.test` names the workspace and
|
|
509
|
-
// the installing person.
|
|
510
|
-
flow: {
|
|
511
|
-
tokenUrl: "https://slack.com/api/oauth.v2.access",
|
|
512
|
-
revokeUrl: "https://slack.com/api/auth.revoke",
|
|
513
|
-
pkce: false,
|
|
514
|
-
scopeDialect: "slack",
|
|
515
|
-
identity: {
|
|
516
|
-
url: "https://slack.com/api/auth.test",
|
|
517
|
-
label: "team",
|
|
518
|
-
id: "user_id",
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
},
|
|
522
|
-
// Clients several apps share with different needs, so each app lists the
|
|
523
|
-
// scope sets it uses: Open CRM reads a member's own mailbox and calendar
|
|
524
|
-
// (`gmail.read`, `calendar.read`; `identity`, `mail.read`), OpenSEO reads
|
|
525
|
-
// a site's Search Console and Analytics (`identity`, `search-console.read`,
|
|
526
|
-
// `analytics.read`). Every set is read-only. Google's is one Cloud project
|
|
527
|
-
// apart from the YouTube preset's; Gmail's read scope is restricted and needs
|
|
528
|
-
// Google's verification, and whether Search Console and Analytics share
|
|
529
|
-
// that consent screen with it is the operator's choice when verifying.
|
|
530
|
-
"google-workspace": {
|
|
531
|
-
mode: "oauth_client",
|
|
532
|
-
label: "Google (Gmail, Calendar, Search Console and Analytics)",
|
|
533
|
-
secrets: {
|
|
534
|
-
clientId: "GOOGLE_WORKSPACE_CLIENT_ID",
|
|
535
|
-
clientSecret: "GOOGLE_WORKSPACE_CLIENT_SECRET",
|
|
536
|
-
},
|
|
537
|
-
token: [
|
|
538
|
-
{
|
|
539
|
-
host: "oauth2.googleapis.com",
|
|
540
|
-
path: "/token",
|
|
541
|
-
methods: ["POST"],
|
|
542
|
-
inject: "form",
|
|
543
|
-
},
|
|
544
|
-
],
|
|
545
|
-
access: ["write"],
|
|
546
|
-
console: "https://console.cloud.google.com/apis/credentials",
|
|
547
|
-
setup: "setup/google.md",
|
|
548
|
-
authorize: {
|
|
549
|
-
url: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
550
|
-
scopes: [
|
|
551
|
-
"openid",
|
|
552
|
-
"email",
|
|
553
|
-
"profile",
|
|
554
|
-
"https://www.googleapis.com/auth/gmail.readonly",
|
|
555
|
-
"https://www.googleapis.com/auth/calendar.readonly",
|
|
556
|
-
"https://www.googleapis.com/auth/webmasters.readonly",
|
|
557
|
-
"https://www.googleapis.com/auth/analytics.readonly",
|
|
558
|
-
],
|
|
559
|
-
},
|
|
560
|
-
scopePolicy: {
|
|
561
|
-
dialect: "google",
|
|
562
|
-
// Google documents no scope on either token leg: the response's
|
|
563
|
-
// `scope` is where the gateway learns what a token holds.
|
|
564
|
-
grantTypes: ["authorization_code", "refresh_token"],
|
|
565
|
-
requestScope: "drop",
|
|
566
|
-
alwaysRequested: [],
|
|
567
|
-
// Both spellings: Google documents `email`/`profile` and the userinfo
|
|
568
|
-
// URLs as the same grants, and echoes the URLs.
|
|
569
|
-
tolerated: [
|
|
570
|
-
"openid",
|
|
571
|
-
"email",
|
|
572
|
-
"profile",
|
|
573
|
-
"https://www.googleapis.com/auth/userinfo.email",
|
|
574
|
-
"https://www.googleapis.com/auth/userinfo.profile",
|
|
575
|
-
],
|
|
576
|
-
// Gmail's and Calendar's `/batch/<api>/<version>` carry whole requests
|
|
577
|
-
// inside; Analytics' measurement protocol secrets are readable under
|
|
578
|
-
// the read-only scope.
|
|
579
|
-
deniedSegments: ["batch", "measurementProtocolSecrets"],
|
|
580
|
-
sets: {
|
|
581
|
-
identity: {
|
|
582
|
-
label: "Google account (who you are)",
|
|
583
|
-
access: "read",
|
|
584
|
-
scopes: ["openid", "email", "profile"],
|
|
585
|
-
routes: [
|
|
586
|
-
{ host: "openidconnect.googleapis.com", paths: ["/v1/userinfo"] },
|
|
587
|
-
{
|
|
588
|
-
host: "www.googleapis.com",
|
|
589
|
-
paths: [
|
|
590
|
-
"/oauth2/v2/userinfo",
|
|
591
|
-
"/oauth2/v3/userinfo",
|
|
592
|
-
"/userinfo/v2/me",
|
|
593
|
-
],
|
|
594
|
-
},
|
|
595
|
-
],
|
|
596
|
-
},
|
|
597
|
-
"gmail.read": {
|
|
598
|
-
label: "Gmail (read-only)",
|
|
599
|
-
access: "read",
|
|
600
|
-
scopes: ["https://www.googleapis.com/auth/gmail.readonly"],
|
|
601
|
-
routes: [
|
|
602
|
-
{
|
|
603
|
-
host: "gmail.googleapis.com",
|
|
604
|
-
paths: ["/gmail/v1/users/"],
|
|
605
|
-
// Push notifications start and stop; `messages/send`, drafts
|
|
606
|
-
// and `modify` are the other POSTs under the same prefix.
|
|
607
|
-
posts: [/^\/gmail\/v1\/users\/[^/]+\/(watch|stop)$/],
|
|
608
|
-
},
|
|
609
|
-
],
|
|
610
|
-
},
|
|
611
|
-
"calendar.read": {
|
|
612
|
-
label: "Google Calendar (read-only)",
|
|
613
|
-
access: "read",
|
|
614
|
-
scopes: ["https://www.googleapis.com/auth/calendar.readonly"],
|
|
615
|
-
routes: [
|
|
616
|
-
{
|
|
617
|
-
host: "www.googleapis.com",
|
|
618
|
-
paths: ["/calendar/v3/"],
|
|
619
|
-
posts: [
|
|
620
|
-
/^\/calendar\/v3\/freeBusy$/,
|
|
621
|
-
/^\/calendar\/v3\/calendars\/[^/]+\/events\/watch$/,
|
|
622
|
-
/^\/calendar\/v3\/users\/me\/calendarList\/watch$/,
|
|
623
|
-
/^\/calendar\/v3\/channels\/stop$/,
|
|
624
|
-
],
|
|
625
|
-
},
|
|
626
|
-
],
|
|
627
|
-
},
|
|
628
|
-
"search-console.read": {
|
|
629
|
-
label: "Search Console (read-only)",
|
|
630
|
-
access: "read",
|
|
631
|
-
scopes: ["https://www.googleapis.com/auth/webmasters.readonly"],
|
|
632
|
-
// The v3 paths answer on both hosts; URL inspection is v1 only.
|
|
633
|
-
// A site is one segment, `https%3A%2F%2Fexample.com%2F` or
|
|
634
|
-
// `sc-domain%3Aexample.com`, which is why routes match the raw path.
|
|
635
|
-
routes: [
|
|
636
|
-
{
|
|
637
|
-
host: "www.googleapis.com",
|
|
638
|
-
paths: ["/webmasters/v3/"],
|
|
639
|
-
posts: [
|
|
640
|
-
/^\/webmasters\/v3\/sites\/[^/]+\/searchAnalytics\/query$/,
|
|
641
|
-
],
|
|
642
|
-
},
|
|
643
|
-
{
|
|
644
|
-
host: "searchconsole.googleapis.com",
|
|
645
|
-
paths: ["/webmasters/v3/"],
|
|
646
|
-
posts: [
|
|
647
|
-
/^\/webmasters\/v3\/sites\/[^/]+\/searchAnalytics\/query$/,
|
|
648
|
-
/^\/v1\/urlInspection\/index:inspect$/,
|
|
649
|
-
],
|
|
650
|
-
},
|
|
651
|
-
],
|
|
652
|
-
},
|
|
653
|
-
"analytics.read": {
|
|
654
|
-
label: "Google Analytics (read-only)",
|
|
655
|
-
access: "read",
|
|
656
|
-
scopes: ["https://www.googleapis.com/auth/analytics.readonly"],
|
|
657
|
-
routes: [
|
|
658
|
-
{
|
|
659
|
-
// Reports are POSTed queries.
|
|
660
|
-
host: "analyticsdata.googleapis.com",
|
|
661
|
-
paths: ["/v1beta/properties/"],
|
|
662
|
-
posts: [
|
|
663
|
-
/^\/v1beta\/properties\/[^/]+:(runReport|batchRunReports|runPivotReport|batchRunPivotReports|runRealtimeReport|checkCompatibility)$/,
|
|
664
|
-
],
|
|
665
|
-
},
|
|
666
|
-
{
|
|
667
|
-
// Reads only: accounts, properties and what hangs off them
|
|
668
|
-
// (data streams, key events, enhanced measurement settings).
|
|
669
|
-
host: "analyticsadmin.googleapis.com",
|
|
670
|
-
paths: [
|
|
671
|
-
"/v1beta/accountSummaries",
|
|
672
|
-
"/v1beta/accounts",
|
|
673
|
-
"/v1beta/accounts/",
|
|
674
|
-
"/v1beta/properties",
|
|
675
|
-
"/v1beta/properties/",
|
|
676
|
-
"/v1alpha/properties/",
|
|
677
|
-
],
|
|
678
|
-
},
|
|
679
|
-
],
|
|
680
|
-
},
|
|
681
|
-
},
|
|
682
|
-
},
|
|
683
|
-
api: [
|
|
684
|
-
"gmail.googleapis.com",
|
|
685
|
-
"www.googleapis.com",
|
|
686
|
-
"searchconsole.googleapis.com",
|
|
687
|
-
"analyticsdata.googleapis.com",
|
|
688
|
-
"analyticsadmin.googleapis.com",
|
|
689
|
-
"openidconnect.googleapis.com",
|
|
690
|
-
],
|
|
691
|
-
// The Gateway-owned flow: a refresh token needs `access_type=offline`,
|
|
692
|
-
// and `prompt=consent` makes Google issue one on every connect. No
|
|
693
|
-
// revoke: Google's `/revoke` is per person per client and would also
|
|
694
|
-
// kill the tokens an app-driven OpenSEO holds under the same client.
|
|
695
|
-
flow: {
|
|
696
|
-
tokenUrl: "https://oauth2.googleapis.com/token",
|
|
697
|
-
pkce: true,
|
|
698
|
-
scopeDialect: "google",
|
|
699
|
-
authorizeParams: { access_type: "offline", prompt: "consent" },
|
|
700
|
-
identity: {
|
|
701
|
-
url: "https://openidconnect.googleapis.com/v1/userinfo",
|
|
702
|
-
label: "email",
|
|
703
|
-
id: "sub",
|
|
704
|
-
},
|
|
705
|
-
},
|
|
706
|
-
},
|
|
707
|
-
"microsoft-365": {
|
|
708
|
-
mode: "oauth_client",
|
|
709
|
-
label: "Microsoft 365 (Outlook mail and calendar)",
|
|
710
|
-
secrets: {
|
|
711
|
-
clientId: "MICROSOFT_365_CLIENT_ID",
|
|
712
|
-
clientSecret: "MICROSOFT_365_CLIENT_SECRET",
|
|
713
|
-
},
|
|
714
|
-
token: [
|
|
715
|
-
{
|
|
716
|
-
// The multi-tenant endpoint: register the client for accounts in
|
|
717
|
-
// any organization and personal accounts. A single-tenant client
|
|
718
|
-
// answers only on its tenant's path, which this does not complete.
|
|
719
|
-
host: "login.microsoftonline.com",
|
|
720
|
-
path: "/common/oauth2/v2.0/token",
|
|
721
|
-
methods: ["POST"],
|
|
722
|
-
inject: "form",
|
|
723
|
-
},
|
|
724
|
-
],
|
|
725
|
-
access: ["write"],
|
|
726
|
-
console: "https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade",
|
|
727
|
-
setup: "setup/microsoft-365.md",
|
|
728
|
-
authorize: {
|
|
729
|
-
url: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
|
730
|
-
scopes: ["offline_access", "User.Read", "Mail.Read", "Calendars.Read"],
|
|
731
|
-
},
|
|
732
|
-
scopePolicy: {
|
|
733
|
-
dialect: "microsoft",
|
|
734
|
-
grantTypes: ["authorization_code", "refresh_token"],
|
|
735
|
-
// The token leg's `scope` is Microsoft's extension for naming the
|
|
736
|
-
// resource; the gateway sets it to the app's list so a token covers
|
|
737
|
-
// Graph alone.
|
|
738
|
-
requestScope: "replace",
|
|
739
|
-
// Refresh tokens; Entra never echoes it in a response's `scope`.
|
|
740
|
-
alwaysRequested: ["offline_access"],
|
|
741
|
-
// Compared case-insensitively, as Microsoft spells them both ways.
|
|
742
|
-
tolerated: ["openid", "profile", "email", "offline_access", "User.Read"],
|
|
743
|
-
// `$batch` carries whole requests inside; `beta` is another API.
|
|
744
|
-
deniedSegments: ["$batch", "beta"],
|
|
745
|
-
// `/v1.0/me/…` only: `/v1.0/users/<id>/…` reaches shared mailboxes
|
|
746
|
-
// and calendars under the same permissions.
|
|
747
|
-
sets: {
|
|
748
|
-
identity: {
|
|
749
|
-
label: "Microsoft account (who you are)",
|
|
750
|
-
access: "read",
|
|
751
|
-
scopes: ["User.Read"],
|
|
752
|
-
routes: [
|
|
753
|
-
{
|
|
754
|
-
host: "graph.microsoft.com",
|
|
755
|
-
paths: ["/v1.0/me", "/oidc/userinfo"],
|
|
756
|
-
},
|
|
757
|
-
],
|
|
758
|
-
},
|
|
759
|
-
"mail.read": {
|
|
760
|
-
label: "Outlook mail (read-only)",
|
|
761
|
-
access: "read",
|
|
762
|
-
scopes: ["Mail.Read"],
|
|
763
|
-
routes: [
|
|
764
|
-
{
|
|
765
|
-
host: "graph.microsoft.com",
|
|
766
|
-
paths: [
|
|
767
|
-
"/v1.0/me/messages",
|
|
768
|
-
"/v1.0/me/messages/",
|
|
769
|
-
"/v1.0/me/mailFolders",
|
|
770
|
-
"/v1.0/me/mailFolders/",
|
|
771
|
-
],
|
|
772
|
-
},
|
|
773
|
-
],
|
|
774
|
-
},
|
|
775
|
-
"calendar.read": {
|
|
776
|
-
label: "Outlook calendar (read-only)",
|
|
777
|
-
access: "read",
|
|
778
|
-
scopes: ["Calendars.Read"],
|
|
779
|
-
routes: [
|
|
780
|
-
{
|
|
781
|
-
host: "graph.microsoft.com",
|
|
782
|
-
paths: [
|
|
783
|
-
"/v1.0/me/calendar",
|
|
784
|
-
"/v1.0/me/calendar/",
|
|
785
|
-
"/v1.0/me/calendars",
|
|
786
|
-
"/v1.0/me/calendars/",
|
|
787
|
-
"/v1.0/me/events",
|
|
788
|
-
"/v1.0/me/events/",
|
|
789
|
-
"/v1.0/me/calendarView",
|
|
790
|
-
"/v1.0/me/calendarView/",
|
|
791
|
-
],
|
|
792
|
-
// Free/busy is a POSTed query.
|
|
793
|
-
posts: [/^\/v1\.0\/me\/calendar\/getSchedule$/],
|
|
794
|
-
},
|
|
795
|
-
],
|
|
796
|
-
},
|
|
797
|
-
},
|
|
798
|
-
},
|
|
799
|
-
api: ["graph.microsoft.com"],
|
|
800
|
-
flow: {
|
|
801
|
-
tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
|
802
|
-
pkce: true,
|
|
803
|
-
scopeDialect: "microsoft",
|
|
804
|
-
identity: {
|
|
805
|
-
url: "https://graph.microsoft.com/v1.0/me",
|
|
806
|
-
label: "userPrincipalName",
|
|
807
|
-
id: "id",
|
|
808
|
-
},
|
|
809
|
-
},
|
|
810
|
-
},
|
|
811
296
|
// The first fifty beyond the entries above (catalog/*.ts, PR 3 of the
|
|
812
297
|
// provider registry), after them so the derived lists keep their order.
|
|
813
298
|
...CATALOG_ENTRIES,
|
|
@@ -831,7 +316,12 @@ export function capabilitySettings(capability) {
|
|
|
831
316
|
...(capability.hostSetting ? [capability.hostSetting] : []),
|
|
832
317
|
];
|
|
833
318
|
case "ai":
|
|
834
|
-
|
|
319
|
+
// Every setting `auth` names, as for an API-key provider: a Basic
|
|
320
|
+
// username held as a setting is checked, bound and listed like the key.
|
|
321
|
+
return [
|
|
322
|
+
...authSettingNames(capability.auth),
|
|
323
|
+
...(capability.alsoNeeds ?? []),
|
|
324
|
+
];
|
|
835
325
|
case "service":
|
|
836
326
|
return [...capability.settings, ...capability.optionalSettings];
|
|
837
327
|
case "oauth_client":
|
|
@@ -864,7 +354,13 @@ export function capabilityIdsOf(lookup) {
|
|
|
864
354
|
* to encode, or taken as already encoded when it holds no colon.
|
|
865
355
|
*/
|
|
866
356
|
export function authorizationFor(capability, settings) {
|
|
867
|
-
|
|
357
|
+
// Only the settings the entry declares are visible: whatever `auth` reads
|
|
358
|
+
// beyond them (a setting no row check saw) is unset, and the call fails closed.
|
|
359
|
+
const declared = {};
|
|
360
|
+
for (const name of capabilitySettings(capability)) {
|
|
361
|
+
declared[name] = settings[name];
|
|
362
|
+
}
|
|
363
|
+
return authorizationOf(capability.auth, declared);
|
|
868
364
|
}
|
|
869
365
|
/** {@link authorizationFor} for an `auth` block alone (the SDK's AI fallback holds the block, not the entry). */
|
|
870
366
|
export function authorizationOf(auth, settings) {
|
|
@@ -959,9 +455,8 @@ export function serviceRoutePath(id, route) {
|
|
|
959
455
|
/**
|
|
960
456
|
* The capability call an AppGateway path names, or null when the path names
|
|
961
457
|
* an unknown capability (or an AI provider, which has its own route), a
|
|
962
|
-
* host outside the provider's, a path that could leave that host, a
|
|
963
|
-
*
|
|
964
|
-
* capability doesn't declare. `settings` resolves an API-key provider's
|
|
458
|
+
* host outside the provider's, a path that could leave that host, or a
|
|
459
|
+
* route a service capability doesn't declare. `settings` resolves an API-key provider's
|
|
965
460
|
* `hostSetting` (a Shopify store's host); `lookup` is where the id is found,
|
|
966
461
|
* the catalog alone by default.
|
|
967
462
|
*/
|
|
@@ -986,13 +481,12 @@ export function parseIntegrationProxyPath(pathname, search, settings, lookup = C
|
|
|
986
481
|
};
|
|
987
482
|
}
|
|
988
483
|
if (capability.mode === "oauth_client") {
|
|
989
|
-
const upstream = capability.
|
|
484
|
+
const upstream = capability.api.includes(host)
|
|
990
485
|
? httpsUpstream(host, path ?? "/", search)
|
|
991
486
|
: null;
|
|
992
|
-
|
|
993
|
-
if (!upstream || !endpoint)
|
|
487
|
+
if (!upstream)
|
|
994
488
|
return null;
|
|
995
|
-
return { kind: "oauth_client", id, capability, upstream
|
|
489
|
+
return { kind: "oauth_client", id, capability, upstream };
|
|
996
490
|
}
|
|
997
491
|
if (capability.mode !== "api_key")
|
|
998
492
|
return null;
|
|
@@ -1013,21 +507,6 @@ function httpsUpstream(host, path, search) {
|
|
|
1013
507
|
return null;
|
|
1014
508
|
return upstream;
|
|
1015
509
|
}
|
|
1016
|
-
/**
|
|
1017
|
-
* The token endpoint `upstream` is, by its exact host and path, or null.
|
|
1018
|
-
* Its method is the caller's to check.
|
|
1019
|
-
*/
|
|
1020
|
-
export function tokenEndpointFor(capability, upstream) {
|
|
1021
|
-
if (upstream.protocol !== "https:")
|
|
1022
|
-
return null;
|
|
1023
|
-
return (capability.token.find(({ host, path }) => host === upstream.host && path === upstream.pathname) ?? null);
|
|
1024
|
-
}
|
|
1025
|
-
/** An OAuth client's token endpoints, as `POST https://host/path` lines for messages. */
|
|
1026
|
-
export function describeTokenEndpoints(capability) {
|
|
1027
|
-
return capability.token
|
|
1028
|
-
.map(({ host, path, methods }) => `${methods.join("/")} https://${host}${path}`)
|
|
1029
|
-
.join(", ");
|
|
1030
|
-
}
|
|
1031
510
|
/**
|
|
1032
511
|
* The command that gives the gateway `capability`'s client:
|
|
1033
512
|
* `pnpm everyapp secret set <ID> <SECRET>`.
|
|
@@ -146,7 +146,7 @@ export const COMMERCE = {
|
|
|
146
146
|
},
|
|
147
147
|
tags: ["payments", "billing"],
|
|
148
148
|
},
|
|
149
|
-
// Legacy admin custom apps only: Shopify no longer lets a store create one, and Dev Dashboard tokens expire daily (the hint says so; shipping it is Ben's call
|
|
149
|
+
// Legacy admin custom apps only: Shopify no longer lets a store create one, and Dev Dashboard tokens expire daily (the hint says so; shipping it is Ben's call).
|
|
150
150
|
shopify: {
|
|
151
151
|
mode: "api_key",
|
|
152
152
|
label: "Shopify",
|