@agent-native/core 0.7.1 → 0.7.4
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/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 +148 -36
- 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 +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/create.js +1 -1
- package/dist/cli/create.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/client/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +279 -30
- 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 +17 -0
- package/dist/client/FeedbackButton.d.ts.map +1 -0
- package/dist/client/FeedbackButton.js +147 -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/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +27 -24
- 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 +21 -4
- package/dist/client/composer/TiptapComposer.js.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 +5 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +2 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/onboarding/OnboardingBanner.js +2 -2
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +139 -52
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -1
- package/dist/client/onboarding/SetupButton.js +13 -3
- package/dist/client/onboarding/SetupButton.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +12 -7
- 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 +57 -2
- 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 +17 -10
- 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 +12 -10
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +6 -3
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/ComingSoonSection.js +1 -1
- package/dist/client/settings/ComingSoonSection.js.map +1 -1
- package/dist/client/settings/LLMSection.d.ts.map +1 -1
- package/dist/client/settings/LLMSection.js +1 -1
- package/dist/client/settings/LLMSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts +12 -0
- package/dist/client/settings/SecretsSection.d.ts.map +1 -0
- package/dist/client/settings/SecretsSection.js +148 -0
- package/dist/client/settings/SecretsSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +114 -23
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.js +2 -2
- package/dist/client/settings/SettingsSection.js.map +1 -1
- 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 +1 -0
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/index.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +14 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -0
- package/dist/client/sharing/ShareButton.js +43 -0
- package/dist/client/sharing/ShareButton.js.map +1 -0
- package/dist/client/sharing/ShareDialog.d.ts +15 -0
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -0
- package/dist/client/sharing/ShareDialog.js +209 -0
- package/dist/client/sharing/ShareDialog.js.map +1 -0
- package/dist/client/sharing/VisibilityBadge.d.ts +11 -0
- package/dist/client/sharing/VisibilityBadge.d.ts.map +1 -0
- package/dist/client/sharing/VisibilityBadge.js +20 -0
- package/dist/client/sharing/VisibilityBadge.js.map +1 -0
- package/dist/client/sharing/index.d.ts +4 -0
- package/dist/client/sharing/index.d.ts.map +1 -0
- package/dist/client/sharing/index.js +4 -0
- package/dist/client/sharing/index.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +74 -6
- 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/db/schema.d.ts +1 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +4 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/deploy/build.js +22 -3
- package/dist/deploy/build.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +7 -2
- package/dist/jobs/scheduler.js.map +1 -1
- 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/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +62 -18
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/org/accept-pending.d.ts +22 -0
- package/dist/org/accept-pending.d.ts.map +1 -0
- package/dist/org/accept-pending.js +75 -0
- package/dist/org/accept-pending.js.map +1 -0
- package/dist/org/context.js +1 -1
- package/dist/org/handlers.d.ts +2 -0
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +87 -11
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/index.d.ts +2 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.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/handlers.js +1 -1
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts.map +1 -1
- package/dist/resources/metadata.js +2 -2
- package/dist/resources/metadata.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +27 -1
- package/dist/resources/store.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/secrets/index.d.ts +15 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +15 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/onboarding.d.ts +18 -0
- package/dist/secrets/onboarding.d.ts.map +1 -0
- package/dist/secrets/onboarding.js +87 -0
- package/dist/secrets/onboarding.js.map +1 -0
- package/dist/secrets/register.d.ts +63 -0
- package/dist/secrets/register.d.ts.map +1 -0
- package/dist/secrets/register.js +55 -0
- package/dist/secrets/register.js.map +1 -0
- package/dist/secrets/routes.d.ts +67 -0
- package/dist/secrets/routes.d.ts.map +1 -0
- package/dist/secrets/routes.js +275 -0
- package/dist/secrets/routes.js.map +1 -0
- package/dist/secrets/schema.d.ts +154 -0
- package/dist/secrets/schema.d.ts.map +1 -0
- package/dist/secrets/schema.js +41 -0
- package/dist/secrets/schema.js.map +1 -0
- package/dist/secrets/storage.d.ts +54 -0
- package/dist/secrets/storage.d.ts.map +1 -0
- package/dist/secrets/storage.js +181 -0
- package/dist/secrets/storage.js.map +1 -0
- package/dist/server/action-discovery.d.ts +18 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +97 -0
- 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 +26 -0
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +12 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +507 -48
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.js +2 -2
- 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 +21 -58
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/app-name.d.ts +13 -0
- package/dist/server/app-name.d.ts.map +1 -0
- package/dist/server/app-name.js +41 -0
- package/dist/server/app-name.js.map +1 -0
- package/dist/server/app-url.d.ts +24 -0
- package/dist/server/app-url.d.ts.map +1 -0
- package/dist/server/app-url.js +68 -0
- package/dist/server/app-url.js.map +1 -0
- package/dist/server/auth.d.ts +6 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +284 -41
- 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 +102 -7
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +21 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +67 -4
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +151 -4
- package/dist/server/core-routes-plugin.js.map +1 -1
- 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-template.d.ts +51 -0
- package/dist/server/email-template.d.ts.map +1 -0
- package/dist/server/email-template.js +146 -0
- package/dist/server/email-template.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 +29 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +19 -3
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +5 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -1
- 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 +2 -0
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +2 -0
- 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 +229 -25
- 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/sharing/access.d.ts +56 -0
- package/dist/sharing/access.d.ts.map +1 -0
- package/dist/sharing/access.js +149 -0
- package/dist/sharing/access.js.map +1 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +3 -0
- package/dist/sharing/actions/list-resource-shares.d.ts.map +1 -0
- package/dist/sharing/actions/list-resource-shares.js +38 -0
- package/dist/sharing/actions/list-resource-shares.js.map +1 -0
- package/dist/sharing/actions/set-resource-visibility.d.ts +3 -0
- package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -0
- package/dist/sharing/actions/set-resource-visibility.js +24 -0
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -0
- package/dist/sharing/actions/share-resource.d.ts +3 -0
- package/dist/sharing/actions/share-resource.d.ts.map +1 -0
- package/dist/sharing/actions/share-resource.js +64 -0
- package/dist/sharing/actions/share-resource.js.map +1 -0
- package/dist/sharing/actions/unshare-resource.d.ts +3 -0
- package/dist/sharing/actions/unshare-resource.d.ts.map +1 -0
- package/dist/sharing/actions/unshare-resource.js +24 -0
- package/dist/sharing/actions/unshare-resource.js.map +1 -0
- package/dist/sharing/index.d.ts +11 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +11 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/sharing/registry.d.ts +44 -0
- package/dist/sharing/registry.d.ts.map +1 -0
- package/dist/sharing/registry.js +54 -0
- package/dist/sharing/registry.js.map +1 -0
- package/dist/sharing/schema.d.ts +202 -0
- package/dist/sharing/schema.d.ts.map +1 -0
- package/dist/sharing/schema.js +88 -0
- package/dist/sharing/schema.js.map +1 -0
- package/dist/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -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/action-types-plugin.d.ts +5 -0
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +129 -28
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +55 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/deployment.md +59 -2
- package/docs/content/resources.md +9 -9
- package/docs/content/workspace-management.md +2 -2
- package/package.json +13 -5
- package/src/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- /package/dist/templates/workspace-core/{skills → .agents/skills}/company-policies/SKILL.md +0 -0
- /package/src/templates/workspace-core/{skills → .agents/skills}/company-policies/SKILL.md +0 -0
|
@@ -292,6 +292,19 @@ ${googleOnly
|
|
|
292
292
|
<input id="l-pass" type="password" autocomplete="current-password" placeholder="Enter password" required />
|
|
293
293
|
<button type="submit">Sign in</button>
|
|
294
294
|
<p class="msg error" id="l-msg"></p>
|
|
295
|
+
<p style="margin-top:0.75rem;font-size:0.75rem;text-align:right">
|
|
296
|
+
<a href="#" id="forgot-link" style="color:#888;text-decoration:underline;text-underline-offset:2px">Forgot password?</a>
|
|
297
|
+
</p>
|
|
298
|
+
</form>
|
|
299
|
+
|
|
300
|
+
<form id="forgot-form" class="form">
|
|
301
|
+
<label for="f-email">Email</label>
|
|
302
|
+
<input id="f-email" type="email" autocomplete="email" placeholder="you@example.com" required />
|
|
303
|
+
<button type="submit">Send reset link</button>
|
|
304
|
+
<p class="msg" id="f-msg"></p>
|
|
305
|
+
<p style="margin-top:0.75rem;font-size:0.75rem;text-align:center">
|
|
306
|
+
<a href="#" id="back-to-login" style="color:#888;text-decoration:underline;text-underline-offset:2px">Back to sign in</a>
|
|
307
|
+
</p>
|
|
295
308
|
</form>`}
|
|
296
309
|
${localModeBlock}
|
|
297
310
|
</div>
|
|
@@ -321,6 +334,8 @@ ${googleOnly
|
|
|
321
334
|
|
|
322
335
|
document.getElementById('signup-form').addEventListener('submit', async function(e) {
|
|
323
336
|
e.preventDefault();
|
|
337
|
+
var form = e.currentTarget;
|
|
338
|
+
var btn = form.querySelector('button[type="submit"]');
|
|
324
339
|
var msg = document.getElementById('s-msg');
|
|
325
340
|
msg.classList.remove('show', 'error', 'success');
|
|
326
341
|
var pass = document.getElementById('s-pass').value;
|
|
@@ -330,48 +345,127 @@ ${googleOnly
|
|
|
330
345
|
msg.classList.add('show', 'error');
|
|
331
346
|
return;
|
|
332
347
|
}
|
|
333
|
-
var
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
var data = await res.json().catch(function() { return {}; });
|
|
340
|
-
if (res.ok) {
|
|
341
|
-
msg.textContent = 'Account created — signing you in...';
|
|
342
|
-
msg.classList.add('show', 'success');
|
|
343
|
-
var loginRes = await fetch('/_agent-native/auth/login', {
|
|
348
|
+
var originalLabel = btn.textContent;
|
|
349
|
+
btn.disabled = true;
|
|
350
|
+
btn.textContent = 'Creating account…';
|
|
351
|
+
try {
|
|
352
|
+
var email = document.getElementById('s-email').value;
|
|
353
|
+
var res = await fetch('/_agent-native/auth/register', {
|
|
344
354
|
method: 'POST',
|
|
345
355
|
headers: { 'Content-Type': 'application/json' },
|
|
346
356
|
body: JSON.stringify({ email: email, password: pass }),
|
|
347
357
|
});
|
|
348
|
-
|
|
349
|
-
|
|
358
|
+
var data = await res.json().catch(function() { return {}; });
|
|
359
|
+
if (res.ok) {
|
|
360
|
+
msg.textContent = 'Account created — signing you in…';
|
|
361
|
+
msg.classList.add('show', 'success');
|
|
362
|
+
btn.textContent = 'Signing in…';
|
|
363
|
+
var loginRes = await fetch('/_agent-native/auth/login', {
|
|
364
|
+
method: 'POST',
|
|
365
|
+
headers: { 'Content-Type': 'application/json' },
|
|
366
|
+
body: JSON.stringify({ email: email, password: pass }),
|
|
367
|
+
});
|
|
368
|
+
if (loginRes.ok) {
|
|
369
|
+
window.location.reload();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
350
372
|
}
|
|
351
|
-
} else {
|
|
352
373
|
msg.textContent = data.error || 'Registration failed';
|
|
353
374
|
msg.classList.add('show', 'error');
|
|
375
|
+
btn.disabled = false;
|
|
376
|
+
btn.textContent = originalLabel;
|
|
377
|
+
} catch (err) {
|
|
378
|
+
msg.textContent = 'Network error — please try again';
|
|
379
|
+
msg.classList.add('show', 'error');
|
|
380
|
+
btn.disabled = false;
|
|
381
|
+
btn.textContent = originalLabel;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
var forgotLink = document.getElementById('forgot-link');
|
|
386
|
+
var backToLogin = document.getElementById('back-to-login');
|
|
387
|
+
if (forgotLink) forgotLink.addEventListener('click', function(e) {
|
|
388
|
+
e.preventDefault();
|
|
389
|
+
document.getElementById('login-form').classList.remove('active');
|
|
390
|
+
document.getElementById('forgot-form').classList.add('active');
|
|
391
|
+
var fEmail = document.getElementById('f-email');
|
|
392
|
+
var lEmail = document.getElementById('l-email');
|
|
393
|
+
if (lEmail && lEmail.value) fEmail.value = lEmail.value;
|
|
394
|
+
setTimeout(function() { fEmail.focus(); }, 0);
|
|
395
|
+
});
|
|
396
|
+
if (backToLogin) backToLogin.addEventListener('click', function(e) {
|
|
397
|
+
e.preventDefault();
|
|
398
|
+
document.getElementById('forgot-form').classList.remove('active');
|
|
399
|
+
document.getElementById('login-form').classList.add('active');
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
var forgotForm = document.getElementById('forgot-form');
|
|
403
|
+
if (forgotForm) forgotForm.addEventListener('submit', async function(e) {
|
|
404
|
+
e.preventDefault();
|
|
405
|
+
var btn = e.currentTarget.querySelector('button[type="submit"]');
|
|
406
|
+
var msg = document.getElementById('f-msg');
|
|
407
|
+
msg.classList.remove('show', 'error', 'success');
|
|
408
|
+
var original = btn.textContent;
|
|
409
|
+
btn.disabled = true;
|
|
410
|
+
btn.textContent = 'Sending…';
|
|
411
|
+
try {
|
|
412
|
+
var email = document.getElementById('f-email').value;
|
|
413
|
+
var res = await fetch('/_agent-native/auth/ba/request-password-reset', {
|
|
414
|
+
method: 'POST',
|
|
415
|
+
headers: { 'Content-Type': 'application/json' },
|
|
416
|
+
body: JSON.stringify({ email: email }),
|
|
417
|
+
});
|
|
418
|
+
if (res.ok) {
|
|
419
|
+
msg.textContent = 'If that email exists, a reset link is on its way.';
|
|
420
|
+
msg.classList.add('show', 'success');
|
|
421
|
+
btn.textContent = 'Sent';
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
var data = await res.json().catch(function() { return {}; });
|
|
425
|
+
msg.textContent = (data && (data.message || data.error)) || 'Could not send reset email.';
|
|
426
|
+
msg.classList.add('show', 'error');
|
|
427
|
+
btn.disabled = false;
|
|
428
|
+
btn.textContent = original;
|
|
429
|
+
} catch (err) {
|
|
430
|
+
msg.textContent = 'Network error — please try again';
|
|
431
|
+
msg.classList.add('show', 'error');
|
|
432
|
+
btn.disabled = false;
|
|
433
|
+
btn.textContent = original;
|
|
354
434
|
}
|
|
355
435
|
});
|
|
356
436
|
|
|
357
437
|
document.getElementById('login-form').addEventListener('submit', async function(e) {
|
|
358
438
|
e.preventDefault();
|
|
439
|
+
var form = e.currentTarget;
|
|
440
|
+
var btn = form.querySelector('button[type="submit"]');
|
|
359
441
|
var msg = document.getElementById('l-msg');
|
|
360
442
|
msg.classList.remove('show');
|
|
361
|
-
var
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
443
|
+
var originalLabel = btn.textContent;
|
|
444
|
+
btn.disabled = true;
|
|
445
|
+
btn.textContent = 'Signing in…';
|
|
446
|
+
try {
|
|
447
|
+
var res = await fetch('/_agent-native/auth/login', {
|
|
448
|
+
method: 'POST',
|
|
449
|
+
headers: { 'Content-Type': 'application/json' },
|
|
450
|
+
body: JSON.stringify({
|
|
451
|
+
email: document.getElementById('l-email').value,
|
|
452
|
+
password: document.getElementById('l-pass').value,
|
|
453
|
+
}),
|
|
454
|
+
});
|
|
455
|
+
if (res.ok) {
|
|
456
|
+
window.location.reload();
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
372
459
|
var data = await res.json().catch(function() { return {}; });
|
|
373
460
|
msg.textContent = data.error || 'Invalid email or password';
|
|
374
461
|
msg.classList.add('show');
|
|
462
|
+
btn.disabled = false;
|
|
463
|
+
btn.textContent = originalLabel;
|
|
464
|
+
} catch (err) {
|
|
465
|
+
msg.textContent = 'Network error — please try again';
|
|
466
|
+
msg.classList.add('show');
|
|
467
|
+
btn.disabled = false;
|
|
468
|
+
btn.textContent = originalLabel;
|
|
375
469
|
}
|
|
376
470
|
});
|
|
377
471
|
`}${localModeScript}
|
|
@@ -435,4 +529,114 @@ ${showGoogle
|
|
|
435
529
|
}
|
|
436
530
|
/** @deprecated Use getOnboardingHtml() instead */
|
|
437
531
|
export const ONBOARDING_HTML = getOnboardingHtml();
|
|
532
|
+
/**
|
|
533
|
+
* HTML for the password reset page — shown when the user clicks the link in
|
|
534
|
+
* their reset email. Posts `{ newPassword, token }` to Better Auth's
|
|
535
|
+
* `/reset-password` endpoint, then redirects to the login page.
|
|
536
|
+
*/
|
|
537
|
+
export function getResetPasswordHtml() {
|
|
538
|
+
return `<!DOCTYPE html>
|
|
539
|
+
<html lang="en">
|
|
540
|
+
<head>
|
|
541
|
+
<meta charset="UTF-8">
|
|
542
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
543
|
+
<title>Reset password</title>
|
|
544
|
+
<style>
|
|
545
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
546
|
+
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0a0a0a; color: #e5e5e5; display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 1rem; }
|
|
547
|
+
.card { width: 100%; max-width: 400px; padding: 2rem; background: #141414; border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; }
|
|
548
|
+
h1 { font-size: 1.25rem; font-weight: 600; margin-bottom: 0.25rem; color: #fff; }
|
|
549
|
+
.subtitle { font-size: 0.8125rem; color: #888; margin-bottom: 1.5rem; }
|
|
550
|
+
label { display: block; font-size: 0.8125rem; color: #888; margin-bottom: 0.375rem; }
|
|
551
|
+
input { width: 100%; padding: 0.5rem 0.75rem; background: transparent; border: 1px solid rgba(255,255,255,0.12); border-radius: 6px; color: #e5e5e5; font-size: 0.875rem; outline: none; margin-bottom: 0.875rem; }
|
|
552
|
+
input:focus { border-color: rgba(255,255,255,0.3); box-shadow: 0 0 0 1px rgba(255,255,255,0.1); }
|
|
553
|
+
input::placeholder { color: #555; }
|
|
554
|
+
button[type="submit"] { width: 100%; margin-top: 0.25rem; padding: 0.5rem; background: #fff; color: #000; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; }
|
|
555
|
+
button[type="submit"]:hover { background: #e5e5e5; }
|
|
556
|
+
button[type="submit"]:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
557
|
+
.msg { margin-top: 0.75rem; font-size: 0.8125rem; display: none; }
|
|
558
|
+
.msg.error { color: #f87171; }
|
|
559
|
+
.msg.success { color: #4ade80; }
|
|
560
|
+
.msg.show { display: block; }
|
|
561
|
+
.back { display: inline-block; margin-top: 1rem; font-size: 0.75rem; color: #888; text-decoration: none; }
|
|
562
|
+
.back:hover { color: #bbb; }
|
|
563
|
+
</style>
|
|
564
|
+
</head>
|
|
565
|
+
<body>
|
|
566
|
+
<div class="card">
|
|
567
|
+
<h1>Choose a new password</h1>
|
|
568
|
+
<p class="subtitle">Set a new password for your account.</p>
|
|
569
|
+
<form id="reset-form">
|
|
570
|
+
<label for="p1">New password</label>
|
|
571
|
+
<input id="p1" type="password" autocomplete="new-password" autofocus placeholder="At least 8 characters" required minlength="8" />
|
|
572
|
+
<label for="p2">Confirm password</label>
|
|
573
|
+
<input id="p2" type="password" autocomplete="new-password" placeholder="Confirm password" required minlength="8" />
|
|
574
|
+
<button type="submit">Save new password</button>
|
|
575
|
+
<p class="msg" id="msg"></p>
|
|
576
|
+
</form>
|
|
577
|
+
<a class="back" id="back-link" href="/">Back to sign in</a>
|
|
578
|
+
</div>
|
|
579
|
+
<script>
|
|
580
|
+
(function() {
|
|
581
|
+
// Derive the app's base path so apps mounted under a prefix
|
|
582
|
+
// (e.g. /mail, /calendar) get sent home instead of to the root domain.
|
|
583
|
+
var RESET_PATH = '/_agent-native/auth/reset';
|
|
584
|
+
var pathname = window.location.pathname;
|
|
585
|
+
var idx = pathname.indexOf(RESET_PATH);
|
|
586
|
+
var basePath = (idx >= 0 ? pathname.slice(0, idx) : '') || '';
|
|
587
|
+
var homeHref = basePath + '/';
|
|
588
|
+
var backLink = document.getElementById('back-link');
|
|
589
|
+
if (backLink) backLink.setAttribute('href', homeHref);
|
|
590
|
+
var params = new URLSearchParams(location.search);
|
|
591
|
+
var token = params.get('token') || '';
|
|
592
|
+
var msg = document.getElementById('msg');
|
|
593
|
+
if (!token) {
|
|
594
|
+
msg.textContent = 'Missing or invalid reset token. Request a new reset link.';
|
|
595
|
+
msg.classList.add('show', 'error');
|
|
596
|
+
document.getElementById('reset-form').style.display = 'none';
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
document.getElementById('reset-form').addEventListener('submit', async function(e) {
|
|
600
|
+
e.preventDefault();
|
|
601
|
+
var btn = e.currentTarget.querySelector('button[type="submit"]');
|
|
602
|
+
var p1 = document.getElementById('p1').value;
|
|
603
|
+
var p2 = document.getElementById('p2').value;
|
|
604
|
+
msg.classList.remove('show', 'error', 'success');
|
|
605
|
+
if (p1 !== p2) {
|
|
606
|
+
msg.textContent = 'Passwords do not match';
|
|
607
|
+
msg.classList.add('show', 'error');
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
var original = btn.textContent;
|
|
611
|
+
btn.disabled = true;
|
|
612
|
+
btn.textContent = 'Saving…';
|
|
613
|
+
try {
|
|
614
|
+
var res = await fetch(basePath + '/_agent-native/auth/ba/reset-password', {
|
|
615
|
+
method: 'POST',
|
|
616
|
+
headers: { 'Content-Type': 'application/json' },
|
|
617
|
+
body: JSON.stringify({ newPassword: p1, token: token }),
|
|
618
|
+
});
|
|
619
|
+
if (res.ok) {
|
|
620
|
+
msg.textContent = 'Password updated — redirecting to sign in…';
|
|
621
|
+
msg.classList.add('show', 'success');
|
|
622
|
+
setTimeout(function() { window.location.href = homeHref; }, 1200);
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
var data = await res.json().catch(function() { return {}; });
|
|
626
|
+
msg.textContent = (data && (data.message || data.error)) || 'Reset failed. The link may have expired — request a new one.';
|
|
627
|
+
msg.classList.add('show', 'error');
|
|
628
|
+
btn.disabled = false;
|
|
629
|
+
btn.textContent = original;
|
|
630
|
+
} catch (err) {
|
|
631
|
+
msg.textContent = 'Network error — please try again';
|
|
632
|
+
msg.classList.add('show', 'error');
|
|
633
|
+
btn.disabled = false;
|
|
634
|
+
btn.textContent = original;
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
})();
|
|
638
|
+
</script>
|
|
639
|
+
</body>
|
|
640
|
+
</html>`;
|
|
641
|
+
}
|
|
438
642
|
//# sourceMappingURL=onboarding-html.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding-html.js","sourceRoot":"","sources":["../../src/server/onboarding-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,SAAS,eAAe;IACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IACjC,OAAO,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,MAAM,CAAC;AACjD,CAAC;AAED,SAAS,cAAc;IACrB,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,GAAG;QAAE,OAAO,qBAAqB,CAAC;IACvC,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACrE,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,eAAe,CAAC;QACtD,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,mBAAmB,CAAC;QACzD,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,qBAAqB,CAAC;IAC1D,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAC;IAC5E,OAAO,cAAc,CAAC;AACxB,CAAC;AAWD,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD,MAAM,UAAU,iBAAiB,CAAC,OAA8B,EAAE;IAChE,MAAM,aAAa,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAC7D,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;IACrC,MAAM,cAAc,GAAG,aAAa;QAClC,CAAC,CAAC;;;;mHAI6G;QAC/G,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,eAAe,GAAG,aAAa;QACnC,CAAC,CAAC;;;;;;;oCAO8B,gBAAgB;qCACf,gBAAgB;;;;;;;;;;;;;;IAcjD;QACA,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoLP,UAAU;QACR,CAAC,CAAC;;;;;;EAMJ,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qCAAqC;CACxD;QACG,CAAC,CAAC,UAAU;YACV,CAAC,CAAC;;;;;CAKP;YACK,CAAC,CAAC,EACR;EAEE,UAAU;QACR,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"onboarding-html.js","sourceRoot":"","sources":["../../src/server/onboarding-html.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/server/poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/server/poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AA2BD,8CAA8C;AAC9C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB,GAAG,IAAI,CAOP;AAED,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAMA;AA4ED;;;;GAIG;AACH,wBAAgB,iBAAiB;aAzFtB,MAAM;YACP,WAAW,EAAE;IAiGtB"}
|
package/dist/server/poll.js
CHANGED
|
@@ -23,6 +23,19 @@ const _buffer = [];
|
|
|
23
23
|
let _lastDbCheck = 0;
|
|
24
24
|
let _lastAppStateTs = 0;
|
|
25
25
|
let _lastSettingsTs = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Tracks the latest updated_at seen on the `__screen_refresh__` key in
|
|
28
|
+
* application_state. Bumped when the agent calls the `refresh-screen` tool,
|
|
29
|
+
* and surfaced as a distinct `screen-refresh` event so clients can remount
|
|
30
|
+
* the main content subtree via React key.
|
|
31
|
+
*
|
|
32
|
+
* `_screenRefreshInitialized` guards against spurious emits on the first
|
|
33
|
+
* poll after a restart (where an existing row would look like a fresh bump).
|
|
34
|
+
* Once we've taken a baseline reading, any subsequent increase emits.
|
|
35
|
+
*/
|
|
36
|
+
let _lastScreenRefreshTs = 0;
|
|
37
|
+
let _screenRefreshInitialized = false;
|
|
38
|
+
const SCREEN_REFRESH_KEY = "__screen_refresh__";
|
|
26
39
|
/** Get the current global version counter. */
|
|
27
40
|
export function getVersion() {
|
|
28
41
|
return _version;
|
|
@@ -65,6 +78,41 @@ async function checkExternalDbChanges() {
|
|
|
65
78
|
}
|
|
66
79
|
_lastAppStateTs = appTs;
|
|
67
80
|
}
|
|
81
|
+
// Check for screen-refresh requests from the agent. The `refresh-screen`
|
|
82
|
+
// tool writes to application_state under a well-known key; when its
|
|
83
|
+
// updated_at bumps, emit a distinct event so the client invalidates
|
|
84
|
+
// all queries (not just the ones matching its default queryKey prefix).
|
|
85
|
+
const refreshResult = await db.execute({
|
|
86
|
+
sql: "SELECT updated_at, value FROM application_state WHERE key = ?",
|
|
87
|
+
args: [SCREEN_REFRESH_KEY],
|
|
88
|
+
});
|
|
89
|
+
const refreshTs = Number(refreshResult.rows[0]?.updated_at) || 0;
|
|
90
|
+
if (!_screenRefreshInitialized) {
|
|
91
|
+
// First poll — take a baseline so we don't emit for the existing row
|
|
92
|
+
// (if any). Subsequent increases will emit normally, including the
|
|
93
|
+
// very next `refresh-screen` call made by the agent.
|
|
94
|
+
_lastScreenRefreshTs = refreshTs;
|
|
95
|
+
_screenRefreshInitialized = true;
|
|
96
|
+
}
|
|
97
|
+
else if (refreshTs > _lastScreenRefreshTs) {
|
|
98
|
+
let scope;
|
|
99
|
+
try {
|
|
100
|
+
const raw = refreshResult.rows[0]?.value;
|
|
101
|
+
if (typeof raw === "string") {
|
|
102
|
+
const parsed = JSON.parse(raw);
|
|
103
|
+
if (typeof parsed?.scope === "string")
|
|
104
|
+
scope = parsed.scope;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch { }
|
|
108
|
+
recordChange({
|
|
109
|
+
source: "screen-refresh",
|
|
110
|
+
type: "change",
|
|
111
|
+
key: SCREEN_REFRESH_KEY,
|
|
112
|
+
...(scope ? { scope } : {}),
|
|
113
|
+
});
|
|
114
|
+
_lastScreenRefreshTs = refreshTs;
|
|
115
|
+
}
|
|
68
116
|
// Check settings for external writes
|
|
69
117
|
const settingsResult = await db.execute("SELECT MAX(updated_at) as max_ts FROM settings");
|
|
70
118
|
const settingsTs = Number(settingsResult.rows[0]?.max_ts) || 0;
|
package/dist/server/poll.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/server/poll.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/server/poll.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Access-control helpers for shareable resources.
|
|
3
|
+
*
|
|
4
|
+
* The access model combines:
|
|
5
|
+
* 1. Direct ownership — `owner_email = currentUser`.
|
|
6
|
+
* 2. Visibility — `'private' | 'org' | 'public'`. `org` grants read to anyone
|
|
7
|
+
* in the same org; `public` grants read to any authenticated user.
|
|
8
|
+
* 3. Share rows — per-user or per-org grants in the `{type}_shares` table
|
|
9
|
+
* with a role (`viewer | editor | admin`).
|
|
10
|
+
*
|
|
11
|
+
* Use `applyAccessFilter()` on list/read queries to filter rows the current
|
|
12
|
+
* user can see. Use `assertAccess()` at the top of write actions to reject
|
|
13
|
+
* callers who lack the required role.
|
|
14
|
+
*/
|
|
15
|
+
import { type SQL } from "drizzle-orm";
|
|
16
|
+
import { type ShareRole } from "./schema.js";
|
|
17
|
+
export declare class ForbiddenError extends Error {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
constructor(message?: string);
|
|
20
|
+
}
|
|
21
|
+
export interface AccessContext {
|
|
22
|
+
userEmail?: string;
|
|
23
|
+
orgId?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Current request's access context. Pulls from request-context ALS. */
|
|
26
|
+
export declare function currentAccess(): AccessContext;
|
|
27
|
+
/**
|
|
28
|
+
* Build a Drizzle `WHERE` clause that admits rows the current user can see.
|
|
29
|
+
* Pass the ownable resource table and its shares table; optional min role
|
|
30
|
+
* (defaults to 'viewer') gates which share rows count.
|
|
31
|
+
*
|
|
32
|
+
* Example:
|
|
33
|
+
*
|
|
34
|
+
* const rows = await db
|
|
35
|
+
* .select()
|
|
36
|
+
* .from(schema.documents)
|
|
37
|
+
* .where(accessFilter(schema.documents, schema.documentShares));
|
|
38
|
+
*/
|
|
39
|
+
export declare function accessFilter(resourceTable: any, sharesTable: any, ctx?: AccessContext, minRole?: ShareRole): SQL;
|
|
40
|
+
export interface ResolvedAccess {
|
|
41
|
+
/** Effective role: 'owner' for the resource owner, or the share role. */
|
|
42
|
+
role: "owner" | ShareRole;
|
|
43
|
+
/** The resource row (already loaded). */
|
|
44
|
+
resource: any;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Return the effective role the current user has on a specific resource, or
|
|
48
|
+
* null if they have no access. Loads the resource and relevant share rows.
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveAccess(resourceType: string, resourceId: string, ctx?: AccessContext): Promise<ResolvedAccess | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Throw ForbiddenError if the current user can't act on this resource with at
|
|
53
|
+
* least the given role. Used at the top of update/delete actions.
|
|
54
|
+
*/
|
|
55
|
+
export declare function assertAccess(resourceType: string, resourceId: string, minRole?: ShareRole | "owner", ctx?: AccessContext): Promise<ResolvedAccess>;
|
|
56
|
+
//# sourceMappingURL=access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/sharing/access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAoB,KAAK,GAAG,EAAE,MAAM,aAAa,CAAC;AASzD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAExD,qBAAa,cAAe,SAAQ,KAAK;IACvC,UAAU,SAAO;gBACL,OAAO,SAAc;CAIlC;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,wBAAgB,aAAa,IAAI,aAAa,CAK7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,GAAG,EAChB,GAAG,GAAE,aAA+B,EACpC,OAAO,GAAE,SAAoB,GAC5B,GAAG,CAkCL;AAaD,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,EAAE,GAAG,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,aAA+B,GACnC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA2BhC;AA+BD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,SAAS,GAAG,OAAkB,EACvC,GAAG,GAAE,aAA+B,GACnC,OAAO,CAAC,cAAc,CAAC,CAWzB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Access-control helpers for shareable resources.
|
|
3
|
+
*
|
|
4
|
+
* The access model combines:
|
|
5
|
+
* 1. Direct ownership — `owner_email = currentUser`.
|
|
6
|
+
* 2. Visibility — `'private' | 'org' | 'public'`. `org` grants read to anyone
|
|
7
|
+
* in the same org; `public` grants read to any authenticated user.
|
|
8
|
+
* 3. Share rows — per-user or per-org grants in the `{type}_shares` table
|
|
9
|
+
* with a role (`viewer | editor | admin`).
|
|
10
|
+
*
|
|
11
|
+
* Use `applyAccessFilter()` on list/read queries to filter rows the current
|
|
12
|
+
* user can see. Use `assertAccess()` at the top of write actions to reject
|
|
13
|
+
* callers who lack the required role.
|
|
14
|
+
*/
|
|
15
|
+
import { and, eq, or, sql } from "drizzle-orm";
|
|
16
|
+
import { getRequestUserEmail, getRequestOrgId, } from "../server/request-context.js";
|
|
17
|
+
import { requireShareableResource, } from "./registry.js";
|
|
18
|
+
import { ROLE_RANK } from "./schema.js";
|
|
19
|
+
export class ForbiddenError extends Error {
|
|
20
|
+
statusCode = 403;
|
|
21
|
+
constructor(message = "Forbidden") {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "ForbiddenError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Current request's access context. Pulls from request-context ALS. */
|
|
27
|
+
export function currentAccess() {
|
|
28
|
+
return {
|
|
29
|
+
userEmail: getRequestUserEmail(),
|
|
30
|
+
orgId: getRequestOrgId(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build a Drizzle `WHERE` clause that admits rows the current user can see.
|
|
35
|
+
* Pass the ownable resource table and its shares table; optional min role
|
|
36
|
+
* (defaults to 'viewer') gates which share rows count.
|
|
37
|
+
*
|
|
38
|
+
* Example:
|
|
39
|
+
*
|
|
40
|
+
* const rows = await db
|
|
41
|
+
* .select()
|
|
42
|
+
* .from(schema.documents)
|
|
43
|
+
* .where(accessFilter(schema.documents, schema.documentShares));
|
|
44
|
+
*/
|
|
45
|
+
export function accessFilter(resourceTable, sharesTable, ctx = currentAccess(), minRole = "viewer") {
|
|
46
|
+
const { userEmail, orgId } = ctx;
|
|
47
|
+
const clauses = [];
|
|
48
|
+
if (userEmail) {
|
|
49
|
+
clauses.push(eq(resourceTable.ownerEmail, userEmail));
|
|
50
|
+
}
|
|
51
|
+
clauses.push(eq(resourceTable.visibility, "public"));
|
|
52
|
+
if (orgId) {
|
|
53
|
+
clauses.push(and(eq(resourceTable.visibility, "org"), eq(resourceTable.orgId, orgId)));
|
|
54
|
+
}
|
|
55
|
+
if (userEmail) {
|
|
56
|
+
clauses.push(sql `exists (select 1 from ${sharesTable}
|
|
57
|
+
where ${sharesTable.resourceId} = ${resourceTable.id}
|
|
58
|
+
and ${sharesTable.principalType} = 'user'
|
|
59
|
+
and ${sharesTable.principalId} = ${userEmail}
|
|
60
|
+
and ${minRoleSql(minRole)})`);
|
|
61
|
+
}
|
|
62
|
+
if (orgId) {
|
|
63
|
+
clauses.push(sql `exists (select 1 from ${sharesTable}
|
|
64
|
+
where ${sharesTable.resourceId} = ${resourceTable.id}
|
|
65
|
+
and ${sharesTable.principalType} = 'org'
|
|
66
|
+
and ${sharesTable.principalId} = ${orgId}
|
|
67
|
+
and ${minRoleSql(minRole)})`);
|
|
68
|
+
}
|
|
69
|
+
// If there's no user and no org (fully anonymous), only public resources.
|
|
70
|
+
return or(...clauses) ?? eq(resourceTable.visibility, "public");
|
|
71
|
+
}
|
|
72
|
+
function minRoleSql(minRole) {
|
|
73
|
+
if (minRole === "viewer") {
|
|
74
|
+
// any role satisfies viewer
|
|
75
|
+
return sql `1=1`;
|
|
76
|
+
}
|
|
77
|
+
if (minRole === "editor") {
|
|
78
|
+
return sql `role in ('editor','admin')`;
|
|
79
|
+
}
|
|
80
|
+
return sql `role = 'admin'`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Return the effective role the current user has on a specific resource, or
|
|
84
|
+
* null if they have no access. Loads the resource and relevant share rows.
|
|
85
|
+
*/
|
|
86
|
+
export async function resolveAccess(resourceType, resourceId, ctx = currentAccess()) {
|
|
87
|
+
const reg = requireShareableResource(resourceType);
|
|
88
|
+
const db = reg.getDb();
|
|
89
|
+
const [resource] = await db
|
|
90
|
+
.select()
|
|
91
|
+
.from(reg.resourceTable)
|
|
92
|
+
.where(eq(reg.resourceTable.id, resourceId));
|
|
93
|
+
if (!resource)
|
|
94
|
+
return null;
|
|
95
|
+
const { userEmail, orgId } = ctx;
|
|
96
|
+
if (userEmail && resource.ownerEmail === userEmail) {
|
|
97
|
+
return { role: "owner", resource };
|
|
98
|
+
}
|
|
99
|
+
if (resource.visibility === "public") {
|
|
100
|
+
// No share row needed; default viewer unless upgraded below.
|
|
101
|
+
const role = await highestShareRole(reg, resourceId, ctx);
|
|
102
|
+
return { role: role ?? "viewer", resource };
|
|
103
|
+
}
|
|
104
|
+
if (resource.visibility === "org" && orgId && resource.orgId === orgId) {
|
|
105
|
+
const role = await highestShareRole(reg, resourceId, ctx);
|
|
106
|
+
return { role: role ?? "viewer", resource };
|
|
107
|
+
}
|
|
108
|
+
const role = await highestShareRole(reg, resourceId, ctx);
|
|
109
|
+
if (role)
|
|
110
|
+
return { role, resource };
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
async function highestShareRole(reg, resourceId, ctx) {
|
|
114
|
+
const { userEmail, orgId } = ctx;
|
|
115
|
+
if (!userEmail && !orgId)
|
|
116
|
+
return null;
|
|
117
|
+
const db = reg.getDb();
|
|
118
|
+
const rows = await db
|
|
119
|
+
.select()
|
|
120
|
+
.from(reg.sharesTable)
|
|
121
|
+
.where(eq(reg.sharesTable.resourceId, resourceId));
|
|
122
|
+
let best = null;
|
|
123
|
+
for (const r of rows) {
|
|
124
|
+
const matches = (r.principalType === "user" &&
|
|
125
|
+
userEmail &&
|
|
126
|
+
r.principalId === userEmail) ||
|
|
127
|
+
(r.principalType === "org" && orgId && r.principalId === orgId);
|
|
128
|
+
if (!matches)
|
|
129
|
+
continue;
|
|
130
|
+
if (!best || ROLE_RANK[r.role] > ROLE_RANK[best])
|
|
131
|
+
best = r.role;
|
|
132
|
+
}
|
|
133
|
+
return best;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Throw ForbiddenError if the current user can't act on this resource with at
|
|
137
|
+
* least the given role. Used at the top of update/delete actions.
|
|
138
|
+
*/
|
|
139
|
+
export async function assertAccess(resourceType, resourceId, minRole = "viewer", ctx = currentAccess()) {
|
|
140
|
+
const access = await resolveAccess(resourceType, resourceId, ctx);
|
|
141
|
+
if (!access) {
|
|
142
|
+
throw new ForbiddenError(`No access to ${resourceType} ${resourceId}`);
|
|
143
|
+
}
|
|
144
|
+
if (ROLE_RANK[access.role] < ROLE_RANK[minRole]) {
|
|
145
|
+
throw new ForbiddenError(`Requires ${minRole} role on ${resourceType} ${resourceId} (have ${access.role})`);
|
|
146
|
+
}
|
|
147
|
+
return access;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/sharing/access.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-resource-shares.d.ts","sourceRoot":"","sources":["../../../src/sharing/actions/list-resource-shares.ts"],"names":[],"mappings":";AAMA,wBAiCG"}
|