@every-app/sdk 0.2.0 → 0.3.0-rc.10

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 (189) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +609 -3
  3. package/dist/cloudflare/catalogSettings.generated.d.ts +81 -0
  4. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  5. package/dist/cloudflare/catalogSettings.generated.js +174 -0
  6. package/dist/cloudflare/index.d.ts +23 -0
  7. package/dist/cloudflare/index.d.ts.map +1 -0
  8. package/dist/cloudflare/index.js +24 -0
  9. package/dist/cloudflare/sentinel.d.ts +127 -0
  10. package/dist/cloudflare/sentinel.d.ts.map +1 -0
  11. package/dist/cloudflare/sentinel.js +85 -0
  12. package/dist/cloudflare/worker.d.ts +805 -0
  13. package/dist/cloudflare/worker.d.ts.map +1 -0
  14. package/dist/cloudflare/worker.js +997 -0
  15. package/dist/dev/index.d.ts +8 -0
  16. package/dist/dev/index.d.ts.map +1 -0
  17. package/dist/dev/index.js +7 -0
  18. package/dist/dev/keypair.d.ts +26 -0
  19. package/dist/dev/keypair.d.ts.map +1 -0
  20. package/dist/dev/keypair.js +62 -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 +204 -0
  25. package/dist/internal/aiDefault.d.ts.map +1 -0
  26. package/dist/internal/aiDefault.js +334 -0
  27. package/dist/internal/aiProviders.d.ts +72 -0
  28. package/dist/internal/aiProviders.d.ts.map +1 -0
  29. package/dist/internal/aiProviders.js +233 -0
  30. package/dist/internal/appSettings.d.ts +315 -0
  31. package/dist/internal/appSettings.d.ts.map +1 -0
  32. package/dist/internal/appSettings.js +549 -0
  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 +3174 -0
  37. package/dist/internal/capabilities.d.ts.map +1 -0
  38. package/dist/internal/capabilities.js +1110 -0
  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 +1973 -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 +423 -0
  52. package/dist/internal/catalog/infra.d.ts.map +1 -0
  53. package/dist/internal/catalog/infra.js +543 -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 +49 -0
  58. package/dist/internal/devProviders.d.ts.map +1 -0
  59. package/dist/internal/devProviders.js +80 -0
  60. package/dist/internal/email.d.ts +280 -0
  61. package/dist/internal/email.d.ts.map +1 -0
  62. package/dist/internal/email.js +613 -0
  63. package/dist/internal/events.d.ts +193 -0
  64. package/dist/internal/events.d.ts.map +1 -0
  65. package/dist/internal/events.js +367 -0
  66. package/dist/internal/gatewaySettings.d.ts +83 -0
  67. package/dist/internal/gatewaySettings.d.ts.map +1 -0
  68. package/dist/internal/gatewaySettings.js +215 -0
  69. package/dist/internal/identity.d.ts +57 -5
  70. package/dist/internal/identity.d.ts.map +1 -1
  71. package/dist/internal/identity.js +99 -22
  72. package/dist/internal/index.d.ts +22 -1
  73. package/dist/internal/index.d.ts.map +1 -1
  74. package/dist/internal/index.js +22 -1
  75. package/dist/internal/members.d.ts +36 -0
  76. package/dist/internal/members.d.ts.map +1 -0
  77. package/dist/internal/members.js +7 -0
  78. package/dist/internal/oauthClient.d.ts +61 -0
  79. package/dist/internal/oauthClient.d.ts.map +1 -0
  80. package/dist/internal/oauthClient.js +133 -0
  81. package/dist/internal/oauthPresets.d.ts +33 -0
  82. package/dist/internal/oauthPresets.d.ts.map +1 -0
  83. package/dist/internal/oauthPresets.js +1064 -0
  84. package/dist/internal/oauthScopes.d.ts +172 -0
  85. package/dist/internal/oauthScopes.d.ts.map +1 -0
  86. package/dist/internal/oauthScopes.js +510 -0
  87. package/dist/internal/oauthSpec.d.ts +102 -0
  88. package/dist/internal/oauthSpec.d.ts.map +1 -0
  89. package/dist/internal/oauthSpec.js +789 -0
  90. package/dist/internal/organizationName.d.ts +18 -0
  91. package/dist/internal/organizationName.d.ts.map +1 -0
  92. package/dist/internal/organizationName.js +24 -0
  93. package/dist/internal/protocol.d.ts +150 -3
  94. package/dist/internal/protocol.d.ts.map +1 -1
  95. package/dist/internal/protocol.js +163 -2
  96. package/dist/internal/providerApps.d.ts +75 -0
  97. package/dist/internal/providerApps.d.ts.map +1 -0
  98. package/dist/internal/providerApps.js +59 -0
  99. package/dist/internal/providerRegistry.d.ts +218 -0
  100. package/dist/internal/providerRegistry.d.ts.map +1 -0
  101. package/dist/internal/providerRegistry.js +432 -0
  102. package/dist/internal/providerSpec.d.ts +66 -0
  103. package/dist/internal/providerSpec.d.ts.map +1 -0
  104. package/dist/internal/providerSpec.js +1154 -0
  105. package/dist/internal/remoteMcp.d.ts +188 -0
  106. package/dist/internal/remoteMcp.d.ts.map +1 -0
  107. package/dist/internal/remoteMcp.js +543 -0
  108. package/dist/internal/signInProviders.d.ts +104 -0
  109. package/dist/internal/signInProviders.d.ts.map +1 -0
  110. package/dist/internal/signInProviders.js +245 -0
  111. package/dist/internal/tools.d.ts +115 -0
  112. package/dist/internal/tools.d.ts.map +1 -0
  113. package/dist/internal/tools.js +80 -0
  114. package/dist/manifest.d.ts +238 -0
  115. package/dist/manifest.d.ts.map +1 -0
  116. package/dist/manifest.js +30 -0
  117. package/dist/server/ai.d.ts +111 -0
  118. package/dist/server/ai.d.ts.map +1 -0
  119. package/dist/server/ai.js +145 -0
  120. package/dist/server/aiBinding.d.ts +68 -0
  121. package/dist/server/aiBinding.d.ts.map +1 -0
  122. package/dist/server/aiBinding.js +294 -0
  123. package/dist/server/attribution.d.ts +43 -0
  124. package/dist/server/attribution.d.ts.map +1 -0
  125. package/dist/server/attribution.js +75 -0
  126. package/dist/server/authorizeUrl.d.ts +43 -0
  127. package/dist/server/authorizeUrl.d.ts.map +1 -0
  128. package/dist/server/authorizeUrl.js +106 -0
  129. package/dist/server/connectUrl.d.ts +21 -0
  130. package/dist/server/connectUrl.d.ts.map +1 -0
  131. package/dist/server/connectUrl.js +37 -0
  132. package/dist/server/context.d.ts +68 -0
  133. package/dist/server/context.d.ts.map +1 -0
  134. package/dist/server/context.js +117 -0
  135. package/dist/server/emailBinding.d.ts +72 -0
  136. package/dist/server/emailBinding.d.ts.map +1 -0
  137. package/dist/server/emailBinding.js +124 -0
  138. package/dist/server/emit.d.ts +63 -0
  139. package/dist/server/emit.d.ts.map +1 -0
  140. package/dist/server/emit.js +101 -0
  141. package/dist/server/env.d.ts +44 -0
  142. package/dist/server/env.d.ts.map +1 -0
  143. package/dist/server/env.js +1 -0
  144. package/dist/server/everyApp.d.ts +65 -19
  145. package/dist/server/everyApp.d.ts.map +1 -1
  146. package/dist/server/everyApp.js +195 -30
  147. package/dist/server/fromMcpTools.d.ts +89 -0
  148. package/dist/server/fromMcpTools.d.ts.map +1 -0
  149. package/dist/server/fromMcpTools.js +192 -0
  150. package/dist/server/gatewayFetch.d.ts +54 -14
  151. package/dist/server/gatewayFetch.d.ts.map +1 -1
  152. package/dist/server/gatewayFetch.js +201 -37
  153. package/dist/server/gatewayUrl.d.ts +13 -0
  154. package/dist/server/gatewayUrl.d.ts.map +1 -0
  155. package/dist/server/gatewayUrl.js +34 -0
  156. package/dist/server/index.d.ts +23 -3
  157. package/dist/server/index.d.ts.map +1 -1
  158. package/dist/server/index.js +19 -2
  159. package/dist/server/integrationFetch.d.ts +162 -0
  160. package/dist/server/integrationFetch.d.ts.map +1 -0
  161. package/dist/server/integrationFetch.js +688 -0
  162. package/dist/server/listMembers.d.ts +32 -0
  163. package/dist/server/listMembers.d.ts.map +1 -0
  164. package/dist/server/listMembers.js +71 -0
  165. package/dist/server/nodeServer.d.ts +48 -0
  166. package/dist/server/nodeServer.d.ts.map +1 -0
  167. package/dist/server/nodeServer.js +45 -0
  168. package/dist/server/refusal.d.ts +55 -0
  169. package/dist/server/refusal.d.ts.map +1 -0
  170. package/dist/server/refusal.js +193 -0
  171. package/dist/server/sendEmail.d.ts +39 -0
  172. package/dist/server/sendEmail.d.ts.map +1 -0
  173. package/dist/server/sendEmail.js +114 -0
  174. package/dist/server/tools.d.ts +184 -0
  175. package/dist/server/tools.d.ts.map +1 -0
  176. package/dist/server/tools.js +347 -0
  177. package/dist/server/toolsEndpoint.d.ts +32 -0
  178. package/dist/server/toolsEndpoint.d.ts.map +1 -0
  179. package/dist/server/toolsEndpoint.js +237 -0
  180. package/dist/tanstack-start/index.d.ts +9 -0
  181. package/dist/tanstack-start/index.d.ts.map +1 -0
  182. package/dist/tanstack-start/index.js +29 -0
  183. package/dist/testing/index.d.ts +93 -0
  184. package/dist/testing/index.d.ts.map +1 -0
  185. package/dist/testing/index.js +156 -0
  186. package/package.json +42 -8
  187. package/dist/server/mcp.d.ts +0 -66
  188. package/dist/server/mcp.d.ts.map +0 -1
  189. package/dist/server/mcp.js +0 -147
