@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.
Files changed (181) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -64
  3. package/dist/cloudflare/catalogSettings.generated.d.ts +84 -0
  4. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  5. package/dist/cloudflare/catalogSettings.generated.js +175 -0
  6. package/dist/cloudflare/index.d.ts +3 -2
  7. package/dist/cloudflare/index.d.ts.map +1 -1
  8. package/dist/cloudflare/index.js +4 -1
  9. package/dist/cloudflare/sentinel.d.ts +60 -2
  10. package/dist/cloudflare/sentinel.d.ts.map +1 -1
  11. package/dist/cloudflare/sentinel.js +37 -2
  12. package/dist/cloudflare/worker.d.ts +391 -63
  13. package/dist/cloudflare/worker.d.ts.map +1 -1
  14. package/dist/cloudflare/worker.js +394 -108
  15. package/dist/dev/index.d.ts +1 -1
  16. package/dist/dev/index.d.ts.map +1 -1
  17. package/dist/dev/index.js +1 -1
  18. package/dist/dev/keypair.d.ts +2 -0
  19. package/dist/dev/keypair.d.ts.map +1 -1
  20. package/dist/dev/keypair.js +2 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +5 -0
  24. package/dist/internal/aiDefault.d.ts +205 -0
  25. package/dist/internal/aiDefault.d.ts.map +1 -0
  26. package/dist/internal/aiDefault.js +335 -0
  27. package/dist/internal/aiProviders.d.ts +7 -2
  28. package/dist/internal/aiProviders.d.ts.map +1 -1
  29. package/dist/internal/aiProviders.js +19 -6
  30. package/dist/internal/appSettings.d.ts +82 -4
  31. package/dist/internal/appSettings.d.ts.map +1 -1
  32. package/dist/internal/appSettings.js +204 -29
  33. package/dist/internal/audit.d.ts +108 -0
  34. package/dist/internal/audit.d.ts.map +1 -0
  35. package/dist/internal/audit.js +235 -0
  36. package/dist/internal/capabilities.d.ts +2261 -815
  37. package/dist/internal/capabilities.d.ts.map +1 -1
  38. package/dist/internal/capabilities.js +122 -1034
  39. package/dist/internal/catalog/commerce.d.ts +394 -0
  40. package/dist/internal/catalog/commerce.d.ts.map +1 -0
  41. package/dist/internal/catalog/commerce.js +477 -0
  42. package/dist/internal/catalog/comms.d.ts +375 -0
  43. package/dist/internal/catalog/comms.d.ts.map +1 -0
  44. package/dist/internal/catalog/comms.js +520 -0
  45. package/dist/internal/catalog/index.d.ts +2008 -0
  46. package/dist/internal/catalog/index.d.ts.map +1 -0
  47. package/dist/internal/catalog/index.js +19 -0
  48. package/dist/internal/catalog/inference.d.ts +393 -0
  49. package/dist/internal/catalog/inference.d.ts.map +1 -0
  50. package/dist/internal/catalog/inference.js +460 -0
  51. package/dist/internal/catalog/infra.d.ts +458 -0
  52. package/dist/internal/catalog/infra.d.ts.map +1 -0
  53. package/dist/internal/catalog/infra.js +608 -0
  54. package/dist/internal/catalog/search.d.ts +400 -0
  55. package/dist/internal/catalog/search.d.ts.map +1 -0
  56. package/dist/internal/catalog/search.js +463 -0
  57. package/dist/internal/devProviders.d.ts +2 -2
  58. package/dist/internal/devProviders.d.ts.map +1 -1
  59. package/dist/internal/devProviders.js +19 -1
  60. package/dist/internal/events.d.ts +65 -3
  61. package/dist/internal/events.d.ts.map +1 -1
  62. package/dist/internal/events.js +110 -5
  63. package/dist/internal/gatewaySettings.d.ts +3 -2
  64. package/dist/internal/gatewaySettings.d.ts.map +1 -1
  65. package/dist/internal/gatewaySettings.js +12 -6
  66. package/dist/internal/identity.d.ts +41 -4
  67. package/dist/internal/identity.d.ts.map +1 -1
  68. package/dist/internal/identity.js +48 -10
  69. package/dist/internal/index.d.ts +6 -1
  70. package/dist/internal/index.d.ts.map +1 -1
  71. package/dist/internal/index.js +6 -1
  72. package/dist/internal/members.d.ts +3 -2
  73. package/dist/internal/members.d.ts.map +1 -1
  74. package/dist/internal/oauthBuiltIns.d.ts +101 -0
  75. package/dist/internal/oauthBuiltIns.d.ts.map +1 -0
  76. package/dist/internal/oauthBuiltIns.js +122 -0
  77. package/dist/internal/oauthClient.d.ts +8 -50
  78. package/dist/internal/oauthClient.d.ts.map +1 -1
  79. package/dist/internal/oauthClient.js +2 -177
  80. package/dist/internal/oauthPresets.d.ts +32 -0
  81. package/dist/internal/oauthPresets.d.ts.map +1 -0
  82. package/dist/internal/oauthPresets.js +253 -0
  83. package/dist/internal/oauthScopes.d.ts +43 -100
  84. package/dist/internal/oauthScopes.d.ts.map +1 -1
  85. package/dist/internal/oauthScopes.js +83 -382
  86. package/dist/internal/oauthSpec.d.ts +103 -0
  87. package/dist/internal/oauthSpec.d.ts.map +1 -0
  88. package/dist/internal/oauthSpec.js +520 -0
  89. package/dist/internal/protocol.d.ts +97 -5
  90. package/dist/internal/protocol.d.ts.map +1 -1
  91. package/dist/internal/protocol.js +89 -1
  92. package/dist/internal/providerRegistry.d.ts +17 -6
  93. package/dist/internal/providerRegistry.d.ts.map +1 -1
  94. package/dist/internal/providerRegistry.js +71 -8
  95. package/dist/internal/providerSpec.d.ts +18 -7
  96. package/dist/internal/providerSpec.d.ts.map +1 -1
  97. package/dist/internal/providerSpec.js +420 -34
  98. package/dist/internal/remoteMcp.d.ts.map +1 -1
  99. package/dist/internal/remoteMcp.js +1 -5
  100. package/dist/internal/signInProviders.d.ts +104 -0
  101. package/dist/internal/signInProviders.d.ts.map +1 -0
  102. package/dist/internal/signInProviders.js +245 -0
  103. package/dist/internal/tools.d.ts +5 -4
  104. package/dist/internal/tools.d.ts.map +1 -1
  105. package/dist/internal/tools.js +4 -3
  106. package/dist/manifest.d.ts +267 -0
  107. package/dist/manifest.d.ts.map +1 -0
  108. package/dist/manifest.js +30 -0
  109. package/dist/server/ai.d.ts +111 -0
  110. package/dist/server/ai.d.ts.map +1 -0
  111. package/dist/server/ai.js +145 -0
  112. package/dist/server/aiBinding.d.ts +68 -0
  113. package/dist/server/aiBinding.d.ts.map +1 -0
  114. package/dist/server/aiBinding.js +294 -0
  115. package/dist/server/attribution.d.ts +18 -5
  116. package/dist/server/attribution.d.ts.map +1 -1
  117. package/dist/server/attribution.js +19 -5
  118. package/dist/server/connectUrl.d.ts +16 -0
  119. package/dist/server/connectUrl.d.ts.map +1 -0
  120. package/dist/server/connectUrl.js +40 -0
  121. package/dist/server/context.d.ts +68 -0
  122. package/dist/server/context.d.ts.map +1 -0
  123. package/dist/server/context.js +117 -0
  124. package/dist/server/emailBinding.d.ts +72 -0
  125. package/dist/server/emailBinding.d.ts.map +1 -0
  126. package/dist/server/emailBinding.js +124 -0
  127. package/dist/server/emit.d.ts +1 -1
  128. package/dist/server/emit.d.ts.map +1 -1
  129. package/dist/server/emit.js +7 -7
  130. package/dist/server/env.d.ts +44 -0
  131. package/dist/server/env.d.ts.map +1 -0
  132. package/dist/server/env.js +1 -0
  133. package/dist/server/eventsEndpoint.d.ts +48 -0
  134. package/dist/server/eventsEndpoint.d.ts.map +1 -0
  135. package/dist/server/eventsEndpoint.js +145 -0
  136. package/dist/server/everyApp.d.ts +40 -11
  137. package/dist/server/everyApp.d.ts.map +1 -1
  138. package/dist/server/everyApp.js +116 -6
  139. package/dist/server/fromMcpTools.d.ts +89 -0
  140. package/dist/server/fromMcpTools.d.ts.map +1 -0
  141. package/dist/server/fromMcpTools.js +192 -0
  142. package/dist/server/gatewayFetch.d.ts +42 -18
  143. package/dist/server/gatewayFetch.d.ts.map +1 -1
  144. package/dist/server/gatewayFetch.js +138 -19
  145. package/dist/server/gatewayUrl.d.ts +13 -0
  146. package/dist/server/gatewayUrl.d.ts.map +1 -0
  147. package/dist/server/gatewayUrl.js +34 -0
  148. package/dist/server/index.d.ts +16 -4
  149. package/dist/server/index.d.ts.map +1 -1
  150. package/dist/server/index.js +13 -3
  151. package/dist/server/integrationFetch.d.ts +92 -73
  152. package/dist/server/integrationFetch.d.ts.map +1 -1
  153. package/dist/server/integrationFetch.js +206 -319
  154. package/dist/server/listMembers.d.ts +1 -1
  155. package/dist/server/listMembers.d.ts.map +1 -1
  156. package/dist/server/listMembers.js +8 -11
  157. package/dist/server/refusal.d.ts +55 -0
  158. package/dist/server/refusal.d.ts.map +1 -0
  159. package/dist/server/refusal.js +193 -0
  160. package/dist/server/sendEmail.d.ts +1 -1
  161. package/dist/server/sendEmail.d.ts.map +1 -1
  162. package/dist/server/sendEmail.js +7 -7
  163. package/dist/server/tools.d.ts +7 -2
  164. package/dist/server/tools.d.ts.map +1 -1
  165. package/dist/server/tools.js +2 -1
  166. package/dist/server/toolsEndpoint.d.ts +3 -1
  167. package/dist/server/toolsEndpoint.d.ts.map +1 -1
  168. package/dist/server/toolsEndpoint.js +19 -7
  169. package/dist/server/webhooks.d.ts +56 -0
  170. package/dist/server/webhooks.d.ts.map +1 -0
  171. package/dist/server/webhooks.js +205 -0
  172. package/dist/tanstack-start/index.d.ts +9 -0
  173. package/dist/tanstack-start/index.d.ts.map +1 -0
  174. package/dist/tanstack-start/index.js +29 -0
  175. package/dist/testing/index.d.ts +93 -0
  176. package/dist/testing/index.d.ts.map +1 -0
  177. package/dist/testing/index.js +156 -0
  178. package/package.json +35 -14
  179. package/dist/server/authorizeUrl.d.ts +0 -43
  180. package/dist/server/authorizeUrl.d.ts.map +0 -1
  181. package/dist/server/authorizeUrl.js +0 -110
