@agent-native/core 0.7.81 → 0.7.83

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 (257) hide show
  1. package/dist/action.d.ts +8 -0
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +4 -0
  4. package/dist/action.js.map +1 -1
  5. package/dist/agent/production-agent.d.ts +12 -2
  6. package/dist/agent/production-agent.d.ts.map +1 -1
  7. package/dist/agent/production-agent.js +58 -20
  8. package/dist/agent/production-agent.js.map +1 -1
  9. package/dist/agent/run-manager.d.ts +8 -1
  10. package/dist/agent/run-manager.d.ts.map +1 -1
  11. package/dist/agent/run-manager.js +11 -12
  12. package/dist/agent/run-manager.js.map +1 -1
  13. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  14. package/dist/agent/thread-data-builder.js +13 -17
  15. package/dist/agent/thread-data-builder.js.map +1 -1
  16. package/dist/agent/types.d.ts +4 -0
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/agent/types.js.map +1 -1
  19. package/dist/application-state/handlers.d.ts.map +1 -1
  20. package/dist/application-state/handlers.js +3 -8
  21. package/dist/application-state/handlers.js.map +1 -1
  22. package/dist/application-state/script-helpers.d.ts +2 -4
  23. package/dist/application-state/script-helpers.d.ts.map +1 -1
  24. package/dist/application-state/script-helpers.js +10 -47
  25. package/dist/application-state/script-helpers.js.map +1 -1
  26. package/dist/cli/create.d.ts +1 -1
  27. package/dist/cli/create.d.ts.map +1 -1
  28. package/dist/cli/create.js +35 -10
  29. package/dist/cli/create.js.map +1 -1
  30. package/dist/cli/workspace-dev.js +78 -15
  31. package/dist/cli/workspace-dev.js.map +1 -1
  32. package/dist/client/AgentPanel.d.ts.map +1 -1
  33. package/dist/client/AgentPanel.js +6 -2
  34. package/dist/client/AgentPanel.js.map +1 -1
  35. package/dist/client/AssistantChat.d.ts +0 -15
  36. package/dist/client/AssistantChat.d.ts.map +1 -1
  37. package/dist/client/AssistantChat.js +69 -57
  38. package/dist/client/AssistantChat.js.map +1 -1
  39. package/dist/client/ConnectBuilderCard.d.ts +7 -1
  40. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  41. package/dist/client/ConnectBuilderCard.js +46 -5
  42. package/dist/client/ConnectBuilderCard.js.map +1 -1
  43. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  44. package/dist/client/ErrorBoundary.js +20 -5
  45. package/dist/client/ErrorBoundary.js.map +1 -1
  46. package/dist/client/FeedbackButton.d.ts +3 -2
  47. package/dist/client/FeedbackButton.d.ts.map +1 -1
  48. package/dist/client/FeedbackButton.js +23 -15
  49. package/dist/client/FeedbackButton.js.map +1 -1
  50. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  51. package/dist/client/agent-chat-adapter.js +303 -169
  52. package/dist/client/agent-chat-adapter.js.map +1 -1
  53. package/dist/client/builder-frame.d.ts +36 -0
  54. package/dist/client/builder-frame.d.ts.map +1 -1
  55. package/dist/client/builder-frame.js +80 -9
  56. package/dist/client/builder-frame.js.map +1 -1
  57. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
  58. package/dist/client/composer/ComposerPlusMenu.js +7 -2
  59. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  60. package/dist/client/composer/PastedTextChip.d.ts +9 -0
  61. package/dist/client/composer/PastedTextChip.d.ts.map +1 -0
  62. package/dist/client/composer/PastedTextChip.js +47 -0
  63. package/dist/client/composer/PastedTextChip.js.map +1 -0
  64. package/dist/client/composer/PromptComposer.d.ts +4 -2
  65. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  66. package/dist/client/composer/PromptComposer.js +33 -5
  67. package/dist/client/composer/PromptComposer.js.map +1 -1
  68. package/dist/client/composer/TiptapComposer.d.ts +13 -1
  69. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  70. package/dist/client/composer/TiptapComposer.js +61 -16
  71. package/dist/client/composer/TiptapComposer.js.map +1 -1
  72. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  73. package/dist/client/composer/VoiceButton.js +5 -1
  74. package/dist/client/composer/VoiceButton.js.map +1 -1
  75. package/dist/client/composer/pasted-text.d.ts +6 -0
  76. package/dist/client/composer/pasted-text.d.ts.map +1 -0
  77. package/dist/client/composer/pasted-text.js +49 -0
  78. package/dist/client/composer/pasted-text.js.map +1 -0
  79. package/dist/client/composer/useVoiceDictation.d.ts +1 -0
  80. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  81. package/dist/client/composer/useVoiceDictation.js +18 -0
  82. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  83. package/dist/client/index.d.ts +0 -1
  84. package/dist/client/index.d.ts.map +1 -1
  85. package/dist/client/index.js +0 -1
  86. package/dist/client/index.js.map +1 -1
  87. package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
  88. package/dist/client/integrations/IntegrationCard.js +14 -2
  89. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  90. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  91. package/dist/client/integrations/IntegrationsPanel.js +23 -4
  92. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  93. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
  94. package/dist/client/notifications/NotificationsBell.js +4 -42
  95. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  96. package/dist/client/org/OrgSwitcher.d.ts +4 -6
  97. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  98. package/dist/client/org/OrgSwitcher.js +84 -74
  99. package/dist/client/org/OrgSwitcher.js.map +1 -1
  100. package/dist/client/org/TeamPage.d.ts.map +1 -1
  101. package/dist/client/org/TeamPage.js +3 -154
  102. package/dist/client/org/TeamPage.js.map +1 -1
  103. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  104. package/dist/client/resources/ResourcesPanel.js +13 -35
  105. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  106. package/dist/client/settings/SettingsPanel.js +1 -1
  107. package/dist/client/settings/SettingsPanel.js.map +1 -1
  108. package/dist/client/settings/useBuilderStatus.d.ts +6 -0
  109. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  110. package/dist/client/settings/useBuilderStatus.js +3 -0
  111. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  112. package/dist/client/sse-event-processor.d.ts +15 -1
  113. package/dist/client/sse-event-processor.d.ts.map +1 -1
  114. package/dist/client/sse-event-processor.js +58 -54
  115. package/dist/client/sse-event-processor.js.map +1 -1
  116. package/dist/client/tools/ToolEditor.d.ts.map +1 -1
  117. package/dist/client/tools/ToolEditor.js +34 -4
  118. package/dist/client/tools/ToolEditor.js.map +1 -1
  119. package/dist/client/tools/ToolViewer.d.ts.map +1 -1
  120. package/dist/client/tools/ToolViewer.js +20 -1
  121. package/dist/client/tools/ToolViewer.js.map +1 -1
  122. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  123. package/dist/client/tools/ToolsListPage.js +2 -1
  124. package/dist/client/tools/ToolsListPage.js.map +1 -1
  125. package/dist/client/tools/ToolsSidebarSection.js +1 -1
  126. package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
  127. package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
  128. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  129. package/dist/client/use-chat-threads.d.ts.map +1 -1
  130. package/dist/client/use-chat-threads.js +7 -2
  131. package/dist/client/use-chat-threads.js.map +1 -1
  132. package/dist/collab/client.d.ts.map +1 -1
  133. package/dist/collab/client.js +26 -7
  134. package/dist/collab/client.js.map +1 -1
  135. package/dist/jobs/scheduler.js +0 -4
  136. package/dist/jobs/scheduler.js.map +1 -1
  137. package/dist/oauth-tokens/store.d.ts +0 -4
  138. package/dist/oauth-tokens/store.d.ts.map +1 -1
  139. package/dist/oauth-tokens/store.js +3 -24
  140. package/dist/oauth-tokens/store.js.map +1 -1
  141. package/dist/observability/routes.d.ts.map +1 -1
  142. package/dist/observability/routes.js +1 -9
  143. package/dist/observability/routes.js.map +1 -1
  144. package/dist/onboarding/default-steps.js +1 -1
  145. package/dist/onboarding/default-steps.js.map +1 -1
  146. package/dist/onboarding/plugin.d.ts.map +1 -1
  147. package/dist/onboarding/plugin.js +1 -8
  148. package/dist/onboarding/plugin.js.map +1 -1
  149. package/dist/org/accept-pending.d.ts.map +1 -1
  150. package/dist/org/accept-pending.js +1 -2
  151. package/dist/org/accept-pending.js.map +1 -1
  152. package/dist/org/context.d.ts +0 -2
  153. package/dist/org/context.d.ts.map +1 -1
  154. package/dist/org/context.js +0 -5
  155. package/dist/org/context.js.map +1 -1
  156. package/dist/resources/script-helpers.d.ts +3 -4
  157. package/dist/resources/script-helpers.d.ts.map +1 -1
  158. package/dist/resources/script-helpers.js +8 -15
  159. package/dist/resources/script-helpers.js.map +1 -1
  160. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  161. package/dist/scripts/chat/search-chats.js +4 -4
  162. package/dist/scripts/chat/search-chats.js.map +1 -1
  163. package/dist/scripts/manage-agent-loop-settings.js +2 -2
  164. package/dist/scripts/manage-agent-loop-settings.js.map +1 -1
  165. package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
  166. package/dist/scripts/resources/delete-memory.js +4 -2
  167. package/dist/scripts/resources/delete-memory.js.map +1 -1
  168. package/dist/scripts/resources/delete.d.ts.map +1 -1
  169. package/dist/scripts/resources/delete.js +11 -4
  170. package/dist/scripts/resources/delete.js.map +1 -1
  171. package/dist/scripts/resources/list.d.ts.map +1 -1
  172. package/dist/scripts/resources/list.js +5 -3
  173. package/dist/scripts/resources/list.js.map +1 -1
  174. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
  175. package/dist/scripts/resources/migrate-learnings.js +5 -2
  176. package/dist/scripts/resources/migrate-learnings.js.map +1 -1
  177. package/dist/scripts/resources/read.d.ts.map +1 -1
  178. package/dist/scripts/resources/read.js +4 -2
  179. package/dist/scripts/resources/read.js.map +1 -1
  180. package/dist/scripts/resources/save-memory.d.ts.map +1 -1
  181. package/dist/scripts/resources/save-memory.js +4 -2
  182. package/dist/scripts/resources/save-memory.js.map +1 -1
  183. package/dist/scripts/resources/write.d.ts.map +1 -1
  184. package/dist/scripts/resources/write.js +11 -4
  185. package/dist/scripts/resources/write.js.map +1 -1
  186. package/dist/secrets/onboarding.d.ts.map +1 -1
  187. package/dist/secrets/onboarding.js +1 -9
  188. package/dist/secrets/onboarding.js.map +1 -1
  189. package/dist/secrets/routes.d.ts.map +1 -1
  190. package/dist/secrets/routes.js +2 -7
  191. package/dist/secrets/routes.js.map +1 -1
  192. package/dist/server/action-discovery.d.ts +15 -0
  193. package/dist/server/action-discovery.d.ts.map +1 -1
  194. package/dist/server/action-discovery.js +49 -0
  195. package/dist/server/action-discovery.js.map +1 -1
  196. package/dist/server/agent-chat-plugin.d.ts +5 -0
  197. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  198. package/dist/server/agent-chat-plugin.js +81 -20
  199. package/dist/server/agent-chat-plugin.js.map +1 -1
  200. package/dist/server/agent-discovery.d.ts.map +1 -1
  201. package/dist/server/agent-discovery.js +5 -7
  202. package/dist/server/agent-discovery.js.map +1 -1
  203. package/dist/server/auth.d.ts +16 -20
  204. package/dist/server/auth.d.ts.map +1 -1
  205. package/dist/server/auth.js +115 -333
  206. package/dist/server/auth.js.map +1 -1
  207. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  208. package/dist/server/core-routes-plugin.js +23 -16
  209. package/dist/server/core-routes-plugin.js.map +1 -1
  210. package/dist/server/credential-provider.d.ts.map +1 -1
  211. package/dist/server/credential-provider.js +1 -2
  212. package/dist/server/credential-provider.js.map +1 -1
  213. package/dist/server/google-oauth.d.ts +14 -2
  214. package/dist/server/google-oauth.d.ts.map +1 -1
  215. package/dist/server/google-oauth.js +32 -10
  216. package/dist/server/google-oauth.js.map +1 -1
  217. package/dist/server/index.d.ts +3 -3
  218. package/dist/server/index.d.ts.map +1 -1
  219. package/dist/server/index.js +2 -2
  220. package/dist/server/index.js.map +1 -1
  221. package/dist/server/oauth-helpers.d.ts +2 -4
  222. package/dist/server/oauth-helpers.d.ts.map +1 -1
  223. package/dist/server/oauth-helpers.js +2 -4
  224. package/dist/server/oauth-helpers.js.map +1 -1
  225. package/dist/server/transcribe-voice.d.ts.map +1 -1
  226. package/dist/server/transcribe-voice.js +2 -4
  227. package/dist/server/transcribe-voice.js.map +1 -1
  228. package/dist/triggers/dispatcher.d.ts.map +1 -1
  229. package/dist/triggers/dispatcher.js +0 -3
  230. package/dist/triggers/dispatcher.js.map +1 -1
  231. package/dist/vite/client.d.ts.map +1 -1
  232. package/dist/vite/client.js +13 -0
  233. package/dist/vite/client.js.map +1 -1
  234. package/docs/content/actions.md +1 -0
  235. package/docs/content/authentication.md +3 -20
  236. package/docs/content/creating-templates.md +1 -1
  237. package/docs/content/deployment.md +0 -1
  238. package/docs/content/security.md +0 -1
  239. package/docs/content/template-analytics.md +10 -0
  240. package/docs/content/template-calendar.md +10 -0
  241. package/docs/content/template-clips.md +10 -0
  242. package/docs/content/template-content.md +11 -1
  243. package/docs/content/template-dispatch.md +10 -0
  244. package/docs/content/template-forms.md +10 -0
  245. package/docs/content/template-mail.md +10 -0
  246. package/docs/content/template-slides.md +11 -1
  247. package/docs/content/template-starter.md +11 -1
  248. package/docs/content/template-video.md +10 -0
  249. package/package.json +1 -1
  250. package/dist/client/dev-mode.d.ts +0 -14
  251. package/dist/client/dev-mode.d.ts.map +0 -1
  252. package/dist/client/dev-mode.js +0 -14
  253. package/dist/client/dev-mode.js.map +0 -1
  254. package/dist/server/local-migration.d.ts +0 -41
  255. package/dist/server/local-migration.d.ts.map +0 -1
  256. package/dist/server/local-migration.js +0 -235
  257. package/dist/server/local-migration.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"credential-provider.d.ts","sourceRoot":"","sources":["../../src/server/credential-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;gBAElB,IAAI,EAAE;QAChB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;CAUF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvE;AAwBD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEvE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvE;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,OAAO,CAAC,CAEpE;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC,CASD;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IACL,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc3E;AAcD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsBvE;AAOD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,IAAI,MAAM,CAO9C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAKjD;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAGpD"}