@@ -0,0 +1,215 @@
1
+ /**
2
+ * The Gateway's settings and the app's own secrets, by name: the Gateway
3
+ * settings an operator changes with `everyapp secret set <NAME>` (plain
4
+ * secrets on the Gateway Worker, read on its next request), the ones the
5
+ * install writes once, and the names an app's own secret can never take.
6
+ * What an app's manifest needs of them is appSettings.ts. One registry serves
7
+ * the CLI (a Gateway name goes to the Gateway, any other to the app in the
8
+ * current directory), the manifest validator (an app's `secrets` may not
9
+ * take a Gateway name, since the app reaches those through `providers` and
10
+ * `capabilities`) and the Gateway's dev config, which a test keeps
11
+ * declaring every settable one.
12
+ */
13
+ import { CAPABILITIES, CAPABILITY_IDS, capabilitySettings, } from "./capabilities.js";
14
+ import { PLAIN_SIGN_IN_SETTINGS, SIGN_IN_GATEWAY_SETTINGS, } from "./signInProviders.js";
15
+ /**
16
+ * The Gateway's own settings: the install writes them once (`everyapp
17
+ * setup`), or an operator by hand (THIRD_PARTY_DEPLOYS), and `everyapp
18
+ * secret set` never changes them. An app's own Worker may still have a
19
+ * secret of the same name (OpenSEO's BETTER_AUTH_SECRET): the two never meet.
20
+ */
21
+ export const INSTALL_OWNED_GATEWAY_SETTINGS = [
22
+ "GATEWAY_URL",
23
+ "APP_BASE_DOMAIN",
24
+ "BETTER_AUTH_SECRET",
25
+ "JWT_PRIVATE_KEY",
26
+ "JWT_PUBLIC_KEY",
27
+ "GATEWAY_DEPLOYMENT_MODE",
28
+ "CLOUDFLARE_ACCOUNT_ID",
29
+ "THIRD_PARTY_DEPLOYS",
30
+ ];
31
+ const INSTALL_OWNED = new Set(INSTALL_OWNED_GATEWAY_SETTINGS);
32
+ export function isInstallOwnedGatewaySetting(name) {
33
+ return INSTALL_OWNED.has(name);
34
+ }
35
+ /**
36
+ * The settings the catalog's providers read (the AI providers' keys, the
37
+ * API-key providers' keys and hosts, the OAuth clients), in catalog order, the install's own left out: what `everyapp
38
+ * secret set` accepts because a provider reads it. A gateway's registered
39
+ * rows add theirs at run time (providerRegistry.settingNames()).
40
+ */
41
+ const PROVIDER_GATEWAY_SETTINGS = [
42
+ ...new Set(CAPABILITY_IDS.flatMap((id) => {
43
+ const capability = CAPABILITIES[id];
44
+ return capability.mode === "service"
45
+ ? []
46
+ : capabilitySettings(capability);
47
+ })),
48
+ ].filter((name) => !INSTALL_OWNED.has(name));
49
+ /** The Gateway's own optional settings `everyapp secret set` changes: nothing a provider reads. */
50
+ export const GATEWAY_OWN_SETTINGS = [
51
+ "AI_PROXY_EXTRA_ROUTES",
52
+ // Email's providers: Cloudflare's REST token, Resend's key, the choice.
53
+ "EMAIL_REST_API_TOKEN",
54
+ "RESEND_API_KEY",
55
+ "EMAIL_PROVIDER",
56
+ "EMAIL_FROM",
57
+ "EMAIL_FROM_NAME",
58
+ "MCP_OAUTH_ENABLED",
59
+ "MCP_DCR_ENABLED",
60
+ "MCP_ALLOWED_ORIGINS",
61
+ "MCP_AUDIT_RETENTION_DAYS",
62
+ "CLOUDFLARE_ACCESS_OIDC_ISSUER",
63
+ "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID",
64
+ "CLOUDFLARE_ACCESS_OIDC_CLIENT_SECRET",
65
+ "CLOUDFLARE_ACCESS_OIDC_LABEL",
66
+ "CLOUDFLARE_ACCESS_TEAM_DOMAIN",
67
+ "CLOUDFLARE_ACCESS_AUD",
68
+ "CLOUDFLARE_ACCESS_APPS_AUD",
69
+ "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS",
70
+ "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN",
71
+ "EMAIL_PASSWORD_SIGN_IN",
72
+ // "false" keeps the hosted gateway's sign-up invite-only.
73
+ "HOSTED_OPEN_SIGNUP",
74
+ // Release deployers and the hosted third-party domain. The hosted launch
75
+ // gate, THIRD_PARTY_DEPLOYS, is never set from here: it is opened by
76
+ // hand once the launch checks pass (docs/runbooks/hosted-install.md).
77
+ "CF_DEPLOY_TOKEN",
78
+ // Self-hosted Gateway app installs: off unless exactly "on" (everyapp deploy-token add).
79
+ "BROWSER_APP_INSTALLS",
80
+ "DISPATCH_NAMESPACE",
81
+ "THIRD_PARTY_DOMAIN",
82
+ // "true" lets event webhooks target http: and private hosts (self-host only).
83
+ "EVENTS_ALLOW_PRIVATE_TARGETS",
84
+ ];
85
+ /**
86
+ * The Gateway's optional settings `everyapp secret set` changes: every
87
+ * setting a catalog provider reads, the Gateway's own, then the sign-in
88
+ * providers' (`<ID>_SIGNIN_<FIELD>`, ./signInProviders.ts).
89
+ */
90
+ export const SETTABLE_GATEWAY_SETTINGS = [
91
+ ...PROVIDER_GATEWAY_SETTINGS,
92
+ ...GATEWAY_OWN_SETTINGS,
93
+ ...SIGN_IN_GATEWAY_SETTINGS,
94
+ ];
95
+ const SETTABLE = new Set(SETTABLE_GATEWAY_SETTINGS);
96
+ /**
97
+ * The credential names of remote MCP apps (`everyapp mcp add <url>`,
98
+ * ./remoteMcp.ts): `<ID>_MCP_TOKEN` by default, any name ending in
99
+ * `_MCP_TOKEN` by choice. A family rather than a list, so the names a
100
+ * registry row declares at run time route to the Gateway like the fixed
101
+ * names (`everyapp secret set` reads no registry to decide), an app's own
102
+ * secret can never take one (the manifest validator refuses the family),
103
+ * and a remote server can never be given a fixed provider key.
104
+ */
105
+ export const REMOTE_MCP_SECRET_PATTERN = /^[A-Z][A-Z0-9_]*_MCP_TOKEN$/;
106
+ /** Whether `name` is a remote MCP app's credential name (`TREG_MCP_TOKEN`). */
107
+ export function isRemoteMcpSecretName(name) {
108
+ return REMOTE_MCP_SECRET_PATTERN.test(name);
109
+ }
110
+ /**
111
+ * Whether `everyapp secret set <name>` changes the Gateway: one of the
112
+ * fixed settings, or a remote MCP app's credential name.
113
+ */
114
+ export function isSettableGatewaySetting(name) {
115
+ return SETTABLE.has(name) || isRemoteMcpSecretName(name);
116
+ }
117
+ /**
118
+ * Settable Gateway settings whose value is a plain word, address, list
119
+ * or switch rather than a credential: a sender, a provider choice, a
120
+ * URL, an audience, a flag. `everyapp secret set` may show these as they
121
+ * are typed and check their shape; anything else is a credential and
122
+ * stays hidden.
123
+ */
124
+ export const PLAIN_GATEWAY_SETTINGS = [
125
+ "EMAIL_FROM",
126
+ "EMAIL_FROM_NAME",
127
+ "EMAIL_PROVIDER",
128
+ "EMAIL_PASSWORD_SIGN_IN",
129
+ "AI_PROXY_EXTRA_ROUTES",
130
+ "MCP_OAUTH_ENABLED",
131
+ "MCP_DCR_ENABLED",
132
+ "MCP_ALLOWED_ORIGINS",
133
+ "MCP_AUDIT_RETENTION_DAYS",
134
+ "CLOUDFLARE_ACCESS_OIDC_ISSUER",
135
+ "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID",
136
+ "CLOUDFLARE_ACCESS_OIDC_LABEL",
137
+ "CLOUDFLARE_ACCESS_TEAM_DOMAIN",
138
+ "CLOUDFLARE_ACCESS_AUD",
139
+ "CLOUDFLARE_ACCESS_APPS_AUD",
140
+ "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS",
141
+ "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN",
142
+ "HOSTED_OPEN_SIGNUP",
143
+ "BROWSER_APP_INSTALLS",
144
+ "DISPATCH_NAMESPACE",
145
+ "THIRD_PARTY_DOMAIN",
146
+ "EVENTS_ALLOW_PRIVATE_TARGETS",
147
+ ];
148
+ const PLAIN = new Set([
149
+ ...PLAIN_GATEWAY_SETTINGS,
150
+ // The sign-in providers' ids, issuer, label and tenant; their client
151
+ // secrets are credentials.
152
+ ...PLAIN_SIGN_IN_SETTINGS,
153
+ ]);
154
+ /** Whether a settable Gateway setting's value is a plain value, not a credential. */
155
+ export function isPlainGatewaySetting(name) {
156
+ return PLAIN.has(name);
157
+ }
158
+ /**
159
+ * Settable Gateway settings only the hosted gateway reads: a self-hosted
160
+ * install never needs them, so `secret list` leaves them out there.
161
+ */
162
+ export const HOSTED_ONLY_GATEWAY_SETTINGS = [
163
+ "HOSTED_OPEN_SIGNUP",
164
+ "DISPATCH_NAMESPACE",
165
+ "THIRD_PARTY_DOMAIN",
166
+ ];
167
+ const HOSTED_ONLY = new Set(HOSTED_ONLY_GATEWAY_SETTINGS);
168
+ export function isHostedOnlyGatewaySetting(name) {
169
+ return HOSTED_ONLY.has(name);
170
+ }
171
+ /** Gateway settings for local testing only, set in the gateway's `.dev.vars`, never deployed. */
172
+ export const DEV_ONLY_GATEWAY_SETTINGS = [
173
+ "MCP_ACCESS_TOKEN_TTL",
174
+ // "true" sends the DataForSEO provider app's calls to the free sandbox.
175
+ "DATAFORSEO_SANDBOX",
176
+ ];
177
+ export function isDevOnlyGatewaySetting(name) {
178
+ return DEV_ONLY_GATEWAY_SETTINGS.includes(name);
179
+ }
180
+ /**
181
+ * Names an app's own secret can't take: the deploy sets GATEWAY_URL on
182
+ * every Worker and builds in the identity settings, the gateway binding
183
+ * and the platform's own namespaces. Checked without regard to case. The
184
+ * SDK's `everyAppWorker()` keeps the same rule as a regex (its config
185
+ * module can't import this one); a test keeps them in step.
186
+ */
187
+ const RESERVED_APP_SECRET_NAMES = new Set([
188
+ "GATEWAY_URL",
189
+ "CF_VERSION_METADATA",
190
+ ]);
191
+ const RESERVED_APP_SECRET_PREFIXES = [
192
+ "EVERYAPP_",
193
+ "EVERY_APP_",
194
+ "APP__",
195
+ ];
196
+ /** What the reserved names are, for messages. */
197
+ export const RESERVED_APP_SECRET_NAMES_TEXT = "GATEWAY_URL, CF_VERSION_METADATA and the EVERYAPP_*, EVERY_APP_* and APP__* names";
198
+ export function isReservedAppSecretName(name) {
199
+ const upper = name.toUpperCase();
200
+ return (RESERVED_APP_SECRET_NAMES.has(upper) ||
201
+ RESERVED_APP_SECRET_PREFIXES.some((prefix) => upper.startsWith(prefix)));
202
+ }
203
+ /**
204
+ * The AI provider or capability a Gateway setting belongs to: what to list
205
+ * in a manifest instead of holding the key as the app's own.
206
+ */
207
+ export function gatewaySettingOwner(name) {
208
+ for (const id of CAPABILITY_IDS) {
209
+ const capability = CAPABILITIES[id];
210
+ if (capabilitySettings(capability).includes(name)) {
211
+ return { kind: capability.mode === "ai" ? "provider" : "capability", id };
212
+ }
213
+ }
214
+ return null;
215
+ }
@@ -1,12 +1,23 @@
1
- import { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel } from "./protocol.js";
2
- export { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, };
1
+ import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, type SystemClaims, type SystemTokenPurpose } from "./protocol.js";
2
+ export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, };
3
3
  export declare class IdentityError extends Error {
4
4
  readonly status = 401;
5
5
  constructor(message: string);
6
6
  }