@@ -0,0 +1,253 @@
1
+ /**
2
+ * OAuth presets: ready `oauth2-user` specs, in the JSON shape `everyapp
3
+ * provider add` takes, for providers people most often want a "Connect"
4
+ * button for. A preset becomes a `providers` row when added (`everyapp
5
+ * provider add --oauth github-oauth`, the Admin dialog,
6
+ * `everyapp_provider_add` with `preset`), so an operator may `provider
7
+ * show` and edit a copy; nothing here is a hidden catalog entry, and no
8
+ * gateway reserves a preset's setting names until it is added. Google,
9
+ * Microsoft and Slack are built in (./oauthBuiltIns.ts) and are offered
10
+ * in the same picker.
11
+ *
12
+ * Each preset parses with `parseProviderSpec` (oauthPresets.test.ts) and
13
+ * names a console where the client is made, the API hosts the token is
14
+ * sent to, and how the provider spells scopes. Which scopes a connection
15
+ * holds is each app's `everyapp.config.ts`, never the preset. Endpoints
16
+ * were checked against the providers' docs on 2026-10-25; only GitHub's
17
+ * and Google's have been tried against a live connect.
18
+ */
19
+ import { parseProviderSpec, } from "./providerSpec.js";
20
+ export const OAUTH_PRESETS = {
21
+ "github-oauth": {
22
+ id: "github-oauth",
23
+ name: "GitHub",
24
+ description: "Repositories, issues, pull requests and the person's profile.",
25
+ docs: "https://github.com/settings/developers",
26
+ api: "https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps",
27
+ hosts: ["api.github.com"],
28
+ auth: {
29
+ kind: "oauth2-user",
30
+ authorizeUrl: "https://github.com/login/oauth/authorize",
31
+ tokenUrl: "https://github.com/login/oauth/access_token",
32
+ revokeUrl: "https://api.github.com/applications/{client_id}/grant",
33
+ revokeMethod: "DELETE",
34
+ clientId: "GITHUB_OAUTH_CLIENT_ID",
35
+ clientSecret: "GITHUB_OAUTH_CLIENT_SECRET",
36
+ inject: "form",
37
+ pkce: true,
38
+ scopeSeparator: "comma",
39
+ tokenHeaders: { Accept: "application/json" },
40
+ // GET /user answers with the public profile under any token.
41
+ identity: {
42
+ url: "https://api.github.com/user",
43
+ label: "login",
44
+ id: "id",
45
+ },
46
+ },
47
+ hint: "Register an OAuth App (not a GitHub App) and paste its client id and secret. GitHub's `repo` scope is read and write.",
48
+ },
49
+ "notion-oauth": {
50
+ id: "notion-oauth",
51
+ name: "Notion",
52
+ description: "Pages and databases the person shares with the integration.",
53
+ docs: "https://www.notion.so/my-integrations",
54
+ api: "https://developers.notion.com/reference",
55
+ hosts: ["api.notion.com"],
56
+ auth: {
57
+ kind: "oauth2-user",
58
+ authorizeUrl: "https://api.notion.com/v1/oauth/authorize",
59
+ tokenUrl: "https://api.notion.com/v1/oauth/token",
60
+ clientId: "NOTION_OAUTH_CLIENT_ID",
61
+ clientSecret: "NOTION_OAUTH_CLIENT_SECRET",
62
+ inject: "basic",
63
+ pkce: false,
64
+ scopeSeparator: "space",
65
+ authorizeParams: { owner: "user" },
66
+ },
67
+ hint: "Notion has no scopes: an app lists scopes: [] and the person picks the pages to share on Notion's consent screen. Make the integration public to get a client id and secret. Apps send `Notion-Version` on every call.",
68
+ },
69
+ "linear-oauth": {
70
+ id: "linear-oauth",
71
+ name: "Linear",
72
+ description: "Issues, projects and teams, over Linear's GraphQL API.",
73
+ docs: "https://linear.app/settings/api/applications",
74
+ api: "https://developers.linear.app/docs/oauth/authentication",
75
+ hosts: ["api.linear.app"],
76
+ auth: {
77
+ kind: "oauth2-user",
78
+ authorizeUrl: "https://linear.app/oauth/authorize",
79
+ tokenUrl: "https://api.linear.app/oauth/token",
80
+ revokeUrl: "https://api.linear.app/oauth/revoke",
81
+ clientId: "LINEAR_OAUTH_CLIENT_ID",
82
+ clientSecret: "LINEAR_OAUTH_CLIENT_SECRET",
83
+ inject: "form",
84
+ pkce: false,
85
+ scopeSeparator: "comma",
86
+ },
87
+ hint: "Linear's scopes are read, write, issues:create and comments:create; its API is GraphQL over POST.",
88
+ },
89
+ "gitlab-oauth": {
90
+ id: "gitlab-oauth",
91
+ name: "GitLab",
92
+ description: "Projects, merge requests and issues on gitlab.com.",
93
+ docs: "https://gitlab.com/-/user_settings/applications",
94
+ api: "https://docs.gitlab.com/integration/oauth_provider/#view-all-authorized-applications",
95
+ hosts: ["gitlab.com"],
96
+ auth: {
97
+ kind: "oauth2-user",
98
+ authorizeUrl: "https://gitlab.com/oauth/authorize",
99
+ tokenUrl: "https://gitlab.com/oauth/token",
100
+ revokeUrl: "https://gitlab.com/oauth/revoke",
101
+ clientId: "GITLAB_OAUTH_CLIENT_ID",
102
+ clientSecret: "GITLAB_OAUTH_CLIENT_SECRET",
103
+ inject: "form",
104
+ pkce: true,
105
+ scopeSeparator: "space",
106
+ identity: {
107
+ url: "https://gitlab.com/api/v4/user",
108
+ label: "username",
109
+ id: "id",
110
+ scopes: ["read_user"],
111
+ },
112
+ },
113
+ hint: "A self-managed GitLab needs a custom provider with its own host in place of gitlab.com.",
114
+ },
115
+ atlassian: {
116
+ id: "atlassian",
117
+ name: "Atlassian (Jira and Confluence)",
118
+ description: "Jira issues and Confluence pages on the sites the person grants.",
119
+ docs: "https://developer.atlassian.com/console/myapps/",
120
+ api: "https://developer.atlassian.com/cloud/jira/platform/scopes-for-oauth-2-3LO-and-forge-apps/",
121
+ hosts: ["api.atlassian.com"],
122
+ auth: {
123
+ kind: "oauth2-user",
124
+ authorizeUrl: "https://auth.atlassian.com/authorize",
125
+ tokenUrl: "https://auth.atlassian.com/oauth/token",
126
+ clientId: "ATLASSIAN_CLIENT_ID",
127
+ clientSecret: "ATLASSIAN_CLIENT_SECRET",
128
+ inject: "form",
129
+ pkce: false,
130
+ scopeSeparator: "space",
131
+ authorizeParams: { audience: "api.atlassian.com", prompt: "consent" },
132
+ identity: {
133
+ url: "https://api.atlassian.com/me",
134
+ label: "email",
135
+ id: "account_id",
136
+ // `offline_access` is what yields a refresh token.
137
+ scopes: ["read:me", "offline_access"],
138
+ },
139
+ },
140
+ hint: "Calls go to api.atlassian.com/ex/jira/<cloud id>/… ; the cloud id comes from /oauth/token/accessible-resources.",
141
+ },
142
+ "hubspot-oauth": {
143
+ id: "hubspot-oauth",
144
+ name: "HubSpot",
145
+ description: "CRM contacts, companies and deals.",
146
+ docs: "https://developers.hubspot.com/",
147
+ api: "https://developers.hubspot.com/docs/api/working-with-oauth",
148
+ hosts: ["api.hubapi.com"],
149
+ auth: {
150
+ kind: "oauth2-user",
151
+ authorizeUrl: "https://app.hubspot.com/oauth/authorize",
152
+ tokenUrl: "https://api.hubapi.com/oauth/v1/token",
153
+ clientId: "HUBSPOT_OAUTH_CLIENT_ID",
154
+ clientSecret: "HUBSPOT_OAUTH_CLIENT_SECRET",
155
+ inject: "form",
156
+ pkce: false,
157
+ scopeSeparator: "space",
158
+ },
159
+ hint: "The app's scopes in HubSpot's developer console must include the scopes apps list, or HubSpot refuses the authorize URL.",
160
+ },
161
+ zoom: {
162
+ id: "zoom",
163
+ name: "Zoom",
164
+ description: "The person's meetings and recordings.",
165
+ docs: "https://marketplace.zoom.us/develop/create",
166
+ api: "https://developers.zoom.us/docs/integrations/oauth-scopes-overview/",
167
+ hosts: ["api.zoom.us"],
168
+ auth: {
169
+ kind: "oauth2-user",
170
+ authorizeUrl: "https://zoom.us/oauth/authorize",
171
+ tokenUrl: "https://zoom.us/oauth/token",
172
+ revokeUrl: "https://zoom.us/oauth/revoke",
173
+ clientId: "ZOOM_CLIENT_ID",
174
+ clientSecret: "ZOOM_CLIENT_SECRET",
175
+ inject: "basic",
176
+ pkce: true,
177
+ scopeSeparator: "space",
178
+ identity: {
179
+ url: "https://api.zoom.us/v2/users/me",
180
+ label: "email",
181
+ id: "id",
182
+ scopes: ["user:read:user"],
183
+ },
184
+ },
185
+ hint: "A General app with user-managed OAuth, using Zoom's granular scope names.",
186
+ },
187
+ dropbox: {
188
+ id: "dropbox",
189
+ name: "Dropbox",
190
+ description: "Files and folders in the person's Dropbox.",
191
+ docs: "https://www.dropbox.com/developers/apps",
192
+ api: "https://developers.dropbox.com/oauth-guide",
193
+ hosts: ["api.dropboxapi.com", "content.dropboxapi.com"],
194
+ auth: {
195
+ kind: "oauth2-user",
196
+ authorizeUrl: "https://www.dropbox.com/oauth2/authorize",
197
+ tokenUrl: "https://api.dropboxapi.com/oauth2/token",
198
+ revokeUrl: "https://api.dropboxapi.com/2/auth/token/revoke",
199
+ clientId: "DROPBOX_OAUTH_CLIENT_ID",
200
+ clientSecret: "DROPBOX_OAUTH_CLIENT_SECRET",
201
+ inject: "form",
202
+ pkce: true,
203
+ scopeSeparator: "space",
204
+ authorizeParams: { token_access_type: "offline" },
205
+ // Dropbox grants account_info.read to every app.
206
+ tolerated: ["account_info.read"],
207
+ },
208
+ hint: "`token_access_type=offline` is what yields a refresh token.",
209
+ },
210
+ spotify: {
211
+ id: "spotify",
212
+ name: "Spotify",
213
+ description: "The person's library, playlists and listening.",
214
+ docs: "https://developer.spotify.com/dashboard",
215
+ api: "https://developer.spotify.com/documentation/web-api/concepts/scopes",
216
+ hosts: ["api.spotify.com"],
217
+ auth: {
218
+ kind: "oauth2-user",
219
+ authorizeUrl: "https://accounts.spotify.com/authorize",
220
+ tokenUrl: "https://accounts.spotify.com/api/token",
221
+ clientId: "SPOTIFY_CLIENT_ID",
222
+ clientSecret: "SPOTIFY_CLIENT_SECRET",
223
+ inject: "basic",
224
+ pkce: true,
225
+ scopeSeparator: "space",
226
+ // GET /v1/me names the account under any token.
227
+ identity: {
228
+ url: "https://api.spotify.com/v1/me",
229
+ label: "display_name",
230
+ id: "id",
231
+ },
232
+ },
233
+ },
234
+ };
235
+ /** The preset ids, in the order the picker shows them. */
236
+ export function oauthPresetIds() {
237
+ return Object.keys(OAUTH_PRESETS);
238
+ }
239
+ /** A preset's parsed capability, for the picker's labels; throws for an unknown id (the test parses every preset). */
240
+ export function oauthPreset(id) {
241
+ const spec = OAUTH_PRESETS[id];
242
+ if (!spec)
243
+ return null;
244
+ const parsed = parseProviderSpec(spec);
245
+ if (!parsed.ok) {
246
+ throw new Error(`preset ${id} doesn't parse: ${JSON.stringify(parsed.problems)}`);
247
+ }
248
+ return parsed.capability;
249
+ }
250
+ /** Whether `capability` is an OAuth provider the Gateway runs the flow for. */
251
+ export function isOAuthProvider(capability) {
252
+ return capability?.mode === "oauth_client" && capability.flow !== undefined;
253
+ }
@@ -1,117 +1,60 @@
1
1
  /**
2
- * Scope sets for an `oauth_client` capability with a `scopePolicy`
3
- * (docs/capabilities.md "OAuth clients"): what an app's manifest entry
4
- * declares, what that lets the app ask the provider for, how each provider
5
- * spells what it granted, and which API routes a set unlocks. Pure
6
- * functions over the registry, shared by the gateway's token-endpoint
7
- * check, the SDK's local-dev twin of it and, later, the proxy and the
8
- * outbound Worker. Nothing here reads a secret or a token value.
9
- */
10
- import type { OAuthScopePolicy } from "./capabilities.js";
11
- import type { TokenRequest } from "./oauthClient.js";
12
- /** Scopes by the token they belong to: the bot or only token, and Slack's user token. */
13
- export interface ScopeList {
14
- scopes: string[];
15
- userScopes: string[];
16
- }
17
- /** What a token response says it granted; a field is present when that kind of token is. */
18
- export interface GrantedScopes {
19
- scopes?: string[];
20
- userScopes?: string[];
21
- }
22
- /**
23
- * The scope set names a manifest entry declares, or null when the entry
24
- * voids its grant: `scopes` missing, not an array, empty, a non-string
25
- * element, a name listed twice, or any name the policy doesn't offer. An
26
- * unknown name voids the whole grant rather than narrowing it silently, so
27
- * a newer CLI's set name reaching an older gateway is refused outright and
28
- * a message can say so.
29
- */
30
- export declare function declaredScopeSets(policy: OAuthScopePolicy, entry: {
31
- scopes?: unknown;
32
- } | undefined): string[] | null;
33
- /**
34
- * What an app with `sets` asks the provider for: the sets' scopes in
35
- * registry order, deduplicated, then `alwaysRequested`. The status hands
36
- * these out and the authorize URL (Microsoft: the token leg too) carries
37
- * them verbatim.
38
- */
39
- export declare function requestedScopes(policy: OAuthScopePolicy, sets: readonly string[]): ScopeList;
40
- /**
41
- * What a token an app with `sets` is handed may carry: the requested
42
- * scopes and the tolerated ones, in the dialect's canonical spelling so a
43
- * granted list canonicalised the same way compares exactly.
44
- */
45
- export declare function allowedScopes(policy: OAuthScopePolicy, sets: readonly string[]): ScopeList;
46
- /**
47
- * Whether a token response body carries a token: an access, refresh or ID
48
- * token, or Slack's user token under `authed_user`. A 2xx without one
49
- * (Slack's `ok: false`) is an error the app must see, not a grant.
2
+ * Scopes for an OAuth provider the Gateway runs the flow for: what a
3
+ * connect asks for, what a token response says it granted, whether that
4
+ * is more than was asked, and whether a connection holds what an app
5
+ * declares. One set of rules for every provider, driven by its spec
6
+ * (./oauthSpec.ts): the separator, the prefix, the identity scopes and
7
+ * the tolerated ones. Nothing here names a provider, reads a secret or a
8
+ * token value.
9
+ *
10
+ * An app's `everyapp.config.ts` lists the provider's own scope strings,
11
+ * short (`gmail.modify`, joined onto the spec's `scopePrefix`) or in
12
+ * full. Comparison is of the canonical form: percent-decoded, lower case,
13
+ * the prefix taken off.
50
14
  */
