@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 @@
1
+ {"version":3,"file":"oauthBuiltIns.d.ts","sourceRoot":"","sources":["../../src/internal/oauthBuiltIns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8GvB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,oBAAoB,CAAC"}
@@ -0,0 +1,122 @@
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 const BUILT_IN_OAUTH_SPECS = {
16
+ // One Google Cloud project's OAuth client: Gmail, Calendar, Search
17
+ // Console, Analytics and any other Google API an app names a scope for.
18
+ "google-workspace": {
19
+ id: "google-workspace",
20
+ name: "Google",
21
+ description: "Gmail, Calendar, Drive, Search Console, Analytics and the other Google APIs, as the person who connects.",
22
+ docs: "https://console.cloud.google.com/apis/credentials",
23
+ api: "https://developers.google.com/identity/protocols/oauth2/scopes",
24
+ hosts: [
25
+ "gmail.googleapis.com",
26
+ "www.googleapis.com",
27
+ "searchconsole.googleapis.com",
28
+ "analyticsdata.googleapis.com",
29
+ "analyticsadmin.googleapis.com",
30
+ "openidconnect.googleapis.com",
31
+ ],
32
+ auth: {
33
+ kind: "oauth2-user",
34
+ authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
35
+ tokenUrl: "https://oauth2.googleapis.com/token",
36
+ clientId: "GOOGLE_WORKSPACE_CLIENT_ID",
37
+ clientSecret: "GOOGLE_WORKSPACE_CLIENT_SECRET",
38
+ inject: "form",
39
+ pkce: true,
40
+ scopeSeparator: "space",
41
+ // An app writes `gmail.modify`; the authorize URL carries the full
42
+ // `https://www.googleapis.com/auth/gmail.modify`.
43
+ scopePrefix: "https://www.googleapis.com/auth/",
44
+ // A refresh token needs `access_type=offline`; `prompt=consent`
45
+ // makes Google issue one on every connect.
46
+ authorizeParams: { access_type: "offline", prompt: "consent" },
47
+ identity: {
48
+ url: "https://openidconnect.googleapis.com/v1/userinfo",
49
+ label: "email",
50
+ id: "sub",
51
+ scopes: ["openid", "email"],
52
+ },
53
+ // Google answers `email` and `profile` as the userinfo URLs, and may
54
+ // add `profile` beside `openid`.
55
+ tolerated: [
56
+ "profile",
57
+ "https://www.googleapis.com/auth/userinfo.email",
58
+ "https://www.googleapis.com/auth/userinfo.profile",
59
+ ],
60
+ },
61
+ 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.",
62
+ },
63
+ // The multi-tenant Entra endpoints: register the client for accounts in
64
+ // any organization and personal accounts.
65
+ "microsoft-365": {
66
+ id: "microsoft-365",
67
+ name: "Microsoft 365",
68
+ description: "Outlook mail and calendar, OneDrive and the rest of Microsoft Graph, as the person who connects.",
69
+ docs: "https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade",
70
+ api: "https://learn.microsoft.com/graph/permissions-reference",
71
+ hosts: ["graph.microsoft.com"],
72
+ auth: {
73
+ kind: "oauth2-user",
74
+ authorizeUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
75
+ tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
76
+ clientId: "MICROSOFT_365_CLIENT_ID",
77
+ clientSecret: "MICROSOFT_365_CLIENT_SECRET",
78
+ inject: "form",
79
+ pkce: true,
80
+ scopeSeparator: "space",
81
+ // An app writes `Mail.Read`; Graph's scopes are fully qualified on
82
+ // the wire and may come back either way.
83
+ scopePrefix: "https://graph.microsoft.com/",
84
+ identity: {
85
+ url: "https://graph.microsoft.com/v1.0/me",
86
+ label: "userPrincipalName",
87
+ id: "id",
88
+ // `offline_access` is what makes Entra issue a refresh token.
89
+ scopes: ["User.Read", "offline_access"],
90
+ },
91
+ tolerated: ["openid", "profile", "email"],
92
+ },
93
+ 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.",
94
+ },
95
+ // A Slack app's bot token: the top-level token of `oauth.v2.access`.
96
+ slack: {
97
+ id: "slack",
98
+ name: "Slack",
99
+ description: "Channels, members and messages, as the Slack app.",
100
+ docs: "https://api.slack.com/apps",
101
+ api: "https://api.slack.com/scopes",
102
+ hosts: ["slack.com"],
103
+ auth: {
104
+ kind: "oauth2-user",
105
+ authorizeUrl: "https://slack.com/oauth/v2/authorize",
106
+ tokenUrl: "https://slack.com/api/oauth.v2.access",
107
+ revokeUrl: "https://slack.com/api/auth.revoke",
108
+ clientId: "SLACK_CLIENT_ID",
109
+ clientSecret: "SLACK_CLIENT_SECRET",
110
+ inject: "form",
111
+ // Slack refuses `code_challenge`.
112
+ pkce: false,
113
+ scopeSeparator: "comma",
114
+ identity: {
115
+ url: "https://slack.com/api/auth.test",
116
+ label: "team",
117
+ id: "team_id",
118
+ },
119
+ },
120
+ hint: "A Slack app with the Gateway's callback as its redirect URL and the bot scopes your apps list.",
121
+ },
122
+ };
@@ -1,13 +1,13 @@
1
1
  /**
2
- * The `oauth_client` capability's wire rules (docs/capabilities.md "OAuth
3
- * clients"), shared by the gateway, which puts the operator's client on an
4
- * app's token request, and the SDK's local-dev fallback, which puts the
5
- * developer's own on it the same way.
2
+ * An OAuth provider's client as the gateway holds it in its settings
3
+ * (`everyapp secret set <CLIENT_ID> <CLIENT_SECRET>`); one an owner or
4
+ * admin pasted under Manage workspace → Providers is the gateway's own
5
+ * D1 row instead.
6
6
  */
7
- import { type CapabilitySettings, type OAuthClientCapability, type OAuthTokenEndpoint } from "./capabilities.js";
8
- /** The largest token request body the gateway reads: real ones are a few hundred bytes. */
7
+ import type { CapabilitySettings, OAuthClientCapability } from "./capabilities.js";
8
+ /** The largest token answer the gateway reads: real ones are a few kilobytes. */
9
9
  export declare const OAUTH_TOKEN_BODY_LIMIT: number;
10
- /** An OAuth client as the gateway (or `.dev.vars`) holds it. */
10
+ /** An OAuth client as the gateway holds it. */
11
11
  export interface OAuthClientCredentials {
12
12
  clientId: string;
13
13
  /** Absent for a public client. */
@@ -15,49 +15,7 @@ export interface OAuthClientCredentials {
15
15
  }
16
16
  /**
17
17
  * The client `settings` hold for `capability`, or null until every setting
18
- * it needs is set: the id, the secret (unless it is a public client), and a
19
- * `hostSetting` that is an https origin when it is set at all.
18
+ * it needs is set: the id, and the secret unless it is a public client.
20
19
  */
21
20
  export declare function oauthClientCredentials(capability: OAuthClientCapability, settings: CapabilitySettings): OAuthClientCredentials | null;
22
- /** A token request: where it goes, its headers, its (buffered) body. */
23
- export interface TokenRequest {
24
- url: URL;
25
- headers: Headers;
26
- body: string | null;
27
- }
28
- export type InjectedTokenRequest = ({
29
- ok: true;
30
- } & TokenRequest) | {
31
- ok: false;
32
- problem: string;
33
- };
34
- /**
35
- * `request` with `client` put where `rule` says (the form body, HTTP Basic,
36
- * the query string or the JSON body), and every client credential the app
37
- * sent removed wherever it was: the `Authorization` header, and
38
- * `client_id`/`client_secret` (or the rule's names for them, in any case) in
39
- * the query string and the body. Bodies are re-serialised from their parsed
40
- * values, so a crafted body can't carry a second secret past the parser.
41
- * Token requests are form-encoded or JSON; anything else is refused.
42
- */
43
- export declare function injectClientCredentials(request: TokenRequest, rule: OAuthTokenEndpoint, client: OAuthClientCredentials): InjectedTokenRequest;
44
- /**
45
- * The grants the gateway completes: each ends in a user's own tokens. The
46
- * client-credentials grant, and anything else a network serves on the same
47
- * endpoint, would mint a token for the gateway's own application instead,
48
- * which on Meta, Discord, Twitch or Kick manages the application's
49
- * settings, its webhooks and every tenant's tokens.
50
- */
51
- export declare const USER_BOUND_GRANT_TYPES: ReadonlySet<string>;
52
- /**
53
- * A token request's `grant_type` as the app sent it, from its body or query
54
- * string, or null when it names none (Meta's code exchange). Never the
55
- * request's other fields.
56
- */
57
- export declare function requestedGrantType(request: TokenRequest): string | null;
58
- /**
59
- * A token request's `grant_type` for logs: one of the known grant types,
60
- * `other`, or null when it names none.
61
- */
62
- export declare function tokenGrantType(request: TokenRequest): string | null;
63
21
  //# sourceMappingURL=oauthClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauthClient.d.ts","sourceRoot":"","sources":["../../src/internal/oauthClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD,gEAAgE;AAChE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,qBAAqB,EACjC,QAAQ,EAAE,kBAAkB,GAC3B,sBAAsB,GAAG,IAAI,CAW/B;AAMD,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,GAAG,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,MAAM,oBAAoB,GAC5B,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,YAAY,CAAC,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAKnC;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,sBAAsB,GAC7B,oBAAoB,CAyFtB;AAaD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAOrD,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAUvE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAInE"}
1
+ {"version":3,"file":"oauthClient.d.ts","sourceRoot":"","sources":["../../src/internal/oauthClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,qBAAqB,EACjC,QAAQ,EAAE,kBAAkB,GAC3B,sBAAsB,GAAG,IAAI,CAQ/B"}
@@ -1,16 +1,8 @@
1
- /**
2
- * The `oauth_client` capability's wire rules (docs/capabilities.md "OAuth
3
- * clients"), shared by the gateway, which puts the operator's client on an
4
- * app's token request, and the SDK's local-dev fallback, which puts the
5
- * developer's own on it the same way.
6
- */
7
- import { base64Utf8, oauthClientOrigin, } from "./capabilities.js";
8
- /** The largest token request body the gateway reads: real ones are a few hundred bytes. */
1
+ /** The largest token answer the gateway reads: real ones are a few kilobytes. */
9
2
  export const OAUTH_TOKEN_BODY_LIMIT = 64 * 1024;
10
3
  /**
11
4
  * The client `settings` hold for `capability`, or null until every setting
12
- * it needs is set: the id, the secret (unless it is a public client), and a
13
- * `hostSetting` that is an https origin when it is set at all.
5
+ * it needs is set: the id, and the secret unless it is a public client.
14
6
  */
15
7
  export function oauthClientCredentials(capability, settings) {
16
8
  const clientId = settingValue(settings[capability.secrets.clientId]);
@@ -20,175 +12,8 @@ export function oauthClientCredentials(capability, settings) {
20
12
  : undefined;
21
13
  if (!clientId || (secretName && !clientSecret))
22
14
  return null;
23
- if (capability.hostSetting && !oauthClientOrigin(capability, settings)) {
24
- return null;
25
- }
26
15
  return { clientId, ...(clientSecret ? { clientSecret } : {}) };
27
16
  }
28
17
  function settingValue(value) {
29
18
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
30
19
  }
31
- const FORM = "application/x-www-form-urlencoded";
32
- const JSON_TYPE = "application/json";
33
- /**
34
- * `request` with `client` put where `rule` says (the form body, HTTP Basic,
35
- * the query string or the JSON body), and every client credential the app
36
- * sent removed wherever it was: the `Authorization` header, and
37
- * `client_id`/`client_secret` (or the rule's names for them, in any case) in
38
- * the query string and the body. Bodies are re-serialised from their parsed
39
- * values, so a crafted body can't carry a second secret past the parser.
40
- * Token requests are form-encoded or JSON; anything else is refused.
41
- */
42
- export function injectClientCredentials(request, rule, client) {
43
- const idName = rule.params?.clientId ?? "client_id";
44
- const secretName = rule.params?.clientSecret ?? "client_secret";
45
- const credentialNames = new Set(["client_id", "client_secret", idName, secretName].map((name) => name.toLowerCase()));
46
- const isCredential = (name) => credentialNames.has(name.toLowerCase());
47
- const fields = [
48
- [idName, client.clientId],
49
- ...(client.clientSecret
50
- ? [[secretName, client.clientSecret]]
51
- : []),
52
- ];
53
- // The query keeps the app's other fields as they were sent.
54
- const url = new URL(request.url);
55
- const query = url.search
56
- .slice(1)
57
- .split("&")
58
- .filter((pair) => {
59
- const [name] = new URLSearchParams(pair).keys();
60
- return pair !== "" && !(name !== undefined && isCredential(name));
61
- });
62
- if (rule.inject === "query") {
63
- query.push(new URLSearchParams(fields).toString());
64
- }
65
- url.search = query.join("&");
66
- const headers = new Headers(request.headers);
67
- headers.delete("authorization");
68
- headers.delete("content-length");
69
- if (rule.inject === "basic") {
70
- headers.set("authorization", `Basic ${base64Utf8(`${client.clientId}:${client.clientSecret ?? ""}`)}`);
71
- }
72
- const type = mediaType(headers.get("content-type"));
73
- let body = request.body;
74
- if (body === null || body === "") {
75
- // Nothing the app sent; the form and JSON rules make the body.
76
- if (rule.inject === "form") {
77
- headers.set("content-type", FORM);
78
- body = new URLSearchParams(fields).toString();
79
- }
80
- else if (rule.inject === "json") {
81
- headers.set("content-type", JSON_TYPE);
82
- body = JSON.stringify(Object.fromEntries(fields));
83
- }
84
- }
85
- else if (type === FORM) {
86
- if (rule.inject === "json") {
87
- return { ok: false, problem: "This token endpoint takes a JSON body." };
88
- }
89
- const params = new URLSearchParams(body);
90
- for (const name of new Set([...params.keys()].filter(isCredential))) {
91
- params.delete(name);
92
- }
93
- if (rule.inject === "form") {
94
- for (const [name, value] of fields)
95
- params.set(name, value);
96
- }
97
- body = params.toString();
98
- }
99
- else if (type === JSON_TYPE) {
100
- if (rule.inject === "form") {
101
- return {
102
- ok: false,
103
- problem: `This token endpoint takes a form-encoded body (${FORM}).`,
104
- };
105
- }
106
- const parsed = jsonObject(body);
107
- if (!parsed) {
108
- return { ok: false, problem: "The body is not a JSON object." };
109
- }
110
- for (const name of Object.keys(parsed)) {
111
- if (isCredential(name))
112
- delete parsed[name];
113
- }
114
- if (rule.inject === "json") {
115
- for (const [name, value] of fields)
116
- parsed[name] = value;
117
- }
118
- body = JSON.stringify(parsed);
119
- }
120
- else {
121
- return {
122
- ok: false,
123
- problem: `A token request's body is form-encoded (${FORM}) or JSON (${JSON_TYPE}).`,
124
- };
125
- }
126
- return { ok: true, url, headers, body };
127
- }
128
- /** The grant types logs may name; anything else is logged as `other`. */
129
- const GRANT_TYPES = new Set([
130
- "authorization_code",
131
- "refresh_token",
132
- "client_credentials",
133
- "fb_exchange_token",
134
- "ig_exchange_token",
135
- "th_exchange_token",
136
- "urn:ietf:params:oauth:grant-type:token-exchange",
137
- ]);
138
- /**
139
- * The grants the gateway completes: each ends in a user's own tokens. The
140
- * client-credentials grant, and anything else a network serves on the same
141
- * endpoint, would mint a token for the gateway's own application instead,
142
- * which on Meta, Discord, Twitch or Kick manages the application's
143
- * settings, its webhooks and every tenant's tokens.
144
- */
145
- export const USER_BOUND_GRANT_TYPES = new Set([
146
- "authorization_code",
147
- "refresh_token",
148
- "fb_exchange_token",
149
- "ig_exchange_token",
150
- "th_exchange_token",
151
- "urn:ietf:params:oauth:grant-type:token-exchange",
152
- ]);
153
- /**
154
- * A token request's `grant_type` as the app sent it, from its body or query
155
- * string, or null when it names none (Meta's code exchange). Never the
156
- * request's other fields.
157
- */
158
- export function requestedGrantType(request) {
159
- let value = null;
160
- const type = mediaType(request.headers.get("content-type"));
161
- if (request.body && type === FORM) {
162
- value = new URLSearchParams(request.body).get("grant_type");
163
- }
164
- else if (request.body && type === JSON_TYPE) {
165
- value = jsonObject(request.body)?.["grant_type"] ?? null;
166
- }
167
- value ??= request.url.searchParams.get("grant_type");
168
- return typeof value === "string" && value ? value : null;
169
- }
170
- /**
171
- * A token request's `grant_type` for logs: one of the known grant types,
172
- * `other`, or null when it names none.
173
- */
174
- export function tokenGrantType(request) {
175
- const value = requestedGrantType(request);
176
- if (value === null)
177
- return null;
178
- return GRANT_TYPES.has(value) ? value : "other";
179
- }
180
- /** A Content-Type's media type, lowercased and without parameters. */
181
- function mediaType(contentType) {
182
- return (contentType ?? "").split(";")[0].trim().toLowerCase();
183
- }
184
- function jsonObject(text) {
185
- try {
186
- const value = JSON.parse(text);
187
- return value && typeof value === "object" && !Array.isArray(value)
188
- ? value
189
- : null;
190
- }
191
- catch {
192
- return null;
193
- }
194
- }
@@ -0,0 +1,32 @@
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 { type RegistrableCapability } from "./providerSpec.js";
20
+ /** A preset's spec as JSON: the shape of ./oauthSpec.ts. */
21
+ export type OAuthPresetSpec = Readonly<Record<string, unknown>>;
22
+ export declare const OAUTH_PRESETS: Readonly<Record<string, OAuthPresetSpec>>;
23
+ /** The preset ids, in the order the picker shows them. */
24
+ export declare function oauthPresetIds(): string[];
25
+ /** A preset's parsed capability, for the picker's labels; throws for an unknown id (the test parses every preset). */
26
+ export declare function oauthPreset(id: string): RegistrableCapability | null;
27
+ /** Whether `capability` is an OAuth provider the Gateway runs the flow for. */
28
+ export declare function isOAuthProvider(capability: {
29
+ mode: string;
30
+ flow?: unknown;
31
+ } | undefined): boolean;
32
+ //# sourceMappingURL=oauthPresets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauthPresets.d.ts","sourceRoot":"","sources":["../../src/internal/oauthPresets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhE,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAwNnE,CAAC;AAEF,0DAA0D;AAC1D,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAED,sHAAsH;AACtH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAUpE;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAC7B,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GACvD,OAAO,CAET"}