7
7
  export declare class ConfigurationError extends Error {
8
8
  readonly status = 500;
9
- constructor(message: string);
9
+ /**
10
+ * The Gateway refusal code the same gap gets once deployed
11
+ * (`ai_provider_not_configured`, `ai_default_not_configured`), when the
12
+ * error is "not set up" rather than a mistake in the code.
13
+ */
14
+ readonly code: string | undefined;
15
+ /** The settings that would close the gap (`.dev.vars` names in local dev). */
16
+ readonly settings: readonly string[];
17
+ constructor(message: string, setup?: {
18
+ code: string;
19
+ settings?: readonly string[];
20
+ });
10
21
  }
11
22
  /**
12
23
  * Parse the public key set from an env var value. Accepts a JSON array of PEM
@@ -23,7 +34,7 @@ export interface VerifyOptions {
23
34
  /**
24
35
  * Accept the dev identity kid ({@link IDENTITY_DEV_KEY_ID}). Set ONLY in
25
36
  * local dev (driven by the {@link DEV_ENV} worker env var). Never true in
26
- * production.
37
+ * production. Requires `issuer` to be {@link DEV_ISSUER}.
27
38
  */
28
39
  allowDevIdentities?: boolean;
29
40
  /** Override for tests. */
@@ -35,6 +46,33 @@ export interface VerifyOptions {
35
46
  * claims).