51
- export declare function carriesToken(json: unknown): boolean;
15
+ import type { OAuthFlow } from "./capabilities.js";
16
+ /** The scope rules of a provider's flow. */
17
+ type ScopeRules = Pick<OAuthFlow, "scopeSeparator" | "scopePrefix" | "identityScopes" | "tolerated">;
52
18
  /**
53
- * The scopes a token response says it granted, canonicalised per dialect,
54
- * or null when the answer names none for a token it carries, which fails
55
- * closed: every documented success response of the three providers names
56
- * them (map-providers: Google and Microsoft `scope`, Slack `scope` and
57
- * `authed_user.scope`), so a missing field is an answer the gateway can't
58
- * hold to anything.
19
+ * A scope as the provider is asked for it: an app's short scope joined
20
+ * onto the spec's prefix; a full one (with `://`), one of the spec's own
21
+ * identity or tolerated scopes, or any scope of a provider without a
22
+ * prefix, as written.
59
23
  */
60
- export declare function grantedScopes(policy: OAuthScopePolicy, json: unknown): GrantedScopes | null;
24
+ export declare function expandScope(rules: ScopeRules, scope: string): string;
25
+ /** A scope in the one spelling comparisons use: decoded, lower case, without the prefix. */
26
+ export declare function canonicalScope(rules: ScopeRules, scope: string): string;
27
+ /** `scopes` canonical, deduplicated, order kept. */
28
+ export declare function canonicalScopes(rules: ScopeRules, scopes: readonly string[]): string[];
61
29
  /**
62
- * What `granted` carries beyond `allowed`, per token kind, for a refusal's
63
- * message and log line: the user token's extras as `user:<scope>`. Both
64
- * lists are in the dialect's canonical spelling already.
30
+ * What a connect for an app that declares `declared` asks the provider
31
+ * for, in the provider's spelling: the app's scopes, then the spec's
32
+ * identity scopes, each once.
65
33
  */
