@agent-native/core 0.6.1 → 0.7.2
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.
- package/README.md +43 -3
- package/dist/action.d.ts +8 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +18 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +9 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +301 -39
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +20 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +14 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +63 -6
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +3 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/create-workspace.d.ts +8 -0
- package/dist/cli/create-workspace.d.ts.map +1 -0
- package/dist/cli/create-workspace.js +18 -0
- package/dist/cli/create-workspace.js.map +1 -0
- package/dist/cli/create.d.ts +35 -7
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +444 -251
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +59 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup-agents.d.ts.map +1 -1
- package/dist/cli/setup-agents.js +0 -2
- package/dist/cli/setup-agents.js.map +1 -1
- package/dist/cli/templates-meta.d.ts +52 -0
- package/dist/cli/templates-meta.d.ts.map +1 -0
- package/dist/cli/templates-meta.js +165 -0
- package/dist/cli/templates-meta.js.map +1 -0
- package/dist/cli/workspacify.d.ts +18 -0
- package/dist/cli/workspacify.d.ts.map +1 -0
- package/dist/cli/workspacify.js +74 -0
- package/dist/cli/workspacify.js.map +1 -0
- package/dist/client/AgentPanel.d.ts +6 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +328 -241
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +172 -40
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts +21 -0
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -0
- package/dist/client/ConnectBuilderCard.js +196 -0
- package/dist/client/ConnectBuilderCard.js.map +1 -0
- package/dist/client/FeedbackButton.d.ts +15 -0
- package/dist/client/FeedbackButton.d.ts.map +1 -0
- package/dist/client/FeedbackButton.js +72 -0
- package/dist/client/FeedbackButton.js.map +1 -0
- package/dist/client/IframeEmbed.d.ts +17 -0
- package/dist/client/IframeEmbed.d.ts.map +1 -0
- package/dist/client/IframeEmbed.js +108 -0
- package/dist/client/IframeEmbed.js.map +1 -0
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +34 -7
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +34 -15
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +7 -0
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +86 -5
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +42 -26
- package/dist/client/composer/MentionPopover.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +24 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/types.d.ts +1 -1
- package/dist/client/composer/types.d.ts.map +1 -1
- package/dist/client/embed.d.ts +28 -0
- package/dist/client/embed.d.ts.map +1 -0
- package/dist/client/embed.js +50 -0
- package/dist/client/embed.js.map +1 -0
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +4 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +22 -9
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/onboarding/OnboardingBanner.d.ts +13 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.js +36 -0
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts +16 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +447 -0
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -0
- package/dist/client/onboarding/SetupButton.d.ts +10 -0
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -0
- package/dist/client/onboarding/SetupButton.js +36 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -0
- package/dist/client/onboarding/index.d.ts +12 -0
- package/dist/client/onboarding/index.d.ts.map +1 -0
- package/dist/client/onboarding/index.js +11 -0
- package/dist/client/onboarding/index.js.map +1 -0
- package/dist/client/onboarding/use-onboarding.d.ts +34 -0
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -0
- package/dist/client/onboarding/use-onboarding.js +101 -0
- package/dist/client/onboarding/use-onboarding.js.map +1 -0
- package/dist/client/org/TeamPage.d.ts +6 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +97 -21
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +104 -78
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +5 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +31 -11
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +142 -14
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +5 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts +2 -0
- package/dist/client/settings/AgentsSection.d.ts.map +1 -0
- package/dist/client/settings/AgentsSection.js +201 -0
- package/dist/client/settings/AgentsSection.js.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts +2 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.js +46 -0
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -0
- package/dist/client/settings/BrowserSection.d.ts +2 -0
- package/dist/client/settings/BrowserSection.d.ts.map +1 -0
- package/dist/client/settings/BrowserSection.js +10 -0
- package/dist/client/settings/BrowserSection.js.map +1 -0
- package/dist/client/settings/ComingSoonSection.d.ts +13 -0
- package/dist/client/settings/ComingSoonSection.d.ts.map +1 -0
- package/dist/client/settings/ComingSoonSection.js +9 -0
- package/dist/client/settings/ComingSoonSection.js.map +1 -0
- package/dist/client/settings/LLMSection.d.ts +2 -0
- package/dist/client/settings/LLMSection.d.ts.map +1 -0
- package/dist/client/settings/LLMSection.js +64 -0
- package/dist/client/settings/LLMSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts +8 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -0
- package/dist/client/settings/SettingsPanel.js +111 -0
- package/dist/client/settings/SettingsPanel.js.map +1 -0
- package/dist/client/settings/SettingsSection.d.ts +19 -0
- package/dist/client/settings/SettingsSection.d.ts.map +1 -0
- package/dist/client/settings/SettingsSection.js +10 -0
- package/dist/client/settings/SettingsSection.js.map +1 -0
- package/dist/client/settings/UsageSection.d.ts +2 -0
- package/dist/client/settings/UsageSection.d.ts.map +1 -0
- package/dist/client/settings/UsageSection.js +70 -0
- package/dist/client/settings/UsageSection.js.map +1 -0
- package/dist/client/settings/index.d.ts +3 -0
- package/dist/client/settings/index.d.ts.map +1 -0
- package/dist/client/settings/index.js +3 -0
- package/dist/client/settings/index.js.map +1 -0
- package/dist/client/settings/useBuilderStatus.d.ts +22 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -0
- package/dist/client/settings/useBuilderStatus.js +41 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +67 -4
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +25 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +62 -1
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +16 -1
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/db/client.d.ts +12 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +89 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts +11 -0
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +47 -3
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +62 -5
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/build.js +198 -54
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +5 -0
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +38 -7
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +28 -0
- package/dist/deploy/workspace-core.d.ts.map +1 -0
- package/dist/deploy/workspace-core.js +223 -0
- package/dist/deploy/workspace-core.js.map +1 -0
- package/dist/deploy/workspace-deploy.d.ts +11 -0
- package/dist/deploy/workspace-deploy.d.ts.map +1 -0
- package/dist/deploy/workspace-deploy.js +148 -0
- package/dist/deploy/workspace-deploy.js.map +1 -0
- package/dist/file-upload/builder.d.ts +11 -0
- package/dist/file-upload/builder.d.ts.map +1 -0
- package/dist/file-upload/builder.js +53 -0
- package/dist/file-upload/builder.js.map +1 -0
- package/dist/file-upload/index.d.ts +4 -0
- package/dist/file-upload/index.d.ts.map +1 -0
- package/dist/file-upload/index.js +3 -0
- package/dist/file-upload/index.js.map +1 -0
- package/dist/file-upload/registry.d.ts +23 -0
- package/dist/file-upload/registry.d.ts.map +1 -0
- package/dist/file-upload/registry.js +52 -0
- package/dist/file-upload/registry.js.map +1 -0
- package/dist/file-upload/types.d.ts +37 -0
- package/dist/file-upload/types.d.ts.map +1 -0
- package/dist/file-upload/types.js +10 -0
- package/dist/file-upload/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/google-docs.d.ts +89 -0
- package/dist/integrations/adapters/google-docs.d.ts.map +1 -0
- package/dist/integrations/adapters/google-docs.js +261 -0
- package/dist/integrations/adapters/google-docs.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +34 -0
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +32 -0
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts +54 -0
- package/dist/integrations/google-docs-poller.d.ts.map +1 -0
- package/dist/integrations/google-docs-poller.js +442 -0
- package/dist/integrations/google-docs-poller.js.map +1 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +49 -2
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +33 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +10 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +13 -3
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.d.ts +3 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +87 -61
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +20 -3
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp-client/config.d.ts +46 -0
- package/dist/mcp-client/config.d.ts.map +1 -0
- package/dist/mcp-client/config.js +152 -0
- package/dist/mcp-client/config.js.map +1 -0
- package/dist/mcp-client/index.d.ts +17 -0
- package/dist/mcp-client/index.d.ts.map +1 -0
- package/dist/mcp-client/index.js +53 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/manager.d.ts +76 -0
- package/dist/mcp-client/manager.d.ts.map +1 -0
- package/dist/mcp-client/manager.js +212 -0
- package/dist/mcp-client/manager.js.map +1 -0
- package/dist/oauth-tokens/google-refresh.d.ts +31 -0
- package/dist/oauth-tokens/google-refresh.d.ts.map +1 -0
- package/dist/oauth-tokens/google-refresh.js +115 -0
- package/dist/oauth-tokens/google-refresh.js.map +1 -0
- package/dist/oauth-tokens/index.d.ts +1 -0
- package/dist/oauth-tokens/index.d.ts.map +1 -1
- package/dist/oauth-tokens/index.js +1 -0
- package/dist/oauth-tokens/index.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +3 -1
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts +10 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -0
- package/dist/onboarding/default-steps.js +203 -0
- package/dist/onboarding/default-steps.js.map +1 -0
- package/dist/onboarding/index.d.ts +12 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +11 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/plugin.d.ts +19 -0
- package/dist/onboarding/plugin.d.ts.map +1 -0
- package/dist/onboarding/plugin.js +147 -0
- package/dist/onboarding/plugin.js.map +1 -0
- package/dist/onboarding/registry.d.ts +24 -0
- package/dist/onboarding/registry.d.ts.map +1 -0
- package/dist/onboarding/registry.js +40 -0
- package/dist/onboarding/registry.js.map +1 -0
- package/dist/onboarding/types.d.ts +71 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +10 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/org/context.js +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +35 -10
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +37 -22
- package/dist/org/plugin.js.map +1 -1
- package/dist/resources/agents.d.ts +4 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +44 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/handlers.d.ts +17 -0
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +49 -12
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts +48 -0
- package/dist/resources/metadata.d.ts.map +1 -0
- package/dist/resources/metadata.js +150 -0
- package/dist/resources/metadata.js.map +1 -0
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +3 -2
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +59 -18
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +3 -2
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +2 -1
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/core-scripts.d.ts.map +1 -1
- package/dist/scripts/core-scripts.js +2 -0
- package/dist/scripts/core-scripts.js.map +1 -1
- package/dist/scripts/db/patch.d.ts.map +1 -1
- package/dist/scripts/db/patch.js +273 -11
- package/dist/scripts/db/patch.js.map +1 -1
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +3 -2
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/docs/index.d.ts +2 -0
- package/dist/scripts/docs/index.d.ts.map +1 -0
- package/dist/scripts/docs/index.js +4 -0
- package/dist/scripts/docs/index.js.map +1 -0
- package/dist/scripts/docs/search.d.ts +13 -0
- package/dist/scripts/docs/search.d.ts.map +1 -0
- package/dist/scripts/docs/search.js +130 -0
- package/dist/scripts/docs/search.js.map +1 -0
- package/dist/scripts/resources/delete-memory.d.ts +7 -0
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -0
- package/dist/scripts/resources/delete-memory.js +49 -0
- package/dist/scripts/resources/delete-memory.js.map +1 -0
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +2 -1
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/index.d.ts.map +1 -1
- package/dist/scripts/resources/index.js +2 -0
- package/dist/scripts/resources/index.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +2 -1
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +2 -1
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +2 -1
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts +9 -0
- package/dist/scripts/resources/save-memory.d.ts.map +1 -0
- package/dist/scripts/resources/save-memory.js +78 -0
- package/dist/scripts/resources/save-memory.js.map +1 -0
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +2 -1
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/scripts/utils.d.ts +10 -1
- package/dist/scripts/utils.d.ts.map +1 -1
- package/dist/scripts/utils.js +45 -2
- package/dist/scripts/utils.js.map +1 -1
- package/dist/server/action-discovery.d.ts +5 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +53 -20
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +88 -56
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +15 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +853 -91
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +13 -25
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +23 -59
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/agents-bundle.d.ts +33 -5
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +108 -64
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts +7 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +448 -93
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +272 -10
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +61 -0
- package/dist/server/builder-browser.d.ts.map +1 -0
- package/dist/server/builder-browser.js +229 -0
- package/dist/server/builder-browser.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +273 -9
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +37 -0
- package/dist/server/credential-provider.d.ts.map +1 -0
- package/dist/server/credential-provider.js +49 -0
- package/dist/server/credential-provider.js.map +1 -0
- package/dist/server/desktop-sso.d.ts +30 -0
- package/dist/server/desktop-sso.d.ts.map +1 -0
- package/dist/server/desktop-sso.js +74 -0
- package/dist/server/desktop-sso.js.map +1 -0
- package/dist/server/email.d.ts +23 -0
- package/dist/server/email.d.ts.map +1 -0
- package/dist/server/email.js +105 -0
- package/dist/server/email.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +71 -3
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-auth-plugin.js +1 -1
- package/dist/server/google-oauth.d.ts +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +34 -13
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/local-migration.d.ts +9 -0
- package/dist/server/local-migration.d.ts.map +1 -1
- package/dist/server/local-migration.js +44 -14
- package/dist/server/local-migration.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +3 -0
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +7 -4
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +6 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +323 -28
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +48 -0
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +20 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +41 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +2 -1
- package/dist/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- package/dist/templates/default/.agents/skills/security/SKILL.md +145 -40
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
- package/dist/templates/default/_gitignore +1 -0
- package/dist/templates/default/app/root.tsx +4 -1
- package/dist/templates/workspace-core/.agents/skills/company-policies/SKILL.md +42 -0
- package/dist/templates/workspace-core/AGENTS.md +62 -0
- package/dist/templates/workspace-core/actions/company-directory.ts +38 -0
- package/dist/templates/workspace-core/package.json +39 -0
- package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/dist/templates/workspace-core/src/client/index.ts +26 -0
- package/dist/templates/workspace-core/src/credentials.ts +29 -0
- package/dist/templates/workspace-core/src/index.ts +21 -0
- package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/dist/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/dist/templates/workspace-core/src/server/index.ts +22 -0
- package/dist/templates/workspace-core/tailwind.preset.ts +34 -0
- package/dist/templates/workspace-core/tsconfig.json +9 -0
- package/dist/templates/workspace-root/.env.example +37 -0
- package/dist/templates/workspace-root/README.md +62 -0
- package/dist/templates/workspace-root/_gitignore +23 -0
- package/dist/templates/workspace-root/package.json +18 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/dist/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/usage/store.d.ts +74 -12
- package/dist/usage/store.d.ts.map +1 -1
- package/dist/usage/store.js +210 -44
- package/dist/usage/store.js.map +1 -1
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +65 -15
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +16 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +130 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.md +223 -0
- package/docs/content/actions.md +129 -0
- package/docs/content/agent-mentions.md +171 -0
- package/docs/content/authentication.md +155 -0
- package/docs/content/cli-adapters.md +244 -0
- package/docs/content/client.md +175 -0
- package/docs/content/context-awareness.md +168 -0
- package/docs/content/creating-templates.md +311 -0
- package/docs/content/database.md +82 -0
- package/docs/content/deployment.md +237 -0
- package/docs/content/enterprise-workspace.md +235 -0
- package/docs/content/faq.md +101 -0
- package/docs/content/file-uploads.md +102 -0
- package/docs/content/frames.md +47 -0
- package/docs/content/getting-started.md +104 -0
- package/docs/content/integrations.md +198 -0
- package/docs/content/key-concepts.md +246 -0
- package/docs/content/mcp-clients.md +110 -0
- package/docs/content/mcp-protocol.md +168 -0
- package/docs/content/onboarding.md +107 -0
- package/docs/content/real-time-collaboration.md +185 -0
- package/docs/content/resources.md +277 -0
- package/docs/content/security.md +158 -0
- package/docs/content/server.md +200 -0
- package/docs/content/skills-guide.md +107 -0
- package/docs/content/what-is-agent-native.md +100 -0
- package/docs/content/workspace-management.md +224 -0
- package/package.json +13 -3
- package/src/templates/default/.agents/skills/actions/SKILL.md +2 -1
- package/src/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- package/src/templates/default/.agents/skills/security/SKILL.md +145 -40
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
- package/src/templates/default/_gitignore +1 -0
- package/src/templates/default/app/root.tsx +4 -1
- package/src/templates/workspace-core/.agents/skills/company-policies/SKILL.md +42 -0
- package/src/templates/workspace-core/AGENTS.md +62 -0
- package/src/templates/workspace-core/actions/company-directory.ts +38 -0
- package/src/templates/workspace-core/package.json +39 -0
- package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/src/templates/workspace-core/src/client/index.ts +26 -0
- package/src/templates/workspace-core/src/credentials.ts +29 -0
- package/src/templates/workspace-core/src/index.ts +21 -0
- package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/src/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/src/templates/workspace-core/src/server/index.ts +22 -0
- package/src/templates/workspace-core/tailwind.preset.ts +34 -0
- package/src/templates/workspace-core/tsconfig.json +9 -0
- package/src/templates/workspace-root/.env.example +37 -0
- package/src/templates/workspace-root/README.md +62 -0
- package/src/templates/workspace-root/_gitignore +23 -0
- package/src/templates/workspace-root/package.json +18 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/src/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/templates/templates/default/.agents/skills/actions/SKILL.md +0 -142
- package/dist/templates/templates/default/.agents/skills/agent-engines/SKILL.md +0 -127
- package/dist/templates/templates/default/.agents/skills/capture-learnings/SKILL.md +0 -50
- package/dist/templates/templates/default/.agents/skills/create-skill/SKILL.md +0 -167
- package/dist/templates/templates/default/.agents/skills/delegate-to-agent/SKILL.md +0 -90
- package/dist/templates/templates/default/.agents/skills/frontend-design/SKILL.md +0 -69
- package/dist/templates/templates/default/.agents/skills/real-time-collab/SKILL.md +0 -183
- package/dist/templates/templates/default/.agents/skills/real-time-sync/SKILL.md +0 -112
- package/dist/templates/templates/default/.agents/skills/security/SKILL.md +0 -108
- package/dist/templates/templates/default/.agents/skills/self-modifying-code/SKILL.md +0 -79
- package/dist/templates/templates/default/.agents/skills/storing-data/SKILL.md +0 -110
- package/dist/templates/templates/default/.claude/settings.json +0 -100
- package/dist/templates/templates/default/.env.example +0 -5
- package/dist/templates/templates/default/.ignore +0 -0
- package/dist/templates/templates/default/.prettierrc +0 -5
- package/dist/templates/templates/default/AGENTS.md +0 -110
- package/dist/templates/templates/default/DEVELOPING.md +0 -117
- package/dist/templates/templates/default/_gitignore +0 -37
- package/dist/templates/templates/default/actions/hello.ts +0 -20
- package/dist/templates/templates/default/actions/navigate.ts +0 -53
- package/dist/templates/templates/default/actions/run.ts +0 -2
- package/dist/templates/templates/default/actions/view-screen.ts +0 -39
- package/dist/templates/templates/default/app/entry.client.tsx +0 -4
- package/dist/templates/templates/default/app/entry.server.tsx +0 -56
- package/dist/templates/templates/default/app/global.css +0 -95
- package/dist/templates/templates/default/app/lib/utils.ts +0 -1
- package/dist/templates/templates/default/app/root.tsx +0 -107
- package/dist/templates/templates/default/app/routes/_index.tsx +0 -62
- package/dist/templates/templates/default/app/routes.ts +0 -4
- package/dist/templates/templates/default/app/vite-env.d.ts +0 -6
- package/dist/templates/templates/default/components.json +0 -20
- package/dist/templates/templates/default/data/.gitkeep +0 -0
- package/dist/templates/templates/default/data/sync-config.json +0 -1
- package/dist/templates/templates/default/learnings.defaults.md +0 -5
- package/dist/templates/templates/default/learnings.md +0 -0
- package/dist/templates/templates/default/package.json +0 -46
- package/dist/templates/templates/default/postcss.config.js +0 -6
- package/dist/templates/templates/default/public/icon-180.svg +0 -4
- package/dist/templates/templates/default/public/icon-192.svg +0 -4
- package/dist/templates/templates/default/public/icon-512.svg +0 -4
- package/dist/templates/templates/default/public/manifest.json +0 -13
- package/dist/templates/templates/default/react-router.config.ts +0 -6
- package/dist/templates/templates/default/server/middleware/auth.ts +0 -15
- package/dist/templates/templates/default/server/plugins/.gitkeep +0 -0
- package/dist/templates/templates/default/server/routes/[...page].get.ts +0 -5
- package/dist/templates/templates/default/server/routes/api/hello.get.ts +0 -5
- package/dist/templates/templates/default/shared/api.ts +0 -6
- package/dist/templates/templates/default/ssr-entry.ts +0 -20
- package/dist/templates/templates/default/tailwind.config.ts +0 -7
- package/dist/templates/templates/default/tsconfig.json +0 -11
- package/dist/templates/templates/default/vite.config.ts +0 -6
package/dist/server/auth.js
CHANGED
|
@@ -14,48 +14,82 @@ import { defineEventHandler, getMethod, getQuery, setResponseHeader, setResponse
|
|
|
14
14
|
function toWebRequest(event) {
|
|
15
15
|
return event.req;
|
|
16
16
|
}
|
|
17
|
-
import { getDbExec, isPostgres, intType } from "../db/client.js";
|
|
17
|
+
import { getDbExec, isPostgres, intType, isLocalDatabase, } from "../db/client.js";
|
|
18
18
|
import { getBetterAuth, getBetterAuthSync } from "./better-auth-instance.js";
|
|
19
|
-
import { getOnboardingHtml } from "./onboarding-html.js";
|
|
19
|
+
import { getOnboardingHtml, getResetPasswordHtml } from "./onboarding-html.js";
|
|
20
20
|
import { migrateLocalUserData } from "./local-migration.js";
|
|
21
21
|
import { readBody } from "../server/h3-helpers.js";
|
|
22
|
+
import { readDesktopSso, writeDesktopSso, clearDesktopSso, } from "./desktop-sso.js";
|
|
23
|
+
import { isElectron as isElectronRequest } from "./google-oauth.js";
|
|
24
|
+
/**
|
|
25
|
+
* Get the configured session max age. Desktop SSO broker writes from
|
|
26
|
+
* OAuth flows read this so expiration stays consistent with the cookie.
|
|
27
|
+
*/
|
|
28
|
+
export function getSessionMaxAge() {
|
|
29
|
+
return sessionMaxAge;
|
|
30
|
+
}
|
|
22
31
|
// ---------------------------------------------------------------------------
|
|
23
32
|
// Constants
|
|
24
33
|
// ---------------------------------------------------------------------------
|
|
25
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Cookie name for the framework's session cookie.
|
|
36
|
+
*
|
|
37
|
+
* Browsers scope cookies by host (NOT host+port — RFC 6265), so two apps
|
|
38
|
+
* running on different localhost ports share one cookie jar. When multiple
|
|
39
|
+
* templates run side-by-side (`dev:all`, the desktop app, multi-template
|
|
40
|
+
* deploys on a shared domain), they would otherwise stomp on each other's
|
|
41
|
+
* `an_session` cookie and ping-pong each other into a logged-out state.
|
|
42
|
+
*
|
|
43
|
+
* When `APP_NAME` is set, suffix the cookie so each app gets its own slot.
|
|
44
|
+
*/
|
|
45
|
+
const APP_NAME_SLUG = (process.env.APP_NAME || "")
|
|
46
|
+
.toLowerCase()
|
|
47
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
48
|
+
.replace(/^_+|_+$/g, "");
|
|
49
|
+
export const COOKIE_NAME = APP_NAME_SLUG
|
|
50
|
+
? `an_session_${APP_NAME_SLUG}`
|
|
51
|
+
: "an_session";
|
|
26
52
|
const DEFAULT_MAX_AGE = 60 * 60 * 24 * 30; // 30 days
|
|
53
|
+
const LOCAL_MODE_MARKER_PATH = path.resolve(process.cwd(), ".agent-native", "auth-mode");
|
|
27
54
|
// ---------------------------------------------------------------------------
|
|
28
55
|
// AUTH_MODE detection
|
|
29
56
|
// ---------------------------------------------------------------------------
|
|
57
|
+
let _warnedRemoteLocalMode = false;
|
|
30
58
|
/**
|
|
31
59
|
* Check if the app is in local-only mode (no auth).
|
|
32
60
|
*
|
|
33
|
-
* Returns true when
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* configured (no ACCESS_TOKEN, no BYOA). This makes dev "just work"
|
|
37
|
-
* without requiring auth setup, while still respecting auth when configured.
|
|
61
|
+
* Returns true when AUTH_MODE=local is explicitly set or when the dev
|
|
62
|
+
* onboarding flow has enabled local mode for the current workspace via
|
|
63
|
+
* a runtime marker file.
|
|
38
64
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* developer has explicitly opted into requiring authentication.
|
|
65
|
+
* Local mode is an explicit escape hatch for when you want to guarantee
|
|
66
|
+
* no auth is used. In development, getSession() also falls back to
|
|
67
|
+
* local@localhost automatically if no other auth method succeeds, so
|
|
68
|
+
* apps are always usable without configuration in dev.
|
|
44
69
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
70
|
+
* Refuses to enable on any non-local database (Postgres, Turso, D1): local
|
|
71
|
+
* mode uses a single shared virtual user with no per-machine scoping, so on
|
|
72
|
+
* a shared DB every developer would land on the same account and collide.
|
|
47
73
|
*/
|
|
48
|
-
function
|
|
74
|
+
async function isLocalModeEnabled() {
|
|
75
|
+
if (!isLocalDatabase()) {
|
|
76
|
+
if (process.env.AUTH_MODE === "local" && !_warnedRemoteLocalMode) {
|
|
77
|
+
_warnedRemoteLocalMode = true;
|
|
78
|
+
console.warn("[agent-native] AUTH_MODE=local ignored: database is not local SQLite. " +
|
|
79
|
+
"local@localhost has no per-user scoping and would collide across developers on a shared DB.");
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
49
83
|
if (process.env.AUTH_MODE === "local")
|
|
50
84
|
return true;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
85
|
+
try {
|
|
86
|
+
const fs = await getFs();
|
|
87
|
+
const mode = fs.readFileSync(LOCAL_MODE_MARKER_PATH, "utf-8").trim();
|
|
88
|
+
return mode === "local";
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
57
92
|
}
|
|
58
|
-
return false;
|
|
59
93
|
}
|
|
60
94
|
/**
|
|
61
95
|
* Check if we're in a development/test environment.
|
|
@@ -179,6 +213,15 @@ let _authGuardConfig = null;
|
|
|
179
213
|
* /_agent-native/* routes).
|
|
180
214
|
*/
|
|
181
215
|
let _authGuardFn = null;
|
|
216
|
+
/**
|
|
217
|
+
* The H3 app the auth routes + guard were last mounted on. Module-level
|
|
218
|
+
* state survives Vite HMR restarts, but each HMR cycle creates a fresh
|
|
219
|
+
* nitroApp/H3 instance whose middleware array is empty again. Tracking the
|
|
220
|
+
* app here lets autoMountAuth detect "same module state, new app" and
|
|
221
|
+
* re-mount routes instead of silently skipping them because `_authGuardFn`
|
|
222
|
+
* looks populated from a previous cycle.
|
|
223
|
+
*/
|
|
224
|
+
let _mountedApp = null;
|
|
182
225
|
/**
|
|
183
226
|
* Run the auth guard on an event. Returns a Response/object to block the
|
|
184
227
|
* request (login page or 401), or undefined to allow it through.
|
|
@@ -212,9 +255,12 @@ function createAuthGuardFn() {
|
|
|
212
255
|
const { loginHtml, publicPaths } = config;
|
|
213
256
|
const url = event.node?.req?.url ?? event.path ?? "/";
|
|
214
257
|
const p = url.split("?")[0];
|
|
215
|
-
// Skip auth routes
|
|
258
|
+
// Skip auth routes and specific Google OAuth endpoints that must be public
|
|
259
|
+
// (callback and auth-url). Other Google endpoints like /status require auth.
|
|
216
260
|
if (p.startsWith("/_agent-native/auth/") ||
|
|
217
|
-
p
|
|
261
|
+
p === "/_agent-native/google/callback" ||
|
|
262
|
+
p === "/_agent-native/google/auth-url" ||
|
|
263
|
+
p === "/_agent-native/google/add-account/callback") {
|
|
218
264
|
return;
|
|
219
265
|
}
|
|
220
266
|
// Skip static assets (Vite chunks, fonts, images, etc.)
|
|
@@ -267,10 +313,11 @@ function mapBetterAuthSession(baSession) {
|
|
|
267
313
|
* 5. Better Auth → check session via Better Auth API (cookie or Bearer)
|
|
268
314
|
* 6. Legacy cookie → check an_session cookie in legacy sessions table
|
|
269
315
|
* 7. Mobile _session query param → promote to cookie
|
|
316
|
+
* 8. Dev-mode fallback → local@localhost (never block in development)
|
|
270
317
|
*/
|
|
271
318
|
export async function getSession(event) {
|
|
272
319
|
// 1. AUTH_MODE=local — explicit local-only mode
|
|
273
|
-
if (
|
|
320
|
+
if ((await isLocalModeEnabled()) || authDisabledMode) {
|
|
274
321
|
// Check for a real session cookie first (e.g. from Google OAuth)
|
|
275
322
|
try {
|
|
276
323
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
@@ -315,6 +362,14 @@ export async function getSession(event) {
|
|
|
315
362
|
const session = await customGetSession(event);
|
|
316
363
|
if (session)
|
|
317
364
|
return session;
|
|
365
|
+
// Desktop SSO broker: even with BYOA auth, fall back to the broker
|
|
366
|
+
// for Electron requests so cross-template SSO works for custom-auth
|
|
367
|
+
// templates too.
|
|
368
|
+
if (isElectronRequest(event)) {
|
|
369
|
+
const sso = await readDesktopSso();
|
|
370
|
+
if (sso?.email)
|
|
371
|
+
return { email: sso.email, token: sso.token };
|
|
372
|
+
}
|
|
318
373
|
// Fall through to mobile _session check
|
|
319
374
|
}
|
|
320
375
|
else {
|
|
@@ -326,6 +381,9 @@ export async function getSession(event) {
|
|
|
326
381
|
headers: event.headers,
|
|
327
382
|
});
|
|
328
383
|
if (baSession?.user?.email) {
|
|
384
|
+
// Successful real sign-in — clear the upgrade-pending marker so
|
|
385
|
+
// the dev fallback becomes reachable again for future local work.
|
|
386
|
+
clearUpgradePendingCookie(event);
|
|
329
387
|
return mapBetterAuthSession(baSession);
|
|
330
388
|
}
|
|
331
389
|
}
|
|
@@ -337,8 +395,24 @@ export async function getSession(event) {
|
|
|
337
395
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
338
396
|
if (cookie) {
|
|
339
397
|
const email = await getSessionEmail(cookie);
|
|
340
|
-
if (email)
|
|
398
|
+
if (email) {
|
|
399
|
+
clearUpgradePendingCookie(event);
|
|
341
400
|
return { email, token: cookie };
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// 5b. Desktop SSO broker fallback.
|
|
404
|
+
// Each template in the Electron desktop app has its own database, so
|
|
405
|
+
// a session token created by one template doesn't resolve in another.
|
|
406
|
+
// When an Electron request has no resolvable session, trust the
|
|
407
|
+
// home-dir SSO record written by whichever template the user signed
|
|
408
|
+
// into. Gated on Electron user-agent so no non-desktop code path
|
|
409
|
+
// consults the file.
|
|
410
|
+
if (isElectronRequest(event)) {
|
|
411
|
+
const sso = await readDesktopSso();
|
|
412
|
+
if (sso?.email) {
|
|
413
|
+
clearUpgradePendingCookie(event);
|
|
414
|
+
return { email: sso.email, token: sso.token };
|
|
415
|
+
}
|
|
342
416
|
}
|
|
343
417
|
}
|
|
344
418
|
// 6. Mobile WebView bridge — _session query param
|
|
@@ -348,8 +422,7 @@ export async function getSession(event) {
|
|
|
348
422
|
if (email) {
|
|
349
423
|
setCookie(event, COOKIE_NAME, qToken, {
|
|
350
424
|
httpOnly: true,
|
|
351
|
-
|
|
352
|
-
sameSite: "lax",
|
|
425
|
+
...crossSiteCookieAttrs(event),
|
|
353
426
|
path: "/",
|
|
354
427
|
maxAge: sessionMaxAge,
|
|
355
428
|
});
|
|
@@ -357,8 +430,113 @@ export async function getSession(event) {
|
|
|
357
430
|
return { email, token: qToken };
|
|
358
431
|
}
|
|
359
432
|
}
|
|
433
|
+
// 7. Dev-mode safety net — in development on a local SQLite database, fall
|
|
434
|
+
// back to local@localhost so the app is usable without any auth configuration.
|
|
435
|
+
// This prevents 401 errors when Better Auth isn't configured, the marker file
|
|
436
|
+
// is missing, or the user simply wants to play around locally.
|
|
437
|
+
//
|
|
438
|
+
// Gated on isLocalDatabase() because local@localhost has no per-user scoping:
|
|
439
|
+
// on a shared DB (Postgres, Turso, D1) this fallback would land every
|
|
440
|
+
// developer on the same account and expose each other's data.
|
|
441
|
+
//
|
|
442
|
+
// EXCEPTION: if the user has explicitly exited local mode (clicked "Upgrade
|
|
443
|
+
// to real account"), they've signaled they want real auth. The upgrade
|
|
444
|
+
// cookie suppresses this fallback so the onboarding/sign-in page is served
|
|
445
|
+
// instead of silently re-authenticating them as local@localhost.
|
|
446
|
+
if (isDevEnvironment() &&
|
|
447
|
+
isLocalDatabase() &&
|
|
448
|
+
!isUpgradePending(event) &&
|
|
449
|
+
!hasSignInFlag(event)) {
|
|
450
|
+
return LOCAL_SESSION;
|
|
451
|
+
}
|
|
360
452
|
return null;
|
|
361
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Cookie set by POST /_agent-native/auth/exit-local-mode so we know the user
|
|
456
|
+
* is in the middle of upgrading from local@localhost to a real account.
|
|
457
|
+
* While this cookie is present we skip the dev-mode "auto local session"
|
|
458
|
+
* fallback so the onboarding/sign-in page can actually render.
|
|
459
|
+
* Cleared on successful sign-in/sign-up.
|
|
460
|
+
*/
|
|
461
|
+
const UPGRADE_COOKIE = "an_upgrade_pending";
|
|
462
|
+
function isUpgradePending(event) {
|
|
463
|
+
try {
|
|
464
|
+
return getCookie(event, UPGRADE_COOKIE) === "1";
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function setUpgradePendingCookie(event) {
|
|
471
|
+
setCookie(event, UPGRADE_COOKIE, "1", {
|
|
472
|
+
httpOnly: true,
|
|
473
|
+
...crossSiteCookieAttrs(event),
|
|
474
|
+
path: "/",
|
|
475
|
+
maxAge: 60 * 60, // 1 hour — enough to complete sign-in
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* URL-flag fallback for third-party iframe contexts (e.g. the Builder.io
|
|
480
|
+
* editor) where SameSite=Lax cookies from an exit-local-mode POST are not
|
|
481
|
+
* delivered on the subsequent reload. TeamPage reloads with ?signin=1 so
|
|
482
|
+
* we can reliably suppress the dev-mode local fallback without a cookie.
|
|
483
|
+
*/
|
|
484
|
+
function hasSignInFlag(event) {
|
|
485
|
+
try {
|
|
486
|
+
return getQuery(event)?.signin === "1";
|
|
487
|
+
}
|
|
488
|
+
catch {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Cookie attributes that work in both same-site and third-party iframe
|
|
494
|
+
* contexts. Over HTTPS we emit `SameSite=None; Secure` (required by browsers
|
|
495
|
+
* to ship the cookie back inside a cross-origin iframe); for plain HTTP dev
|
|
496
|
+
* we keep `SameSite=Lax` since `None` requires Secure.
|
|
497
|
+
*/
|
|
498
|
+
function crossSiteCookieAttrs(event) {
|
|
499
|
+
return isHttpsRequest(event)
|
|
500
|
+
? { sameSite: "none", secure: true }
|
|
501
|
+
: { sameSite: "lax", secure: false };
|
|
502
|
+
}
|
|
503
|
+
function isHttpsRequest(event) {
|
|
504
|
+
try {
|
|
505
|
+
const req = event.req ?? event.node?.req;
|
|
506
|
+
const headers = req?.headers;
|
|
507
|
+
const get = (k) => {
|
|
508
|
+
if (!headers)
|
|
509
|
+
return undefined;
|
|
510
|
+
if (typeof headers.get === "function") {
|
|
511
|
+
return headers.get(k) ?? undefined;
|
|
512
|
+
}
|
|
513
|
+
const v = headers[k];
|
|
514
|
+
return Array.isArray(v) ? v[0] : v;
|
|
515
|
+
};
|
|
516
|
+
const xfProto = get("x-forwarded-proto");
|
|
517
|
+
if (xfProto && String(xfProto).split(",")[0].trim() === "https") {
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
const url = req?.url;
|
|
521
|
+
if (typeof url === "string" && url.startsWith("https://"))
|
|
522
|
+
return true;
|
|
523
|
+
const appUrl = process.env.APP_URL || process.env.BETTER_AUTH_URL || "";
|
|
524
|
+
if (appUrl.startsWith("https://"))
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
// ignore
|
|
529
|
+
}
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
function clearUpgradePendingCookie(event) {
|
|
533
|
+
try {
|
|
534
|
+
deleteCookie(event, UPGRADE_COOKIE, { path: "/" });
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
// ignore
|
|
538
|
+
}
|
|
539
|
+
}
|
|
362
540
|
// ---------------------------------------------------------------------------
|
|
363
541
|
// Public path matching
|
|
364
542
|
// ---------------------------------------------------------------------------
|
|
@@ -373,7 +551,7 @@ const TOKEN_LOGIN_HTML = `<!DOCTYPE html>
|
|
|
373
551
|
<html lang="en">
|
|
374
552
|
<head>
|
|
375
553
|
<meta charset="UTF-8">
|
|
376
|
-
<meta name="viewport" content="width=device-width, initial-scale=1
|
|
554
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
377
555
|
<title>Sign in</title>
|
|
378
556
|
<style>
|
|
379
557
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
@@ -458,21 +636,8 @@ const TOKEN_LOGIN_HTML = `<!DOCTYPE html>
|
|
|
458
636
|
async function setAuthModeLocal() {
|
|
459
637
|
try {
|
|
460
638
|
const fs = await getFs();
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
try {
|
|
464
|
-
content = fs.readFileSync(envPath, "utf-8");
|
|
465
|
-
}
|
|
466
|
-
catch {
|
|
467
|
-
// .env doesn't exist yet
|
|
468
|
-
}
|
|
469
|
-
if (content.includes("AUTH_MODE=")) {
|
|
470
|
-
content = content.replace(/AUTH_MODE=.*/g, "AUTH_MODE=local");
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
content = content.trimEnd() + "\nAUTH_MODE=local\n";
|
|
474
|
-
}
|
|
475
|
-
fs.writeFileSync(envPath, content, "utf-8");
|
|
639
|
+
fs.mkdirSync(path.dirname(LOCAL_MODE_MARKER_PATH), { recursive: true });
|
|
640
|
+
fs.writeFileSync(LOCAL_MODE_MARKER_PATH, "local\n", "utf-8");
|
|
476
641
|
process.env.AUTH_MODE = "local";
|
|
477
642
|
return true;
|
|
478
643
|
}
|
|
@@ -483,20 +648,12 @@ async function setAuthModeLocal() {
|
|
|
483
648
|
async function removeAuthModeLocal() {
|
|
484
649
|
try {
|
|
485
650
|
const fs = await getFs();
|
|
486
|
-
const envPath = path.resolve(process.cwd(), ".env");
|
|
487
|
-
let content = "";
|
|
488
651
|
try {
|
|
489
|
-
|
|
652
|
+
fs.unlinkSync(LOCAL_MODE_MARKER_PATH);
|
|
490
653
|
}
|
|
491
654
|
catch {
|
|
492
|
-
|
|
493
|
-
}
|
|
494
|
-
// Remove AUTH_MODE=local line entirely
|
|
495
|
-
content = content
|
|
496
|
-
.split("\n")
|
|
497
|
-
.filter((line) => !line.match(/^\s*AUTH_MODE\s*=/))
|
|
498
|
-
.join("\n");
|
|
499
|
-
fs.writeFileSync(envPath, content, "utf-8");
|
|
655
|
+
// Marker already absent
|
|
656
|
+
}
|
|
500
657
|
delete process.env.AUTH_MODE;
|
|
501
658
|
return true;
|
|
502
659
|
}
|
|
@@ -504,6 +661,38 @@ async function removeAuthModeLocal() {
|
|
|
504
661
|
return false;
|
|
505
662
|
}
|
|
506
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* POST /_agent-native/auth/migrate-local-data handler. Exposed here (not
|
|
666
|
+
* inlined in a single mount function) because it must be registered from
|
|
667
|
+
* every auth-mount path — including local-mode and fallback — so the
|
|
668
|
+
* upgrade-from-local flow never 500s when BetterAuth init is skipped or
|
|
669
|
+
* failed. Previously this was only mounted inside mountBetterAuthRoutes()
|
|
670
|
+
* which meant that in local mode (or when BetterAuth failed to init) the
|
|
671
|
+
* request fell through to the Nitro SSR renderer and produced a 500.
|
|
672
|
+
*/
|
|
673
|
+
const migrateLocalDataHandler = defineEventHandler(async (event) => {
|
|
674
|
+
if (getMethod(event) !== "POST") {
|
|
675
|
+
setResponseStatus(event, 405);
|
|
676
|
+
return { error: "Method not allowed" };
|
|
677
|
+
}
|
|
678
|
+
const session = await getSession(event);
|
|
679
|
+
if (!session?.email || session.email === "local@localhost") {
|
|
680
|
+
setResponseStatus(event, 401);
|
|
681
|
+
return { error: "Not authenticated as a real account" };
|
|
682
|
+
}
|
|
683
|
+
try {
|
|
684
|
+
const result = await migrateLocalUserData(session.email);
|
|
685
|
+
return { ok: true, ...result };
|
|
686
|
+
}
|
|
687
|
+
catch (e) {
|
|
688
|
+
console.error("[migrate-local-data] Migration threw for", session.email, e);
|
|
689
|
+
setResponseStatus(event, 500);
|
|
690
|
+
return {
|
|
691
|
+
error: e?.message || "Migration failed",
|
|
692
|
+
stack: isDevEnvironment() ? e?.stack : undefined,
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
});
|
|
507
696
|
// ---------------------------------------------------------------------------
|
|
508
697
|
// mountBetterAuthRoutes — Better Auth powered auth with backward-compat routes
|
|
509
698
|
// ---------------------------------------------------------------------------
|
|
@@ -549,7 +738,7 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
549
738
|
const ok = await setAuthModeLocal();
|
|
550
739
|
if (!ok) {
|
|
551
740
|
setResponseStatus(event, 500);
|
|
552
|
-
return { error: "Failed to
|
|
741
|
+
return { error: "Failed to enable local mode" };
|
|
553
742
|
}
|
|
554
743
|
return { ok: true };
|
|
555
744
|
}));
|
|
@@ -562,8 +751,11 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
562
751
|
const ok = await removeAuthModeLocal();
|
|
563
752
|
if (!ok) {
|
|
564
753
|
setResponseStatus(event, 500);
|
|
565
|
-
return { error: "Failed to
|
|
754
|
+
return { error: "Failed to disable local mode" };
|
|
566
755
|
}
|
|
756
|
+
// Mark the browser so getSession's dev-mode fallback won't silently
|
|
757
|
+
// re-authenticate the user as local@localhost on the next request.
|
|
758
|
+
setUpgradePendingCookie(event);
|
|
567
759
|
return { ok: true };
|
|
568
760
|
}));
|
|
569
761
|
// Backward-compat: POST /_agent-native/auth/login
|
|
@@ -585,8 +777,7 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
585
777
|
await addSession(sessionToken, "user");
|
|
586
778
|
setCookie(event, COOKIE_NAME, sessionToken, {
|
|
587
779
|
httpOnly: true,
|
|
588
|
-
|
|
589
|
-
sameSite: "lax",
|
|
780
|
+
...crossSiteCookieAttrs(event),
|
|
590
781
|
path: "/",
|
|
591
782
|
maxAge: sessionMaxAge,
|
|
592
783
|
});
|
|
@@ -606,12 +797,18 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
606
797
|
if (result?.token) {
|
|
607
798
|
setCookie(event, COOKIE_NAME, result.token, {
|
|
608
799
|
httpOnly: true,
|
|
609
|
-
|
|
610
|
-
sameSite: "lax",
|
|
800
|
+
...crossSiteCookieAttrs(event),
|
|
611
801
|
path: "/",
|
|
612
802
|
maxAge: sessionMaxAge,
|
|
613
803
|
});
|
|
614
804
|
await addSession(result.token, email);
|
|
805
|
+
if (isElectronRequest(event)) {
|
|
806
|
+
await writeDesktopSso({
|
|
807
|
+
email,
|
|
808
|
+
token: result.token,
|
|
809
|
+
expiresAt: Date.now() + sessionMaxAge * 1000,
|
|
810
|
+
});
|
|
811
|
+
}
|
|
615
812
|
}
|
|
616
813
|
return { ok: true };
|
|
617
814
|
}
|
|
@@ -660,6 +857,8 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
660
857
|
catch {
|
|
661
858
|
// Ignore if no Better Auth session
|
|
662
859
|
}
|
|
860
|
+
if (isElectronRequest(event))
|
|
861
|
+
await clearDesktopSso();
|
|
663
862
|
return { ok: true };
|
|
664
863
|
}));
|
|
665
864
|
// GET /_agent-native/auth/session
|
|
@@ -674,24 +873,18 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
674
873
|
// POST /_agent-native/auth/migrate-local-data — move local-mode data to
|
|
675
874
|
// the currently signed-in account. Called by the UI after a user upgrades
|
|
676
875
|
// from local mode to a real account so they don't lose their data.
|
|
677
|
-
app.use("/_agent-native/auth/migrate-local-data",
|
|
678
|
-
|
|
876
|
+
app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
|
|
877
|
+
// GET /_agent-native/auth/reset — HTML page shown when a user clicks the
|
|
878
|
+
// reset link in their email. Reads ?token=... and POSTs to Better Auth's
|
|
879
|
+
// /reset-password endpoint on submit.
|
|
880
|
+
app.use("/_agent-native/auth/reset", defineEventHandler((event) => {
|
|
881
|
+
if (getMethod(event) !== "GET") {
|
|
679
882
|
setResponseStatus(event, 405);
|
|
680
883
|
return { error: "Method not allowed" };
|
|
681
884
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
return { error: "Not authenticated as a real account" };
|
|
686
|
-
}
|
|
687
|
-
try {
|
|
688
|
-
const result = await migrateLocalUserData(session.email);
|
|
689
|
-
return { ok: true, ...result };
|
|
690
|
-
}
|
|
691
|
-
catch (e) {
|
|
692
|
-
setResponseStatus(event, 500);
|
|
693
|
-
return { error: e?.message || "Migration failed" };
|
|
694
|
-
}
|
|
885
|
+
return new Response(getResetPasswordHtml(), {
|
|
886
|
+
headers: { "Content-Type": "text/html; charset=utf-8" },
|
|
887
|
+
});
|
|
695
888
|
}));
|
|
696
889
|
// Auth guard — stored both in framework middleware registry AND in
|
|
697
890
|
// _authGuardFn so the server middleware can enforce it on ALL routes.
|
|
@@ -721,8 +914,7 @@ function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
|
|
|
721
914
|
await addSession(sessionToken, "user");
|
|
722
915
|
setCookie(event, COOKIE_NAME, sessionToken, {
|
|
723
916
|
httpOnly: true,
|
|
724
|
-
|
|
725
|
-
sameSite: "lax",
|
|
917
|
+
...crossSiteCookieAttrs(event),
|
|
726
918
|
path: "/",
|
|
727
919
|
maxAge: sessionMaxAge,
|
|
728
920
|
});
|
|
@@ -733,6 +925,8 @@ function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
|
|
|
733
925
|
if (cookie)
|
|
734
926
|
await removeSession(cookie);
|
|
735
927
|
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
928
|
+
if (isElectronRequest(event))
|
|
929
|
+
await clearDesktopSso();
|
|
736
930
|
return { ok: true };
|
|
737
931
|
}));
|
|
738
932
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
@@ -743,6 +937,7 @@ function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
|
|
|
743
937
|
const session = await getSession(event);
|
|
744
938
|
return session ?? { error: "Not authenticated" };
|
|
745
939
|
}));
|
|
940
|
+
app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
|
|
746
941
|
_authGuardConfig = { loginHtml: TOKEN_LOGIN_HTML, publicPaths };
|
|
747
942
|
const guardFn = createAuthGuardFn();
|
|
748
943
|
_authGuardFn = guardFn;
|
|
@@ -770,10 +965,150 @@ function mountLocalModeRoutes(app) {
|
|
|
770
965
|
const ok = await removeAuthModeLocal();
|
|
771
966
|
if (!ok) {
|
|
772
967
|
setResponseStatus(event, 500);
|
|
773
|
-
return { error: "Failed to
|
|
968
|
+
return { error: "Failed to disable local mode" };
|
|
969
|
+
}
|
|
970
|
+
// Mark the browser so getSession's dev-mode fallback won't silently
|
|
971
|
+
// re-authenticate the user as local@localhost on the next request.
|
|
972
|
+
setUpgradePendingCookie(event);
|
|
973
|
+
return { ok: true };
|
|
974
|
+
}));
|
|
975
|
+
// Upgrade path: migrate-local-data must be reachable from local mode
|
|
976
|
+
// because the user is still in local mode when they trigger the upgrade.
|
|
977
|
+
app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
|
|
978
|
+
}
|
|
979
|
+
// ---------------------------------------------------------------------------
|
|
980
|
+
// mountAuthFallbackRoutes — minimal auth endpoints when Better Auth init fails
|
|
981
|
+
// ---------------------------------------------------------------------------
|
|
982
|
+
function mountAuthFallbackRoutes(app) {
|
|
983
|
+
app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
|
|
984
|
+
if (getMethod(event) !== "POST") {
|
|
985
|
+
setResponseStatus(event, 405);
|
|
986
|
+
return { error: "Method not allowed" };
|
|
987
|
+
}
|
|
988
|
+
const body = await readBody(event);
|
|
989
|
+
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
990
|
+
const password = body?.password;
|
|
991
|
+
if (!email || !password) {
|
|
992
|
+
setResponseStatus(event, 400);
|
|
993
|
+
return { error: "Email and password are required" };
|
|
994
|
+
}
|
|
995
|
+
try {
|
|
996
|
+
const auth = await getBetterAuth();
|
|
997
|
+
const result = await auth.api.signInEmail({
|
|
998
|
+
body: { email, password },
|
|
999
|
+
});
|
|
1000
|
+
if (result?.token) {
|
|
1001
|
+
setCookie(event, COOKIE_NAME, result.token, {
|
|
1002
|
+
httpOnly: true,
|
|
1003
|
+
...crossSiteCookieAttrs(event),
|
|
1004
|
+
path: "/",
|
|
1005
|
+
maxAge: sessionMaxAge,
|
|
1006
|
+
});
|
|
1007
|
+
await addSession(result.token, email);
|
|
1008
|
+
if (isElectronRequest(event)) {
|
|
1009
|
+
await writeDesktopSso({
|
|
1010
|
+
email,
|
|
1011
|
+
token: result.token,
|
|
1012
|
+
expiresAt: Date.now() + sessionMaxAge * 1000,
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
return { ok: true };
|
|
1017
|
+
}
|
|
1018
|
+
catch (e) {
|
|
1019
|
+
setResponseStatus(event, 401);
|
|
1020
|
+
return { error: e?.message || "Invalid email or password" };
|
|
1021
|
+
}
|
|
1022
|
+
}));
|
|
1023
|
+
app.use("/_agent-native/auth/register", defineEventHandler(async (event) => {
|
|
1024
|
+
if (getMethod(event) !== "POST") {
|
|
1025
|
+
setResponseStatus(event, 405);
|
|
1026
|
+
return { error: "Method not allowed" };
|
|
1027
|
+
}
|
|
1028
|
+
const body = await readBody(event);
|
|
1029
|
+
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
1030
|
+
const password = body?.password;
|
|
1031
|
+
if (!email || typeof email !== "string" || !email.includes("@")) {
|
|
1032
|
+
setResponseStatus(event, 400);
|
|
1033
|
+
return { error: "Valid email is required" };
|
|
1034
|
+
}
|
|
1035
|
+
if (!password || typeof password !== "string" || password.length < 8) {
|
|
1036
|
+
setResponseStatus(event, 400);
|
|
1037
|
+
return { error: "Password must be at least 8 characters" };
|
|
1038
|
+
}
|
|
1039
|
+
try {
|
|
1040
|
+
const auth = await getBetterAuth();
|
|
1041
|
+
await auth.api.signUpEmail({
|
|
1042
|
+
body: { email, password, name: email.split("@")[0] },
|
|
1043
|
+
});
|
|
1044
|
+
return { ok: true };
|
|
1045
|
+
}
|
|
1046
|
+
catch (e) {
|
|
1047
|
+
setResponseStatus(event, 409);
|
|
1048
|
+
return { error: e?.message || "Registration failed" };
|
|
1049
|
+
}
|
|
1050
|
+
}));
|
|
1051
|
+
app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
|
|
1052
|
+
const cookie = getCookie(event, COOKIE_NAME);
|
|
1053
|
+
if (cookie)
|
|
1054
|
+
await removeSession(cookie);
|
|
1055
|
+
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
1056
|
+
try {
|
|
1057
|
+
const auth = await getBetterAuth();
|
|
1058
|
+
await auth.api.signOut({ headers: event.headers });
|
|
1059
|
+
}
|
|
1060
|
+
catch {
|
|
1061
|
+
// Ignore if Better Auth is still unavailable
|
|
1062
|
+
}
|
|
1063
|
+
if (isElectronRequest(event))
|
|
1064
|
+
await clearDesktopSso();
|
|
1065
|
+
return { ok: true };
|
|
1066
|
+
}));
|
|
1067
|
+
app.use("/_agent-native/auth/local-mode", defineEventHandler(async (event) => {
|
|
1068
|
+
if (getMethod(event) !== "POST") {
|
|
1069
|
+
setResponseStatus(event, 405);
|
|
1070
|
+
return { error: "Method not allowed" };
|
|
1071
|
+
}
|
|
1072
|
+
if (!isDevEnvironment()) {
|
|
1073
|
+
setResponseStatus(event, 403);
|
|
1074
|
+
return {
|
|
1075
|
+
error: "Local mode is not available in production. Create an account to continue.",
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
const ok = await setAuthModeLocal();
|
|
1079
|
+
if (!ok) {
|
|
1080
|
+
setResponseStatus(event, 500);
|
|
1081
|
+
return { error: "Failed to enable local mode" };
|
|
1082
|
+
}
|
|
1083
|
+
return { ok: true };
|
|
1084
|
+
}));
|
|
1085
|
+
app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
|
|
1086
|
+
if (getMethod(event) !== "POST") {
|
|
1087
|
+
setResponseStatus(event, 405);
|
|
1088
|
+
return { error: "Method not allowed" };
|
|
1089
|
+
}
|
|
1090
|
+
const ok = await removeAuthModeLocal();
|
|
1091
|
+
if (!ok) {
|
|
1092
|
+
setResponseStatus(event, 500);
|
|
1093
|
+
return { error: "Failed to disable local mode" };
|
|
774
1094
|
}
|
|
1095
|
+
// Mark the browser so getSession's dev-mode fallback won't silently
|
|
1096
|
+
// re-authenticate the user as local@localhost on the next request.
|
|
1097
|
+
setUpgradePendingCookie(event);
|
|
775
1098
|
return { ok: true };
|
|
776
1099
|
}));
|
|
1100
|
+
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
1101
|
+
if (getMethod(event) !== "GET") {
|
|
1102
|
+
setResponseStatus(event, 405);
|
|
1103
|
+
return { error: "Method not allowed" };
|
|
1104
|
+
}
|
|
1105
|
+
const session = await getSession(event);
|
|
1106
|
+
return session ?? { error: "Not authenticated" };
|
|
1107
|
+
}));
|
|
1108
|
+
// Must be reachable from fallback mode too — otherwise a user who
|
|
1109
|
+
// upgrades-from-local on a server that couldn't init Better Auth gets a
|
|
1110
|
+
// 500 instead of a clear 401.
|
|
1111
|
+
app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
|
|
777
1112
|
}
|
|
778
1113
|
// ---------------------------------------------------------------------------
|
|
779
1114
|
// autoMountAuth — the recommended entry point
|
|
@@ -792,13 +1127,17 @@ function mountLocalModeRoutes(app) {
|
|
|
792
1127
|
* Returns true if auth was mounted, false if skipped.
|
|
793
1128
|
*/
|
|
794
1129
|
export async function autoMountAuth(app, options = {}) {
|
|
795
|
-
// If auth is already mounted (e.g., default plugin ran before
|
|
796
|
-
// don't re-mount routes — but DO
|
|
797
|
-
//
|
|
798
|
-
//
|
|
799
|
-
//
|
|
800
|
-
//
|
|
801
|
-
|
|
1130
|
+
// If auth is already mounted on THIS app (e.g., default plugin ran before
|
|
1131
|
+
// custom plugin in the same server boot), don't re-mount routes — but DO
|
|
1132
|
+
// update the live config if custom options like googleOnly or loginHtml
|
|
1133
|
+
// were provided. createAuthGuardFn() reads from _authGuardConfig on every
|
|
1134
|
+
// request, so updating it here takes effect immediately.
|
|
1135
|
+
//
|
|
1136
|
+
// We gate on `_mountedApp === app` because module-level state survives
|
|
1137
|
+
// Vite HMR — without this check, an HMR-restarted Nitro instance (fresh
|
|
1138
|
+
// H3 app, empty middleware) would short-circuit here and end up with no
|
|
1139
|
+
// auth routes mounted at all.
|
|
1140
|
+
if (_authGuardFn && _mountedApp === app) {
|
|
802
1141
|
if (_authGuardConfig) {
|
|
803
1142
|
if (options.googleOnly || options.loginHtml) {
|
|
804
1143
|
_authGuardConfig.loginHtml =
|
|
@@ -814,8 +1153,13 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
814
1153
|
}
|
|
815
1154
|
return true;
|
|
816
1155
|
}
|
|
1156
|
+
// Fresh app (first boot, or HMR created a new Nitro instance) — reset
|
|
1157
|
+
// the guard so the mount path below installs it on the new app.
|
|
1158
|
+
_authGuardFn = null;
|
|
1159
|
+
_authGuardConfig = null;
|
|
1160
|
+
_mountedApp = app;
|
|
817
1161
|
if (!app) {
|
|
818
|
-
if (
|
|
1162
|
+
if ((await isLocalModeEnabled()) || isDevEnvironment()) {
|
|
819
1163
|
authDisabledMode = false;
|
|
820
1164
|
customGetSession = null;
|
|
821
1165
|
return false;
|
|
@@ -831,11 +1175,18 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
831
1175
|
customGetSession = options.getSession;
|
|
832
1176
|
}
|
|
833
1177
|
// AUTH_MODE=local — explicit local-only mode (escape hatch)
|
|
834
|
-
if (
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
1178
|
+
if (await isLocalModeEnabled()) {
|
|
1179
|
+
try {
|
|
1180
|
+
// Mount the standard auth endpoints and guard even in local mode so the
|
|
1181
|
+
// app can switch back to real auth immediately after AUTH_MODE is
|
|
1182
|
+
// cleared, without waiting for a server restart/remount.
|
|
1183
|
+
await mountBetterAuthRoutes(app, options);
|
|
1184
|
+
}
|
|
1185
|
+
catch (err) {
|
|
1186
|
+
console.error("[agent-native] Failed to initialize Better Auth in local mode:", err);
|
|
1187
|
+
mountLocalModeRoutes(app);
|
|
1188
|
+
}
|
|
1189
|
+
console.log("[agent-native] Auth mode: local (upgrade path enabled).");
|
|
839
1190
|
return false;
|
|
840
1191
|
}
|
|
841
1192
|
// BYOA — custom getSession provider
|
|
@@ -854,8 +1205,11 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
854
1205
|
if (cookie)
|
|
855
1206
|
await removeSession(cookie);
|
|
856
1207
|
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
1208
|
+
if (isElectronRequest(event))
|
|
1209
|
+
await clearDesktopSso();
|
|
857
1210
|
return { ok: true };
|
|
858
1211
|
}));
|
|
1212
|
+
app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
|
|
859
1213
|
const byoaLoginHtml = options.loginHtml ?? TOKEN_LOGIN_HTML;
|
|
860
1214
|
_authGuardConfig = { loginHtml: byoaLoginHtml, publicPaths };
|
|
861
1215
|
const guardFn = createAuthGuardFn();
|
|
@@ -886,6 +1240,7 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
886
1240
|
}
|
|
887
1241
|
catch (err) {
|
|
888
1242
|
console.error("[agent-native] Failed to initialize Better Auth:", err);
|
|
1243
|
+
mountAuthFallbackRoutes(app);
|
|
889
1244
|
// CRITICAL: Even if Better Auth fails, register the auth guard so
|
|
890
1245
|
// unauthenticated users can't access the app. They'll see the login
|
|
891
1246
|
// page but won't be able to sign in until the DB is available.
|