36
47
  */
37
48
  export declare function verifyIdentityJwt(token: string, options: VerifyOptions): Promise<EveryAppUser>;
49
+ /** A verified identity, with when it stops being one. */
50
+ export interface VerifiedIdentity {
51
+ user: EveryAppUser;
52
+ /** The token's `exp`, in epoch milliseconds. */
53
+ expiresAt: number;
54
+ }
55
+ /**
56
+ * {@link verifyIdentityJwt}, keeping the token's expiry: the SDK's request
57
+ * context stops forwarding an identity shortly before it, and goes on as
58
+ * the organization's background work.
59
+ */
60
+ export declare function verifyIdentity(token: string, options: VerifyOptions): Promise<VerifiedIdentity>;
61
+ /**
62
+ * The organization pin: a deployed Worker serves one organization
63
+ * (`EVERY_APP_ORG_ID`), and an identity for any other is refused, whatever
64
+ * its audience says. Throws {@link IdentityError} on a mismatch; a Worker
65
+ * with no pin (a shared app's) accepts every organization.
66
+ */
67
+ export declare function assertOrganizationPin(user: EveryAppUser, organizationId: string | undefined): void;
68
+ /**
69
+ * Verify the gateway's system token (the value of `x-everyapp-system`)
70
+ * fail-closed, for exactly one purpose. A user identity or public marker is
71
+ * never a system token, and a system token is never an identity.
72
+ */
73
+ export declare function verifySystemJwt(token: string, options: VerifyOptions & {
74
+ purpose: SystemTokenPurpose;
75
+ }): Promise<SystemClaims>;
38
76
  /**
39
77
  * Verify a public-route marker (the value of `x-everyapp-public`). The marker
40
78
  * is a gateway-signed, app-scoped JWT with `pub: true` and `typ: "public"` —
@@ -48,9 +86,16 @@ export interface IdentityResult {
48
86
  user: EveryAppUser | null;
49
87
  /** True when the gateway marked this request as a public route. */