66
- export declare function scopeExcess(granted: GrantedScopes, allowed: ScopeList): string[];
34
+ export declare function requestedScopes(rules: ScopeRules, declared: readonly string[]): string[];
35
+ /** Scopes joined as the provider's `scope` parameter takes them. */
36
+ export declare function joinScopes(rules: Pick<OAuthFlow, "scopeSeparator">, scopes: readonly string[]): string;
67
37
  /**
68
- * The scopes a token request itself asks for (`scope`, and Slack's
69
- * `user_scope`, in any case) in its form or JSON body, canonicalised per
70
- * dialect for comparison with `allowedScopes()`, or null when the body
71
- * names none. The query string is never read: the gateway refuses a
72
- * request that puts these there, so only one place decides.
38
+ * The scopes a token response says it granted, canonical. A response
39
+ * with no `scope` field is taken as granted exactly as `requested` (RFC
40
+ * 6749 §5.1); one whose `scope` isn't a string is null (refused).
73
41
  */
74
- export declare function requestedTokenScopes(policy: OAuthScopePolicy, request: TokenRequest): GrantedScopes | null;
42
+ export declare function grantedScopes(rules: ScopeRules, body: Record<string, unknown>, requested: readonly string[]): string[] | null;
75
43
  /**
76
- * `request` with its `scope`, in any case, as the policy's `requestScope`
77
- * says: replaced by the requested list of the app's `sets`, dropped, or
78
- * kept as sent. A separate step after `injectClientCredentials()`, whose
79
- * re-serialised form or JSON body this edits the same way; any other body
80
- * is left alone.
44
+ * The mint check: what `granted` (canonical) carries beyond `requested`,
45
+ * the identity scopes and the tolerated ones. Empty means the token may
46
+ * be kept; anything else and the Gateway drops it.
81
47
  */