1
+ {"version":3,"file":"credential-provider.d.ts","sourceRoot":"","sources":["../../src/server/credential-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;gBAElB,IAAI,EAAE;QAChB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;CAUF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvE;AAwBD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEvE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvE;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,OAAO,CAAC,CAEpE;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC,CASD;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IACL,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc3E;AAcD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsBvE;AAOD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,IAAI,MAAM,CAO9C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAKjD;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAGpD"}
@@ -18,7 +18,6 @@
18
18
  * (e.g. additional Builder-hosted services) without rewrites.
19
19
  */
20
20
  import { getRequestUserEmail } from "./request-context.js";
21
- import { DEV_MODE_USER_EMAIL } from "./auth.js";
22
21
  export class FeatureNotConfiguredError extends Error {
23
22
  requiredCredential;
24
23
  builderConnectUrl;
@@ -187,7 +186,7 @@ export async function deleteBuilderCredentials(email) {
187
186
  */
188
187
  export async function resolveSecret(key) {
189
188
  const email = getRequestUserEmail();
190
- if (email && email !== DEV_MODE_USER_EMAIL) {
189
+ if (email) {
191
190
  try {
192
191
  const { readAppSecret } = await import("../secrets/storage.js");
193
192
  const secret = await readAppSecret({
@@ -1 +1 @@
1
- {"version":3,"file":"credential-provider.js","sourceRoot":"","sources":["../../src/server/credential-provider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential provider abstraction.\n *\n * Every feature that needs an external credential (Anthropic API key,\n * Google OAuth tokens, OpenAI key, Slack bot token, etc.) should go through\n * one of the resolve*() helpers here instead of reading `process.env`\n * directly. That way the same feature can work in three modes:\n *\n * 1. User set their own key in .env → use it directly\n * 2. User connected Builder via `/cli-auth` → route through Builder proxy\n * 3. Neither → throw FeatureNotConfigured\n *\n * Templates catch FeatureNotConfigured and show a \"Connect Builder (1 click) /\n * set up your own key (guide)\" card.\n *\n * Today these helpers are used by the Builder-hosted LLM gateway, and the\n * shape is meant to grow to cover future managed credential integrations\n * (e.g. additional Builder-hosted services) without rewrites.\n */\n\nimport { getRequestUserEmail } from \"./request-context.js\";\nimport { DEV_MODE_USER_EMAIL } from \"./auth.js\";\n\nexport class FeatureNotConfiguredError extends Error {\n readonly requiredCredential: string;\n readonly builderConnectUrl?: string;\n readonly byokDocsUrl?: string;\n\n constructor(opts: {\n requiredCredential: string;\n message?: string;\n builderConnectUrl?: string;\n byokDocsUrl?: string;\n }) {\n super(\n opts.message ??\n `Feature requires credential \"${opts.requiredCredential}\". Connect Builder or set your own key.`,\n );\n this.name = \"FeatureNotConfiguredError\";\n this.requiredCredential = opts.requiredCredential;\n this.builderConnectUrl = opts.builderConnectUrl;\n this.byokDocsUrl = opts.byokDocsUrl;\n }\n}\n\n/**\n * Deployment-level credential fallback for single-tenant/local operation.\n * Multi-tenant call sites must gate this explicitly before calling.\n */\nexport function readDeployCredentialEnv(key: string): string | undefined {\n return process.env[key] || undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Builder credential resolution — two mutually-exclusive deployment modes:\n//\n// 1. **Single-tenant / env-managed.** When BUILDER_PRIVATE_KEY is set at\n// the deployment level, it is THE Builder identity for every user of\n// this deploy. The operator setting the env explicitly opts in to\n// \"everyone shares one Builder space\" — same shape as DATABASE_URL or\n// BETTER_AUTH_SECRET. The UI hides the per-user connect/disconnect\n// flow when env-managed (see `isBuilderEnvManaged`).\n//\n// 2. **Multi-tenant / per-user OAuth.** When the env is unset, each user\n// OAuth-connects their own Builder via the cli-auth flow. Their keys\n// land in `app_secrets` (scope=user, scopeId=email) via the callback\n// handler. They can disconnect via the settings panel.\n//\n// To run multi-tenant SaaS: leave the env unset. Setting BUILDER_PRIVATE_KEY\n// on a multi-tenant deploy will silently route every authenticated user\n// through the env-key owner's Builder identity — that was the KVesta Space\n// cross-tenant attribution leak (2026-04). The mode is binary: env-set\n// means single-tenant intent.\n// ---------------------------------------------------------------------------\n\nexport async function resolveBuilderCredential(\n key: string,\n): Promise<string | null> {\n // Env-managed mode wins when set: deploy-level Builder identity for\n // every user. Per-user app_secrets (left over from a previous OAuth\n // connection or a mode switch) are intentionally ignored — the\n // operator's deploy-level config is authoritative.\n const envValue = readDeployCredentialEnv(key);\n if (envValue) return envValue;\n\n // No env value: per-user OAuth fallback.\n const email = getRequestUserEmail();\n if (email) {\n try {\n const { readAppSecret } = await import(\"../secrets/storage.js\");\n const secret = await readAppSecret({\n key,\n scope: \"user\",\n scopeId: email,\n });\n if (secret) return secret.value;\n } catch {\n // Secrets table not ready — treat as missing.\n }\n }\n return null;\n}\n\n/**\n * True when `BUILDER_PRIVATE_KEY` is set at the deployment level — every\n * user of this deploy shares the operator's Builder identity, and per-user\n * connect/disconnect is disabled. UIs read this via `/builder/status` to\n * swap the \"Connect Builder\" prompts for a read-only \"managed by deployment\"\n * chip and to suppress the disconnect button.\n */\nexport function isBuilderEnvManaged(): boolean {\n return !!process.env.BUILDER_PRIVATE_KEY;\n}\n\n/**\n * Resolve the Builder private key for the current request. In env-managed\n * mode (deploy-level `BUILDER_PRIVATE_KEY` set) returns the env value for\n * every caller. Otherwise reads the current user's per-user OAuth-stored\n * key from `app_secrets`.\n */\nexport async function resolveBuilderPrivateKey(): Promise<string | null> {\n return resolveBuilderCredential(\"BUILDER_PRIVATE_KEY\");\n}\n\n/**\n * Resolve the current user's Builder auth header.\n * Returns `\"Bearer <key>\"` or null.\n */\nexport async function resolveBuilderAuthHeader(): Promise<string | null> {\n const key = await resolveBuilderPrivateKey();\n return key ? `Bearer ${key}` : null;\n}\n\n/**\n * Check whether the current user has a Builder private key configured\n * (per-user or deployment-level).\n */\nexport async function resolveHasBuilderPrivateKey(): Promise<boolean> {\n return !!(await resolveBuilderPrivateKey());\n}\n\n/**\n * Resolve all per-user Builder credentials. Used by the status endpoint\n * and agent-chat-plugin to get orgName, userId, etc.\n */\nexport async function resolveBuilderCredentials(): Promise<{\n privateKey: string | null;\n publicKey: string | null;\n userId: string | null;\n orgName: string | null;\n orgKind: string | null;\n}> {\n const [privateKey, publicKey, userId, orgName, orgKind] = await Promise.all([\n resolveBuilderCredential(\"BUILDER_PRIVATE_KEY\"),\n resolveBuilderCredential(\"BUILDER_PUBLIC_KEY\"),\n resolveBuilderCredential(\"BUILDER_USER_ID\"),\n resolveBuilderCredential(\"BUILDER_ORG_NAME\"),\n resolveBuilderCredential(\"BUILDER_ORG_KIND\"),\n ]);\n return { privateKey, publicKey, userId, orgName, orgKind };\n}\n\n/**\n * Write Builder credentials for the current user to per-user app_secrets.\n */\nexport async function writeBuilderCredentials(\n email: string,\n creds: {\n privateKey: string;\n publicKey: string;\n userId?: string | null;\n orgName?: string | null;\n orgKind?: string | null;\n },\n): Promise<void> {\n const { writeAppSecret } = await import(\"../secrets/storage.js\");\n const entries: Array<{ key: string; value: string }> = [\n { key: \"BUILDER_PRIVATE_KEY\", value: creds.privateKey },\n { key: \"BUILDER_PUBLIC_KEY\", value: creds.publicKey },\n ];\n if (creds.userId) {\n entries.push({ key: \"BUILDER_USER_ID\", value: creds.userId });\n }\n if (creds.orgName) {\n entries.push({ key: \"BUILDER_ORG_NAME\", value: creds.orgName });\n }\n if (creds.orgKind) {\n entries.push({ key: \"BUILDER_ORG_KIND\", value: creds.orgKind });\n }\n await Promise.all(\n entries.map(({ key, value }) =>\n writeAppSecret({ key, value, scope: \"user\", scopeId: email }),\n ),\n );\n}\n\n/**\n * Delete Builder credentials for the current user from app_secrets.\n */\nexport async function deleteBuilderCredentials(email: string): Promise<void> {\n const { deleteAppSecret } = await import(\"../secrets/storage.js\");\n const keys = [\n \"BUILDER_PRIVATE_KEY\",\n \"BUILDER_PUBLIC_KEY\",\n \"BUILDER_USER_ID\",\n \"BUILDER_ORG_NAME\",\n \"BUILDER_ORG_KIND\",\n ];\n await Promise.all(\n keys.map((key) =>\n deleteAppSecret({ key, scope: \"user\", scopeId: email }).catch(() => {}),\n ),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Generic per-user secret resolution\n//\n// New consumers should prefer this over reading `process.env.X` directly.\n// User-pasted secrets live in `app_secrets` (encrypted, scope=user); the\n// settings UI / onboarding panels write here. Deploy-level env vars are\n// the fallback for unauthenticated/CLI/background contexts where there's\n// no user to scope by — never the silent fallback for an authenticated\n// request, since on a multi-tenant deploy that would silently identify\n// every user as whoever set the deploy-level key (KVesta Space, 2026-04).\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a per-user secret. Reads from `app_secrets` first (scoped by\n * the current request's authenticated user); falls back to `process.env`\n * only for unauthenticated/CLI/background contexts.\n */\nexport async function resolveSecret(key: string): Promise<string | null> {\n const email = getRequestUserEmail();\n if (email && email !== DEV_MODE_USER_EMAIL) {\n try {\n const { readAppSecret } = await import(\"../secrets/storage.js\");\n const secret = await readAppSecret({\n key,\n scope: \"user\",\n scopeId: email,\n });\n if (secret?.value) return secret.value;\n } catch {\n // Secrets table not ready — treat as missing.\n }\n // Authenticated multi-tenant context: never fall back to process.env.\n // The deploy-level value would silently impersonate the actual key\n // owner across every tenant.\n return null;\n }\n // Unauthenticated / local-dev / CLI / background context: env fallback\n // is safe because there's no user to mis-identify.\n return process.env[key] || null;\n}\n\n// ---------------------------------------------------------------------------\n// Synchronous helpers — env-only fallbacks for contexts where per-user\n// lookup isn't possible (sync isConfigured checks, CLI scripts).\n// ---------------------------------------------------------------------------\n\n/**\n * True when a Builder private key is configured at the deployment level.\n *\n * This is the same check as `isBuilderEnvManaged()` (env-managed mode is\n * defined as \"deploy-level BUILDER_PRIVATE_KEY is set\"). Prefer\n * `isBuilderEnvManaged()` for new call sites — its name reflects what the\n * boolean means semantically. For \"does this user have access to Builder\n * (env or per-user)?\" use the async `resolveHasBuilderPrivateKey()`.\n */\nexport function hasBuilderPrivateKey(): boolean {\n return !!process.env.BUILDER_PRIVATE_KEY;\n}\n\n/** The origin for Builder-proxied API calls. Overridable for testing. */\nexport function getBuilderProxyOrigin(): string {\n return (\n process.env.BUILDER_PROXY_ORIGIN ||\n process.env.AIR_HOST ||\n process.env.BUILDER_API_HOST ||\n \"https://ai-services.builder.io\"\n );\n}\n\n/**\n * Base URL for the public Builder LLM gateway (distinct from the internal\n * proxy origin above — the public gateway lives at api.builder.io/codegen,\n * while the internal origin is ai-services.builder.io).\n * Override via BUILDER_GATEWAY_BASE_URL for staging / testing.\n */\nexport function getBuilderGatewayBaseUrl(): string {\n return (\n process.env.BUILDER_GATEWAY_BASE_URL ||\n \"https://api.builder.io/codegen/gateway/v1\"\n );\n}\n\n/** Authorization header value for Builder-proxied calls (env-only). */\nexport function getBuilderAuthHeader(): string | null {\n const key = process.env.BUILDER_PRIVATE_KEY;\n return key ? `Bearer ${key}` : null;\n}\n"]}
1
+ {"version":3,"file":"credential-provider.js","sourceRoot":"","sources":["../../src/server/credential-provider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential provider abstraction.\n *\n * Every feature that needs an external credential (Anthropic API key,\n * Google OAuth tokens, OpenAI key, Slack bot token, etc.) should go through\n * one of the resolve*() helpers here instead of reading `process.env`\n * directly. That way the same feature can work in three modes:\n *\n * 1. User set their own key in .env → use it directly\n * 2. User connected Builder via `/cli-auth` → route through Builder proxy\n * 3. Neither → throw FeatureNotConfigured\n *\n * Templates catch FeatureNotConfigured and show a \"Connect Builder (1 click) /\n * set up your own key (guide)\" card.\n *\n * Today these helpers are used by the Builder-hosted LLM gateway, and the\n * shape is meant to grow to cover future managed credential integrations\n * (e.g. additional Builder-hosted services) without rewrites.\n */\n\nimport { getRequestUserEmail } from \"./request-context.js\";\n\nexport class FeatureNotConfiguredError extends Error {\n readonly requiredCredential: string;\n readonly builderConnectUrl?: string;\n readonly byokDocsUrl?: string;\n\n constructor(opts: {\n requiredCredential: string;\n message?: string;\n builderConnectUrl?: string;\n byokDocsUrl?: string;\n }) {\n super(\n opts.message ??\n `Feature requires credential \"${opts.requiredCredential}\". Connect Builder or set your own key.`,\n );\n this.name = \"FeatureNotConfiguredError\";\n this.requiredCredential = opts.requiredCredential;\n this.builderConnectUrl = opts.builderConnectUrl;\n this.byokDocsUrl = opts.byokDocsUrl;\n }\n}\n\n/**\n * Deployment-level credential fallback for single-tenant/local operation.\n * Multi-tenant call sites must gate this explicitly before calling.\n */\nexport function readDeployCredentialEnv(key: string): string | undefined {\n return process.env[key] || undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Builder credential resolution — two mutually-exclusive deployment modes:\n//\n// 1. **Single-tenant / env-managed.** When BUILDER_PRIVATE_KEY is set at\n// the deployment level, it is THE Builder identity for every user of\n// this deploy. The operator setting the env explicitly opts in to\n// \"everyone shares one Builder space\" — same shape as DATABASE_URL or\n// BETTER_AUTH_SECRET. The UI hides the per-user connect/disconnect\n// flow when env-managed (see `isBuilderEnvManaged`).\n//\n// 2. **Multi-tenant / per-user OAuth.** When the env is unset, each user\n// OAuth-connects their own Builder via the cli-auth flow. Their keys\n// land in `app_secrets` (scope=user, scopeId=email) via the callback\n// handler. They can disconnect via the settings panel.\n//\n// To run multi-tenant SaaS: leave the env unset. Setting BUILDER_PRIVATE_KEY\n// on a multi-tenant deploy will silently route every authenticated user\n// through the env-key owner's Builder identity — that was the KVesta Space\n// cross-tenant attribution leak (2026-04). The mode is binary: env-set\n// means single-tenant intent.\n// ---------------------------------------------------------------------------\n\nexport async function resolveBuilderCredential(\n key: string,\n): Promise<string | null> {\n // Env-managed mode wins when set: deploy-level Builder identity for\n // every user. Per-user app_secrets (left over from a previous OAuth\n // connection or a mode switch) are intentionally ignored — the\n // operator's deploy-level config is authoritative.\n const envValue = readDeployCredentialEnv(key);\n if (envValue) return envValue;\n\n // No env value: per-user OAuth fallback.\n const email = getRequestUserEmail();\n if (email) {\n try {\n const { readAppSecret } = await import(\"../secrets/storage.js\");\n const secret = await readAppSecret({\n key,\n scope: \"user\",\n scopeId: email,\n });\n if (secret) return secret.value;\n } catch {\n // Secrets table not ready — treat as missing.\n }\n }\n return null;\n}\n\n/**\n * True when `BUILDER_PRIVATE_KEY` is set at the deployment level — every\n * user of this deploy shares the operator's Builder identity, and per-user\n * connect/disconnect is disabled. UIs read this via `/builder/status` to\n * swap the \"Connect Builder\" prompts for a read-only \"managed by deployment\"\n * chip and to suppress the disconnect button.\n */\nexport function isBuilderEnvManaged(): boolean {\n return !!process.env.BUILDER_PRIVATE_KEY;\n}\n\n/**\n * Resolve the Builder private key for the current request. In env-managed\n * mode (deploy-level `BUILDER_PRIVATE_KEY` set) returns the env value for\n * every caller. Otherwise reads the current user's per-user OAuth-stored\n * key from `app_secrets`.\n */\nexport async function resolveBuilderPrivateKey(): Promise<string | null> {\n return resolveBuilderCredential(\"BUILDER_PRIVATE_KEY\");\n}\n\n/**\n * Resolve the current user's Builder auth header.\n * Returns `\"Bearer <key>\"` or null.\n */\nexport async function resolveBuilderAuthHeader(): Promise<string | null> {\n const key = await resolveBuilderPrivateKey();\n return key ? `Bearer ${key}` : null;\n}\n\n/**\n * Check whether the current user has a Builder private key configured\n * (per-user or deployment-level).\n */\nexport async function resolveHasBuilderPrivateKey(): Promise<boolean> {\n return !!(await resolveBuilderPrivateKey());\n}\n\n/**\n * Resolve all per-user Builder credentials. Used by the status endpoint\n * and agent-chat-plugin to get orgName, userId, etc.\n */\nexport async function resolveBuilderCredentials(): Promise<{\n privateKey: string | null;\n publicKey: string | null;\n userId: string | null;\n orgName: string | null;\n orgKind: string | null;\n}> {\n const [privateKey, publicKey, userId, orgName, orgKind] = await Promise.all([\n resolveBuilderCredential(\"BUILDER_PRIVATE_KEY\"),\n resolveBuilderCredential(\"BUILDER_PUBLIC_KEY\"),\n resolveBuilderCredential(\"BUILDER_USER_ID\"),\n resolveBuilderCredential(\"BUILDER_ORG_NAME\"),\n resolveBuilderCredential(\"BUILDER_ORG_KIND\"),\n ]);\n return { privateKey, publicKey, userId, orgName, orgKind };\n}\n\n/**\n * Write Builder credentials for the current user to per-user app_secrets.\n */\nexport async function writeBuilderCredentials(\n email: string,\n creds: {\n privateKey: string;\n publicKey: string;\n userId?: string | null;\n orgName?: string | null;\n orgKind?: string | null;\n },\n): Promise<void> {\n const { writeAppSecret } = await import(\"../secrets/storage.js\");\n const entries: Array<{ key: string; value: string }> = [\n { key: \"BUILDER_PRIVATE_KEY\", value: creds.privateKey },\n { key: \"BUILDER_PUBLIC_KEY\", value: creds.publicKey },\n ];\n if (creds.userId) {\n entries.push({ key: \"BUILDER_USER_ID\", value: creds.userId });\n }\n if (creds.orgName) {\n entries.push({ key: \"BUILDER_ORG_NAME\", value: creds.orgName });\n }\n if (creds.orgKind) {\n entries.push({ key: \"BUILDER_ORG_KIND\", value: creds.orgKind });\n }\n await Promise.all(\n entries.map(({ key, value }) =>\n writeAppSecret({ key, value, scope: \"user\", scopeId: email }),\n ),\n );\n}\n\n/**\n * Delete Builder credentials for the current user from app_secrets.\n */\nexport async function deleteBuilderCredentials(email: string): Promise<void> {\n const { deleteAppSecret } = await import(\"../secrets/storage.js\");\n const keys = [\n \"BUILDER_PRIVATE_KEY\",\n \"BUILDER_PUBLIC_KEY\",\n \"BUILDER_USER_ID\",\n \"BUILDER_ORG_NAME\",\n \"BUILDER_ORG_KIND\",\n ];\n await Promise.all(\n keys.map((key) =>\n deleteAppSecret({ key, scope: \"user\", scopeId: email }).catch(() => {}),\n ),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Generic per-user secret resolution\n//\n// New consumers should prefer this over reading `process.env.X` directly.\n// User-pasted secrets live in `app_secrets` (encrypted, scope=user); the\n// settings UI / onboarding panels write here. Deploy-level env vars are\n// the fallback for unauthenticated/CLI/background contexts where there's\n// no user to scope by — never the silent fallback for an authenticated\n// request, since on a multi-tenant deploy that would silently identify\n// every user as whoever set the deploy-level key (KVesta Space, 2026-04).\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a per-user secret. Reads from `app_secrets` first (scoped by\n * the current request's authenticated user); falls back to `process.env`\n * only for unauthenticated/CLI/background contexts.\n */\nexport async function resolveSecret(key: string): Promise<string | null> {\n const email = getRequestUserEmail();\n if (email) {\n try {\n const { readAppSecret } = await import(\"../secrets/storage.js\");\n const secret = await readAppSecret({\n key,\n scope: \"user\",\n scopeId: email,\n });\n if (secret?.value) return secret.value;\n } catch {\n // Secrets table not ready — treat as missing.\n }\n // Authenticated multi-tenant context: never fall back to process.env.\n // The deploy-level value would silently impersonate the actual key\n // owner across every tenant.\n return null;\n }\n // Unauthenticated / local-dev / CLI / background context: env fallback\n // is safe because there's no user to mis-identify.\n return process.env[key] || null;\n}\n\n// ---------------------------------------------------------------------------\n// Synchronous helpers — env-only fallbacks for contexts where per-user\n// lookup isn't possible (sync isConfigured checks, CLI scripts).\n// ---------------------------------------------------------------------------\n\n/**\n * True when a Builder private key is configured at the deployment level.\n *\n * This is the same check as `isBuilderEnvManaged()` (env-managed mode is\n * defined as \"deploy-level BUILDER_PRIVATE_KEY is set\"). Prefer\n * `isBuilderEnvManaged()` for new call sites — its name reflects what the\n * boolean means semantically. For \"does this user have access to Builder\n * (env or per-user)?\" use the async `resolveHasBuilderPrivateKey()`.\n */\nexport function hasBuilderPrivateKey(): boolean {\n return !!process.env.BUILDER_PRIVATE_KEY;\n}\n\n/** The origin for Builder-proxied API calls. Overridable for testing. */\nexport function getBuilderProxyOrigin(): string {\n return (\n process.env.BUILDER_PROXY_ORIGIN ||\n process.env.AIR_HOST ||\n process.env.BUILDER_API_HOST ||\n \"https://ai-services.builder.io\"\n );\n}\n\n/**\n * Base URL for the public Builder LLM gateway (distinct from the internal\n * proxy origin above — the public gateway lives at api.builder.io/codegen,\n * while the internal origin is ai-services.builder.io).\n * Override via BUILDER_GATEWAY_BASE_URL for staging / testing.\n */\nexport function getBuilderGatewayBaseUrl(): string {\n return (\n process.env.BUILDER_GATEWAY_BASE_URL ||\n \"https://api.builder.io/codegen/gateway/v1\"\n );\n}\n\n/** Authorization header value for Builder-proxied calls (env-only). */\nexport function getBuilderAuthHeader(): string | null {\n const key = process.env.BUILDER_PRIVATE_KEY;\n return key ? `Bearer ${key}` : null;\n}\n"]}
@@ -7,7 +7,20 @@
7
7
  * google-auth.ts handler.
8
8
  */
9
9
  import { type H3Event } from "h3";
10
- /** Detect requests from the Electron desktop app webview. */
10
+ /**
11
+ * Detect requests from the Agent Native desktop app specifically.
12
+ *
13
+ * The desktop app appends `AgentNativeDesktop/<version>` to its user-agent
14
+ * (see `packages/desktop-app/src/main/index.ts`). We check for that marker
15
+ * rather than matching generic `Electron`, which would also match other
16
+ * Electron-based webviews like Builder.io's Fusion, Slack desktop, Discord,
17
+ * etc. Falsely treating those as "the desktop app" sends users to the
18
+ * `agentnative://oauth-complete` deep-link success page after Google sign-in,
19
+ * where the protocol handler can't fire and the "Open Agent Native" button
20
+ * does nothing.
21
+ *
22
+ * Kept exported as `isElectron` for backwards compatibility with consumers.
23
+ */
11
24
  export declare function isElectron(event: H3Event): boolean;
12
25
  /** Detect requests from a mobile browser (iOS/Android). */
13
26
  export declare function isMobile(event: H3Event): boolean;
@@ -122,7 +135,6 @@ export declare function encodeOAuthState(redirectUri: string, owner?: string, de
122
135
  export declare function decodeOAuthState(stateParam: string | undefined, fallbackUri: string): OAuthStatePayload;
123
136
  export interface OAuthOwnerResult {
124
137
  owner: string | undefined;
125
- isDevSession: boolean;
126
138
  hasProductionSession: boolean;
127
139
  }
128
140
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"google-oauth.d.ts","sourceRoot":"","sources":["../../src/server/google-oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAML,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AAqCZ,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElD;AAED,2DAA2D;AAC3D,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhD;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsBhD;AASD,uEAAuE;AACvE,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,SAAM,GAAG,MAAM,CAG5D;AA4CD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,GACb,OAAO,CA+BT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,WAAW,SAAmC,GAC7C,MAAM,GAAG,IAAI,CAMf;AAID,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6CD;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAAC;AACxE,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,EACjB,UAAU,CAAC,EAAE,OAAO,EACpB,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAAC;AA0CV;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAqCnB;AAID,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,OAAO,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IACJ,oBAAoB,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACA,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IACJ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,CA6EpE;AAED;;;kEAGkE;AAClE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAWxD;AAED,wBAAgB,wBAAwB,CACtC,OAAO,SAA4B,GAClC,QAAQ,CAKV"}
1
+ {"version":3,"file":"google-oauth.d.ts","sourceRoot":"","sources":["../../src/server/google-oauth.ts"],"names":[],"mappings":"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"}
@@ -34,9 +34,22 @@ function escapeHtml(s) {
34
34
  .replace(/"/g, "&quot;")
35
35
  .replace(/'/g, "&#39;");
36
36
  }
37
- /** Detect requests from the Electron desktop app webview. */
37
+ /**
38
+ * Detect requests from the Agent Native desktop app specifically.
39
+ *
40
+ * The desktop app appends `AgentNativeDesktop/<version>` to its user-agent
41
+ * (see `packages/desktop-app/src/main/index.ts`). We check for that marker
42
+ * rather than matching generic `Electron`, which would also match other
43
+ * Electron-based webviews like Builder.io's Fusion, Slack desktop, Discord,
44
+ * etc. Falsely treating those as "the desktop app" sends users to the
45
+ * `agentnative://oauth-complete` deep-link success page after Google sign-in,
46
+ * where the protocol handler can't fire and the "Open Agent Native" button
47
+ * does nothing.
48
+ *
49
+ * Kept exported as `isElectron` for backwards compatibility with consumers.
50
+ */
38
51
  export function isElectron(event) {
39
- return /Electron/i.test(getHeader(event, "user-agent") || "");
52
+ return /AgentNativeDesktop/i.test(getHeader(event, "user-agent") || "");
40
53
  }
41
54
  /** Detect requests from a mobile browser (iOS/Android). */
42
55
  export function isMobile(event) {
@@ -345,14 +358,11 @@ export function decodeOAuthState(stateParam, fallbackUri) {
345
358
  */
346
359
  export async function resolveOAuthOwner(event, stateOwner) {
347
360
  const existingSession = await getSession(event);
348
- const isDevSession = existingSession?.email === "local@localhost";
349
- const hasProductionSession = !!(existingSession?.email && !isDevSession);
350
- // Never use "local@localhost" as a token owner — it creates shared-ownership
351
- // bugs where multiple users can see the same tokens.
361
+ const hasProductionSession = !!existingSession?.email;
352
362
  const owner = hasProductionSession
353
363
  ? existingSession.email
354
364
  : stateOwner || undefined;
355
- return { owner, isDevSession, hasProductionSession };
365
+ return { owner, hasProductionSession };
356
366
  }
357
367
  /**
358
368
  * Create a session token after a successful OAuth exchange.
@@ -434,8 +444,15 @@ export function oauthCallbackResponse(event, email, opts) {
434
444
  const msg = safeEmail ? `Signed in as ${safeEmail}!` : "Signed in!";
435
445
  return htmlResponse(`<!DOCTYPE html><html><head><meta charset="utf-8"><title>Connected</title></head><body style="background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px"><p style="font-size:16px">${msg}</p><p style="font-size:13px;color:#888">You can close this tab and return to ${safeAppName}.</p></body></html>`);
436
446
  }
437
- // Desktop login: deep link back to Electron app
438
- if (opts.desktop) {
447
+ // Desktop login: deep link back to Electron app — only when the callback
448
+ // request actually carries the AgentNativeDesktop UA marker. Without this
449
+ // check, any client whose OAuth state was minted with `desktop=true` (e.g.
450
+ // a stale link, or an upstream that wrongly set `?desktop=1`) would land
451
+ // on the `agentnative://` page where the deep link can't fire and the
452
+ // "Open Agent Native" button does nothing — surfaces inside Builder.io's
453
+ // Fusion webview hit this exact dead-end. Fall through to the web flow
454
+ // for non-Agent-Native-Desktop clients so they get a real redirect.
455
+ if (opts.desktop && isElectron(event)) {
439
456
  return desktopSuccessPage(event, email, opts.sessionToken, callbackState);
440
457
  }
441
458
  // Add-account web flow: close-tab page. The email is rendered into the
@@ -507,7 +524,12 @@ function desktopSuccessPage(_event, email, sessionToken, state) {
507
524
  if (sessionToken) {
508
525
  const deepLink = buildOAuthCompleteDeepLink(sessionToken, state);
509
526
  const deepLinkJson = JSON.stringify(deepLink);
510
- return htmlResponse(`<!DOCTYPE html><html><head><meta charset="utf-8"><title>Connected</title><style>@keyframes spin{to{transform:rotate(360deg)}}@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.spinner{width:28px;height:28px;border:2px solid #333;border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}.fallback{display:none;flex-direction:column;align-items:center;gap:8px;animation:fadeIn .2s ease-out}.fallback.show{display:flex}</style></head><body style="background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:16px"><p style="font-size:16px;margin:0">${msg}</p><div id="loading" class="spinner"></div><div id="fallback" class="fallback"><a href=${deepLinkJson} style="display:inline-block;padding:10px 24px;background:#fff;color:#000;border-radius:8px;text-decoration:none;font-size:14px;font-weight:500">Open Agent Native</a><p style="font-size:12px;color:#666;margin:0">If the app didn\u2019t open automatically, click the button above.</p></div><script>window.location.href=${deepLinkJson};setTimeout(function(){document.getElementById("loading").style.display="none";document.getElementById("fallback").classList.add("show")},3000)</script></body></html>`);
527
+ // Defence in depth: if this page somehow gets served to a UA that isn't
528
+ // the Agent Native desktop app (server gate bypassed, stale link, etc.),
529
+ // skip the `agentnative://` deep link entirely and bounce to the app
530
+ // root. The deep link silently fails outside the desktop app and the
531
+ // "Open Agent Native" button is a dead end in a generic browser/webview.
532
+ return htmlResponse(`<!DOCTYPE html><html><head><meta charset="utf-8"><title>Connected</title><style>@keyframes spin{to{transform:rotate(360deg)}}@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.spinner{width:28px;height:28px;border:2px solid #333;border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}.fallback{display:none;flex-direction:column;align-items:center;gap:8px;animation:fadeIn .2s ease-out}.fallback.show{display:flex}</style></head><body style="background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:16px"><p style="font-size:16px;margin:0">${msg}</p><div id="loading" class="spinner"></div><div id="fallback" class="fallback"><a href=${deepLinkJson} style="display:inline-block;padding:10px 24px;background:#fff;color:#000;border-radius:8px;text-decoration:none;font-size:14px;font-weight:500">Open Agent Native</a><p style="font-size:12px;color:#666;margin:0">If the app didn\u2019t open automatically, click the button above.</p></div><script>(function(){var ua=(navigator.userAgent||"");if(ua.indexOf("AgentNativeDesktop")===-1){window.location.replace("/");return}window.location.href=${deepLinkJson};setTimeout(function(){document.getElementById("loading").style.display="none";document.getElementById("fallback").classList.add("show")},3000)})()</script></body></html>`);
511
533
  }
512
534
  return htmlResponse(`<!DOCTYPE html><html><head><meta charset="utf-8"><title>Connected</title></head><body style="background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px"><p style="font-size:16px">${msg}</p><p style="font-size:13px;color:#888">You can close this tab and return to Agent Native.</p></body></html>`);
513
535
  }
@@ -1 +1 @@
1
- {"version":3,"file":"google-oauth.js","sourceRoot":"","sources":["../../src/server/google-oauth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared Google OAuth utilities for all templates.\n *\n * Handles platform detection (desktop/mobile), state encoding,\n * session token creation, and deep-link responses — the logic\n * that was previously copy-pasted across every template's\n * google-auth.ts handler.\n */\n\nimport crypto from \"node:crypto\";\nimport {\n getHeader,\n getQuery,\n setCookie,\n setResponseStatus,\n setResponseHeader,\n type H3Event,\n} from \"h3\";\nimport {\n addSession,\n getSession,\n COOKIE_NAME,\n getSessionMaxAge,\n safeReturnPath,\n} from \"./auth.js\";\nimport { getAppName } from \"./app-name.js\";\nimport { writeDesktopSso } from \"./desktop-sso.js\";\n\n// ─── Platform Detection ─────────────────────────────────────────────────────\n\n/** Return an HTML response with the correct Content-Type.\n * Uses a web-standard Response to ensure the header survives\n * Nitro dev mode's mock-node-response pipeline. */\nfunction htmlResponse(html: string, status = 200): Response {\n return new Response(html, {\n status,\n headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n });\n}\n\n/**\n * HTML escape — minimal but covers the cases that matter when interpolating\n * user-controlled values into our OAuth callback HTML. Mirrors the helper in\n * email-template.ts; kept inline here to avoid a circular import.\n */\nfunction escapeHtml(s: string): string {\n return String(s ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/** Detect requests from the Electron desktop app webview. */\nexport function isElectron(event: H3Event): boolean {\n return /Electron/i.test(getHeader(event, \"user-agent\") || \"\");\n}\n\n/** Detect requests from a mobile browser (iOS/Android). */\nexport function isMobile(event: H3Event): boolean {\n return /iPhone|iPad|iPod|Android/i.test(getHeader(event, \"user-agent\") || \"\");\n}\n\n/**\n * Build the static allowlist of origins we trust for `getOrigin`. Reads\n * `APP_URL` and `BETTER_AUTH_URL` (both are deployment-known public URLs).\n * Each entry is normalised to `${proto}://${host}` (no path). Duplicates\n * collapse, invalid entries are dropped silently.\n */\nfunction getConfiguredOriginAllowlist(): Set<string> {\n const out = new Set<string>();\n for (const raw of [process.env.APP_URL, process.env.BETTER_AUTH_URL]) {\n if (!raw) continue;\n try {\n const u = new URL(raw);\n out.add(`${u.protocol}//${u.host}`);\n } catch {\n // Ignore — env value isn't a parseable URL.\n }\n }\n return out;\n}\n\n/**\n * Get the origin from forwarded headers or Host.\n *\n * Defends against Host-header injection: in production we require the\n * resolved origin to match `APP_URL` / `BETTER_AUTH_URL`, falling back to\n * those values when the inbound headers are missing or don't match. In\n * dev we accept the inbound `Host` so localhost / ngrok / preview hosts\n * keep working without configuration. The protocol defaults to `https`\n * in production (so a TLS-terminating proxy that drops `x-forwarded-proto`\n * doesn't downgrade us to plain HTTP).\n */\nexport function getOrigin(event: H3Event): string {\n const headerHost =\n getHeader(event, \"x-forwarded-host\") || getHeader(event, \"host\");\n const isProd = process.env.NODE_ENV === \"production\";\n const headerProto =\n getHeader(event, \"x-forwarded-proto\") || (isProd ? \"https\" : \"http\");\n\n if (isProd) {\n const allow = getConfiguredOriginAllowlist();\n // If the deploy declares its public URL, prefer it over inbound headers.\n if (allow.size > 0) {\n const inbound = headerHost ? `${headerProto}://${headerHost}` : \"\";\n if (inbound && allow.has(inbound)) return inbound;\n // Inbound didn't match — fall back to the first configured origin.\n return [...allow][0];\n }\n // No allowlist configured: still default to https, but accept the\n // inbound Host (best we can do without a configured base URL).\n return `${headerProto}://${headerHost ?? \"\"}`;\n }\n\n return `${headerProto}://${headerHost ?? \"localhost\"}`;\n}\n\nfunction normalizeAppBasePath(value: string | undefined): string {\n if (!value || value === \"/\") return \"\";\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n return `/${trimmed.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\")}`;\n}\n\n/** App mount prefix, if the template is served under APP_BASE_PATH. */\nexport function getAppBasePath(): string {\n return normalizeAppBasePath(\n process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH,\n );\n}\n\n/** Build an absolute same-origin URL that preserves APP_BASE_PATH. */\nexport function getAppUrl(event: H3Event, path = \"/\"): string {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${getOrigin(event)}${getAppBasePath()}${cleanPath}`;\n}\n\nfunction getOriginalRequestPath(event: H3Event): string {\n const mountedPathname = (event as any).context?._mountedPathname;\n if (typeof mountedPathname === \"string\" && mountedPathname) {\n return mountedPathname;\n }\n\n const urlPathname = (event as any).url?.pathname;\n if (typeof urlPathname === \"string\" && urlPathname) return urlPathname;\n\n const nodeUrl = event.node?.req?.url;\n if (typeof nodeUrl === \"string\" && nodeUrl) {\n const queryStart = nodeUrl.indexOf(\"?\");\n return queryStart >= 0 ? nodeUrl.slice(0, queryStart) : nodeUrl;\n }\n\n const eventPath = (event as any).path;\n if (typeof eventPath === \"string\" && eventPath) {\n const queryStart = eventPath.indexOf(\"?\");\n return queryStart >= 0 ? eventPath.slice(0, queryStart) : eventPath;\n }\n\n return \"/\";\n}\n\nfunction isRequestUnderAppBasePath(event: H3Event): boolean {\n const basePath = getAppBasePath();\n if (!basePath) return false;\n const requestPath = getOriginalRequestPath(event);\n return (\n requestPath === `${basePath}/_agent-native` ||\n requestPath.startsWith(`${basePath}/_agent-native/`)\n );\n}\n\nfunction getDefaultOAuthRedirectUrl(event: H3Event, path: string): string {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n const basePath = isRequestUnderAppBasePath(event) ? getAppBasePath() : \"\";\n return `${getOrigin(event)}${basePath}${cleanPath}`;\n}\n\n// ─── redirect_uri Allowlist ──────────────────────────────────────────────────\n\n/**\n * Validate a user-supplied `redirect_uri` for OAuth flows.\n *\n * Defends against authorization-code interception (RFC 6819 §4.4.1.7):\n * even though the upstream provider (Google/Atlassian/Zoom) refuses\n * unregistered redirect URIs, prefix-style registrations and side\n * registrations on the same host let a malicious caller swap in an\n * attacker-controlled URI that the provider still accepts. We reject any\n * candidate that isn't on this server's own origin AND under the\n * framework's `/_agent-native/` namespace. Returns the validated URI on\n * success, or `undefined` on rejection — callers must treat `undefined`\n * as a 400.\n *\n * The intentional shape is exact-prefix:\n * - Origin must equal `getOrigin(event)` — no Host-header injection\n * reusing somebody else's registered redirect URI.\n * - Path must start with `${appBasePath}/_agent-native/` so we never\n * hand auth codes to a public marketing or open-redirect endpoint\n * on the same registered host.\n *\n * For desktop / native flows that need ephemeral `http://127.0.0.1:<port>`\n * loopback URIs, callers should validate those at the template level\n * with a dedicated allowlist — this helper rejects them by design.\n */\nexport function isAllowedOAuthRedirectUri(\n candidate: string,\n event: H3Event,\n): boolean {\n if (typeof candidate !== \"string\" || candidate.length === 0) return false;\n let url: URL;\n try {\n url = new URL(candidate);\n } catch {\n return false;\n }\n // Must be same origin as our server.\n const expectedOrigin = getOrigin(event);\n let expectedUrl: URL;\n try {\n expectedUrl = new URL(expectedOrigin);\n } catch {\n return false;\n }\n if (url.protocol !== expectedUrl.protocol) return false;\n if (url.host !== expectedUrl.host) return false;\n // Must live under the framework's namespace. Workspace deploys can route\n // root /_agent-native/* to Dispatch even when Dispatch itself is mounted at\n // /dispatch, but app-prefixed requests should not be able to swap their\n // callback to that root namespace.\n const basePath = getAppBasePath();\n const allowedPrefixes =\n basePath && isRequestUnderAppBasePath(event)\n ? [`${basePath}/_agent-native/`]\n : [\"/_agent-native/\"];\n if (!allowedPrefixes.some((prefix) => url.pathname.startsWith(prefix))) {\n return false;\n }\n return true;\n}\n\n/**\n * Resolve the `redirect_uri` for an outbound OAuth `auth-url` request.\n *\n * Reads `?redirect_uri=` from the query and validates it via\n * `isAllowedOAuthRedirectUri`. Returns:\n * - the validated URI when supplied and allowed, OR\n * - the framework default when no override was supplied, OR\n * - `null` when an override was supplied but rejected — callers must\n * respond with 400 in that case.\n *\n * Templates that need a non-default redirect path can pass it via\n * `defaultPath` (e.g. `\"/_agent-native/google/desktop-callback\"` for\n * desktop flows).\n */\nexport function resolveOAuthRedirectUri(\n event: H3Event,\n defaultPath = \"/_agent-native/google/callback\",\n): string | null {\n const supplied = getQuery(event).redirect_uri;\n if (typeof supplied === \"string\" && supplied.length > 0) {\n return isAllowedOAuthRedirectUri(supplied, event) ? supplied : null;\n }\n return getDefaultOAuthRedirectUrl(event, defaultPath);\n}\n\n// ─── OAuth State ─────────────────────────────────────────────────────────────\n\nexport interface OAuthStatePayload {\n redirectUri: string;\n owner?: string;\n desktop?: boolean;\n addAccount?: boolean;\n app?: string;\n /**\n * Same-origin path to redirect to after a successful web-flow sign-in.\n * Threaded through the (HMAC-signed) state so it survives the round trip\n * to Google. Validated again on decode via safeReturnPath as defence in\n * depth. Has no effect on desktop / mobile / add-account flows, which\n * use their own deep-link / close-tab handling.\n */\n returnUrl?: string;\n flowId?: string;\n}\n\n/**\n * Ephemeral in-memory state-signing key for development. Generated lazily\n * on first read so dev sessions don't depend on filesystem writability or\n * env-var configuration. Sessions reset on each restart, which is fine\n * for dev — no real users / production data are involved.\n */\nlet _devStateSigningKey: string | undefined;\n\n/**\n * Derive a server-only signing key for HMAC verification of OAuth state.\n *\n * Uses a dedicated secret — never an OAuth client secret. Reusing a\n * client_secret (which is shared with Google / GitHub / Atlassian) as our\n * own HMAC key conflates two trust domains: rotating the client secret\n * silently invalidates every in-flight OAuth state, and any leak of the\n * client secret also lets an attacker forge our state envelopes.\n *\n * Resolution order:\n * 1. OAUTH_STATE_SECRET (preferred — dedicated to this purpose)\n * 2. BETTER_AUTH_SECRET (already used by Better Auth as a server secret)\n * 3. In dev only, an ephemeral random key (per-process)\n *\n * In production, throws if neither secret is set.\n */\nfunction getStateSigningKey(): string {\n const secret =\n process.env.OAUTH_STATE_SECRET || process.env.BETTER_AUTH_SECRET;\n if (secret) return secret;\n\n const isProd = process.env.NODE_ENV === \"production\";\n if (isProd) {\n throw new Error(\n \"OAuth state signing requires a server secret. \" +\n \"Set OAUTH_STATE_SECRET or BETTER_AUTH_SECRET in production.\",\n );\n }\n\n if (!_devStateSigningKey) {\n _devStateSigningKey = crypto.randomBytes(32).toString(\"hex\");\n }\n return _devStateSigningKey;\n}\n\n/**\n * Options for the named-argument form of {@link encodeOAuthState}.\n * Prefer this form — the positional overload is easy to misuse (the mail\n * and calendar templates historically passed `flowId` in the `returnUrl`\n * slot, smuggling state into a defence-in-depth path).\n */\nexport interface EncodeOAuthStateOptions {\n redirectUri: string;\n owner?: string;\n desktop?: boolean;\n addAccount?: boolean;\n app?: string;\n returnUrl?: string;\n flowId?: string;\n}\n\n/**\n * Encode OAuth state into a signed base64url string.\n * The state is HMAC-signed so the callback can verify it wasn't forged,\n * preventing CSRF attacks on the OAuth flow.\n *\n * Two call shapes are supported:\n * - Recommended: pass an options object — clear, mismatch-proof.\n * `encodeOAuthState({ redirectUri, owner, desktop, ... })`\n * - Legacy positional form (kept working for backward compatibility):\n * `encodeOAuthState(redirectUri, owner, desktop, addAccount, app, returnUrl, flowId)`.\n * Callers should migrate to the options form — see the audit on\n * templates/mail and templates/calendar where the positional shape\n * led to `flowId` being smuggled in via the `returnUrl` slot.\n */\nexport function encodeOAuthState(opts: EncodeOAuthStateOptions): string;\nexport function encodeOAuthState(\n redirectUri: string,\n owner?: string,\n desktop?: boolean,\n addAccount?: boolean,\n app?: string,\n returnUrl?: string,\n flowId?: string,\n): string;\nexport function encodeOAuthState(\n redirectUriOrOpts: string | EncodeOAuthStateOptions,\n owner?: string,\n desktop?: boolean,\n addAccount?: boolean,\n app?: string,\n returnUrl?: string,\n flowId?: string,\n): string {\n const opts: EncodeOAuthStateOptions =\n typeof redirectUriOrOpts === \"string\"\n ? {\n redirectUri: redirectUriOrOpts,\n owner,\n desktop,\n addAccount,\n app,\n returnUrl,\n flowId,\n }\n : redirectUriOrOpts;\n\n const nonce = crypto.randomBytes(8).toString(\"hex\");\n const payload: Record<string, string | boolean> = {\n n: nonce,\n r: opts.redirectUri,\n };\n if (opts.owner) payload.o = opts.owner;\n if (opts.desktop) payload.d = true;\n if (opts.addAccount) payload.a = true;\n if (opts.app) payload.app = opts.app;\n if (opts.returnUrl) payload.r2 = opts.returnUrl;\n if (opts.flowId) payload.f = opts.flowId;\n const data = Buffer.from(JSON.stringify(payload)).toString(\"base64url\");\n const sig = crypto\n .createHmac(\"sha256\", getStateSigningKey())\n .update(data)\n .digest(\"base64url\");\n return `${data}.${sig}`;\n}\n\n/**\n * Decode and verify OAuth state from the callback's state query parameter.\n * Rejects forged or tampered state by checking the HMAC signature.\n * Falls back to the provided URI if decoding or verification fails.\n */\nexport function decodeOAuthState(\n stateParam: string | undefined,\n fallbackUri: string,\n): OAuthStatePayload {\n if (stateParam) {\n try {\n const dotIdx = stateParam.lastIndexOf(\".\");\n if (dotIdx === -1) return { redirectUri: fallbackUri };\n\n const data = stateParam.slice(0, dotIdx);\n const sig = stateParam.slice(dotIdx + 1);\n const expected = crypto\n .createHmac(\"sha256\", getStateSigningKey())\n .update(data)\n .digest(\"base64url\");\n\n if (\n sig.length !== expected.length ||\n !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))\n ) {\n return { redirectUri: fallbackUri };\n }\n\n const parsed = JSON.parse(Buffer.from(data, \"base64url\").toString());\n return {\n redirectUri: parsed.r || fallbackUri,\n owner: parsed.o || undefined,\n desktop: !!parsed.d,\n addAccount: !!parsed.a,\n app: typeof parsed.app === \"string\" ? parsed.app : undefined,\n // Pass returnUrl through as-is — same-origin validation runs at the\n // consumer (oauthCallbackResponse → safeReturnPath). The state is\n // HMAC-signed, but we still validate at consumption as defence in\n // depth in case the signing key ever leaks.\n returnUrl: typeof parsed.r2 === \"string\" ? parsed.r2 : undefined,\n flowId: parsed.f || undefined,\n };\n } catch {}\n }\n return { redirectUri: fallbackUri };\n}\n\n// ─── Session Creation ────────────────────────────────────────────────────────\n\nexport interface OAuthOwnerResult {\n owner: string | undefined;\n isDevSession: boolean;\n hasProductionSession: boolean;\n}\n\n/**\n * Determine the token owner from the current session and OAuth state.\n * Call this BEFORE exchangeCode to get the owner parameter.\n */\nexport async function resolveOAuthOwner(\n event: H3Event,\n stateOwner?: string,\n): Promise<OAuthOwnerResult> {\n const existingSession = await getSession(event);\n const isDevSession = existingSession?.email === \"local@localhost\";\n const hasProductionSession = !!(existingSession?.email && !isDevSession);\n\n // Never use \"local@localhost\" as a token owner — it creates shared-ownership\n // bugs where multiple users can see the same tokens.\n const owner = hasProductionSession\n ? existingSession!.email\n : stateOwner || undefined;\n\n return { owner, isDevSession, hasProductionSession };\n}\n\nexport interface OAuthSessionResult {\n sessionToken: string | undefined;\n}\n\n/**\n * Create a session token after a successful OAuth exchange.\n *\n * Desktop and mobile apps have separate cookie jars from the system\n * browser, so they always get a fresh session token (even if the browser\n * already has one). The token is then passed via deep link so the native\n * app can inject it.\n */\nexport async function createOAuthSession(\n event: H3Event,\n email: string,\n opts: {\n hasProductionSession: boolean;\n desktop?: boolean;\n },\n): Promise<OAuthSessionResult> {\n const mobile = isMobile(event);\n const needsDeepLink = opts.desktop || mobile;\n const maxAge = getSessionMaxAge();\n\n let sessionToken: string | undefined;\n if (!opts.hasProductionSession || needsDeepLink) {\n sessionToken = crypto.randomBytes(32).toString(\"hex\");\n await addSession(sessionToken, email);\n setCookie(event, COOKIE_NAME, sessionToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\",\n path: \"/\",\n maxAge,\n });\n // Desktop SSO: record this session in the home-dir broker file so\n // sibling templates (each with its own database) can resolve the\n // same token without a DB row of their own. Only the PRIMARY\n // sign-in writes the broker — if a production session already\n // exists, this is an add-account flow (connecting a secondary\n // Google account for scraping) and must never switch the active\n // user across sibling templates.\n if (opts.desktop && !opts.hasProductionSession) {\n await writeDesktopSso({\n email,\n token: sessionToken,\n expiresAt: Date.now() + maxAge * 1000,\n });\n }\n }\n\n return { sessionToken };\n}\n\n// ─── Callback Responses ──────────────────────────────────────────────────────\n\n/**\n * Return the appropriate response after a successful OAuth callback.\n *\n * Handles mobile deep links, desktop deep links, add-account close-tab\n * pages, and plain web redirects — so templates don't have to.\n */\nexport function oauthCallbackResponse(\n event: H3Event,\n email: string,\n opts: {\n sessionToken?: string;\n desktop?: boolean;\n addAccount?: boolean;\n /**\n * Same-origin path to return the viewer to after a successful web\n * sign-in. Validated via safeReturnPath; falls back to \"/\" for any\n * shape that escapes same-origin. Has no effect on desktop / mobile\n * / add-account flows — those use their own deep-link handling.\n */\n returnUrl?: string;\n flowId?: string;\n appName?: string;\n },\n): Response | string | unknown | Promise<Response | string | unknown> {\n const mobile = isMobile(event);\n const query = getQuery(event);\n const callbackState =\n typeof query.state === \"string\" && query.state.length > 0\n ? query.state\n : undefined;\n\n // Mobile: deep link back to native app\n if (mobile) {\n const deepLink = buildOAuthCompleteDeepLink(\n opts.sessionToken,\n callbackState,\n );\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"><title>Connected</title></head><body style=\"background:#111;color:#aaa;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0\"><p>Connected! Returning to app…</p><script>window.location.href=${JSON.stringify(deepLink)};setTimeout(function(){window.location.href=\"/\"},1500)</script></body></html>`,\n );\n }\n\n // Desktop add-account: close-tab page (must come before general desktop check\n // to ensure no deep link fires and the existing session is never switched).\n if (opts.desktop && opts.addAccount) {\n const safeEmail = email ? escapeHtml(email) : \"\";\n const safeAppName = escapeHtml(resolveOAuthAppName(opts.appName));\n const msg = safeEmail ? `Connected ${safeEmail}!` : \"Connected!\";\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px\"><p style=\"font-size:16px\">${msg}</p><p style=\"font-size:13px;color:#888\">You can close this tab and return to ${safeAppName}.</p></body></html>`,\n );\n }\n\n // Electron desktop exchange flow: mail/calendar still pass a flow id so the\n // renderer can poll as a fallback, but the main handoff should use the\n // protocol deep link so the popup returns focus to the desktop app.\n if (opts.desktop && opts.flowId && isElectron(event) && opts.sessionToken) {\n return desktopSuccessPage(event, email, opts.sessionToken, callbackState);\n }\n\n // Desktop exchange flow (non-Electron tray app): the tray app polls the\n // desktop-exchange endpoint for the token — no deep link needed.\n if (opts.desktop && opts.flowId) {\n const safeEmail = email ? escapeHtml(email) : \"\";\n const safeAppName = escapeHtml(resolveOAuthAppName(opts.appName));\n const msg = safeEmail ? `Signed in as ${safeEmail}!` : \"Signed in!\";\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px\"><p style=\"font-size:16px\">${msg}</p><p style=\"font-size:13px;color:#888\">You can close this tab and return to ${safeAppName}.</p></body></html>`,\n );\n }\n\n // Desktop login: deep link back to Electron app\n if (opts.desktop) {\n return desktopSuccessPage(event, email, opts.sessionToken, callbackState);\n }\n\n // Add-account web flow: close-tab page. The email is rendered into the\n // page via DOM `textContent` (safe), but we still JSON-stringify so a\n // payload containing `</script>` can't break out of the script tag —\n // and explicitly assert it's a string so a callbacks like `null` or\n // an object won't end up serialised into the page.\n if (opts.addAccount) {\n const safeEmail = JSON.stringify(typeof email === \"string\" ? email : \"\");\n return htmlResponse(`<!DOCTYPE html><html><body><script>\n window.close();\n var p = document.createElement('p');\n p.style.cssText = 'font-family:system-ui;text-align:center;margin-top:40vh';\n p.textContent = 'Connected ' + ${safeEmail} + '! You can close this tab.';\n document.body.appendChild(p);\n </script></body></html>`);\n }\n\n // Web: redirect to the requested return path (validated same-origin) or\n // \"/\" if no return was supplied / the return failed validation. Returning\n // an empty string body keeps h3's `prepareResponseBody` → `FastResponse`\n // path, which merges the prepared event headers (Location + any cookies\n // set via `setCookie(event, ...)`).\n setResponseStatus(event, 302);\n setResponseHeader(event, \"Location\", safeReturnPath(opts.returnUrl));\n return \"\";\n}\n\n/** HTML error page for OAuth failures. The message is HTML-escaped — most\n * callers pass `error.message` from a token-exchange or userinfo failure,\n * which can echo upstream provider strings (and historically attacker-\n * controlled query params via the `error_description` field). */\nexport function oauthErrorPage(message: string): Response {\n const safe = escapeHtml(message);\n return htmlResponse(\n `<!DOCTYPE html><html><body>\n <div style=\"font-family:system-ui;max-width:420px;margin:30vh auto;text-align:center\">\n <p style=\"font-size:15px;color:#e55\">${safe}</p>\n <p style=\"margin-top:16px;font-size:13px;color:#888\"><a href=\"/\" style=\"color:#888\">Back to login</a></p>\n </div>\n </body></html>`,\n 400,\n );\n}\n\nexport function oauthDesktopExchangePage(\n message = \"Returning to the app...\",\n): Response {\n const safe = escapeHtml(message);\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Returning</title></head><body style=\"background:#111;color:#aaa;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0\"><p style=\"font-size:14px\">${safe}</p><script>window.close()</script></body></html>`,\n );\n}\n\n// ─── Internal ────────────────────────────────────────────────────────────────\n\nfunction resolveOAuthAppName(explicit?: string): string {\n const raw = explicit || getAppName() || \"Agent Native\";\n if (!/^[a-z0-9_-]+$/.test(raw)) return raw;\n return raw\n .split(/[-_]+/)\n .filter(Boolean)\n .map((word) => word[0].toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\nfunction buildOAuthCompleteDeepLink(\n sessionToken?: string,\n state?: string,\n): string {\n const params = new URLSearchParams();\n if (sessionToken) params.set(\"token\", sessionToken);\n if (state) params.set(\"state\", state);\n const suffix = params.toString();\n return suffix\n ? `agentnative://oauth-complete?${suffix}`\n : \"agentnative://oauth-complete\";\n}\n\nfunction desktopSuccessPage(\n _event: H3Event,\n email?: string,\n sessionToken?: string,\n state?: string,\n): Response {\n const safeEmail = email ? escapeHtml(email) : \"\";\n const msg = safeEmail ? `Connected ${safeEmail}!` : \"Connected!\";\n if (sessionToken) {\n const deepLink = buildOAuthCompleteDeepLink(sessionToken, state);\n const deepLinkJson = JSON.stringify(deepLink);\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title><style>@keyframes spin{to{transform:rotate(360deg)}}@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.spinner{width:28px;height:28px;border:2px solid #333;border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}.fallback{display:none;flex-direction:column;align-items:center;gap:8px;animation:fadeIn .2s ease-out}.fallback.show{display:flex}</style></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:16px\"><p style=\"font-size:16px;margin:0\">${msg}</p><div id=\"loading\" class=\"spinner\"></div><div id=\"fallback\" class=\"fallback\"><a href=${deepLinkJson} style=\"display:inline-block;padding:10px 24px;background:#fff;color:#000;border-radius:8px;text-decoration:none;font-size:14px;font-weight:500\">Open Agent Native</a><p style=\"font-size:12px;color:#666;margin:0\">If the app didn\\u2019t open automatically, click the button above.</p></div><script>window.location.href=${deepLinkJson};setTimeout(function(){document.getElementById(\"loading\").style.display=\"none\";document.getElementById(\"fallback\").classList.add(\"show\")},3000)</script></body></html>`,\n );\n }\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px\"><p style=\"font-size:16px\">${msg}</p><p style=\"font-size:13px;color:#888\">You can close this tab and return to Agent Native.</p></body></html>`,\n );\n}\n"]}
1
+ {"version":3,"file":"google-oauth.js","sourceRoot":"","sources":["../../src/server/google-oauth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared Google OAuth utilities for all templates.\n *\n * Handles platform detection (desktop/mobile), state encoding,\n * session token creation, and deep-link responses — the logic\n * that was previously copy-pasted across every template's\n * google-auth.ts handler.\n */\n\nimport crypto from \"node:crypto\";\nimport {\n getHeader,\n getQuery,\n setCookie,\n setResponseStatus,\n setResponseHeader,\n type H3Event,\n} from \"h3\";\nimport {\n addSession,\n getSession,\n COOKIE_NAME,\n getSessionMaxAge,\n safeReturnPath,\n} from \"./auth.js\";\nimport { getAppName } from \"./app-name.js\";\nimport { writeDesktopSso } from \"./desktop-sso.js\";\n\n// ─── Platform Detection ─────────────────────────────────────────────────────\n\n/** Return an HTML response with the correct Content-Type.\n * Uses a web-standard Response to ensure the header survives\n * Nitro dev mode's mock-node-response pipeline. */\nfunction htmlResponse(html: string, status = 200): Response {\n return new Response(html, {\n status,\n headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n });\n}\n\n/**\n * HTML escape — minimal but covers the cases that matter when interpolating\n * user-controlled values into our OAuth callback HTML. Mirrors the helper in\n * email-template.ts; kept inline here to avoid a circular import.\n */\nfunction escapeHtml(s: string): string {\n return String(s ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * Detect requests from the Agent Native desktop app specifically.\n *\n * The desktop app appends `AgentNativeDesktop/<version>` to its user-agent\n * (see `packages/desktop-app/src/main/index.ts`). We check for that marker\n * rather than matching generic `Electron`, which would also match other\n * Electron-based webviews like Builder.io's Fusion, Slack desktop, Discord,\n * etc. Falsely treating those as \"the desktop app\" sends users to the\n * `agentnative://oauth-complete` deep-link success page after Google sign-in,\n * where the protocol handler can't fire and the \"Open Agent Native\" button\n * does nothing.\n *\n * Kept exported as `isElectron` for backwards compatibility with consumers.\n */\nexport function isElectron(event: H3Event): boolean {\n return /AgentNativeDesktop/i.test(getHeader(event, \"user-agent\") || \"\");\n}\n\n/** Detect requests from a mobile browser (iOS/Android). */\nexport function isMobile(event: H3Event): boolean {\n return /iPhone|iPad|iPod|Android/i.test(getHeader(event, \"user-agent\") || \"\");\n}\n\n/**\n * Build the static allowlist of origins we trust for `getOrigin`. Reads\n * `APP_URL` and `BETTER_AUTH_URL` (both are deployment-known public URLs).\n * Each entry is normalised to `${proto}://${host}` (no path). Duplicates\n * collapse, invalid entries are dropped silently.\n */\nfunction getConfiguredOriginAllowlist(): Set<string> {\n const out = new Set<string>();\n for (const raw of [process.env.APP_URL, process.env.BETTER_AUTH_URL]) {\n if (!raw) continue;\n try {\n const u = new URL(raw);\n out.add(`${u.protocol}//${u.host}`);\n } catch {\n // Ignore — env value isn't a parseable URL.\n }\n }\n return out;\n}\n\n/**\n * Get the origin from forwarded headers or Host.\n *\n * Defends against Host-header injection: in production we require the\n * resolved origin to match `APP_URL` / `BETTER_AUTH_URL`, falling back to\n * those values when the inbound headers are missing or don't match. In\n * dev we accept the inbound `Host` so localhost / ngrok / preview hosts\n * keep working without configuration. The protocol defaults to `https`\n * in production (so a TLS-terminating proxy that drops `x-forwarded-proto`\n * doesn't downgrade us to plain HTTP).\n */\nexport function getOrigin(event: H3Event): string {\n const headerHost =\n getHeader(event, \"x-forwarded-host\") || getHeader(event, \"host\");\n const isProd = process.env.NODE_ENV === \"production\";\n const headerProto =\n getHeader(event, \"x-forwarded-proto\") || (isProd ? \"https\" : \"http\");\n\n if (isProd) {\n const allow = getConfiguredOriginAllowlist();\n // If the deploy declares its public URL, prefer it over inbound headers.\n if (allow.size > 0) {\n const inbound = headerHost ? `${headerProto}://${headerHost}` : \"\";\n if (inbound && allow.has(inbound)) return inbound;\n // Inbound didn't match — fall back to the first configured origin.\n return [...allow][0];\n }\n // No allowlist configured: still default to https, but accept the\n // inbound Host (best we can do without a configured base URL).\n return `${headerProto}://${headerHost ?? \"\"}`;\n }\n\n return `${headerProto}://${headerHost ?? \"localhost\"}`;\n}\n\nfunction normalizeAppBasePath(value: string | undefined): string {\n if (!value || value === \"/\") return \"\";\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n return `/${trimmed.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\")}`;\n}\n\n/** App mount prefix, if the template is served under APP_BASE_PATH. */\nexport function getAppBasePath(): string {\n return normalizeAppBasePath(\n process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH,\n );\n}\n\n/** Build an absolute same-origin URL that preserves APP_BASE_PATH. */\nexport function getAppUrl(event: H3Event, path = \"/\"): string {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${getOrigin(event)}${getAppBasePath()}${cleanPath}`;\n}\n\nfunction getOriginalRequestPath(event: H3Event): string {\n const mountedPathname = (event as any).context?._mountedPathname;\n if (typeof mountedPathname === \"string\" && mountedPathname) {\n return mountedPathname;\n }\n\n const urlPathname = (event as any).url?.pathname;\n if (typeof urlPathname === \"string\" && urlPathname) return urlPathname;\n\n const nodeUrl = event.node?.req?.url;\n if (typeof nodeUrl === \"string\" && nodeUrl) {\n const queryStart = nodeUrl.indexOf(\"?\");\n return queryStart >= 0 ? nodeUrl.slice(0, queryStart) : nodeUrl;\n }\n\n const eventPath = (event as any).path;\n if (typeof eventPath === \"string\" && eventPath) {\n const queryStart = eventPath.indexOf(\"?\");\n return queryStart >= 0 ? eventPath.slice(0, queryStart) : eventPath;\n }\n\n return \"/\";\n}\n\nfunction isRequestUnderAppBasePath(event: H3Event): boolean {\n const basePath = getAppBasePath();\n if (!basePath) return false;\n const requestPath = getOriginalRequestPath(event);\n return (\n requestPath === `${basePath}/_agent-native` ||\n requestPath.startsWith(`${basePath}/_agent-native/`)\n );\n}\n\nfunction getDefaultOAuthRedirectUrl(event: H3Event, path: string): string {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n const basePath = isRequestUnderAppBasePath(event) ? getAppBasePath() : \"\";\n return `${getOrigin(event)}${basePath}${cleanPath}`;\n}\n\n// ─── redirect_uri Allowlist ──────────────────────────────────────────────────\n\n/**\n * Validate a user-supplied `redirect_uri` for OAuth flows.\n *\n * Defends against authorization-code interception (RFC 6819 §4.4.1.7):\n * even though the upstream provider (Google/Atlassian/Zoom) refuses\n * unregistered redirect URIs, prefix-style registrations and side\n * registrations on the same host let a malicious caller swap in an\n * attacker-controlled URI that the provider still accepts. We reject any\n * candidate that isn't on this server's own origin AND under the\n * framework's `/_agent-native/` namespace. Returns the validated URI on\n * success, or `undefined` on rejection — callers must treat `undefined`\n * as a 400.\n *\n * The intentional shape is exact-prefix:\n * - Origin must equal `getOrigin(event)` — no Host-header injection\n * reusing somebody else's registered redirect URI.\n * - Path must start with `${appBasePath}/_agent-native/` so we never\n * hand auth codes to a public marketing or open-redirect endpoint\n * on the same registered host.\n *\n * For desktop / native flows that need ephemeral `http://127.0.0.1:<port>`\n * loopback URIs, callers should validate those at the template level\n * with a dedicated allowlist — this helper rejects them by design.\n */\nexport function isAllowedOAuthRedirectUri(\n candidate: string,\n event: H3Event,\n): boolean {\n if (typeof candidate !== \"string\" || candidate.length === 0) return false;\n let url: URL;\n try {\n url = new URL(candidate);\n } catch {\n return false;\n }\n // Must be same origin as our server.\n const expectedOrigin = getOrigin(event);\n let expectedUrl: URL;\n try {\n expectedUrl = new URL(expectedOrigin);\n } catch {\n return false;\n }\n if (url.protocol !== expectedUrl.protocol) return false;\n if (url.host !== expectedUrl.host) return false;\n // Must live under the framework's namespace. Workspace deploys can route\n // root /_agent-native/* to Dispatch even when Dispatch itself is mounted at\n // /dispatch, but app-prefixed requests should not be able to swap their\n // callback to that root namespace.\n const basePath = getAppBasePath();\n const allowedPrefixes =\n basePath && isRequestUnderAppBasePath(event)\n ? [`${basePath}/_agent-native/`]\n : [\"/_agent-native/\"];\n if (!allowedPrefixes.some((prefix) => url.pathname.startsWith(prefix))) {\n return false;\n }\n return true;\n}\n\n/**\n * Resolve the `redirect_uri` for an outbound OAuth `auth-url` request.\n *\n * Reads `?redirect_uri=` from the query and validates it via\n * `isAllowedOAuthRedirectUri`. Returns:\n * - the validated URI when supplied and allowed, OR\n * - the framework default when no override was supplied, OR\n * - `null` when an override was supplied but rejected — callers must\n * respond with 400 in that case.\n *\n * Templates that need a non-default redirect path can pass it via\n * `defaultPath` (e.g. `\"/_agent-native/google/desktop-callback\"` for\n * desktop flows).\n */\nexport function resolveOAuthRedirectUri(\n event: H3Event,\n defaultPath = \"/_agent-native/google/callback\",\n): string | null {\n const supplied = getQuery(event).redirect_uri;\n if (typeof supplied === \"string\" && supplied.length > 0) {\n return isAllowedOAuthRedirectUri(supplied, event) ? supplied : null;\n }\n return getDefaultOAuthRedirectUrl(event, defaultPath);\n}\n\n// ─── OAuth State ─────────────────────────────────────────────────────────────\n\nexport interface OAuthStatePayload {\n redirectUri: string;\n owner?: string;\n desktop?: boolean;\n addAccount?: boolean;\n app?: string;\n /**\n * Same-origin path to redirect to after a successful web-flow sign-in.\n * Threaded through the (HMAC-signed) state so it survives the round trip\n * to Google. Validated again on decode via safeReturnPath as defence in\n * depth. Has no effect on desktop / mobile / add-account flows, which\n * use their own deep-link / close-tab handling.\n */\n returnUrl?: string;\n flowId?: string;\n}\n\n/**\n * Ephemeral in-memory state-signing key for development. Generated lazily\n * on first read so dev sessions don't depend on filesystem writability or\n * env-var configuration. Sessions reset on each restart, which is fine\n * for dev — no real users / production data are involved.\n */\nlet _devStateSigningKey: string | undefined;\n\n/**\n * Derive a server-only signing key for HMAC verification of OAuth state.\n *\n * Uses a dedicated secret — never an OAuth client secret. Reusing a\n * client_secret (which is shared with Google / GitHub / Atlassian) as our\n * own HMAC key conflates two trust domains: rotating the client secret\n * silently invalidates every in-flight OAuth state, and any leak of the\n * client secret also lets an attacker forge our state envelopes.\n *\n * Resolution order:\n * 1. OAUTH_STATE_SECRET (preferred — dedicated to this purpose)\n * 2. BETTER_AUTH_SECRET (already used by Better Auth as a server secret)\n * 3. In dev only, an ephemeral random key (per-process)\n *\n * In production, throws if neither secret is set.\n */\nfunction getStateSigningKey(): string {\n const secret =\n process.env.OAUTH_STATE_SECRET || process.env.BETTER_AUTH_SECRET;\n if (secret) return secret;\n\n const isProd = process.env.NODE_ENV === \"production\";\n if (isProd) {\n throw new Error(\n \"OAuth state signing requires a server secret. \" +\n \"Set OAUTH_STATE_SECRET or BETTER_AUTH_SECRET in production.\",\n );\n }\n\n if (!_devStateSigningKey) {\n _devStateSigningKey = crypto.randomBytes(32).toString(\"hex\");\n }\n return _devStateSigningKey;\n}\n\n/**\n * Options for the named-argument form of {@link encodeOAuthState}.\n * Prefer this form — the positional overload is easy to misuse (the mail\n * and calendar templates historically passed `flowId` in the `returnUrl`\n * slot, smuggling state into a defence-in-depth path).\n */\nexport interface EncodeOAuthStateOptions {\n redirectUri: string;\n owner?: string;\n desktop?: boolean;\n addAccount?: boolean;\n app?: string;\n returnUrl?: string;\n flowId?: string;\n}\n\n/**\n * Encode OAuth state into a signed base64url string.\n * The state is HMAC-signed so the callback can verify it wasn't forged,\n * preventing CSRF attacks on the OAuth flow.\n *\n * Two call shapes are supported:\n * - Recommended: pass an options object — clear, mismatch-proof.\n * `encodeOAuthState({ redirectUri, owner, desktop, ... })`\n * - Legacy positional form (kept working for backward compatibility):\n * `encodeOAuthState(redirectUri, owner, desktop, addAccount, app, returnUrl, flowId)`.\n * Callers should migrate to the options form — see the audit on\n * templates/mail and templates/calendar where the positional shape\n * led to `flowId` being smuggled in via the `returnUrl` slot.\n */\nexport function encodeOAuthState(opts: EncodeOAuthStateOptions): string;\nexport function encodeOAuthState(\n redirectUri: string,\n owner?: string,\n desktop?: boolean,\n addAccount?: boolean,\n app?: string,\n returnUrl?: string,\n flowId?: string,\n): string;\nexport function encodeOAuthState(\n redirectUriOrOpts: string | EncodeOAuthStateOptions,\n owner?: string,\n desktop?: boolean,\n addAccount?: boolean,\n app?: string,\n returnUrl?: string,\n flowId?: string,\n): string {\n const opts: EncodeOAuthStateOptions =\n typeof redirectUriOrOpts === \"string\"\n ? {\n redirectUri: redirectUriOrOpts,\n owner,\n desktop,\n addAccount,\n app,\n returnUrl,\n flowId,\n }\n : redirectUriOrOpts;\n\n const nonce = crypto.randomBytes(8).toString(\"hex\");\n const payload: Record<string, string | boolean> = {\n n: nonce,\n r: opts.redirectUri,\n };\n if (opts.owner) payload.o = opts.owner;\n if (opts.desktop) payload.d = true;\n if (opts.addAccount) payload.a = true;\n if (opts.app) payload.app = opts.app;\n if (opts.returnUrl) payload.r2 = opts.returnUrl;\n if (opts.flowId) payload.f = opts.flowId;\n const data = Buffer.from(JSON.stringify(payload)).toString(\"base64url\");\n const sig = crypto\n .createHmac(\"sha256\", getStateSigningKey())\n .update(data)\n .digest(\"base64url\");\n return `${data}.${sig}`;\n}\n\n/**\n * Decode and verify OAuth state from the callback's state query parameter.\n * Rejects forged or tampered state by checking the HMAC signature.\n * Falls back to the provided URI if decoding or verification fails.\n */\nexport function decodeOAuthState(\n stateParam: string | undefined,\n fallbackUri: string,\n): OAuthStatePayload {\n if (stateParam) {\n try {\n const dotIdx = stateParam.lastIndexOf(\".\");\n if (dotIdx === -1) return { redirectUri: fallbackUri };\n\n const data = stateParam.slice(0, dotIdx);\n const sig = stateParam.slice(dotIdx + 1);\n const expected = crypto\n .createHmac(\"sha256\", getStateSigningKey())\n .update(data)\n .digest(\"base64url\");\n\n if (\n sig.length !== expected.length ||\n !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))\n ) {\n return { redirectUri: fallbackUri };\n }\n\n const parsed = JSON.parse(Buffer.from(data, \"base64url\").toString());\n return {\n redirectUri: parsed.r || fallbackUri,\n owner: parsed.o || undefined,\n desktop: !!parsed.d,\n addAccount: !!parsed.a,\n app: typeof parsed.app === \"string\" ? parsed.app : undefined,\n // Pass returnUrl through as-is — same-origin validation runs at the\n // consumer (oauthCallbackResponse → safeReturnPath). The state is\n // HMAC-signed, but we still validate at consumption as defence in\n // depth in case the signing key ever leaks.\n returnUrl: typeof parsed.r2 === \"string\" ? parsed.r2 : undefined,\n flowId: parsed.f || undefined,\n };\n } catch {}\n }\n return { redirectUri: fallbackUri };\n}\n\n// ─── Session Creation ────────────────────────────────────────────────────────\n\nexport interface OAuthOwnerResult {\n owner: string | undefined;\n hasProductionSession: boolean;\n}\n\n/**\n * Determine the token owner from the current session and OAuth state.\n * Call this BEFORE exchangeCode to get the owner parameter.\n */\nexport async function resolveOAuthOwner(\n event: H3Event,\n stateOwner?: string,\n): Promise<OAuthOwnerResult> {\n const existingSession = await getSession(event);\n const hasProductionSession = !!existingSession?.email;\n const owner = hasProductionSession\n ? existingSession!.email\n : stateOwner || undefined;\n\n return { owner, hasProductionSession };\n}\n\nexport interface OAuthSessionResult {\n sessionToken: string | undefined;\n}\n\n/**\n * Create a session token after a successful OAuth exchange.\n *\n * Desktop and mobile apps have separate cookie jars from the system\n * browser, so they always get a fresh session token (even if the browser\n * already has one). The token is then passed via deep link so the native\n * app can inject it.\n */\nexport async function createOAuthSession(\n event: H3Event,\n email: string,\n opts: {\n hasProductionSession: boolean;\n desktop?: boolean;\n },\n): Promise<OAuthSessionResult> {\n const mobile = isMobile(event);\n const needsDeepLink = opts.desktop || mobile;\n const maxAge = getSessionMaxAge();\n\n let sessionToken: string | undefined;\n if (!opts.hasProductionSession || needsDeepLink) {\n sessionToken = crypto.randomBytes(32).toString(\"hex\");\n await addSession(sessionToken, email);\n setCookie(event, COOKIE_NAME, sessionToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\",\n path: \"/\",\n maxAge,\n });\n // Desktop SSO: record this session in the home-dir broker file so\n // sibling templates (each with its own database) can resolve the\n // same token without a DB row of their own. Only the PRIMARY\n // sign-in writes the broker — if a production session already\n // exists, this is an add-account flow (connecting a secondary\n // Google account for scraping) and must never switch the active\n // user across sibling templates.\n if (opts.desktop && !opts.hasProductionSession) {\n await writeDesktopSso({\n email,\n token: sessionToken,\n expiresAt: Date.now() + maxAge * 1000,\n });\n }\n }\n\n return { sessionToken };\n}\n\n// ─── Callback Responses ──────────────────────────────────────────────────────\n\n/**\n * Return the appropriate response after a successful OAuth callback.\n *\n * Handles mobile deep links, desktop deep links, add-account close-tab\n * pages, and plain web redirects — so templates don't have to.\n */\nexport function oauthCallbackResponse(\n event: H3Event,\n email: string,\n opts: {\n sessionToken?: string;\n desktop?: boolean;\n addAccount?: boolean;\n /**\n * Same-origin path to return the viewer to after a successful web\n * sign-in. Validated via safeReturnPath; falls back to \"/\" for any\n * shape that escapes same-origin. Has no effect on desktop / mobile\n * / add-account flows — those use their own deep-link handling.\n */\n returnUrl?: string;\n flowId?: string;\n appName?: string;\n },\n): Response | string | unknown | Promise<Response | string | unknown> {\n const mobile = isMobile(event);\n const query = getQuery(event);\n const callbackState =\n typeof query.state === \"string\" && query.state.length > 0\n ? query.state\n : undefined;\n\n // Mobile: deep link back to native app\n if (mobile) {\n const deepLink = buildOAuthCompleteDeepLink(\n opts.sessionToken,\n callbackState,\n );\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"><title>Connected</title></head><body style=\"background:#111;color:#aaa;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0\"><p>Connected! Returning to app…</p><script>window.location.href=${JSON.stringify(deepLink)};setTimeout(function(){window.location.href=\"/\"},1500)</script></body></html>`,\n );\n }\n\n // Desktop add-account: close-tab page (must come before general desktop check\n // to ensure no deep link fires and the existing session is never switched).\n if (opts.desktop && opts.addAccount) {\n const safeEmail = email ? escapeHtml(email) : \"\";\n const safeAppName = escapeHtml(resolveOAuthAppName(opts.appName));\n const msg = safeEmail ? `Connected ${safeEmail}!` : \"Connected!\";\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px\"><p style=\"font-size:16px\">${msg}</p><p style=\"font-size:13px;color:#888\">You can close this tab and return to ${safeAppName}.</p></body></html>`,\n );\n }\n\n // Electron desktop exchange flow: mail/calendar still pass a flow id so the\n // renderer can poll as a fallback, but the main handoff should use the\n // protocol deep link so the popup returns focus to the desktop app.\n if (opts.desktop && opts.flowId && isElectron(event) && opts.sessionToken) {\n return desktopSuccessPage(event, email, opts.sessionToken, callbackState);\n }\n\n // Desktop exchange flow (non-Electron tray app): the tray app polls the\n // desktop-exchange endpoint for the token — no deep link needed.\n if (opts.desktop && opts.flowId) {\n const safeEmail = email ? escapeHtml(email) : \"\";\n const safeAppName = escapeHtml(resolveOAuthAppName(opts.appName));\n const msg = safeEmail ? `Signed in as ${safeEmail}!` : \"Signed in!\";\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px\"><p style=\"font-size:16px\">${msg}</p><p style=\"font-size:13px;color:#888\">You can close this tab and return to ${safeAppName}.</p></body></html>`,\n );\n }\n\n // Desktop login: deep link back to Electron app — only when the callback\n // request actually carries the AgentNativeDesktop UA marker. Without this\n // check, any client whose OAuth state was minted with `desktop=true` (e.g.\n // a stale link, or an upstream that wrongly set `?desktop=1`) would land\n // on the `agentnative://` page where the deep link can't fire and the\n // \"Open Agent Native\" button does nothing — surfaces inside Builder.io's\n // Fusion webview hit this exact dead-end. Fall through to the web flow\n // for non-Agent-Native-Desktop clients so they get a real redirect.\n if (opts.desktop && isElectron(event)) {\n return desktopSuccessPage(event, email, opts.sessionToken, callbackState);\n }\n\n // Add-account web flow: close-tab page. The email is rendered into the\n // page via DOM `textContent` (safe), but we still JSON-stringify so a\n // payload containing `</script>` can't break out of the script tag —\n // and explicitly assert it's a string so a callbacks like `null` or\n // an object won't end up serialised into the page.\n if (opts.addAccount) {\n const safeEmail = JSON.stringify(typeof email === \"string\" ? email : \"\");\n return htmlResponse(`<!DOCTYPE html><html><body><script>\n window.close();\n var p = document.createElement('p');\n p.style.cssText = 'font-family:system-ui;text-align:center;margin-top:40vh';\n p.textContent = 'Connected ' + ${safeEmail} + '! You can close this tab.';\n document.body.appendChild(p);\n </script></body></html>`);\n }\n\n // Web: redirect to the requested return path (validated same-origin) or\n // \"/\" if no return was supplied / the return failed validation. Returning\n // an empty string body keeps h3's `prepareResponseBody` → `FastResponse`\n // path, which merges the prepared event headers (Location + any cookies\n // set via `setCookie(event, ...)`).\n setResponseStatus(event, 302);\n setResponseHeader(event, \"Location\", safeReturnPath(opts.returnUrl));\n return \"\";\n}\n\n/** HTML error page for OAuth failures. The message is HTML-escaped — most\n * callers pass `error.message` from a token-exchange or userinfo failure,\n * which can echo upstream provider strings (and historically attacker-\n * controlled query params via the `error_description` field). */\nexport function oauthErrorPage(message: string): Response {\n const safe = escapeHtml(message);\n return htmlResponse(\n `<!DOCTYPE html><html><body>\n <div style=\"font-family:system-ui;max-width:420px;margin:30vh auto;text-align:center\">\n <p style=\"font-size:15px;color:#e55\">${safe}</p>\n <p style=\"margin-top:16px;font-size:13px;color:#888\"><a href=\"/\" style=\"color:#888\">Back to login</a></p>\n </div>\n </body></html>`,\n 400,\n );\n}\n\nexport function oauthDesktopExchangePage(\n message = \"Returning to the app...\",\n): Response {\n const safe = escapeHtml(message);\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Returning</title></head><body style=\"background:#111;color:#aaa;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0\"><p style=\"font-size:14px\">${safe}</p><script>window.close()</script></body></html>`,\n );\n}\n\n// ─── Internal ────────────────────────────────────────────────────────────────\n\nfunction resolveOAuthAppName(explicit?: string): string {\n const raw = explicit || getAppName() || \"Agent Native\";\n if (!/^[a-z0-9_-]+$/.test(raw)) return raw;\n return raw\n .split(/[-_]+/)\n .filter(Boolean)\n .map((word) => word[0].toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\nfunction buildOAuthCompleteDeepLink(\n sessionToken?: string,\n state?: string,\n): string {\n const params = new URLSearchParams();\n if (sessionToken) params.set(\"token\", sessionToken);\n if (state) params.set(\"state\", state);\n const suffix = params.toString();\n return suffix\n ? `agentnative://oauth-complete?${suffix}`\n : \"agentnative://oauth-complete\";\n}\n\nfunction desktopSuccessPage(\n _event: H3Event,\n email?: string,\n sessionToken?: string,\n state?: string,\n): Response {\n const safeEmail = email ? escapeHtml(email) : \"\";\n const msg = safeEmail ? `Connected ${safeEmail}!` : \"Connected!\";\n if (sessionToken) {\n const deepLink = buildOAuthCompleteDeepLink(sessionToken, state);\n const deepLinkJson = JSON.stringify(deepLink);\n // Defence in depth: if this page somehow gets served to a UA that isn't\n // the Agent Native desktop app (server gate bypassed, stale link, etc.),\n // skip the `agentnative://` deep link entirely and bounce to the app\n // root. The deep link silently fails outside the desktop app and the\n // \"Open Agent Native\" button is a dead end in a generic browser/webview.\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title><style>@keyframes spin{to{transform:rotate(360deg)}}@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.spinner{width:28px;height:28px;border:2px solid #333;border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}.fallback{display:none;flex-direction:column;align-items:center;gap:8px;animation:fadeIn .2s ease-out}.fallback.show{display:flex}</style></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:16px\"><p style=\"font-size:16px;margin:0\">${msg}</p><div id=\"loading\" class=\"spinner\"></div><div id=\"fallback\" class=\"fallback\"><a href=${deepLinkJson} style=\"display:inline-block;padding:10px 24px;background:#fff;color:#000;border-radius:8px;text-decoration:none;font-size:14px;font-weight:500\">Open Agent Native</a><p style=\"font-size:12px;color:#666;margin:0\">If the app didn\\u2019t open automatically, click the button above.</p></div><script>(function(){var ua=(navigator.userAgent||\"\");if(ua.indexOf(\"AgentNativeDesktop\")===-1){window.location.replace(\"/\");return}window.location.href=${deepLinkJson};setTimeout(function(){document.getElementById(\"loading\").style.display=\"none\";document.getElementById(\"fallback\").classList.add(\"show\")},3000)})()</script></body></html>`,\n );\n }\n return htmlResponse(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Connected</title></head><body style=\"background:#111;color:#ccc;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;flex-direction:column;gap:8px\"><p style=\"font-size:16px\">${msg}</p><p style=\"font-size:13px;color:#888\">You can close this tab and return to Agent Native.</p></body></html>`,\n );\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  export { createServer, upsertEnvFile, type CreateServerOptions, type EnvKeyConfig, } from "./create-server.js";
2
2
  export { readBody, streamFile } from "./h3-helpers.js";
3
3
  export { createSSEHandler, type SSEHandlerOptions } from "./sse.js";
4
- export { mountAuthMiddleware, autoMountAuth, getSession, addSession, removeSession, getSessionEmail, runAuthGuard, setDesktopExchange, setDesktopExchangeError, DEV_MODE_USER_EMAIL, safeReturnPath, type DesktopExchangeErrorPayload, type AuthSession, type AuthOptions, } from "./auth.js";
4
+ export { mountAuthMiddleware, autoMountAuth, getSession, addSession, removeSession, getSessionEmail, runAuthGuard, setDesktopExchange, setDesktopExchangeError, safeReturnPath, type DesktopExchangeErrorPayload, type AuthSession, type AuthOptions, } from "./auth.js";
5
5
  export { requireEnvKey, type MissingKeyResponse } from "./missing-key.js";
6
6
  export { verifyCaptcha, type CaptchaVerifyResult } from "./captcha.js";
7
7
  export { createProductionAgentHandler, type ActionEntry, type ScriptEntry, type ProductionAgentOptions, type ActionTool, type ScriptTool, type AgentMessage, type AgentChatRequest, type AgentChatEvent, type AgentChatReference, type MentionProvider, type MentionProviderItem, } from "../agent/index.js";
@@ -20,7 +20,7 @@ export { spawnTask, getTask, getTaskByThread, listTasks, sendToTask, markTaskErr
20
20
  export { isOAuthConnected, getOAuthAccounts } from "./oauth-helpers.js";
21
21
  export { wrapWithAnalytics } from "./analytics.js";
22
22
  export { getH3App, awaitBootstrap, type H3AppShim, } from "./framework-request-handler.js";
23
- export { autoDiscoverActions, autoDiscoverScripts, loadActionsFromStaticRegistry, mergeCoreSharingActions, } from "./action-discovery.js";
23
+ export { autoDiscoverActions, autoDiscoverScripts, loadActionsFromStaticRegistry, mergeCoreSharingActions, registerPackageActions, } from "./action-discovery.js";
24
24
  export { mountActionRoutes, type MountActionRoutesOptions, } from "./action-routes.js";
25
25
  export { runWithRequestContext, hasRequestContext, getRequestContext, getRequestUserEmail, getRequestOrgId, getRequestTimezone, getCredentialContext, isIntegrationCallerRequest, type RequestContext, } from "./request-context.js";
26
26
  export { formatDateInTimezone, todayInTimezone } from "./date-utils.js";
@@ -35,6 +35,6 @@ export { renderEmail, emailStrong, emailLink, type RenderEmailArgs, type Rendere
35
35
  export { getAppProductionUrl, getFirstPartyProdUrl } from "./app-url.js";
36
36
  export { getConfiguredAppBasePath, normalizeAppBasePath, withConfiguredAppBasePath, } from "./app-base-path.js";
37
37
  export { signShortLivedToken, verifyShortLivedToken, type ShortLivedTokenClaims, type VerifyResult as ShortLivedTokenVerifyResult, } from "./short-lived-token.js";
38
- type NitroPluginDef = (nitroApp: any) => void | Promise<void>;
38
+ export type NitroPluginDef = (nitroApp: any) => void | Promise<void>;
39
39
  export declare function defineNitroPlugin(def: NitroPluginDef): NitroPluginDef;
40
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  export { createServer, upsertEnvFile, } from "./create-server.js";
2
2
  export { readBody, streamFile } from "./h3-helpers.js";
3
3
  export { createSSEHandler } from "./sse.js";
4
- export { mountAuthMiddleware, autoMountAuth, getSession, addSession, removeSession, getSessionEmail, runAuthGuard, setDesktopExchange, setDesktopExchangeError, DEV_MODE_USER_EMAIL, safeReturnPath, } from "./auth.js";
4
+ export { mountAuthMiddleware, autoMountAuth, getSession, addSession, removeSession, getSessionEmail, runAuthGuard, setDesktopExchange, setDesktopExchangeError, safeReturnPath, } from "./auth.js";
5
5
  export { requireEnvKey } from "./missing-key.js";
6
6
  export { verifyCaptcha } from "./captcha.js";
7
7
  export { createProductionAgentHandler, } from "../agent/index.js";
@@ -23,7 +23,7 @@ export { spawnTask, getTask, getTaskByThread, listTasks, sendToTask, markTaskErr
23
23
  export { isOAuthConnected, getOAuthAccounts } from "./oauth-helpers.js";
24
24
  export { wrapWithAnalytics } from "./analytics.js";
25
25
  export { getH3App, awaitBootstrap, } from "./framework-request-handler.js";
26
- export { autoDiscoverActions, autoDiscoverScripts, loadActionsFromStaticRegistry, mergeCoreSharingActions, } from "./action-discovery.js";
26
+ export { autoDiscoverActions, autoDiscoverScripts, loadActionsFromStaticRegistry, mergeCoreSharingActions, registerPackageActions, } from "./action-discovery.js";
27
27
  export { mountActionRoutes, } from "./action-routes.js";
28
28
  export { runWithRequestContext, hasRequestContext, getRequestContext, getRequestUserEmail, getRequestOrgId, getRequestTimezone, getCredentialContext, isIntegrationCallerRequest, } from "./request-context.js";
29
29
  export { formatDateInTimezone, todayInTimezone } from "./date-utils.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n createServer,\n upsertEnvFile,\n type CreateServerOptions,\n type EnvKeyConfig,\n} from \"./create-server.js\";\n\nexport { readBody, streamFile } from \"./h3-helpers.js\";\nexport { createSSEHandler, type SSEHandlerOptions } from \"./sse.js\";\nexport {\n mountAuthMiddleware,\n autoMountAuth,\n getSession,\n addSession,\n removeSession,\n getSessionEmail,\n runAuthGuard,\n setDesktopExchange,\n setDesktopExchangeError,\n DEV_MODE_USER_EMAIL,\n safeReturnPath,\n type DesktopExchangeErrorPayload,\n type AuthSession,\n type AuthOptions,\n} from \"./auth.js\";\nexport { requireEnvKey, type MissingKeyResponse } from \"./missing-key.js\";\nexport { verifyCaptcha, type CaptchaVerifyResult } from \"./captcha.js\";\nexport {\n createProductionAgentHandler,\n type ActionEntry,\n type ScriptEntry,\n type ProductionAgentOptions,\n type ActionTool,\n type ScriptTool,\n type AgentMessage,\n type AgentChatRequest,\n type AgentChatEvent,\n type AgentChatReference,\n type MentionProvider,\n type MentionProviderItem,\n} from \"../agent/index.js\";\nexport { createDevScriptRegistry } from \"../scripts/dev/index.js\";\n\nexport {\n createPollHandler,\n recordChange,\n getVersion,\n getChangesSince,\n} from \"./poll.js\";\nexport { createAuthPlugin, defaultAuthPlugin } from \"./auth-plugin.js\";\n// Re-export the org plugin so the auto-discovery's DEFAULT_PLUGIN_REGISTRY\n// (which references \"defaultOrgPlugin\" from @agent-native/core/server) can\n// resolve it during the deploy build worker-entry generation.\nexport { createOrgPlugin, defaultOrgPlugin } from \"../org/plugin.js\";\nexport {\n createGoogleAuthPlugin,\n type GoogleAuthPluginOptions,\n} from \"./google-auth-plugin.js\";\nexport {\n createAgentChatPlugin,\n defaultAgentChatPlugin,\n type AgentChatPluginOptions,\n} from \"./agent-chat-plugin.js\";\nexport {\n createThread,\n getThread,\n listThreads,\n updateThreadData,\n deleteThread,\n type ChatThread,\n type ChatThreadSummary,\n} from \"../chat-threads/store.js\";\nexport {\n createResourcesPlugin,\n defaultResourcesPlugin,\n} from \"./resources-plugin.js\";\nexport {\n createCoreRoutesPlugin,\n defaultCoreRoutesPlugin,\n FRAMEWORK_ROUTE_PREFIX,\n type CoreRoutesPluginOptions,\n} from \"./core-routes-plugin.js\";\nexport {\n createTerminalPlugin,\n defaultTerminalPlugin,\n type TerminalPluginOptions,\n} from \"../terminal/terminal-plugin.js\";\nexport {\n createCollabPlugin,\n type CollabPluginOptions,\n} from \"./collab-plugin.js\";\n\nexport {\n spawnTask,\n getTask,\n getTaskByThread,\n listTasks,\n sendToTask,\n markTaskErrored,\n type AgentTask,\n type SpawnTaskOptions,\n} from \"./agent-teams.js\";\nexport { isOAuthConnected, getOAuthAccounts } from \"./oauth-helpers.js\";\nexport { wrapWithAnalytics } from \"./analytics.js\";\nexport {\n getH3App,\n awaitBootstrap,\n type H3AppShim,\n} from \"./framework-request-handler.js\";\nexport {\n autoDiscoverActions,\n autoDiscoverScripts,\n loadActionsFromStaticRegistry,\n mergeCoreSharingActions,\n} from \"./action-discovery.js\";\nexport {\n mountActionRoutes,\n type MountActionRoutesOptions,\n} from \"./action-routes.js\";\nexport {\n runWithRequestContext,\n hasRequestContext,\n getRequestContext,\n getRequestUserEmail,\n getRequestOrgId,\n getRequestTimezone,\n getCredentialContext,\n isIntegrationCallerRequest,\n type RequestContext,\n} from \"./request-context.js\";\nexport { formatDateInTimezone, todayInTimezone } from \"./date-utils.js\";\n\nexport {\n createOnboardingPlugin,\n defaultOnboardingPlugin,\n} from \"../onboarding/plugin.js\";\n\nexport {\n registerFileUploadProvider,\n unregisterFileUploadProvider,\n listFileUploadProviders,\n getActiveFileUploadProvider,\n uploadFile,\n builderFileUploadProvider,\n type FileUploadInput,\n type FileUploadProvider,\n type FileUploadResult,\n} from \"../file-upload/index.js\";\n\nexport {\n createIntegrationsPlugin,\n defaultIntegrationsPlugin,\n slackAdapter,\n telegramAdapter,\n whatsappAdapter,\n emailAdapter,\n type PlatformAdapter,\n type IncomingMessage,\n type OutgoingMessage,\n type IntegrationStatus,\n type IntegrationsPluginOptions,\n} from \"../integrations/index.js\";\n\nexport {\n isElectron,\n isMobile,\n getOrigin,\n getAppBasePath,\n getAppUrl,\n resolveOAuthRedirectUri,\n isAllowedOAuthRedirectUri,\n encodeOAuthState,\n decodeOAuthState,\n resolveOAuthOwner,\n createOAuthSession,\n oauthCallbackResponse,\n oauthErrorPage,\n oauthDesktopExchangePage,\n type OAuthStatePayload,\n type OAuthOwnerResult,\n type OAuthSessionResult,\n} from \"./google-oauth.js\";\n\nexport {\n FeatureNotConfiguredError,\n hasBuilderPrivateKey,\n isBuilderEnvManaged,\n getBuilderProxyOrigin,\n getBuilderAuthHeader,\n resolveBuilderPrivateKey,\n resolveBuilderAuthHeader,\n resolveHasBuilderPrivateKey,\n resolveBuilderCredentials,\n resolveBuilderCredential,\n writeBuilderCredentials,\n deleteBuilderCredentials,\n resolveSecret,\n} from \"./credential-provider.js\";\nexport {\n getBuilderBranchProjectId,\n isBuilderBranchingEnabled,\n runBuilderAgent,\n type RunBuilderAgentResult,\n} from \"./builder-browser.js\";\n\nexport {\n sendEmail,\n isEmailConfigured,\n getEmailProvider,\n type EmailProvider,\n type SendEmailArgs,\n} from \"./email.js\";\nexport {\n renderEmail,\n emailStrong,\n emailLink,\n type RenderEmailArgs,\n type RenderedEmail,\n type EmailCta,\n} from \"./email-template.js\";\nexport { getAppProductionUrl, getFirstPartyProdUrl } from \"./app-url.js\";\nexport {\n getConfiguredAppBasePath,\n normalizeAppBasePath,\n withConfiguredAppBasePath,\n} from \"./app-base-path.js\";\nexport {\n signShortLivedToken,\n verifyShortLivedToken,\n type ShortLivedTokenClaims,\n type VerifyResult as ShortLivedTokenVerifyResult,\n} from \"./short-lived-token.js\";\n\n// SSR handler is NOT re-exported here — it uses a virtual module\n// (virtual:react-router/server-build) that only exists at Vite dev/build time.\n// Including it in this barrel would break the esbuild CF Pages bundler.\n// Templates import directly: import { ssrHandler } from \"@agent-native/core/server/ssr-handler\"\n\n// Nitro plugin helper — re-exported so templates don't need nitro as a direct dependency.\n// defineNitroPlugin is an identity function; this typed wrapper lets templates use it\n// without resolving `nitro/runtime` (which requires Nitro's virtual modules at runtime).\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\nexport function defineNitroPlugin(def: NitroPluginDef): NitroPluginDef {\n return def;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n createServer,\n upsertEnvFile,\n type CreateServerOptions,\n type EnvKeyConfig,\n} from \"./create-server.js\";\n\nexport { readBody, streamFile } from \"./h3-helpers.js\";\nexport { createSSEHandler, type SSEHandlerOptions } from \"./sse.js\";\nexport {\n mountAuthMiddleware,\n autoMountAuth,\n getSession,\n addSession,\n removeSession,\n getSessionEmail,\n runAuthGuard,\n setDesktopExchange,\n setDesktopExchangeError,\n safeReturnPath,\n type DesktopExchangeErrorPayload,\n type AuthSession,\n type AuthOptions,\n} from \"./auth.js\";\nexport { requireEnvKey, type MissingKeyResponse } from \"./missing-key.js\";\nexport { verifyCaptcha, type CaptchaVerifyResult } from \"./captcha.js\";\nexport {\n createProductionAgentHandler,\n type ActionEntry,\n type ScriptEntry,\n type ProductionAgentOptions,\n type ActionTool,\n type ScriptTool,\n type AgentMessage,\n type AgentChatRequest,\n type AgentChatEvent,\n type AgentChatReference,\n type MentionProvider,\n type MentionProviderItem,\n} from \"../agent/index.js\";\nexport { createDevScriptRegistry } from \"../scripts/dev/index.js\";\n\nexport {\n createPollHandler,\n recordChange,\n getVersion,\n getChangesSince,\n} from \"./poll.js\";\nexport { createAuthPlugin, defaultAuthPlugin } from \"./auth-plugin.js\";\n// Re-export the org plugin so the auto-discovery's DEFAULT_PLUGIN_REGISTRY\n// (which references \"defaultOrgPlugin\" from @agent-native/core/server) can\n// resolve it during the deploy build worker-entry generation.\nexport { createOrgPlugin, defaultOrgPlugin } from \"../org/plugin.js\";\nexport {\n createGoogleAuthPlugin,\n type GoogleAuthPluginOptions,\n} from \"./google-auth-plugin.js\";\nexport {\n createAgentChatPlugin,\n defaultAgentChatPlugin,\n type AgentChatPluginOptions,\n} from \"./agent-chat-plugin.js\";\nexport {\n createThread,\n getThread,\n listThreads,\n updateThreadData,\n deleteThread,\n type ChatThread,\n type ChatThreadSummary,\n} from \"../chat-threads/store.js\";\nexport {\n createResourcesPlugin,\n defaultResourcesPlugin,\n} from \"./resources-plugin.js\";\nexport {\n createCoreRoutesPlugin,\n defaultCoreRoutesPlugin,\n FRAMEWORK_ROUTE_PREFIX,\n type CoreRoutesPluginOptions,\n} from \"./core-routes-plugin.js\";\nexport {\n createTerminalPlugin,\n defaultTerminalPlugin,\n type TerminalPluginOptions,\n} from \"../terminal/terminal-plugin.js\";\nexport {\n createCollabPlugin,\n type CollabPluginOptions,\n} from \"./collab-plugin.js\";\n\nexport {\n spawnTask,\n getTask,\n getTaskByThread,\n listTasks,\n sendToTask,\n markTaskErrored,\n type AgentTask,\n type SpawnTaskOptions,\n} from \"./agent-teams.js\";\nexport { isOAuthConnected, getOAuthAccounts } from \"./oauth-helpers.js\";\nexport { wrapWithAnalytics } from \"./analytics.js\";\nexport {\n getH3App,\n awaitBootstrap,\n type H3AppShim,\n} from \"./framework-request-handler.js\";\nexport {\n autoDiscoverActions,\n autoDiscoverScripts,\n loadActionsFromStaticRegistry,\n mergeCoreSharingActions,\n registerPackageActions,\n} from \"./action-discovery.js\";\nexport {\n mountActionRoutes,\n type MountActionRoutesOptions,\n} from \"./action-routes.js\";\nexport {\n runWithRequestContext,\n hasRequestContext,\n getRequestContext,\n getRequestUserEmail,\n getRequestOrgId,\n getRequestTimezone,\n getCredentialContext,\n isIntegrationCallerRequest,\n type RequestContext,\n} from \"./request-context.js\";\nexport { formatDateInTimezone, todayInTimezone } from \"./date-utils.js\";\n\nexport {\n createOnboardingPlugin,\n defaultOnboardingPlugin,\n} from \"../onboarding/plugin.js\";\n\nexport {\n registerFileUploadProvider,\n unregisterFileUploadProvider,\n listFileUploadProviders,\n getActiveFileUploadProvider,\n uploadFile,\n builderFileUploadProvider,\n type FileUploadInput,\n type FileUploadProvider,\n type FileUploadResult,\n} from \"../file-upload/index.js\";\n\nexport {\n createIntegrationsPlugin,\n defaultIntegrationsPlugin,\n slackAdapter,\n telegramAdapter,\n whatsappAdapter,\n emailAdapter,\n type PlatformAdapter,\n type IncomingMessage,\n type OutgoingMessage,\n type IntegrationStatus,\n type IntegrationsPluginOptions,\n} from \"../integrations/index.js\";\n\nexport {\n isElectron,\n isMobile,\n getOrigin,\n getAppBasePath,\n getAppUrl,\n resolveOAuthRedirectUri,\n isAllowedOAuthRedirectUri,\n encodeOAuthState,\n decodeOAuthState,\n resolveOAuthOwner,\n createOAuthSession,\n oauthCallbackResponse,\n oauthErrorPage,\n oauthDesktopExchangePage,\n type OAuthStatePayload,\n type OAuthOwnerResult,\n type OAuthSessionResult,\n} from \"./google-oauth.js\";\n\nexport {\n FeatureNotConfiguredError,\n hasBuilderPrivateKey,\n isBuilderEnvManaged,\n getBuilderProxyOrigin,\n getBuilderAuthHeader,\n resolveBuilderPrivateKey,\n resolveBuilderAuthHeader,\n resolveHasBuilderPrivateKey,\n resolveBuilderCredentials,\n resolveBuilderCredential,\n writeBuilderCredentials,\n deleteBuilderCredentials,\n resolveSecret,\n} from \"./credential-provider.js\";\nexport {\n getBuilderBranchProjectId,\n isBuilderBranchingEnabled,\n runBuilderAgent,\n type RunBuilderAgentResult,\n} from \"./builder-browser.js\";\n\nexport {\n sendEmail,\n isEmailConfigured,\n getEmailProvider,\n type EmailProvider,\n type SendEmailArgs,\n} from \"./email.js\";\nexport {\n renderEmail,\n emailStrong,\n emailLink,\n type RenderEmailArgs,\n type RenderedEmail,\n type EmailCta,\n} from \"./email-template.js\";\nexport { getAppProductionUrl, getFirstPartyProdUrl } from \"./app-url.js\";\nexport {\n getConfiguredAppBasePath,\n normalizeAppBasePath,\n withConfiguredAppBasePath,\n} from \"./app-base-path.js\";\nexport {\n signShortLivedToken,\n verifyShortLivedToken,\n type ShortLivedTokenClaims,\n type VerifyResult as ShortLivedTokenVerifyResult,\n} from \"./short-lived-token.js\";\n\n// SSR handler is NOT re-exported here — it uses a virtual module\n// (virtual:react-router/server-build) that only exists at Vite dev/build time.\n// Including it in this barrel would break the esbuild CF Pages bundler.\n// Templates import directly: import { ssrHandler } from \"@agent-native/core/server/ssr-handler\"\n\n// Nitro plugin helper — re-exported so templates don't need nitro as a direct dependency.\n// defineNitroPlugin is an identity function; this typed wrapper lets templates use it\n// without resolving `nitro/runtime` (which requires Nitro's virtual modules at runtime).\nexport type NitroPluginDef = (nitroApp: any) => void | Promise<void>;\nexport function defineNitroPlugin(def: NitroPluginDef): NitroPluginDef {\n return def;\n}\n"]}