@mastra/factory 0.0.0 → 0.1.0-alpha.3

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 (287) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE.md +30 -0
  3. package/dist/auth.d.ts +181 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +370 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/capabilities/connection.d.ts +9 -0
  8. package/dist/capabilities/connection.d.ts.map +1 -0
  9. package/dist/capabilities/connection.js +1 -0
  10. package/dist/capabilities/connection.js.map +1 -0
  11. package/dist/capabilities/intake.d.ts +93 -0
  12. package/dist/capabilities/intake.d.ts.map +1 -0
  13. package/dist/capabilities/intake.js +1 -0
  14. package/dist/capabilities/intake.js.map +1 -0
  15. package/dist/capabilities/version-control.d.ts +239 -0
  16. package/dist/capabilities/version-control.d.ts.map +1 -0
  17. package/dist/capabilities/version-control.js +1 -0
  18. package/dist/capabilities/version-control.js.map +1 -0
  19. package/dist/factory.d.ts +145 -0
  20. package/dist/factory.d.ts.map +1 -0
  21. package/dist/factory.js +38245 -0
  22. package/dist/factory.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +38245 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/integrations/base.d.ts +197 -0
  28. package/dist/integrations/base.d.ts.map +1 -0
  29. package/dist/integrations/base.js +1 -0
  30. package/dist/integrations/base.js.map +1 -0
  31. package/dist/integrations/github/config.d.ts +60 -0
  32. package/dist/integrations/github/config.d.ts.map +1 -0
  33. package/dist/integrations/github/config.js +28 -0
  34. package/dist/integrations/github/config.js.map +1 -0
  35. package/dist/integrations/github/factory-session.d.ts +12 -0
  36. package/dist/integrations/github/factory-session.d.ts.map +1 -0
  37. package/dist/integrations/github/factory-session.js +41 -0
  38. package/dist/integrations/github/factory-session.js.map +1 -0
  39. package/dist/integrations/github/integration.d.ts +191 -0
  40. package/dist/integrations/github/integration.d.ts.map +1 -0
  41. package/dist/integrations/github/integration.js +3001 -0
  42. package/dist/integrations/github/integration.js.map +1 -0
  43. package/dist/integrations/github/issue-triage.d.ts +27 -0
  44. package/dist/integrations/github/issue-triage.d.ts.map +1 -0
  45. package/dist/integrations/github/issue-triage.js +82 -0
  46. package/dist/integrations/github/issue-triage.js.map +1 -0
  47. package/dist/integrations/github/project-lock.d.ts +78 -0
  48. package/dist/integrations/github/project-lock.d.ts.map +1 -0
  49. package/dist/integrations/github/project-lock.js +70 -0
  50. package/dist/integrations/github/project-lock.js.map +1 -0
  51. package/dist/integrations/github/provenance.d.ts +27 -0
  52. package/dist/integrations/github/provenance.d.ts.map +1 -0
  53. package/dist/integrations/github/provenance.js +104 -0
  54. package/dist/integrations/github/provenance.js.map +1 -0
  55. package/dist/integrations/github/routes.d.ts +72 -0
  56. package/dist/integrations/github/routes.d.ts.map +1 -0
  57. package/dist/integrations/github/routes.js +1834 -0
  58. package/dist/integrations/github/routes.js.map +1 -0
  59. package/dist/integrations/github/sandbox.d.ts +268 -0
  60. package/dist/integrations/github/sandbox.d.ts.map +1 -0
  61. package/dist/integrations/github/sandbox.js +381 -0
  62. package/dist/integrations/github/sandbox.js.map +1 -0
  63. package/dist/integrations/github/session-subscriptions.d.ts +23 -0
  64. package/dist/integrations/github/session-subscriptions.d.ts.map +1 -0
  65. package/dist/integrations/github/session-subscriptions.js +190 -0
  66. package/dist/integrations/github/session-subscriptions.js.map +1 -0
  67. package/dist/integrations/github/subscriptions.d.ts +54 -0
  68. package/dist/integrations/github/subscriptions.d.ts.map +1 -0
  69. package/dist/integrations/github/subscriptions.js +70 -0
  70. package/dist/integrations/github/subscriptions.js.map +1 -0
  71. package/dist/integrations/github/webhook.d.ts +87 -0
  72. package/dist/integrations/github/webhook.d.ts.map +1 -0
  73. package/dist/integrations/github/webhook.js +381 -0
  74. package/dist/integrations/github/webhook.js.map +1 -0
  75. package/dist/integrations/linear/agent-tools.d.ts +34 -0
  76. package/dist/integrations/linear/agent-tools.d.ts.map +1 -0
  77. package/dist/integrations/linear/agent-tools.js +108 -0
  78. package/dist/integrations/linear/agent-tools.js.map +1 -0
  79. package/dist/integrations/linear/integration.d.ts +233 -0
  80. package/dist/integrations/linear/integration.d.ts.map +1 -0
  81. package/dist/integrations/linear/integration.js +962 -0
  82. package/dist/integrations/linear/integration.js.map +1 -0
  83. package/dist/integrations/linear/routes.d.ts +61 -0
  84. package/dist/integrations/linear/routes.d.ts.map +1 -0
  85. package/dist/integrations/linear/routes.js +242 -0
  86. package/dist/integrations/linear/routes.js.map +1 -0
  87. package/dist/integrations/linear/storage.d.ts +65 -0
  88. package/dist/integrations/linear/storage.d.ts.map +1 -0
  89. package/dist/integrations/linear/storage.js +1 -0
  90. package/dist/integrations/linear/storage.js.map +1 -0
  91. package/dist/integrations/platform/api-client.d.ts +24 -0
  92. package/dist/integrations/platform/api-client.d.ts.map +1 -0
  93. package/dist/integrations/platform/api-client.js +153 -0
  94. package/dist/integrations/platform/api-client.js.map +1 -0
  95. package/dist/integrations/platform/github/event-worker.d.ts +44 -0
  96. package/dist/integrations/platform/github/event-worker.d.ts.map +1 -0
  97. package/dist/integrations/platform/github/event-worker.js +585 -0
  98. package/dist/integrations/platform/github/event-worker.js.map +1 -0
  99. package/dist/integrations/platform/github/integration.d.ts +36 -0
  100. package/dist/integrations/platform/github/integration.d.ts.map +1 -0
  101. package/dist/integrations/platform/github/integration.js +3253 -0
  102. package/dist/integrations/platform/github/integration.js.map +1 -0
  103. package/dist/integrations/platform/linear/integration.d.ts +46 -0
  104. package/dist/integrations/platform/linear/integration.d.ts.map +1 -0
  105. package/dist/integrations/platform/linear/integration.js +891 -0
  106. package/dist/integrations/platform/linear/integration.js.map +1 -0
  107. package/dist/integrations/workos/integration.d.ts +39 -0
  108. package/dist/integrations/workos/integration.d.ts.map +1 -0
  109. package/dist/integrations/workos/integration.js +96 -0
  110. package/dist/integrations/workos/integration.js.map +1 -0
  111. package/dist/routes/config.d.ts +220 -0
  112. package/dist/routes/config.d.ts.map +1 -0
  113. package/dist/routes/config.js +770 -0
  114. package/dist/routes/config.js.map +1 -0
  115. package/dist/routes/fs.d.ts +105 -0
  116. package/dist/routes/fs.d.ts.map +1 -0
  117. package/dist/routes/fs.js +294 -0
  118. package/dist/routes/fs.js.map +1 -0
  119. package/dist/routes/intake.d.ts +23 -0
  120. package/dist/routes/intake.d.ts.map +1 -0
  121. package/dist/routes/intake.js +179 -0
  122. package/dist/routes/intake.js.map +1 -0
  123. package/dist/routes/oauth.d.ts +43 -0
  124. package/dist/routes/oauth.d.ts.map +1 -0
  125. package/dist/routes/oauth.js +25058 -0
  126. package/dist/routes/oauth.js.map +1 -0
  127. package/dist/routes/projects.d.ts +19 -0
  128. package/dist/routes/projects.d.ts.map +1 -0
  129. package/dist/routes/projects.js +395 -0
  130. package/dist/routes/projects.js.map +1 -0
  131. package/dist/routes/provider-credentials.d.ts +81 -0
  132. package/dist/routes/provider-credentials.d.ts.map +1 -0
  133. package/dist/routes/provider-credentials.js +68 -0
  134. package/dist/routes/provider-credentials.js.map +1 -0
  135. package/dist/routes/route.d.ts +48 -0
  136. package/dist/routes/route.d.ts.map +1 -0
  137. package/dist/routes/route.js +11 -0
  138. package/dist/routes/route.js.map +1 -0
  139. package/dist/routes/skills.d.ts +30 -0
  140. package/dist/routes/skills.d.ts.map +1 -0
  141. package/dist/routes/skills.js +181 -0
  142. package/dist/routes/skills.js.map +1 -0
  143. package/dist/routes/surface.d.ts +83 -0
  144. package/dist/routes/surface.d.ts.map +1 -0
  145. package/dist/routes/surface.js +28519 -0
  146. package/dist/routes/surface.js.map +1 -0
  147. package/dist/routes/tenant-credentials.d.ts +74 -0
  148. package/dist/routes/tenant-credentials.d.ts.map +1 -0
  149. package/dist/routes/tenant-credentials.js +181 -0
  150. package/dist/routes/tenant-credentials.js.map +1 -0
  151. package/dist/routes/work-items.d.ts +40 -0
  152. package/dist/routes/work-items.d.ts.map +1 -0
  153. package/dist/routes/work-items.js +902 -0
  154. package/dist/routes/work-items.js.map +1 -0
  155. package/dist/rules/binding-context.d.ts +5 -0
  156. package/dist/rules/binding-context.d.ts.map +1 -0
  157. package/dist/rules/binding-context.js +40 -0
  158. package/dist/rules/binding-context.js.map +1 -0
  159. package/dist/rules/defaults.d.ts +9 -0
  160. package/dist/rules/defaults.d.ts.map +1 -0
  161. package/dist/rules/defaults.js +334 -0
  162. package/dist/rules/defaults.js.map +1 -0
  163. package/dist/rules/dispatcher.d.ts +40 -0
  164. package/dist/rules/dispatcher.d.ts.map +1 -0
  165. package/dist/rules/dispatcher.js +695 -0
  166. package/dist/rules/dispatcher.js.map +1 -0
  167. package/dist/rules/github-service.d.ts +29 -0
  168. package/dist/rules/github-service.d.ts.map +1 -0
  169. package/dist/rules/github-service.js +474 -0
  170. package/dist/rules/github-service.js.map +1 -0
  171. package/dist/rules/index.d.ts +7 -0
  172. package/dist/rules/index.d.ts.map +1 -0
  173. package/dist/rules/index.js +583 -0
  174. package/dist/rules/index.js.map +1 -0
  175. package/dist/rules/linear-service.d.ts +27 -0
  176. package/dist/rules/linear-service.d.ts.map +1 -0
  177. package/dist/rules/linear-service.js +343 -0
  178. package/dist/rules/linear-service.js.map +1 -0
  179. package/dist/rules/processor.d.ts +54 -0
  180. package/dist/rules/processor.d.ts.map +1 -0
  181. package/dist/rules/processor.js +629 -0
  182. package/dist/rules/processor.js.map +1 -0
  183. package/dist/rules/resolve.d.ts +17 -0
  184. package/dist/rules/resolve.d.ts.map +1 -0
  185. package/dist/rules/resolve.js +27 -0
  186. package/dist/rules/resolve.js.map +1 -0
  187. package/dist/rules/start-coordinator.d.ts +58 -0
  188. package/dist/rules/start-coordinator.d.ts.map +1 -0
  189. package/dist/rules/start-coordinator.js +136 -0
  190. package/dist/rules/start-coordinator.js.map +1 -0
  191. package/dist/rules/tools.d.ts +10 -0
  192. package/dist/rules/tools.d.ts.map +1 -0
  193. package/dist/rules/tools.js +93 -0
  194. package/dist/rules/tools.js.map +1 -0
  195. package/dist/rules/transition-service.d.ts +32 -0
  196. package/dist/rules/transition-service.d.ts.map +1 -0
  197. package/dist/rules/transition-service.js +474 -0
  198. package/dist/rules/transition-service.js.map +1 -0
  199. package/dist/rules/types.d.ts +225 -0
  200. package/dist/rules/types.d.ts.map +1 -0
  201. package/dist/rules/types.js +33 -0
  202. package/dist/rules/types.js.map +1 -0
  203. package/dist/rules/validation.d.ts +11 -0
  204. package/dist/rules/validation.d.ts.map +1 -0
  205. package/dist/rules/validation.js +310 -0
  206. package/dist/rules/validation.js.map +1 -0
  207. package/dist/sandbox/fleet.d.ts +208 -0
  208. package/dist/sandbox/fleet.d.ts.map +1 -0
  209. package/dist/sandbox/fleet.js +259 -0
  210. package/dist/sandbox/fleet.js.map +1 -0
  211. package/dist/sandbox/reattach.d.ts +3 -0
  212. package/dist/sandbox/reattach.d.ts.map +1 -0
  213. package/dist/sandbox/reattach.js +9 -0
  214. package/dist/sandbox/reattach.js.map +1 -0
  215. package/dist/server-error.d.ts +12 -0
  216. package/dist/server-error.d.ts.map +1 -0
  217. package/dist/server-error.js +20 -0
  218. package/dist/server-error.js.map +1 -0
  219. package/dist/skills/service.d.ts +48 -0
  220. package/dist/skills/service.d.ts.map +1 -0
  221. package/dist/skills/service.js +45 -0
  222. package/dist/skills/service.js.map +1 -0
  223. package/dist/spa-static.d.ts +34 -0
  224. package/dist/spa-static.d.ts.map +1 -0
  225. package/dist/spa-static.js +73 -0
  226. package/dist/spa-static.js.map +1 -0
  227. package/dist/state-signing.d.ts +48 -0
  228. package/dist/state-signing.d.ts.map +1 -0
  229. package/dist/state-signing.js +48 -0
  230. package/dist/state-signing.js.map +1 -0
  231. package/dist/storage/domains/audit/agent-audit.d.ts +27 -0
  232. package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -0
  233. package/dist/storage/domains/audit/agent-audit.js +65 -0
  234. package/dist/storage/domains/audit/agent-audit.js.map +1 -0
  235. package/dist/storage/domains/audit/base.d.ts +140 -0
  236. package/dist/storage/domains/audit/base.d.ts.map +1 -0
  237. package/dist/storage/domains/audit/base.js +127 -0
  238. package/dist/storage/domains/audit/base.js.map +1 -0
  239. package/dist/storage/domains/audit/domain.d.ts +69 -0
  240. package/dist/storage/domains/audit/domain.d.ts.map +1 -0
  241. package/dist/storage/domains/audit/domain.js +165 -0
  242. package/dist/storage/domains/audit/domain.js.map +1 -0
  243. package/dist/storage/domains/credentials/base.d.ts +134 -0
  244. package/dist/storage/domains/credentials/base.d.ts.map +1 -0
  245. package/dist/storage/domains/credentials/base.js +257 -0
  246. package/dist/storage/domains/credentials/base.js.map +1 -0
  247. package/dist/storage/domains/intake/base.d.ts +38 -0
  248. package/dist/storage/domains/intake/base.d.ts.map +1 -0
  249. package/dist/storage/domains/intake/base.js +62 -0
  250. package/dist/storage/domains/intake/base.js.map +1 -0
  251. package/dist/storage/domains/integrations/base.d.ts +126 -0
  252. package/dist/storage/domains/integrations/base.d.ts.map +1 -0
  253. package/dist/storage/domains/integrations/base.js +252 -0
  254. package/dist/storage/domains/integrations/base.js.map +1 -0
  255. package/dist/storage/domains/model-packs/base.d.ts +49 -0
  256. package/dist/storage/domains/model-packs/base.d.ts.map +1 -0
  257. package/dist/storage/domains/model-packs/base.js +95 -0
  258. package/dist/storage/domains/model-packs/base.js.map +1 -0
  259. package/dist/storage/domains/projects/base.d.ts +55 -0
  260. package/dist/storage/domains/projects/base.d.ts.map +1 -0
  261. package/dist/storage/domains/projects/base.js +99 -0
  262. package/dist/storage/domains/projects/base.js.map +1 -0
  263. package/dist/storage/domains/queue-health/base.d.ts +52 -0
  264. package/dist/storage/domains/queue-health/base.d.ts.map +1 -0
  265. package/dist/storage/domains/queue-health/base.js +87 -0
  266. package/dist/storage/domains/queue-health/base.js.map +1 -0
  267. package/dist/storage/domains/source-control/base.d.ts +288 -0
  268. package/dist/storage/domains/source-control/base.d.ts.map +1 -0
  269. package/dist/storage/domains/source-control/base.js +722 -0
  270. package/dist/storage/domains/source-control/base.js.map +1 -0
  271. package/dist/storage/domains/source-control/inmemory.d.ts +158 -0
  272. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -0
  273. package/dist/storage/domains/source-control/inmemory.js +348 -0
  274. package/dist/storage/domains/source-control/inmemory.js.map +1 -0
  275. package/dist/storage/domains/work-items/base.d.ts +412 -0
  276. package/dist/storage/domains/work-items/base.d.ts.map +1 -0
  277. package/dist/storage/domains/work-items/base.js +1174 -0
  278. package/dist/storage/domains/work-items/base.js.map +1 -0
  279. package/dist/storage/domains/work-items/metrics.d.ts +101 -0
  280. package/dist/storage/domains/work-items/metrics.d.ts.map +1 -0
  281. package/dist/storage/domains/work-items/metrics.js +203 -0
  282. package/dist/storage/domains/work-items/metrics.js.map +1 -0
  283. package/dist/workspace.d.ts +20 -0
  284. package/dist/workspace.d.ts.map +1 -0
  285. package/dist/workspace.js +364 -0
  286. package/dist/workspace.js.map +1 -0
  287. package/package.json +19 -19
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @mastra/factory
2
2
 