82
- export declare function rewriteTokenRequestScope(policy: OAuthScopePolicy, sets: readonly string[], request: TokenRequest): TokenRequest;
48
+ export declare function scopeExcess(rules: ScopeRules, granted: readonly string[], requested: readonly string[]): string[];
83
49
  /**
84
- * The declared set that unlocks `method upstream`, or null. Not wired to
85
- * any live path yet: it becomes the proxy's boundary once the gateway
86
- * holds tokens, and the outbound Worker's for dispatched apps before that.
87
- *
88
- * In order: https only; the host must be on one of the declared sets'
89
- * routes; the raw pathname is refused when it holds `\`, `//` or `%00`;
90
- * each raw segment, and each percent-decoding of it while a `%` remains
91
- * (a provider's layers may each decode once), is refused when it won't
92
- * decode, holds a control or format character or a backslash, is one of
93
- * the policy's denied segments in any case, or splits on `/` into a dot
94
- * segment: `.` or `..`, with or without a `;` parameter (`..;x`), which
95
- * Google's front end resolves like the bare one. The denied comparison is
96
- * of the whole segment, because an encoded slash is part of one id to the
97
- * provider, never a separator: a Search Console site URL whose own path
98
- * holds `batch` stays matchable, and `2%2FmeasurementProtocolSecrets` is
99
- * a data stream id that doesn't exist, not the secrets. Then the raw
100
- * pathname, case preserved, is matched: GET and HEAD need a `paths` entry
101
- * (exact, or a prefix when it ends in `/`), POST needs a `posts` pattern,
102
- * and no other method goes through. Matching the raw path is what lets
103
- * Search Console's `sites/https%3A%2F%2Fexample.com%2F/searchAnalytics/query`
104
- * match `[^/]+` while `..`, batch tunnels and secrets stay refused however
105
- * encoded. `X-HTTP-Method-Override`, `access_token` and `token` parameters
106
- * are the proxy's to strip before it asks; nothing here reads them. The
107
- * proxy fetches with `redirect: "manual"`: Google answers a dot segment it
108
- * resolves with a 302 to the resolved path, and following one would carry
109
- * the token to a path this never matched.
50
+ * The scopes an app declares that a connection doesn't hold: `held` is
51
+ * the connection's canonical list, `declared` as the app wrote them.
110
52
  */