50
88
  isPublic: boolean;
89
+ /** When the identity expires (epoch ms); null on a public route. */
90
+ expiresAt: number | null;
51
91
  }
52
92
  export interface RequestIdentityOptions {
53
93
  audience: string;
94
+ /**
95
+ * The organization this Worker is pinned to ({@link ORG_ID_ENV}): an
96
+ * identity for another is refused. Undefined accepts every organization.
97
+ */
98
+ organizationId?: string;
54
99
  /** Provide keys directly, or let {@link getIdentityFromRequest} read env. */
55
100
  publicKeys?: string[];
56
101
  /** Env bag to read {@link PUBLIC_KEYS_ENV} / {@link DEV_ENV} from. */
@@ -61,6 +106,13 @@ export interface RequestIdentityOptions {
61
106
  allowDevIdentities?: boolean;
62
107
  now?: number;
63
108
  }
109
+ /**
110
+ * The verification options for a request: keys from options or env, the
111
+ * expected issuer, and the dev-kid opt-in. Throws {@link ConfigurationError}
112
+ * when no key set is configured, or when the dev opt-in meets an issuer other
113
+ * than {@link DEV_ISSUER}.
114
+ */
115
+ export declare function resolveVerifyOptions(options: RequestIdentityOptions): VerifyOptions;
64
116
  /**
65
117
  * Resolve identity for an incoming proxied request. Public routes carry a
66
118
  * gateway-SIGNED marker in `x-everyapp-public` and resolve to
@@ -69,5 +121,5 @@ export interface RequestIdentityOptions {
69
121
  * problem — including a bare/forged public header — so a re-exposed worker
70
122
  * fails closed.
71
123
  */
72
- export declare function getIdentityFromRequest(request: Request, options: RequestIdentityOptions): Promise<IdentityResult>;
124
+ export declare function getIdentityFromRequest(request: Request | Headers, options: RequestIdentityOptions): Promise<IdentityResult>;
73
125
  //# sourceMappingURL=identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/internal/identity.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EAIjB,KAAK,YAAY,EACjB,KAAK,eAAe,EAErB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CA8B7E;AAYD,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAUvB;AAmED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC,CAqCzB"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/internal/identity.ts"],"names":[],"mappings":"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"}
@@ -9,8 +9,8 @@
9
9
  * survives verification produces a user.
10
10
  */
11
11
  import { importSPKI, jwtVerify, decodeProtectedHeader, } from "jose";
12
- import { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, assertPublicMarkerClaims, identityClaimsToEveryAppUser, ProtocolClaimsError, } from "./protocol.js";
13
- export { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, };
12
+ import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, assertPublicMarkerClaims, assertSystemClaims, identityClaimsToEveryAppUser, ProtocolClaimsError, } from "./protocol.js";
13
+ export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, ORG_ID_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, };
14
14
  export class IdentityError extends Error {
15
15
  status = 401;
16
16
  constructor(message) {
@@ -20,9 +20,19 @@ export class IdentityError extends Error {
20
20
  }
21
21
  export class ConfigurationError extends Error {
22
22
  status = 500;
23
- constructor(message) {
23
+ /**
24
+ * The Gateway refusal code the same gap gets once deployed
25
+ * (`ai_provider_not_configured`, `ai_default_not_configured`), when the
26
+ * error is "not set up" rather than a mistake in the code.
27
+ */
28
+ code;
29
+ /** The settings that would close the gap (`.dev.vars` names in local dev). */
30
+ settings;
31
+ constructor(message, setup) {
24
32
  super(message);
25
33
  this.name = "ConfigurationError";
34
+ this.code = setup?.code;
35
+ this.settings = setup?.settings ?? [];
26
36
  }
27
37
  }
28
38
  /**
@@ -65,15 +75,63 @@ function importKey(pem) {
65
75
  }
66
76
  return cached;
67
77
  }
78
+ /**
79
+ * The dev keypair is public (`@every-app/sdk/dev`), so the dev opt-in holds
80
+ * only for the dev issuer: a dev-kid token that names a real gateway as its
81
+ * issuer never verifies, whatever the env says.
82
+ */
83
+ function assertDevIssuer(options) {
84
+ if (options.allowDevIdentities && options.issuer !== DEV_ISSUER) {
85
+ throw new ConfigurationError(`Dev identities are accepted only from the dev issuer ${DEV_ISSUER}, not ${options.issuer ? `"${options.issuer}"` : "an unset issuer"}. ${DEV_ENV} is for \`everyapp dev\` alone.`);
86
+ }
87
+ }
68
88
  /**
69
89
  * Verify an identity JWT fail-closed. Throws {@link IdentityError} on any
70
90
  * problem (bad alg/kid, `none`, wrong key, expired, wrong audience, missing
71
91
  * claims).
72
92
  */
73
93
  export async function verifyIdentityJwt(token, options) {
94
+ return (await verifyIdentity(token, options)).user;
95
+ }
96
+ /**
97
+ * {@link verifyIdentityJwt}, keeping the token's expiry: the SDK's request
98
+ * context stops forwarding an identity shortly before it, and goes on as
99
+ * the organization's background work.
100
+ */
101
+ export async function verifyIdentity(token, options) {
74
102
  const payload = await verifyPinnedJwt(token, options, "user");
75
103
  try {
76
- return identityClaimsToEveryAppUser(payload);
104
+ const user = identityClaimsToEveryAppUser(payload);
105
+ // `exp` is a required claim (verifyPinnedJwt); jose checked it.
106
+ return { user, expiresAt: payload.exp * 1000 };
107
+ }
108
+ catch (error) {
109
+ if (error instanceof ProtocolClaimsError) {
110
+ throw new IdentityError(error.message);
111
+ }
112
+ throw error;
113
+ }
114
+ }
115
+ /**
116
+ * The organization pin: a deployed Worker serves one organization
117
+ * (`EVERY_APP_ORG_ID`), and an identity for any other is refused, whatever
118
+ * its audience says. Throws {@link IdentityError} on a mismatch; a Worker
119
+ * with no pin (a shared app's) accepts every organization.
120
+ */
121
+ export function assertOrganizationPin(user, organizationId) {
122
+ if (organizationId && user.orgId !== organizationId) {
123
+ throw new IdentityError(`identity is for organization "${user.orgId}", and this Worker serves organization "${organizationId}" (${ORG_ID_ENV})`);
124
+ }
125
+ }
126
+ /**
127
+ * Verify the gateway's system token (the value of `x-everyapp-system`)
128
+ * fail-closed, for exactly one purpose. A user identity or public marker is
129
+ * never a system token, and a system token is never an identity.
130
+ */
131
+ export async function verifySystemJwt(token, options) {
132
+ const payload = await verifyPinnedJwt(token, options, "system");
133
+ try {
134
+ return assertSystemClaims(payload, options.purpose);
77
135
  }
78
136
  catch (error) {
79
137
  if (error instanceof ProtocolClaimsError) {
@@ -87,6 +145,7 @@ export async function verifyIdentityJwt(token, options) {
87
145
  * `aud` checked, multi-key (current + next). Returns the verified payload.
88
146
  */
89
147
  async function verifyPinnedJwt(token, options, expectedTyp) {
148
+ assertDevIssuer(options);
90
149
  if (!token)
91
150
  throw new IdentityError("no identity token");
92
151
  // Pin the header BEFORE attempting any signature work. This is what defeats
@@ -108,13 +167,13 @@ async function verifyPinnedJwt(token, options, expectedTyp) {
108
167
  if (!header.kid || !allowedKids.includes(header.kid)) {
109
168
  throw new IdentityError(`unexpected kid "${header.kid}"`);
110
169
  }
111
- if (expectedTyp === "user" && !options.issuer) {
112
- throw new IdentityError(`${ISSUER_ENV} not configured — deploy with the Every App CLI or provide an explicit issuer.`);
170
+ if (expectedTyp !== "public" && !options.issuer) {
171
+ throw new IdentityError(`${ISSUER_ENV} not configured — deploy with the EveryApp CLI or provide an explicit issuer.`);
113
172
  }
114
173
  const verifyOpts = {
115
174
  algorithms: [IDENTITY_ALG],
116
175
  audience: options.audience,
117
- requiredClaims: ["exp"],
176
+ requiredClaims: expectedTyp === "system" ? ["exp", "iat"] : ["exp"],
118
177
  ...(options.issuer ? { issuer: options.issuer } : {}),
119
178
  ...(options.now ? { currentDate: new Date(options.now) } : {}),
120
179
  };
@@ -154,23 +213,21 @@ export async function verifyPublicMarkerJwt(token, options) {
154
213
  }
155
214
  }
156
215
  /**
157
- * Resolve identity for an incoming proxied request. Public routes carry a
158
- * gateway-SIGNED marker in `x-everyapp-public` and resolve to
159
- * `{ user: null, isPublic: true }` only after the marker verifies. Everything
160
- * else requires a valid identity JWT. Throws {@link IdentityError} on any
161
- * problem — including a bare/forged public header — so a re-exposed worker
162
- * fails closed.
216
+ * The verification options for a request: keys from options or env, the
217
+ * expected issuer, and the dev-kid opt-in. Throws {@link ConfigurationError}
218
+ * when no key set is configured, or when the dev opt-in meets an issuer other
219
+ * than {@link DEV_ISSUER}.
163
220
  */
164
- export async function getIdentityFromRequest(request, options) {
221
+ export function resolveVerifyOptions(options) {
165
222
  const publicKeys = options.publicKeys ??
166
223
  parsePublicKeys(options.env?.[options.keysEnvVar ?? PUBLIC_KEYS_ENV] ?? null);
167
- // Dev identities are accepted only when the worker env opts in (everyapp dev
168
- // sets EVERYAPP_DEV in .dev.vars). Production never sets it.
224
+ // Dev identities are accepted only when the worker env opts in
225
+ // (everyAppWorker() sets EVERYAPP_DEV in development). A deploy never does.
169
226
  const devEnv = options.env?.[DEV_ENV];
170
227
  const allowDevIdentities = options.allowDevIdentities ??
171
228
  (typeof devEnv === "string" &&
172
229
  (devEnv === "1" || devEnv.toLowerCase() === "true"));
173
- const verifyOptions = {
230
+ const resolved = {
174
231
  publicKeys,
175
232
  audience: options.audience,
176
233
  issuer: options.issuer ??
@@ -178,15 +235,35 @@ export async function getIdentityFromRequest(request, options) {
178
235
  allowDevIdentities,
179
236
  now: options.now,
180
237
  };
181
- const publicMarker = request.headers.get(PUBLIC_HEADER);
238
+ assertDevIssuer(resolved);
239
+ return resolved;
240
+ }
241
+ /**
242
+ * Resolve identity for an incoming proxied request. Public routes carry a
243
+ * gateway-SIGNED marker in `x-everyapp-public` and resolve to
244
+ * `{ user: null, isPublic: true }` only after the marker verifies. Everything
245
+ * else requires a valid identity JWT. Throws {@link IdentityError} on any
246
+ * problem — including a bare/forged public header — so a re-exposed worker
247
+ * fails closed.
248
+ */
249
+ export async function getIdentityFromRequest(request, options) {
250
+ const verifyOptions = resolveVerifyOptions(options);
251
+ const headers = isRequestLike(request) ? request.headers : request;
252
+ const publicMarker = headers.get(PUBLIC_HEADER);
182
253
  if (publicMarker) {
183
254
  await verifyPublicMarkerJwt(publicMarker, verifyOptions);
184
- return { user: null, isPublic: true };
255
+ return { user: null, isPublic: true, expiresAt: null };
185
256
  }
186
- const token = request.headers.get(IDENTITY_HEADER);
257
+ const token = headers.get(IDENTITY_HEADER);
187
258
  if (!token) {
188
259
  throw new IdentityError("request reached the app without an identity token (not proxied through the gateway?)");
189
260
  }
190
- const user = await verifyIdentityJwt(token, verifyOptions);
191
- return { user, isPublic: false };
261
+ const { user, expiresAt } = await verifyIdentity(token, verifyOptions);
262
+ assertOrganizationPin(user, options.organizationId);
263
+ return { user, isPublic: false, expiresAt };
264
+ }
265
+ // Duck-typed: a Request from another realm (a test runner, a polyfill) still
266
+ // carries its headers the same way.
267
+ function isRequestLike(value) {
268
+ return "headers" in value && typeof value.headers?.get === "function";
192
269
  }
@@ -1,3 +1,24 @@
1
1
  export * from "./protocol.js";
2
- export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, verifyIdentityJwt, verifyPublicMarkerJwt, type IdentityResult, type RequestIdentityOptions, type VerifyOptions, } from "./identity.js";
2
+ export * from "./tools.js";
3
+ export * from "./capabilities.js";
4
+ export * from "./aiProviders.js";
5
+ export * from "./aiDefault.js";
6
+ export * from "./gatewaySettings.js";
7
+ export * from "./appSettings.js";
8
+ export * from "./email.js";
9
+ export * from "./members.js";
10
+ export * from "./organizationName.js";
11
+ export * from "./oauthClient.js";
12
+ export * from "./oauthScopes.js";
13
+ export * from "./oauthSpec.js";
14
+ export * from "./oauthPresets.js";
15
+ export * from "./providerApps.js";
16
+ export * from "./events.js";
17
+ export * from "./audit.js";
18
+ export * from "./providerSpec.js";
19
+ export * from "./providerRegistry.js";
20
+ export * from "./remoteMcp.js";
21
+ export * from "./signInProviders.js";
22
+ export * from "./devProviders.js";
23
+ export { ConfigurationError, IdentityError, assertOrganizationPin, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentity, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, type IdentityResult, type RequestIdentityOptions, type VerifiedIdentity, type VerifyOptions, } from "./identity.js";
3
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
@@ -1,2 +1,23 @@
1
1
  export * from "./protocol.js";
2
- export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, verifyIdentityJwt, verifyPublicMarkerJwt, } from "./identity.js";
2
+ export * from "./tools.js";
3
+ export * from "./capabilities.js";
4
+ export * from "./aiProviders.js";
5
+ export * from "./aiDefault.js";
6
+ export * from "./gatewaySettings.js";
7
+ export * from "./appSettings.js";
8
+ export * from "./email.js";
9
+ export * from "./members.js";
10
+ export * from "./organizationName.js";
11
+ export * from "./oauthClient.js";
12
+ export * from "./oauthScopes.js";
13
+ export * from "./oauthSpec.js";
14
+ export * from "./oauthPresets.js";
15
+ export * from "./providerApps.js";
16
+ export * from "./events.js";
17
+ export * from "./audit.js";
18
+ export * from "./providerSpec.js";
19
+ export * from "./providerRegistry.js";
20
+ export * from "./remoteMcp.js";
21
+ export * from "./signInProviders.js";
22
+ export * from "./devProviders.js";
23
+ export { ConfigurationError, IdentityError, assertOrganizationPin, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentity, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, } from "./identity.js";
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The `members` capability's wire contract (docs/capabilities.md "Gateway
3
+ * services"): what `GET /api/integrations/members/list` answers. The
4
+ * gateway builds it, the SDK's `listMembers()` returns it, and its local-dev
5
+ * fallback answers in the same shape. Types only.
6
+ */
7
+ import type { OrgRole } from "./protocol.js";
8
+ /** A member's role in the organization: the identity token's {@link OrgRole}. */
9
+ export type OrganizationMemberRole = OrgRole;
10
+ /**
11
+ * One member of the organization who can open the app: not deactivated,
12
+ * and, for an organization's own app, granted it.
13
+ */
14
+ export interface OrganizationMember {
15
+ /** The user id, the identity's `sub` (`getEveryAppUser().id`). */
16
+ id: string;
17
+ email: string;
18
+ /** The display name; empty when the person set none. */
19
+ name: string;
20
+ role: OrganizationMemberRole;
21
+ }
22
+ /** What a list answers. */
23
+ export interface ListMembersResult {
24
+ members: OrganizationMember[];
25
+ }
26
+ /** `GET /api/integrations/members`: whether the app may list members. */
27
+ export interface MembersCapabilityStatus {
28
+ capability: "members";
29
+ /** The app's manifest lists `members`. */
30
+ requested: boolean;
31
+ /** Always true: the gateway needs no setting to list its own members. */
32
+ configured: true;
33
+ /** Lists would go through. */
34
+ ready: boolean;
35
+ }
36
+ //# sourceMappingURL=members.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../src/internal/members.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,iFAAiF;AACjF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,sBAAsB,CAAC;CAC9B;AAED,2BAA2B;AAC3B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,SAAS,CAAC;IACtB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,UAAU,EAAE,IAAI,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The `members` capability's wire contract (docs/capabilities.md "Gateway
3
+ * services"): what `GET /api/integrations/members/list` answers. The
4
+ * gateway builds it, the SDK's `listMembers()` returns it, and its local-dev
5
+ * fallback answers in the same shape. Types only.
6
+ */
7
+ export {};