3
+ ## 0.1.0-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Forwarded closed Platform GitHub event-log deliveries into Factory governance before dispatching repository subscriptions, and kept default GitHub rules from auto-starting issues or pull requests created before the Factory. ([#19988](https://github.com/mastra-ai/mastra/pull/19988))
8
+
9
+ - Deployed factories now authenticate API and Studio requests with the same provider, so Studio sessions work without extra configuration. ([#19966](https://github.com/mastra-ai/mastra/pull/19966))
10
+
11
+ - Fixed cloned session threads reading from a previous storage instance. The dynamic memory cache now invalidates when the storage or vector instance changes, so thread cloning always uses the current database. ([#19966](https://github.com/mastra-ai/mastra/pull/19966))
12
+
13
+ - Updated dependencies [[`cc656b9`](https://github.com/mastra-ai/mastra/commit/cc656b92cc8fe40af3e2ea8bb796a6b406e96791), [`cc656b9`](https://github.com/mastra-ai/mastra/commit/cc656b92cc8fe40af3e2ea8bb796a6b406e96791), [`337d41d`](https://github.com/mastra-ai/mastra/commit/337d41d8aae0399d2bf42d42ebddac0c21953891)]:
14
+ - @mastra/code-sdk@1.0.0-alpha.15
15
+
16
+ ## 0.1.0-alpha.2
17
+
18
+ ### Patch Changes
19
+
20
+ - Fixed Factory metrics windowing to use inclusive UTC calendar days. Date-only `from`/`to` bounds now include both selected days, an item completing at the current instant is counted in today's throughput (previously it could be dropped on the window's exclusive edge), and `windowDays` reflects the number of gap-filled day buckets. Cards feed the source mix only when created inside the window. ([#19971](https://github.com/mastra-ai/mastra/pull/19971))
21
+
22
+ - Fixed duplicate repositories in Factory source control settings. ([#19971](https://github.com/mastra-ai/mastra/pull/19971))
23
+
24
+ - Fixed Factory automation so polled GitHub events reach governance rules, authenticated sessions start with the correct ownership, and board moves reliably notify active or idle agents. ([#19979](https://github.com/mastra-ai/mastra/pull/19979))
25
+
3
26
  ## 0.1.0-alpha.1
4
27
 
5
28
  ### Minor Changes
package/LICENSE.md ADDED
@@ -0,0 +1,30 @@
1
+ Portions of this software are licensed as follows:
2
+
3
+ - All content that resides under any directory named "ee/" within this
4
+ repository, including but not limited to:
5
+ - `packages/core/src/auth/ee/`
6
+ - `packages/server/src/server/auth/ee/`
7
+ is licensed under the license defined in `ee/LICENSE`.
8
+
9
+ - All third-party components incorporated into the Mastra Software are
10
+ licensed under the original license provided by the owner of the
11
+ applicable component.
12
+
13
+ - Content outside of the above-mentioned directories or restrictions is
14
+ available under the "Apache License 2.0" as defined below.
15
+
16
+ # Apache License 2.0
17
+
18
+ Copyright (c) 2025 Kepler Software, Inc.
19
+
20
+ Licensed under the Apache License, Version 2.0 (the "License");
21
+ you may not use this file except in compliance with the License.
22
+ You may obtain a copy of the License at
23
+
24
+ http://www.apache.org/licenses/LICENSE-2.0
25
+
26
+ Unless required by applicable law or agreed to in writing, software
27
+ distributed under the License is distributed on an "AS IS" BASIS,
28
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29
+ See the License for the specific language governing permissions and
30
+ limitations under the License.
package/dist/auth.d.ts ADDED
@@ -0,0 +1,181 @@
1
+ import { MastraAuthWorkos } from '@mastra/auth-workos';
2
+ import type { ApiRoute, IMastraAuthProvider } from '@mastra/core/server';
3
+ import type { Context, Hono } from 'hono';
4
+ import type { RouteAuth } from './routes/route.js';
5
+ /**
6
+ * Provider-neutral factory auth gating for the MastraCode web server.
7
+ *
8
+ * When an auth provider is active (a `MastraAuthProvider` instance passed to
9
+ * `MastraFactory`'s `auth` slot, or — back-compat for suites/paths that never
10
+ * boot the factory — implied by the WorkOS env vars), every route on the web
11
+ * server is placed behind it: unauthenticated browser navigations are
12
+ * redirected to the SPA's `/signin` page, API/XHR calls receive a 401, and a
13
+ * small set of public routes stay reachable while signed out — the provider's
14
+ * `/auth/*` routes plus `/auth/me`, the `/signin` page and its `/assets/*`
15
+ * bundle. When no provider is active, `mountFactoryAuth` is a no-op and the server
16
+ * behaves exactly as it does without auth.
17
+ *
18
+ * Provider specifics stay in the providers (`@mastra/auth-workos`,
19
+ * `@mastra/auth-better-auth`, or any custom `IMastraAuthProvider`); this
20
+ * module composes them capability-first via the core type guards:
21
+ * - `authenticateToken` — session/bearer validation (all providers)
22
+ * - `ISSOProvider` — hosted-login `/auth/login`, `/auth/callback`, `/auth/logout`
23
+ * - `IAuthHttpHandler` — provider-owned `/auth/api/*` endpoints (better-auth)
24
+ * - `IOrganizationsProvider` — personal-org bootstrap + admin checks
25
+ * - `ICredentialsProvider.isSignUpEnabled` — SPA sign-up affordance
26
+ * - `getClearSessionHeaders` — session cookie clearing on logout
27
+ */
28
+ /** Minimal shape of the signed-in user surfaced to the SPA (no tokens). */
29
+ export interface FactoryAuthUser {
30
+ /** Stable WorkOS user id used to scope per-user data (GitHub installs etc.). */
31
+ workosId?: string;
32
+ /** Provider user id; WorkOS shapes may use `workosId` instead (see {@link workosId}). */
33
+ id?: string;
34
+ email?: string;
35
+ name?: string;
36
+ /**
37
+ * Organization id. The org is the top-level tenant: it owns the GitHub
38
+ * App installation and connected projects, while each user inside the org gets
39
+ * isolated building instances. Absent for personal (no-org) accounts.
40
+ */
41
+ organizationId?: string;
42
+ }
43
+ /**
44
+ * Tenant identity: the org is the top-level tenant, and each user inside it is
45
+ * an isolated builder. Agent state, worktrees and sandboxes are scoped per
46
+ * `(orgId, userId)`. Personal (no-org) users have `orgId === undefined`.
47
+ */
48
+ export interface FactoryAuthTenant {
49
+ /** Organization id, or `undefined` for personal (no-org) accounts. */
50
+ orgId?: string;
51
+ /** Stable provider user id. */
52
+ userId: string;
53
+ }
54
+ /**
55
+ * Validate that a `returnTo` value is a safe same-site path, to prevent
56
+ * open-redirect attacks. Only absolute local paths (`/foo`) are allowed;
57
+ * protocol-relative (`//evil.com`) and absolute URLs are rejected.
58
+ */
59
+ export declare function sanitizeReturnTo(raw: string | undefined): string;
60
+ /** Extract a bearer token from the Authorization header, if present. */
61
+ export declare function getBearerToken(authorization: string | undefined): string;
62
+ /**
63
+ * Whether the SPA is served cross-origin from this API (platform deploy). When
64
+ * `MASTRACODE_ALLOWED_ORIGINS` is set the browser talks to us cross-site, so
65
+ * session cookies must be `SameSite=None; Secure` for the browser to send them.
66
+ * Same-origin local dev leaves this unset and keeps the stricter `SameSite=Lax`.
67
+ */
68
+ export declare function isCrossSiteAuth(): boolean;
69
+ /** Hono context variables set by the auth gate. */
70
+ export interface FactoryAuthVariables {
71
+ factoryAuthUser: FactoryAuthUser;
72
+ }
73
+ /**
74
+ * Read the authenticated user the gate stashed on the context, or
75
+ * `undefined` when unauthenticated / auth disabled. Used by downstream routes
76
+ * (e.g. GitHub) to scope rows per user.
77
+ */
78
+ export declare function getFactoryAuthUser(c: Context): FactoryAuthUser | undefined;
79
+ /** Resolve the stable user id from an authenticated user shape. */
80
+ export declare function getFactoryAuthUserId(user: FactoryAuthUser | undefined): string | undefined;
81
+ /** Resolve the organization id from a user shape, if present. */
82
+ export declare function getFactoryAuthOrgId(user: FactoryAuthUser | undefined): string | undefined;
83
+ /**
84
+ * Resolve the tenant identity `(orgId, userId)` from the authenticated user on
85
+ * the context. Returns `undefined` when there is no signed-in user (auth
86
+ * disabled or unauthenticated). `orgId` is `undefined` for personal accounts;
87
+ * callers gate org-scoped GitHub features on its presence while agent state
88
+ * falls back to a user-only tenant.
89
+ */
90
+ export declare function factoryAuthTenant(c: Context): FactoryAuthTenant | undefined;
91
+ /**
92
+ * Fail-closed authorization for organization-level administrative mutations.
93
+ * The caller must belong to the same active organization and the provider must
94
+ * explicitly confirm an admin/owner role.
95
+ */
96
+ export declare function isOrganizationAdmin(provider: IMastraAuthProvider | undefined, c: Context, organizationId: string): Promise<boolean>;
97
+ /**
98
+ * Build the factory's implementation of the `RouteAuth` seam over the
99
+ * resolved provider (`undefined` = auth disabled). Constructed once per boot
100
+ * by `MastraFactory.prepare()` and handed to factory route modules at
101
+ * construction — they never import the factory auth module directly.
102
+ */
103
+ export declare function createFactoryRouteAuth(provider: IMastraAuthProvider | undefined): RouteAuth;
104
+ /** True when the given provider is WorkOS. Gates WorkOS-only capabilities. */
105
+ export declare function isWorkOSAuth(provider: IMastraAuthProvider | undefined): boolean;
106
+ /**
107
+ * The raw WorkOS provider, for features that need the WorkOS client directly
108
+ * (audit-log export, Admin Portal links). Callers must gate on
109
+ * {@link isWorkOSAuth} first — throws when the provider is not WorkOS.
110
+ */
111
+ export declare function getWorkOSProvider(provider: IMastraAuthProvider | undefined): MastraAuthWorkos;
112
+ /**
113
+ * Resolve the authenticated user for a request, stashing it on the context.
114
+ *
115
+ * The gate only authenticates non-`/auth/*` requests via the `Authorization`
116
+ * header, so cookie-based browser navigations to public `/auth/*` routes (the
117
+ * GitHub connect/callback flow) arrive without a gate-stashed user. This reads
118
+ * the session cookie from the raw request the same way `/auth/me` does,
119
+ * caches the result on the context, and returns it so downstream helpers like
120
+ * {@link factoryAuthTenant} work uniformly on both gated and public routes.
121
+ *
122
+ * Returns `undefined` when there is no valid session (or auth is disabled).
123
+ */
124
+ export declare function ensureFactoryAuthUser(provider: IMastraAuthProvider | undefined, c: Context): Promise<FactoryAuthUser | undefined>;
125
+ export interface MountFactoryAuthOptions {
126
+ /**
127
+ * Explicit auth provider to mount. When omitted, falls back to a WorkOS
128
+ * provider implied by the `WORKOS_*` env vars (back-compat for suites that
129
+ * never boot the factory).
130
+ */
131
+ provider?: IMastraAuthProvider;
132
+ /**
133
+ * Absolute URL the identity provider redirects back to after login (WorkOS
134
+ * env-fallback path only). Defaults to the `WORKOS_REDIRECT_URI` env var.
135
+ */
136
+ redirectUri?: string;
137
+ /** Browser-facing origin used to derive the SSO callback URL. */
138
+ publicUrl?: string;
139
+ }
140
+ /**
141
+ * Register the public `/auth/*` routes on a Hono app: the capability-derived
142
+ * provider routes (login/callback/logout/provider APIs) plus the
143
+ * provider-neutral `/auth/me`. Split out from `mountFactoryAuth` so both the local
144
+ * Hono server and the platform Mastra entry can reuse the exact same handlers.
145
+ */
146
+ export declare function registerAuthRoutes(app: Hono<any>, provider: IMastraAuthProvider, options?: {
147
+ publicUrl?: string;
148
+ }): void;
149
+ /**
150
+ * Build the public `/auth/*` routes (provider routes + `/auth/me`) as Mastra
151
+ * `server.apiRoutes`. Used by the platform Mastra entry (`src/mastra/index.ts`),
152
+ * which can't register plain Hono routes on the deployer-generated app the way
153
+ * the local server does via {@link registerAuthRoutes}.
154
+ *
155
+ * Handlers are identical to {@link registerAuthRoutes}. All are `requiresAuth: false`
156
+ * (they must be reachable while unauthenticated), and the gate middleware skips
157
+ * `/auth/*` so it never blocks them. `/auth/*` is not under `/api`, so it is a
158
+ * valid custom-route path.
159
+ */
160
+ export declare function buildAuthRoutes(provider: IMastraAuthProvider, options?: {
161
+ publicUrl?: string;
162
+ }): ApiRoute[];
163
+ /**
164
+ * Build the auth gate as a plain Hono middleware handler `(c, next)`. Protects
165
+ * everything that is not a public `/auth/*` route: authenticated requests stash
166
+ * the user on the context and continue; unauthenticated navigations redirect to
167
+ * login and XHR/API calls get a 401 JSON. Shared by the local Hono server
168
+ * (`mountFactoryAuth`) and the platform Mastra entry (`server.middleware`).
169
+ */
170
+ export declare function createFactoryAuthGate(provider: IMastraAuthProvider): (c: Context, next: () => Promise<void>) => Promise<Response | void>;
171
+ /**
172
+ * Mount factory auth gating onto the host app. No-op when auth is disabled
173
+ * (no provider active).
174
+ *
175
+ * Must be called before the Mastra adapter routes, the `/web/*` routes, and
176
+ * the static UI handlers so the gate covers every request. Composes the shared
177
+ * `registerAuthRoutes` + `createFactoryAuthGate` factories so the local Hono server
178
+ * and the platform Mastra entry stay behavior-identical.
179
+ */
180
+ export declare function mountFactoryAuth(app: Hono<any>, options?: MountFactoryAuthOptions): boolean;
181
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AASvD,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAoB,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMhE;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIxE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,eAAe,CAAC;CAClC;AAKD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAE1E;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE1F;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEzF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAK3E;AAyHD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,mBAAmB,GAAG,SAAS,EACzC,CAAC,EAAE,OAAO,EACV,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,SAAS,GAAG,SAAS,CAO3F;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAE/E;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,SAAS,GAAG,gBAAgB,CAG7F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,mBAAmB,GAAG,SAAS,EACzC,CAAC,EAAE,OAAO,GACT,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAatC;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4ND;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EACd,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,IAAI,CAMN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,mBAAmB,EAAE,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,QAAQ,EAAE,CAmB/G;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,IACnD,GAAG,OAAO,EAAE,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAkC/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAO/F"}
package/dist/auth.js ADDED
@@ -0,0 +1,370 @@
1
+ // src/auth.ts
2
+ import { MastraAuthWorkos } from "@mastra/auth-workos";
3
+ import {
4
+ registerApiRoute,
5
+ isAuthHttpHandler,
6
+ isCredentialsProvider,
7
+ isOrganizationsProvider,
8
+ isSessionProvider,
9
+ isSSOProvider
10
+ } from "@mastra/core/server";
11
+ function sanitizeReturnTo(raw) {
12
+ if (!raw) return "/";
13
+ if (!raw.startsWith("/")) return "/";
14
+ if (raw.startsWith("//") || raw.startsWith("/\\")) return "/";
15
+ return raw;
16
+ }
17
+ function getBearerToken(authorization) {
18
+ if (!authorization) return "";
19
+ const match = /^Bearer\s+(.+)$/i.exec(authorization);
20
+ return match?.[1] ?? "";
21
+ }
22
+ function isCrossSiteAuth() {
23
+ return Boolean(process.env.MASTRACODE_ALLOWED_ORIGINS?.trim());
24
+ }
25
+ var FACTORY_AUTH_USER_KEY = "factoryAuthUser";
26
+ function getFactoryAuthUser(c) {
27
+ return c.get(FACTORY_AUTH_USER_KEY);
28
+ }
29
+ function getFactoryAuthUserId(user) {
30
+ return user?.workosId ?? user?.id;
31
+ }
32
+ function getFactoryAuthOrgId(user) {
33
+ return user?.organizationId;
34
+ }
35
+ function factoryAuthTenant(c) {
36
+ const user = getFactoryAuthUser(c);
37
+ const userId = getFactoryAuthUserId(user);
38
+ if (!userId) return void 0;
39
+ return { orgId: getFactoryAuthOrgId(user), userId };
40
+ }
41
+ function envWorkosConfigured() {
42
+ return Boolean(process.env.WORKOS_API_KEY && process.env.WORKOS_CLIENT_ID);
43
+ }
44
+ function envFallbackAuthProvider(redirectUri) {
45
+ if (!envWorkosConfigured()) return void 0;
46
+ return new MastraAuthWorkos({
47
+ redirectUri: redirectUri ?? process.env.WORKOS_REDIRECT_URI,
48
+ fetchMemberships: true
49
+ });
50
+ }
51
+ function toFactoryAuthUser(result) {
52
+ if (!result || typeof result !== "object") return null;
53
+ const record = result;
54
+ if (record.user && typeof record.user === "object" && record.session && typeof record.session === "object") {
55
+ const user = record.user;
56
+ const session = record.session;
57
+ if (typeof user.id !== "string") return null;
58
+ return {
59
+ id: user.id,
60
+ email: typeof user.email === "string" ? user.email : void 0,
61
+ name: typeof user.name === "string" ? user.name : void 0,
62
+ organizationId: typeof session.activeOrganizationId === "string" ? session.activeOrganizationId : void 0
63
+ };
64
+ }
65
+ const flat = record;
66
+ const id = typeof flat.id === "string" ? flat.id : void 0;
67
+ const workosId = typeof flat.workosId === "string" ? flat.workosId : void 0;
68
+ if (!id && !workosId) return null;
69
+ return {
70
+ id,
71
+ workosId,
72
+ email: typeof flat.email === "string" ? flat.email : void 0,
73
+ name: typeof flat.name === "string" ? flat.name : void 0,
74
+ organizationId: typeof flat.organizationId === "string" ? flat.organizationId : void 0
75
+ };
76
+ }
77
+ async function authenticateRequest(provider, token, raw) {
78
+ try {
79
+ const result = await provider.authenticateToken(token, raw);
80
+ return toFactoryAuthUser(result);
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+ async function ensureUserOrg(provider, user) {
86
+ if (getFactoryAuthOrgId(user)) return;
87
+ if (!isOrganizationsProvider(provider)) return;
88
+ const userId = getFactoryAuthUserId(user);
89
+ if (!userId) return;
90
+ try {
91
+ const orgId = await provider.ensureOrganization(userId);
92
+ if (orgId) user.organizationId = orgId;
93
+ } catch {
94
+ }
95
+ }
96
+ function providerClearCookies(provider) {
97
+ const getClearSessionHeaders = provider.getClearSessionHeaders;
98
+ if (typeof getClearSessionHeaders !== "function") return [];
99
+ const headers = getClearSessionHeaders.call(provider) ?? {};
100
+ const setCookie = headers["Set-Cookie"];
101
+ if (!setCookie) return [];
102
+ return setCookie.split(/,(?=\s*[^;=,\s]+=)/).map((cookie) => cookie.trim());
103
+ }
104
+ async function isOrganizationAdmin(provider, c, organizationId) {
105
+ const user = await ensureFactoryAuthUser(provider, c);
106
+ if (!user || user.organizationId !== organizationId || !provider || !isOrganizationsProvider(provider)) {
107
+ return false;
108
+ }
109
+ const userId = getFactoryAuthUserId(user);
110
+ if (!userId) return false;
111
+ try {
112
+ return await provider.isOrganizationAdmin(organizationId, userId);
113
+ } catch {
114
+ return false;
115
+ }
116
+ }
117
+ function createFactoryRouteAuth(provider) {
118
+ return {
119
+ enabled: () => provider !== void 0,
120
+ ensureUser: (c) => ensureFactoryAuthUser(provider, c),
121
+ tenant: (c) => factoryAuthTenant(c),
122
+ isOrganizationAdmin: (c, organizationId) => isOrganizationAdmin(provider, c, organizationId)
123
+ };
124
+ }
125
+ function isWorkOSAuth(provider) {
126
+ return provider instanceof MastraAuthWorkos;
127
+ }
128
+ function getWorkOSProvider(provider) {
129
+ if (provider instanceof MastraAuthWorkos) return provider;
130
+ throw new Error("WorkOS provider requested but the active factory auth provider is not WorkOS");
131
+ }
132
+ async function ensureFactoryAuthUser(provider, c) {
133
+ const existing = getFactoryAuthUser(c);
134
+ if (existing) return existing;
135
+ if (!provider) return void 0;
136
+ const token = getBearerToken(c.req.header("Authorization"));
137
+ const user = await authenticateRequest(provider, token, c.req.raw);
138
+ if (!user) return void 0;
139
+ await ensureUserOrg(provider, user);
140
+ c.set(FACTORY_AUTH_USER_KEY, user);
141
+ return user;
142
+ }
143
+ function isNavigationRequest(path, accept) {
144
+ if (path.startsWith("/api/")) return false;
145
+ return (accept ?? "").includes("text/html");
146
+ }
147
+ async function handleAuthMe(provider, c) {
148
+ const token = getBearerToken(c.req.header("Authorization"));
149
+ const user = await authenticateRequest(provider, token, c.req.raw);
150
+ const signUpDisabled = isCredentialsProvider(provider) && provider.isSignUpEnabled?.() === false;
151
+ const meta = { provider: provider.name, ...signUpDisabled ? { signUpDisabled: true } : {} };
152
+ if (!user) {
153
+ return c.json({ authenticated: false, user: null, ...meta });
154
+ }
155
+ await ensureUserOrg(provider, user);
156
+ return c.json({
157
+ authenticated: true,
158
+ user: {
159
+ userId: getFactoryAuthUserId(user),
160
+ email: user.email,
161
+ name: user.name,
162
+ organizationId: user.organizationId
163
+ },
164
+ ...meta
165
+ });
166
+ }
167
+ function encodeState(returnTo) {
168
+ return Buffer.from(JSON.stringify({ returnTo }), "utf8").toString("base64url");
169
+ }
170
+ function decodeState(state) {
171
+ if (!state) return "/";
172
+ try {
173
+ const parsed = JSON.parse(Buffer.from(state, "base64url").toString("utf8"));
174
+ return sanitizeReturnTo(parsed.returnTo);
175
+ } catch {
176
+ return "/";
177
+ }
178
+ }
179
+ function providerAuthRoutes(provider, publicUrl) {
180
+ const routes = [];
181
+ if (isAuthHttpHandler(provider)) {
182
+ routes.push({
183
+ path: "/auth/api/*",
184
+ method: "ALL",
185
+ handler: (c) => provider.handleAuthRequest(c.req.raw)
186
+ });
187
+ }
188
+ if (isSSOProvider(provider)) {
189
+ routes.push(
190
+ {
191
+ path: "/auth/login",
192
+ method: "GET",
193
+ handler: async (c) => {
194
+ const returnTo = sanitizeReturnTo(c.req.query("returnTo"));
195
+ const state = encodeState(returnTo);
196
+ const redirectUri = publicUrl ? new URL("/auth/callback", publicUrl).toString() : "";
197
+ const loginUrl = await provider.getLoginUrl(redirectUri, state);
198
+ for (const cookie of await provider.getLoginCookies?.(redirectUri, state) ?? []) {
199
+ c.header("Set-Cookie", cookie, { append: true });
200
+ }
201
+ return c.redirect(loginUrl);
202
+ }
203
+ },
204
+ {
205
+ path: "/auth/callback",
206
+ method: "GET",
207
+ handler: async (c) => {
208
+ const code = c.req.query("code");
209
+ const returnTo = decodeState(c.req.query("state"));
210
+ if (!code) {
211
+ return c.redirect("/auth/login");
212
+ }
213
+ try {
214
+ const result = await provider.handleCallback(code, c.req.query("state") ?? "");
215
+ if (result.cookies?.length) {
216
+ for (const cookie of result.cookies) {
217
+ c.header("Set-Cookie", cookie, { append: true });
218
+ }
219
+ } else if (isSessionProvider(provider) && result.tokens) {
220
+ const resultUser = result.user;
221
+ const session = await provider.createSession(resultUser.id, {
222
+ accessToken: result.tokens.accessToken,
223
+ refreshToken: result.tokens.refreshToken,
224
+ expiresAt: result.tokens.expiresAt,
225
+ organizationId: resultUser.organizationId
226
+ });
227
+ for (const [key, value] of Object.entries(provider.getSessionHeaders(session))) {
228
+ c.header(key, value, { append: true });
229
+ }
230
+ }
231
+ return c.redirect(returnTo);
232
+ } catch {
233
+ return c.redirect("/auth/login");
234
+ }
235
+ }
236
+ },
237
+ {
238
+ path: "/auth/logout",
239
+ method: "GET",
240
+ handler: async (c) => {
241
+ let logoutUrl = null;
242
+ try {
243
+ logoutUrl = await provider.getLogoutUrl?.("/", c.req.raw) ?? null;
244
+ } catch {
245
+ logoutUrl = null;
246
+ }
247
+ for (const cookie of providerClearCookies(provider)) {
248
+ c.header("Set-Cookie", cookie, { append: true });
249
+ }
250
+ return c.redirect(logoutUrl ?? "/");
251
+ }
252
+ }
253
+ );
254
+ } else if (isAuthHttpHandler(provider)) {
255
+ routes.push(
256
+ {
257
+ // Hosted-login equivalent: no hosted page, so send the browser to the
258
+ // SPA's /signin form, preserving returnTo.
259
+ path: "/auth/login",
260
+ method: "GET",
261
+ handler: (c) => {
262
+ const returnTo = sanitizeReturnTo(c.req.query("returnTo"));
263
+ return c.redirect(`/signin?returnTo=${encodeURIComponent(returnTo)}`);
264
+ }
265
+ },
266
+ {
267
+ path: "/auth/logout",
268
+ method: "GET",
269
+ handler: async (c) => {
270
+ try {
271
+ const origin = new URL(c.req.url).origin;
272
+ const response = await provider.handleAuthRequest(
273
+ new Request(`${origin}/auth/api/sign-out`, { method: "POST", headers: c.req.raw.headers })
274
+ );
275
+ for (const cookie of response.headers.getSetCookie()) {
276
+ c.header("Set-Cookie", cookie, { append: true });
277
+ }
278
+ } catch {
279
+ }
280
+ for (const cookie of providerClearCookies(provider)) {
281
+ c.header("Set-Cookie", cookie, { append: true });
282
+ }
283
+ return c.redirect("/");
284
+ }
285
+ }
286
+ );
287
+ }
288
+ return routes;
289
+ }
290
+ function registerAuthRoutes(app, provider, options = {}) {
291
+ for (const route of providerAuthRoutes(provider, options.publicUrl)) {
292
+ const methods = route.method === "ALL" ? ["GET", "POST", "PUT", "DELETE", "PATCH"] : [route.method];
293
+ app.on(methods, route.path, (c) => route.handler(c));
294
+ }
295
+ app.get("/auth/me", (c) => handleAuthMe(provider, c));
296
+ }
297
+ function buildAuthRoutes(provider, options = {}) {
298
+ return [
299
+ // `registerApiRoute` handlers see @mastra/core's bundled hono Context type,
300
+ // which is structurally identical to (but nominally distinct from) the
301
+ // local hono version the route handlers are typed against — cast across
302
+ // the seam.
303
+ ...providerAuthRoutes(provider, options.publicUrl).map(
304
+ (route) => registerApiRoute(route.path, {
305
+ method: route.method,
306
+ requiresAuth: false,
307
+ handler: (c) => route.handler(c)
308
+ })
309
+ ),
310
+ registerApiRoute("/auth/me", {
311
+ method: "GET",
312
+ requiresAuth: false,
313
+ handler: (c) => handleAuthMe(provider, c)
314
+ })
315
+ ];
316
+ }
317
+ function createFactoryAuthGate(provider) {
318
+ return async (c, next) => {
319
+ const path = c.req.path;
320
+ if (path.startsWith("/auth/")) {
321
+ return next();
322
+ }
323
+ if (c.req.method === "POST" && path === "/web/github/webhook") {
324
+ return next();
325
+ }
326
+ if (path === "/signin" || path.startsWith("/assets/")) {
327
+ return next();
328
+ }
329
+ const token = getBearerToken(c.req.header("Authorization"));
330
+ const user = await authenticateRequest(provider, token, c.req.raw);
331
+ if (user) {
332
+ await ensureUserOrg(provider, user);
333
+ c.set(FACTORY_AUTH_USER_KEY, user);
334
+ c.get("requestContext")?.set("user", user);
335
+ return next();
336
+ }
337
+ if (isNavigationRequest(path, c.req.header("Accept"))) {
338
+ const url = new URL(c.req.url);
339
+ const returnTo = sanitizeReturnTo(url.pathname + url.search);
340
+ return c.redirect(`/signin?returnTo=${encodeURIComponent(returnTo)}`);
341
+ }
342
+ return c.json({ error: "unauthorized" }, 401);
343
+ };
344
+ }
345
+ function mountFactoryAuth(app, options = {}) {
346
+ const provider = options.provider ?? envFallbackAuthProvider(options.redirectUri);
347
+ if (!provider) return false;
348
+ registerAuthRoutes(app, provider, { publicUrl: options.publicUrl });
349
+ app.use("*", createFactoryAuthGate(provider));
350
+ return true;
351
+ }
352
+ export {
353
+ buildAuthRoutes,
354
+ createFactoryAuthGate,
355
+ createFactoryRouteAuth,
356
+ ensureFactoryAuthUser,
357
+ factoryAuthTenant,
358
+ getBearerToken,
359
+ getFactoryAuthOrgId,
360
+ getFactoryAuthUser,
361
+ getFactoryAuthUserId,
362
+ getWorkOSProvider,
363
+ isCrossSiteAuth,
364
+ isOrganizationAdmin,
365
+ isWorkOSAuth,
366
+ mountFactoryAuth,
367
+ registerAuthRoutes,
368
+ sanitizeReturnTo
369
+ };
370
+ //# sourceMappingURL=auth.js.map