111
- export declare function scopeRouteAllows(policy: OAuthScopePolicy, sets: readonly string[], method: string, upstream: URL): string | null;
53
+ export declare function missingScopes(rules: ScopeRules, held: readonly string[], declared: readonly string[]): string[];
112
54
  /**
113
55
  * `text` as a JSON object, or null for anything else (an array, a scalar,
114
- * not JSON). Shared with the gateway's read of a provider's token answer.
56
+ * not JSON). The gateway's read of a provider's token answer.
115
57
  */
116
58
  export declare function jsonObject(text: string): Record<string, unknown> | null;
59
+ export {};
117
60
  //# sourceMappingURL=oauthScopes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauthScopes.d.ts","sourceRoot":"","sources":["../../src/internal/oauthScopes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAEV,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GACtC,MAAM,EAAE,GAAG,IAAI,CAejB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,SAAS,CASX;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,SAAS,CASX;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CASnD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,OAAO,GACZ,aAAa,GAAG,IAAI,CA6BtB;AA+BD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,SAAS,GACjB,MAAM,EAAE,CASV;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,YAAY,GACpB,aAAa,GAAG,IAAI,CAStB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,YAAY,GACpB,YAAY,CA+Bd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,GAAG,GACZ,MAAM,GAAG,IAAI,CAsBf;AAwJD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMvE"}
1
+ {"version":3,"file":"oauthScopes.d.ts","sourceRoot":"","sources":["../../src/internal/oauthScopes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,4CAA4C;AAC5C,KAAK,UAAU,GAAG,IAAI,CACpB,SAAS,EACT,gBAAgB,GAAG,aAAa,GAAG,gBAAgB,GAAG,WAAW,CAClE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,MAAM,EAAE,CAOV;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,MAAM,EAAE,CASV;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CACxB,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EACxC,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,EAAE,GAAG,IAAI,CAejB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,EAAE,CAOV;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,MAAM,EAAE,CAKV;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CASvE"}