@allbluecn/web-app 0.22.4 → 0.23.1
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/package.json +4 -14
- package/src/__tests__/integration/login-email-acceptance.test.ts +16 -0
- package/src/__tests__/story-view.test.ts +33 -1
- package/src/components/agents/__tests__/agent-bindings-tab.test.tsx +221 -0
- package/src/components/agents/__tests__/agents-page.test.tsx +284 -0
- package/src/components/agents/agent-bindings-tab.tsx +59 -45
- package/src/components/agents/agent-form-dialog.tsx +3 -3
- package/src/components/agents/agent-selector.tsx +2 -3
- package/src/components/agents/agents-page.tsx +66 -31
- package/src/components/agents/slash-skill-menu.tsx +2 -3
- package/src/components/auth/__tests__/session-guard.test.tsx +74 -0
- package/src/components/auth/session-guard.tsx +8 -0
- package/src/components/billing/login-prompt-dialog.tsx +1 -1
- package/src/components/billing/subscription-provider.tsx +2 -16
- package/src/components/bug/__tests__/peek-modes.test.tsx +8 -0
- package/src/components/bug/__tests__/subgroup-header.test.tsx +202 -40
- package/src/components/bug/peek-panel.tsx +5 -3
- package/src/components/bug/views/bug-list/group.tsx +12 -2
- package/src/components/bug/views/bug-list/index.tsx +94 -67
- package/src/components/command/command-palette.tsx +10 -9
- package/src/components/design/canvas/document/frame-custom-presets.ts +9 -1
- package/src/components/design/canvas/panels/toolbar.tsx +21 -22
- package/src/components/design/canvas/react/__tests__/canvas-context-load-echo.test.tsx +199 -0
- package/src/components/design/canvas/react/__tests__/hooks.test.tsx +17 -3
- package/src/components/design/canvas/react/canvas-context.tsx +47 -26
- package/src/components/design/canvas/react/hooks.ts +39 -34
- package/src/components/design/editor/layout/__tests__/collab-param-wiring.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/context-menu.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/no-page-save-toast.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/persistence-restore.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/ssr-localstorage-smoke.test.tsx +17 -1
- package/src/components/design/editor/layout/design-editor-layout.tsx +13 -2
- package/src/components/design/editor/layout/hooks/use-design-auto-save.ts +3 -19
- package/src/components/devtools/devtools-panel.tsx +56 -0
- package/src/components/forms/__tests__/create-app-form.test.tsx +131 -0
- package/src/components/forms/app-field-error.tsx +21 -1
- package/src/components/forms/app-field.tsx +8 -8
- package/src/components/forms/app-submit.tsx +12 -9
- package/src/components/forms/create-app-form.tsx +124 -0
- package/src/components/forms/index.ts +2 -3
- package/src/components/harness/__tests__/gallery-behavior.test.tsx +37 -1
- package/src/components/harness/__tests__/harness-workbench-first-send.test.tsx +4 -1
- package/src/components/harness/__tests__/message-actions.test.tsx +7 -6
- package/src/components/harness/__tests__/use-video-generation.test.tsx +165 -0
- package/src/components/harness/ai-chat-history/index.tsx +5 -3
- package/src/components/harness/gallery/gallery-card.tsx +57 -35
- package/src/components/harness/gallery/gallery-grid.tsx +32 -15
- package/src/components/harness/gallery/gallery-types.ts +19 -0
- package/src/components/harness/gallery/gallery-video-card.tsx +54 -0
- package/src/components/harness/gallery/types.ts +2 -0
- package/src/components/harness/gallery/use-video-generation.ts +95 -0
- package/src/components/harness/harness-workbench-page.tsx +2 -3
- package/src/components/harness/message-actions.tsx +5 -3
- package/src/components/hotkeys/shortcuts-panel.tsx +28 -13
- package/src/components/iteration/__tests__/burndown-chart.test.tsx +118 -0
- package/src/components/iteration/burndown-chart.tsx +54 -23
- package/src/components/knowledge/editor/__tests__/knowledge-doc-editor-collab.test.tsx +96 -0
- package/src/components/knowledge/editor/knowledge-doc-editor.tsx +56 -1
- package/src/components/knowledge/editor/mindmap-doc-editor.tsx +12 -0
- package/src/components/knowledge/editor/use-auto-save-channels.ts +3 -1
- package/src/components/layout/sidebar-03/__tests__/nav-workspace.test.tsx +0 -4
- package/src/components/layout/sidebar-03/nav-knowledge.tsx +11 -11
- package/src/components/layout/sidebar-03/nav-main.tsx +12 -15
- package/src/components/layout/sidebar-03/nav-notifications.tsx +5 -8
- package/src/components/layout/sidebar-03/nav-workspace.tsx +11 -9
- package/src/components/notifications/__tests__/settings-notifications.test.tsx +158 -0
- package/src/components/notifications/settings-notifications.tsx +37 -13
- package/src/components/notifications/team-notifications.tsx +10 -14
- package/src/components/settings/personal-team/account/__tests__/account-client.test.tsx +170 -0
- package/src/components/settings/personal-team/account/account-client.tsx +44 -7
- package/src/components/settings/personal-team/team/team-client.tsx +17 -19
- package/src/components/shared-kit/list-kit/__tests__/frozen-header.test.ts +210 -41
- package/src/components/shared-kit/list-kit/frozen-header.ts +134 -21
- package/src/components/shared-kit/list-kit/kanban/frozen-header.ts +20 -27
- package/src/components/story/__tests__/peek-panel-patch-sync.test.tsx +8 -0
- package/src/components/story/__tests__/story-list-table.test.tsx +214 -0
- package/src/components/story/columns.tsx +11 -2
- package/src/components/story/peek-panel.tsx +4 -2
- package/src/components/story/story-list-table.tsx +16 -1
- package/src/components/story/views/story-list/__tests__/frozen-headers.test.tsx +186 -0
- package/src/components/story/views/story-list/group.tsx +12 -1
- package/src/components/story/views/story-list/index.tsx +101 -68
- package/src/components/testcase/__tests__/case-row.test.tsx +134 -2
- package/src/components/testcase/__tests__/peek-panel.test.tsx +8 -0
- package/src/components/testcase/__tests__/step-editor.test.tsx +106 -0
- package/src/components/testcase/list/grouped-list.tsx +50 -22
- package/src/components/testcase/peek-panel.tsx +7 -4
- package/src/components/testcase/step-editor.tsx +196 -150
- package/src/components/tiptap/notion-like/editor-extensions.ts +0 -3
- package/src/components/tiptap/notion-like/notion-like-editor-header.tsx +1 -31
- package/src/components/tiptap/notion-like/notion-like-editor.tsx +32 -1
- package/src/components/workspace/__tests__/dialogs/create-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/__tests__/dialogs/edit-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/dialogs/create-workspace-dialog.tsx +45 -43
- package/src/components/workspace/dialogs/edit-workspace-dialog.tsx +38 -36
- package/src/design-engine/engine/engine-decor.ts +2 -0
- package/src/design-engine/engine/engine-path.ts +2 -0
- package/src/hooks/__tests__/use-unsaved-guard.test.tsx +180 -0
- package/src/hooks/use-notifications.ts +9 -16
- package/src/hooks/use-unsaved-guard.tsx +87 -0
- package/src/lib/__tests__/pacer.test.ts +33 -96
- package/src/lib/__tests__/query-defaults.test.ts +169 -0
- package/src/lib/__tests__/query-global-error.test.ts +256 -0
- package/src/lib/anyhub/anyhub-store.ts +2 -2
- package/src/lib/changelog/sdk-versions.ts +2 -10
- package/src/lib/collab/presence-store.ts +5 -5
- package/src/lib/collab/use-presence-list-refresh.ts +2 -2
- package/src/lib/collab/use-share-presence.ts +2 -2
- package/src/lib/collections/query-keys.ts +7 -2
- package/src/lib/commands/__tests__/command-palette-state.test.ts +12 -14
- package/src/lib/commands/__tests__/registry.test.ts +6 -3
- package/src/lib/commands/command-palette-state.ts +8 -31
- package/src/lib/hotkeys/__tests__/registry.test.ts +71 -18
- package/src/lib/hotkeys/registry.ts +188 -85
- package/src/lib/hotkeys/types.ts +1 -13
- package/src/lib/pacer.ts +1 -79
- package/src/lib/queries/README.md +67 -0
- package/src/lib/queries/__tests__/agents-queries.test.ts +101 -0
- package/src/lib/queries/__tests__/compliance-queries.test.ts +136 -0
- package/src/lib/queries/__tests__/notifications-queries.test.ts +175 -0
- package/src/lib/queries/__tests__/team-queries.test.ts +87 -0
- package/src/lib/queries/agents.ts +40 -0
- package/src/lib/queries/compliance.ts +69 -0
- package/src/lib/queries/notifications.ts +63 -0
- package/src/lib/queries/team.ts +39 -0
- package/src/lib/query-defaults.ts +8 -0
- package/src/lib/query-global-error.ts +128 -0
- package/src/lib/remote-auth-client.ts +16 -0
- package/src/paraglide/README.md +1 -1
- package/src/paraglide/messages/_index.d.ts +11 -0
- package/src/paraglide/messages/_index.js +5659 -88285
- package/src/paraglide/messages/common_error_generic.d.ts +16 -0
- package/src/paraglide/messages/common_error_generic.js +29 -0
- package/src/paraglide/messages/common_unsaved_body.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_body.js +29 -0
- package/src/paraglide/messages/common_unsaved_leave.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_leave.js +29 -0
- package/src/paraglide/messages/common_unsaved_stay.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_stay.js +29 -0
- package/src/paraglide/messages/common_unsaved_title.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_title.js +29 -0
- package/src/paraglide/messages/gallery_videofailed1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videofailed1.js +30 -0
- package/src/paraglide/messages/gallery_videogenerating1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videogenerating1.js +30 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.d.ts +17 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.js +30 -0
- package/src/paraglide/messages/gallery_videoprogress1.d.ts +19 -0
- package/src/paraglide/messages/gallery_videoprogress1.js +30 -0
- package/src/paraglide/messages/gallery_videostop1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videostop1.js +30 -0
- package/src/paraglide/messages/story_table_resizecolumn1.d.ts +17 -0
- package/src/paraglide/messages/story_table_resizecolumn1.js +30 -0
- package/src/providers/index.tsx +5 -50
- package/src/routeTree.gen.ts +21 -0
- package/src/router.tsx +21 -8
- package/src/routes/__root.tsx +2 -1
- package/src/routes/__tests__/-edition-routing.test.tsx +6 -1
- package/src/routes/_login/forgot-password/route.lazy.tsx +7 -6
- package/src/routes/_login/login/route.lazy.tsx +10 -9
- package/src/routes/_login/register/route.lazy.tsx +19 -18
- package/src/routes/_login/reset-password/route.lazy.tsx +10 -9
- package/src/routes/_nav/knowledge/compliance/$id.lazy.tsx +9 -12
- package/src/routes/_nav/knowledge/compliance/index.lazy.tsx +16 -13
- package/src/routes/_nav/knowledge/laws/$id.lazy.tsx +1 -1
- package/src/routes/_nav/notifications/route.tsx +6 -16
- package/src/routes/_nav/settings/-settings-tabs.tsx +9 -12
- package/src/routes/api/generate/__tests__/media.test.ts +378 -0
- package/src/routes/api/generate/media.ts +179 -0
- package/src/server/__tests__/agent-client-graph.test.ts +0 -1
- package/src/server/__tests__/agent-crud.test.ts +37 -4
- package/src/server/__tests__/bug-groups-two-level.test.ts +34 -1
- package/src/server/__tests__/chat-conversations.test.ts +37 -4
- package/src/server/__tests__/chat-list-messages.test.ts +40 -7
- package/src/server/__tests__/csv-export.test.ts +36 -3
- package/src/server/__tests__/desktop-bootstrap.test.ts +189 -0
- package/src/server/__tests__/remote-auth.test.ts +72 -0
- package/src/server/__tests__/skill-crud.test.ts +37 -4
- package/src/server/__tests__/sso-domain.test.ts +1 -1
- package/src/server/__tests__/sso-rate-limit-singleton.test.ts +123 -0
- package/src/server/__tests__/task-serverfn-crud.test.ts +35 -2
- package/src/server/__tests__/task-serverfn-queries.test.ts +35 -2
- package/src/server/__tests__/testcase-board.test.ts +38 -5
- package/src/server/__tests__/testcase-bulk.test.ts +38 -5
- package/src/server/__tests__/testcase-list-scope.test.ts +38 -5
- package/src/server/ai-gateway/__tests__/ai-output-guard.test.ts +126 -2
- package/src/server/ai-gateway/__tests__/chat-stream-builder-code-mode.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-memory.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-sandbox.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-skills.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-adapter.test.ts +30 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-conformance.test.ts +92 -0
- package/src/server/ai-gateway/__tests__/source-mode.test.ts +49 -8
- package/src/server/ai-gateway/ai-output-guard.ts +50 -2
- package/src/server/ai-gateway/chat-stream-builder.ts +3 -0
- package/src/server/ai-gateway/media/index.ts +36 -29
- package/src/server/ai-gateway/media/trim-input.ts +52 -0
- package/src/server/ai-gateway/memory/pgvector-adapter.ts +27 -13
- package/src/server/ai-gateway/sandbox/__tests__/harness-sandbox.test.ts +252 -41
- package/src/server/ai-gateway/sandbox/harness-sandbox.ts +6 -67
- package/src/server/ai-gateway/source-mode.ts +24 -8
- package/src/server/desktop-bootstrap.ts +74 -0
- package/src/server/lib/__tests__/rate-limit.test.ts +0 -1
- package/src/server/lib/rate-limit.ts +0 -2
- package/src/server/middlewares/__tests__/auth-context.test.ts +156 -0
- package/src/server/middlewares/auth-context.ts +62 -0
- package/src/server/remote-auth.ts +58 -31
- package/src/server/serverFns/__tests__/ai-hosted-models.test.ts +47 -15
- package/src/server/serverFns/__tests__/ai-source-mode.test.ts +45 -15
- package/src/server/serverFns/__tests__/billing.test.ts +37 -2
- package/src/server/serverFns/__tests__/collab-snapshot.test.ts +41 -14
- package/src/server/serverFns/__tests__/collab.test.ts +41 -14
- package/src/server/serverFns/__tests__/compliance.test.ts +33 -1
- package/src/server/serverFns/__tests__/email-verification.test.ts +35 -1
- package/src/server/serverFns/__tests__/knowledge-breadcrumb.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-delete.test.ts +42 -14
- package/src/server/serverFns/__tests__/knowledge-kb-projects.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-public-compliance.test.ts +36 -2
- package/src/server/serverFns/__tests__/knowledge-readable-kb.test.ts +42 -10
- package/src/server/serverFns/__tests__/knowledge-search.test.ts +45 -9
- package/src/server/serverFns/__tests__/legal-code-canonical.test.ts +36 -2
- package/src/server/serverFns/__tests__/link-preview.test.ts +38 -4
- package/src/server/serverFns/__tests__/notifications-list.test.ts +36 -3
- package/src/server/serverFns/__tests__/ownership-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/project-delete-transaction.test.ts +39 -2
- package/src/server/serverFns/__tests__/project-kb.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-member-idor.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-team-assign.test.ts +34 -1
- package/src/server/serverFns/__tests__/read-write-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-comments.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-archive-detail.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-labels-users.test.ts +37 -3
- package/src/server/serverFns/__tests__/story-crud.test.ts +36 -3
- package/src/server/serverFns/__tests__/story-links.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-reactions.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-tree.test.ts +38 -4
- package/src/server/serverFns/__tests__/team-accept.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-invitation.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-join-request.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-members.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-ownership-merge.test.ts +34 -1
- package/src/server/serverFns/__tests__/update-bug-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/update-document-guard.test.ts +38 -4
- package/src/server/serverFns/__tests__/update-page-guard.test.ts +40 -4
- package/src/server/serverFns/__tests__/update-seats.test.ts +33 -1
- package/src/server/serverFns/__tests__/update-story-guard.test.ts +36 -3
- package/src/server/serverFns/__tests__/update-testcase-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/workspace-kb-idor.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace-kb.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace.test.ts +34 -1
- package/src/server/serverFns/activity.ts +10 -14
- package/src/server/serverFns/agents/agent-crud.ts +16 -15
- package/src/server/serverFns/agents/bindings.ts +12 -13
- package/src/server/serverFns/agents/skill-crud.ts +16 -15
- package/src/server/serverFns/ai/code-mode-readiness.ts +3 -4
- package/src/server/serverFns/ai/search-capability.ts +3 -4
- package/src/server/serverFns/anyhub/app.ts +10 -14
- package/src/server/serverFns/anyhub/index.ts +7 -10
- package/src/server/serverFns/anyhub/install.ts +4 -4
- package/src/server/serverFns/anyhub/permissions.ts +10 -14
- package/src/server/serverFns/anyhub/proxy.ts +4 -6
- package/src/server/serverFns/auth/email-verification.ts +4 -5
- package/src/server/serverFns/auth/session.ts +9 -0
- package/src/server/serverFns/billing.ts +18 -28
- package/src/server/serverFns/blob-upload.ts +6 -9
- package/src/server/serverFns/bug/__tests__/bug-access-tokens.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-activities.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-crud.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-fix.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reactions.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reorder.test.ts +39 -5
- package/src/server/serverFns/bug/__tests__/bug-repro.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-story.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-webhooks.test.ts +34 -1
- package/src/server/serverFns/bug/bug-access-tokens.ts +16 -22
- package/src/server/serverFns/bug/bug-activities.ts +4 -6
- package/src/server/serverFns/bug/bug-collect-tokens.ts +13 -18
- package/src/server/serverFns/bug/bug-comments.ts +13 -18
- package/src/server/serverFns/bug/bug-crud/detail.ts +10 -14
- package/src/server/serverFns/bug/bug-crud.ts +28 -38
- package/src/server/serverFns/bug/bug-display-options.ts +8 -11
- package/src/server/serverFns/bug/bug-export.ts +5 -7
- package/src/server/serverFns/bug/bug-fix.ts +10 -14
- package/src/server/serverFns/bug/bug-groups.ts +10 -14
- package/src/server/serverFns/bug/bug-reactions.ts +10 -14
- package/src/server/serverFns/bug/bug-reorder.ts +4 -6
- package/src/server/serverFns/bug/bug-repro.ts +8 -11
- package/src/server/serverFns/bug/bug-story-bulk.ts +13 -18
- package/src/server/serverFns/bug/bug-story.ts +10 -14
- package/src/server/serverFns/bug/bug-views.ts +12 -18
- package/src/server/serverFns/bug/bug-webhooks.ts +13 -18
- package/src/server/serverFns/bug/test-bug-confirm.ts +7 -10
- package/src/server/serverFns/changelog/__tests__/fetch.test.ts +40 -1
- package/src/server/serverFns/changelog/fetch.ts +4 -6
- package/src/server/serverFns/chat/conversations.ts +17 -28
- package/src/server/serverFns/chat/list-messages.ts +4 -7
- package/src/server/serverFns/collab-presence.ts +11 -13
- package/src/server/serverFns/collab-snapshot.ts +6 -7
- package/src/server/serverFns/collab.ts +7 -7
- package/src/server/serverFns/compliance.ts +8 -8
- package/src/server/serverFns/design/__tests__/comments.test.ts +54 -10
- package/src/server/serverFns/design/__tests__/designs.test.ts +39 -16
- package/src/server/serverFns/design/__tests__/page-versions.test.ts +52 -14
- package/src/server/serverFns/design/__tests__/shares-password.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/shares.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/versions.test.ts +44 -14
- package/src/server/serverFns/design/ai/__tests__/agent-conversations.test.ts +50 -21
- package/src/server/serverFns/design/ai/__tests__/providers.test.ts +42 -8
- package/src/server/serverFns/design/ai/agent-conversations.ts +19 -26
- package/src/server/serverFns/design/ai/fill-annotation.ts +5 -7
- package/src/server/serverFns/design/ai/generate-prototype.ts +5 -7
- package/src/server/serverFns/design/ai/hosted-models.ts +4 -5
- package/src/server/serverFns/design/ai/providers.ts +30 -39
- package/src/server/serverFns/design/ai/source-mode.ts +10 -12
- package/src/server/serverFns/design/comments.ts +14 -13
- package/src/server/serverFns/design/designs.ts +13 -19
- package/src/server/serverFns/design/page-versions.ts +17 -18
- package/src/server/serverFns/design/pages.ts +17 -18
- package/src/server/serverFns/design/reviews.ts +8 -9
- package/src/server/serverFns/design/shares-password.ts +13 -19
- package/src/server/serverFns/design/shares.ts +22 -31
- package/src/server/serverFns/design/versions.ts +8 -9
- package/src/server/serverFns/harness/__tests__/attach-prototype.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-kb.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story-ssrf.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/cancel-run.test.ts +40 -15
- package/src/server/serverFns/harness/__tests__/extract-attachment.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/gallery.spec.ts +76 -12
- package/src/server/serverFns/harness/__tests__/github-workspace.spec.ts +38 -6
- package/src/server/serverFns/harness/__tests__/media-prototype.spec.ts +50 -6
- package/src/server/serverFns/harness/__tests__/media.spec.ts +55 -11
- package/src/server/serverFns/harness/__tests__/sandbox-policy.test.ts +41 -16
- package/src/server/serverFns/harness/__tests__/workspace-files.test.ts +41 -16
- package/src/server/serverFns/harness/attach-prototype.ts +4 -4
- package/src/server/serverFns/harness/attach-to-kb.ts +4 -4
- package/src/server/serverFns/harness/attach-to-story.ts +4 -4
- package/src/server/serverFns/harness/cancel-run.ts +4 -6
- package/src/server/serverFns/harness/extract-attachment.ts +3 -4
- package/src/server/serverFns/harness/gallery.ts +19 -23
- package/src/server/serverFns/harness/github-workspace.ts +14 -21
- package/src/server/serverFns/harness/media.ts +18 -117
- package/src/server/serverFns/harness/sandbox-policy.ts +11 -10
- package/src/server/serverFns/harness/search-mention-candidates.ts +4 -6
- package/src/server/serverFns/harness/workspace-files.ts +19 -26
- package/src/server/serverFns/iteration/__tests__/iteration-auto-schedule.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +35 -3
- package/src/server/serverFns/iteration/iteration-auto-schedule.ts +7 -10
- package/src/server/serverFns/iteration/iteration-burndown.ts +4 -6
- package/src/server/serverFns/iteration/iteration-crud.ts +26 -35
- package/src/server/serverFns/iteration/iteration-stories.ts +10 -14
- package/src/server/serverFns/iteration/iteration-transfer.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/categories.ts +11 -15
- package/src/server/serverFns/knowledge/public/bookmarks/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/favorite.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/refresh-favicon.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/sync-github.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/update.ts +6 -8
- package/src/server/serverFns/knowledge/public/compliance/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/compliance/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/entity-tags.ts +4 -6
- package/src/server/serverFns/knowledge/public/favorite.ts +7 -10
- package/src/server/serverFns/knowledge/public/legal/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/legal/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/update.ts +5 -7
- package/src/server/serverFns/knowledge-index.ts +12 -16
- package/src/server/serverFns/knowledge.ts +50 -67
- package/src/server/serverFns/notifications.ts +25 -34
- package/src/server/serverFns/plugins/harness-plugins.ts +16 -23
- package/src/server/serverFns/project/module-overview.ts +7 -10
- package/src/server/serverFns/project.ts +48 -68
- package/src/server/serverFns/references/create.ts +4 -6
- package/src/server/serverFns/references/resolve.ts +4 -6
- package/src/server/serverFns/references/search.ts +4 -6
- package/src/server/serverFns/share/design/[designId]/events.ts +4 -6
- package/src/server/serverFns/sso.ts +1 -1
- package/src/server/serverFns/story/__tests__/bulk.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-attachments.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-crud-date-key.test.ts +42 -17
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-gantt-deps.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-groups.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-read-path-authz.test.ts +40 -4
- package/src/server/serverFns/story/__tests__/story-search.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-transfer.test.ts +34 -1
- package/src/server/serverFns/story/link-preview.ts +5 -7
- package/src/server/serverFns/story/story-assoc.ts +28 -38
- package/src/server/serverFns/story/story-attachments.ts +7 -10
- package/src/server/serverFns/story/story-children.ts +4 -6
- package/src/server/serverFns/story/story-comments.ts +13 -18
- package/src/server/serverFns/story/story-crud/activities.ts +4 -6
- package/src/server/serverFns/story/story-crud/archive.ts +7 -10
- package/src/server/serverFns/story/story-crud/bulk.ts +10 -14
- package/src/server/serverFns/story/story-crud/detail.ts +7 -10
- package/src/server/serverFns/story/story-crud/label-suggest.ts +4 -6
- package/src/server/serverFns/story/story-crud/labels.ts +6 -9
- package/src/server/serverFns/story/story-crud/user-brief.ts +4 -6
- package/src/server/serverFns/story/story-crud.ts +13 -18
- package/src/server/serverFns/story/story-dependencies.ts +16 -22
- package/src/server/serverFns/story/story-groups.ts +10 -14
- package/src/server/serverFns/story/story-links.ts +13 -18
- package/src/server/serverFns/story/story-reactions.ts +13 -18
- package/src/server/serverFns/story/story-search.ts +7 -10
- package/src/server/serverFns/story/story-transfer.ts +10 -14
- package/src/server/serverFns/story/story-tree.ts +7 -10
- package/src/server/serverFns/story-display-options.ts +7 -8
- package/src/server/serverFns/story-view.ts +12 -18
- package/src/server/serverFns/tasks/task-crud.ts +13 -17
- package/src/server/serverFns/tasks/task-queries.ts +12 -18
- package/src/server/serverFns/team.ts +46 -66
- package/src/server/serverFns/testcase/__tests__/automation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/evidence-upload.test.ts +37 -3
- package/src/server/serverFns/testcase/__tests__/generation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/plans.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/regression.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/run-cases.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/runs.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/stats.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-board.test.ts +39 -5
- package/src/server/serverFns/testcase/__tests__/testcase-crud.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-folders.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-groups.test.ts +38 -5
- package/src/server/serverFns/testcase/automation.ts +13 -17
- package/src/server/serverFns/testcase/bulk.ts +10 -14
- package/src/server/serverFns/testcase/evidence-upload.ts +5 -7
- package/src/server/serverFns/testcase/generation.ts +10 -13
- package/src/server/serverFns/testcase/plans.ts +23 -31
- package/src/server/serverFns/testcase/regression.ts +7 -10
- package/src/server/serverFns/testcase/run-cases.ts +13 -18
- package/src/server/serverFns/testcase/runs.ts +13 -18
- package/src/server/serverFns/testcase/stats.ts +13 -18
- package/src/server/serverFns/testcase/testcase-activities.ts +4 -6
- package/src/server/serverFns/testcase/testcase-board.ts +4 -6
- package/src/server/serverFns/testcase/testcase-crud.ts +20 -27
- package/src/server/serverFns/testcase/testcase-display-options.ts +8 -11
- package/src/server/serverFns/testcase/testcase-export.ts +5 -7
- package/src/server/serverFns/testcase/testcase-filter-views.ts +12 -18
- package/src/server/serverFns/testcase/testcase-folders.ts +16 -22
- package/src/server/serverFns/testcase/testcase-groups.ts +4 -6
- package/src/server/serverFns/testcase/testcase-reorder.ts +4 -6
- package/src/server/serverFns/translation.ts +4 -6
- package/src/server/serverFns/user/avatar.ts +4 -6
- package/src/server/serverFns/user/settings.ts +4 -6
- package/src/server/serverFns/user/update-locale.ts +4 -6
- package/src/server/serverFns/workspace-kb.ts +26 -35
- package/src/server/serverFns/workspace.ts +43 -59
- package/src/server/serverFns/ws.ts +4 -6
- package/src/server/serverfn-public-allowlist.ts +117 -0
- package/src/server/story/types.ts +0 -1
- package/src/server/sync/__tests__/scopes.test.ts +64 -0
- package/src/server/sync/scopes.ts +7 -0
- package/src/server/testcase/__tests__/auto-bug.test.ts +44 -12
- package/src/__tests__/bench/baselines/format-timestamp.json +0 -44
- package/src/__typeprobe__.d.ts +0 -4
- package/src/components/forms/app-form-dialog.tsx +0 -126
- package/src/components/forms/hooks/use-form-submit.ts +0 -57
- package/src/components/forms/types.ts +0 -34
- package/src/components/harness/code/workspace-picker.tsx +0 -239
- package/src/components/tiptap/extensions/local-file/insert-local-file.ts +0 -35
- package/src/components/tiptap/extensions/local-file/local-file-node.ts +0 -71
- package/src/devframe-docks/ai-chat-iframe.tsx +0 -29
- package/src/devframe-docks/session-iframe.tsx +0 -90
- package/src/lib/__tests__/desktop-detect.test.ts +0 -19
- package/src/lib/collections/index.ts +0 -22
- package/src/lib/collections/knowledge/index.ts +0 -18
- package/src/lib/collections/knowledge/knowledge-bases-collection.ts +0 -34
- package/src/lib/collections/reference/bookmark-categories-collection.ts +0 -31
- package/src/lib/collections/reference/labels-collection.ts +0 -31
- package/src/lib/collections/reference/projects-collection.ts +0 -31
- package/src/lib/collections/reference/users-brief-collection.ts +0 -35
- package/src/lib/collections/reference/workspaces-collection.ts +0 -34
- package/src/lib/desktop-detect.ts +0 -29
- package/src/paraglide/messages/en.js +0 -28260
- package/src/paraglide/messages/zh.js +0 -28258
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
22
|
import { Prisma } from '@allbluecn/database'
|
|
23
|
-
import { getServerSeam } from '@allbluecn/kernel'
|
|
24
|
-
import { sessionUserId } from '@/server/design/access'
|
|
25
23
|
|
|
26
24
|
const listSchema = z.object({
|
|
27
25
|
take: z.number().int().min(1).max(100).default(20),
|
|
@@ -29,12 +27,11 @@ const listSchema = z.object({
|
|
|
29
27
|
})
|
|
30
28
|
|
|
31
29
|
export const listDesignsFn = createServerFn({ method: 'GET' })
|
|
30
|
+
.middleware([authContextMiddleware])
|
|
32
31
|
.validator(listSchema)
|
|
33
|
-
.handler(async ({ data }) => {
|
|
32
|
+
.handler(async ({ data, context }) => {
|
|
34
33
|
const prisma = await getPrisma()
|
|
35
|
-
const
|
|
36
|
-
const session = await getServerSeam().requireAuth(request)
|
|
37
|
-
const userId = sessionUserId(session)
|
|
34
|
+
const userId = context.user.id
|
|
38
35
|
return prisma.design.findMany({
|
|
39
36
|
where: { userId, isDeleted: false },
|
|
40
37
|
orderBy: { createdAt: 'desc' },
|
|
@@ -59,11 +56,10 @@ const createSchema = z.object({
|
|
|
59
56
|
})
|
|
60
57
|
|
|
61
58
|
export const createDesignFn = createServerFn({ method: 'POST' })
|
|
59
|
+
.middleware([authContextMiddleware])
|
|
62
60
|
.validator(createSchema)
|
|
63
|
-
.handler(async ({ data }) => {
|
|
61
|
+
.handler(async ({ data, context }) => {
|
|
64
62
|
const prisma = await getPrisma()
|
|
65
|
-
const request = getRequest()
|
|
66
|
-
const session = await getServerSeam().requireAuth(request)
|
|
67
63
|
// 服务端同步建首页:否则首个 page 依赖左栏页面树挂载时自动创建,
|
|
68
64
|
// 左栏折叠(localStorage.designLeftPanelOpen 持久化)时首页永不创建,
|
|
69
65
|
// activePageId 恒 null,保存链路静默跳过,编辑内容全丢。
|
|
@@ -74,7 +70,7 @@ export const createDesignFn = createServerFn({ method: 'POST' })
|
|
|
74
70
|
icon: data.icon,
|
|
75
71
|
name: data.name,
|
|
76
72
|
description: data.description,
|
|
77
|
-
userId:
|
|
73
|
+
userId: context.user.id,
|
|
78
74
|
pages: {
|
|
79
75
|
create: {
|
|
80
76
|
name: data.homeName ?? '首页',
|
|
@@ -103,15 +99,14 @@ const updateSchema = z.object({
|
|
|
103
99
|
})
|
|
104
100
|
|
|
105
101
|
export const updateDesignFn = createServerFn({ method: 'POST' })
|
|
102
|
+
.middleware([authContextMiddleware])
|
|
106
103
|
.validator(updateSchema)
|
|
107
|
-
.handler(async ({ data }) => {
|
|
104
|
+
.handler(async ({ data, context }) => {
|
|
108
105
|
const prisma = await getPrisma()
|
|
109
|
-
const request = getRequest()
|
|
110
|
-
const session = await getServerSeam().requireAuth(request)
|
|
111
106
|
// DB-03:属主校验合并进写入(updateMany 计数判定),1 次查询替代 2 次
|
|
112
107
|
const { id: _id, ...rest } = data
|
|
113
108
|
const res = await prisma.design.updateMany({
|
|
114
|
-
where: { id: data.id, userId:
|
|
109
|
+
where: { id: data.id, userId: context.user.id, isDeleted: false },
|
|
115
110
|
data: rest,
|
|
116
111
|
})
|
|
117
112
|
if (res.count === 0) throw new Error('未找到或无权限')
|
|
@@ -119,14 +114,13 @@ export const updateDesignFn = createServerFn({ method: 'POST' })
|
|
|
119
114
|
})
|
|
120
115
|
|
|
121
116
|
export const deleteDesignFn = createServerFn({ method: 'POST' })
|
|
117
|
+
.middleware([authContextMiddleware])
|
|
122
118
|
.validator(z.object({ id: z.string() }))
|
|
123
|
-
.handler(async ({ data }) => {
|
|
119
|
+
.handler(async ({ data, context }) => {
|
|
124
120
|
const prisma = await getPrisma()
|
|
125
|
-
const request = getRequest()
|
|
126
|
-
const session = await getServerSeam().requireAuth(request)
|
|
127
121
|
// DB-03:属主校验合并进写入;where 不含 isDeleted 与原 findFirst 口径一致(重复软删幂等刷新 deletedAt)
|
|
128
122
|
const res = await prisma.design.updateMany({
|
|
129
|
-
where: { id: data.id, userId:
|
|
123
|
+
where: { id: data.id, userId: context.user.id },
|
|
130
124
|
data: { isDeleted: true, deletedAt: new Date() },
|
|
131
125
|
})
|
|
132
126
|
if (res.count === 0) throw new Error('未找到或无权限')
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
|
-
import {
|
|
23
|
-
import { assertPageOwner, assertPageVersionOwner, sessionUserId } from '@/server/design/access'
|
|
22
|
+
import { assertPageOwner, assertPageVersionOwner } from '@/server/design/access'
|
|
24
23
|
import { toNullableJsonInput } from '@/server/lib/prisma-json'
|
|
25
24
|
|
|
26
25
|
const VERSION_NOTES_MAX = 500
|
|
@@ -28,14 +27,14 @@ const VERSION_NOTES_MAX = 500
|
|
|
28
27
|
// 页面版本(快照)全部经 page.design.userId 归属校验:读写一律仅属主。
|
|
29
28
|
|
|
30
29
|
export const listDesignPageVersionsFn = createServerFn({ method: 'GET' })
|
|
30
|
+
.middleware([authContextMiddleware])
|
|
31
31
|
.validator(z.object({
|
|
32
32
|
pageId: z.string(),
|
|
33
33
|
limit: z.number().int().min(1).optional(),
|
|
34
34
|
}))
|
|
35
|
-
.handler(async ({ data }) => {
|
|
35
|
+
.handler(async ({ data, context }) => {
|
|
36
36
|
const prisma = await getPrisma()
|
|
37
|
-
const
|
|
38
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
37
|
+
const userId = context.user.id
|
|
39
38
|
await assertPageOwner(data.pageId, userId)
|
|
40
39
|
|
|
41
40
|
return prisma.pageVersion.findMany({
|
|
@@ -47,11 +46,11 @@ export const listDesignPageVersionsFn = createServerFn({ method: 'GET' })
|
|
|
47
46
|
})
|
|
48
47
|
|
|
49
48
|
export const getDesignPageVersionFn = createServerFn({ method: 'GET' })
|
|
49
|
+
.middleware([authContextMiddleware])
|
|
50
50
|
.validator(z.object({ pageVersionId: z.string() }))
|
|
51
|
-
.handler(async ({ data }) => {
|
|
51
|
+
.handler(async ({ data, context }) => {
|
|
52
52
|
const prisma = await getPrisma()
|
|
53
|
-
const
|
|
54
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
53
|
+
const userId = context.user.id
|
|
55
54
|
await assertPageVersionOwner(data.pageVersionId, userId)
|
|
56
55
|
|
|
57
56
|
const pageVersion = await prisma.pageVersion.findUnique({
|
|
@@ -64,6 +63,7 @@ export const getDesignPageVersionFn = createServerFn({ method: 'GET' })
|
|
|
64
63
|
})
|
|
65
64
|
|
|
66
65
|
export const createDesignPageVersionFn = createServerFn({ method: 'POST' })
|
|
66
|
+
.middleware([authContextMiddleware])
|
|
67
67
|
.validator(z.object({
|
|
68
68
|
pageId: z.string(),
|
|
69
69
|
notes: z.string().optional(),
|
|
@@ -71,10 +71,9 @@ export const createDesignPageVersionFn = createServerFn({ method: 'POST' })
|
|
|
71
71
|
content: z.unknown().optional(),
|
|
72
72
|
restoredFromVersion: z.number().int().optional(),
|
|
73
73
|
}))
|
|
74
|
-
.handler(async ({ data }) => {
|
|
74
|
+
.handler(async ({ data, context }) => {
|
|
75
75
|
const prisma = await getPrisma()
|
|
76
|
-
const
|
|
77
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
76
|
+
const userId = context.user.id
|
|
78
77
|
await assertPageOwner(data.pageId, userId)
|
|
79
78
|
|
|
80
79
|
if (data.notes && data.notes.length > VERSION_NOTES_MAX) {
|
|
@@ -117,16 +116,16 @@ export const createDesignPageVersionFn = createServerFn({ method: 'POST' })
|
|
|
117
116
|
})
|
|
118
117
|
|
|
119
118
|
export const updateDesignPageVersionFn = createServerFn({ method: 'POST' })
|
|
119
|
+
.middleware([authContextMiddleware])
|
|
120
120
|
.validator(z.object({
|
|
121
121
|
pageVersionId: z.string(),
|
|
122
122
|
notes: z.string().optional(),
|
|
123
123
|
canvas: z.unknown().optional(),
|
|
124
124
|
content: z.unknown().optional(),
|
|
125
125
|
}))
|
|
126
|
-
.handler(async ({ data }) => {
|
|
126
|
+
.handler(async ({ data, context }) => {
|
|
127
127
|
const prisma = await getPrisma()
|
|
128
|
-
const
|
|
129
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
128
|
+
const userId = context.user.id
|
|
130
129
|
await assertPageVersionOwner(data.pageVersionId, userId)
|
|
131
130
|
|
|
132
131
|
if (data.notes && data.notes.length > VERSION_NOTES_MAX) {
|
|
@@ -144,11 +143,11 @@ export const updateDesignPageVersionFn = createServerFn({ method: 'POST' })
|
|
|
144
143
|
})
|
|
145
144
|
|
|
146
145
|
export const deleteDesignPageVersionFn = createServerFn({ method: 'POST' })
|
|
146
|
+
.middleware([authContextMiddleware])
|
|
147
147
|
.validator(z.object({ pageVersionId: z.string() }))
|
|
148
|
-
.handler(async ({ data }) => {
|
|
148
|
+
.handler(async ({ data, context }) => {
|
|
149
149
|
const prisma = await getPrisma()
|
|
150
|
-
const
|
|
151
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
150
|
+
const userId = context.user.id
|
|
152
151
|
await assertPageVersionOwner(data.pageVersionId, userId)
|
|
153
152
|
|
|
154
153
|
await prisma.pageVersion.delete({
|
|
@@ -16,24 +16,23 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
22
|
import { Prisma } from '@allbluecn/database'
|
|
23
|
-
import { getServerSeam } from '@allbluecn/kernel'
|
|
24
23
|
import { buildRoomName } from '@allbluecn/collab-core/rooms'
|
|
25
24
|
import { withCollabGuard } from '@/server/collab/write-guard'
|
|
26
|
-
import { assertDesignOwner, assertPageOwner
|
|
25
|
+
import { assertDesignOwner, assertPageOwner } from '@/server/design/access'
|
|
27
26
|
|
|
28
27
|
export const listDesignPagesFn = createServerFn({ method: 'GET' })
|
|
28
|
+
.middleware([authContextMiddleware])
|
|
29
29
|
.validator(z.object({
|
|
30
30
|
designId: z.string(),
|
|
31
31
|
take: z.number().int().min(1).max(200).default(50),
|
|
32
32
|
}))
|
|
33
|
-
.handler(async ({ data }) => {
|
|
33
|
+
.handler(async ({ data, context }) => {
|
|
34
34
|
const prisma = await getPrisma()
|
|
35
|
-
const
|
|
36
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
35
|
+
const userId = context.user.id
|
|
37
36
|
await assertDesignOwner(data.designId, userId)
|
|
38
37
|
return prisma.designPage.findMany({
|
|
39
38
|
where: { designId: data.designId },
|
|
@@ -44,16 +43,16 @@ export const listDesignPagesFn = createServerFn({ method: 'GET' })
|
|
|
44
43
|
})
|
|
45
44
|
|
|
46
45
|
export const createDesignPageFn = createServerFn({ method: 'POST' })
|
|
46
|
+
.middleware([authContextMiddleware])
|
|
47
47
|
.validator(z.object({
|
|
48
48
|
designId: z.string(),
|
|
49
49
|
name: z.string().optional(),
|
|
50
50
|
type: z.string(),
|
|
51
51
|
parentId: z.string().nullable().optional(),
|
|
52
52
|
}))
|
|
53
|
-
.handler(async ({ data }) => {
|
|
53
|
+
.handler(async ({ data, context }) => {
|
|
54
54
|
const prisma = await getPrisma()
|
|
55
|
-
const
|
|
56
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
55
|
+
const userId = context.user.id
|
|
57
56
|
await assertDesignOwner(data.designId, userId)
|
|
58
57
|
const maxOrder = await prisma.designPage.aggregate({
|
|
59
58
|
where: { designId: data.designId, parentId: data.parentId ?? null },
|
|
@@ -87,6 +86,7 @@ export const createDesignPageFn = createServerFn({ method: 'POST' })
|
|
|
87
86
|
})
|
|
88
87
|
|
|
89
88
|
export const updateDesignPageFn = createServerFn({ method: 'POST' })
|
|
89
|
+
.middleware([authContextMiddleware])
|
|
90
90
|
.validator(z.object({
|
|
91
91
|
pageId: z.string(),
|
|
92
92
|
name: z.string().optional(),
|
|
@@ -95,10 +95,9 @@ export const updateDesignPageFn = createServerFn({ method: 'POST' })
|
|
|
95
95
|
canvas: z.any().optional(),
|
|
96
96
|
content: z.any().optional(),
|
|
97
97
|
}))
|
|
98
|
-
.handler(async ({ data }) => {
|
|
98
|
+
.handler(async ({ data, context }) => {
|
|
99
99
|
const prisma = await getPrisma()
|
|
100
|
-
const
|
|
101
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
100
|
+
const userId = context.user.id
|
|
102
101
|
// §5.3 写入门卫(任务 29):Y 属主面 = canvas(整场景 replace 语义)+
|
|
103
102
|
// content(文档 fragment 面)。快照存在 → 转发 collab 内部通道(活跃判定
|
|
104
103
|
// 在 collab 侧);无快照 pass-through、不可达 TTL 降级 → 照旧直写(非协同
|
|
@@ -168,11 +167,11 @@ export const updateDesignPageFn = createServerFn({ method: 'POST' })
|
|
|
168
167
|
})
|
|
169
168
|
|
|
170
169
|
export const deleteDesignPageFn = createServerFn({ method: 'POST' })
|
|
170
|
+
.middleware([authContextMiddleware])
|
|
171
171
|
.validator(z.object({ pageId: z.string() }))
|
|
172
|
-
.handler(async ({ data }) => {
|
|
172
|
+
.handler(async ({ data, context }) => {
|
|
173
173
|
const prisma = await getPrisma()
|
|
174
|
-
const
|
|
175
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
174
|
+
const userId = context.user.id
|
|
176
175
|
await assertPageOwner(data.pageId, userId)
|
|
177
176
|
await prisma.$transaction(async (tx) => {
|
|
178
177
|
const descendants = await tx.$queryRaw<Array<{ id: string }>>`
|
|
@@ -197,11 +196,11 @@ export const deleteDesignPageFn = createServerFn({ method: 'POST' })
|
|
|
197
196
|
})
|
|
198
197
|
|
|
199
198
|
export const getDesignPageFn = createServerFn({ method: 'GET' })
|
|
199
|
+
.middleware([authContextMiddleware])
|
|
200
200
|
.validator(z.object({ pageId: z.string() }))
|
|
201
|
-
.handler(async ({ data }) => {
|
|
201
|
+
.handler(async ({ data, context }) => {
|
|
202
202
|
const prisma = await getPrisma()
|
|
203
|
-
const
|
|
204
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
203
|
+
const userId = context.user.id
|
|
205
204
|
// DB-03:属主校验(经 design.userId 关系过滤)与读取合并为单查询
|
|
206
205
|
const page = await prisma.designPage.findFirst({
|
|
207
206
|
where: { id: data.pageId, design: { userId } },
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
|
-
import {
|
|
23
|
-
import { assertDesignReadable, sessionUserId } from '@/server/design/access'
|
|
22
|
+
import { assertDesignReadable } from '@/server/design/access'
|
|
24
23
|
|
|
25
24
|
const upsertReviewSchema = z.object({
|
|
26
25
|
designId: z.string(),
|
|
@@ -30,11 +29,11 @@ const upsertReviewSchema = z.object({
|
|
|
30
29
|
})
|
|
31
30
|
|
|
32
31
|
export const upsertReviewFn = createServerFn({ method: 'POST' })
|
|
32
|
+
.middleware([authContextMiddleware])
|
|
33
33
|
.validator(upsertReviewSchema)
|
|
34
|
-
.handler(async ({ data }) => {
|
|
34
|
+
.handler(async ({ data, context }) => {
|
|
35
35
|
const prisma = await getPrisma()
|
|
36
|
-
const
|
|
37
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
36
|
+
const userId = context.user.id
|
|
38
37
|
// 审批由分享页评审面板发起(ShareReviewPanel):属主与通过门禁的分享访客(需登录)皆可评审,
|
|
39
38
|
// 不能收成属主专用;versionId 必须属于同一 design,否则可借他人 versionId 污染审批记录
|
|
40
39
|
await assertDesignReadable(data.designId, userId)
|
|
@@ -83,11 +82,11 @@ const getReviewSchema = z.object({
|
|
|
83
82
|
})
|
|
84
83
|
|
|
85
84
|
export const getReviewFn = createServerFn({ method: 'GET' })
|
|
85
|
+
.middleware([authContextMiddleware])
|
|
86
86
|
.validator(getReviewSchema)
|
|
87
|
-
.handler(async ({ data }) => {
|
|
87
|
+
.handler(async ({ data, context }) => {
|
|
88
88
|
const prisma = await getPrisma()
|
|
89
|
-
const
|
|
90
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
89
|
+
const userId = context.user.id
|
|
91
90
|
await assertDesignReadable(data.designId, userId)
|
|
92
91
|
|
|
93
92
|
const review = await prisma.review.findFirst({
|
|
@@ -16,25 +16,22 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
22
|
import type { Prisma } from '@allbluecn/database'
|
|
23
|
-
import { getServerSeam } from '@allbluecn/kernel'
|
|
24
23
|
import { notifyClients } from '@/lib/share-events'
|
|
25
24
|
import { verifyDesignOwner } from '@allbluecn/database/lib/share-utils'
|
|
26
|
-
import { sessionUserId } from '@/server/design/access'
|
|
27
25
|
import { generateSharePassword, hashSharePassword } from '@/server/design/share-generate'
|
|
28
26
|
|
|
29
27
|
export const setDesignSharePasswordFn = createServerFn({ method: 'POST' })
|
|
28
|
+
.middleware([authContextMiddleware])
|
|
30
29
|
.validator(z.object({ designId: z.string() }))
|
|
31
|
-
.handler(async ({ data }) => {
|
|
30
|
+
.handler(async ({ data, context }) => {
|
|
32
31
|
const prisma = await getPrisma()
|
|
33
|
-
const request = getRequest()
|
|
34
|
-
const session = await getServerSeam().requireAuth(request)
|
|
35
32
|
const { designId } = data
|
|
36
33
|
|
|
37
|
-
if (!(await verifyDesignOwner(designId,
|
|
34
|
+
if (!(await verifyDesignOwner(designId, context.user.id))) {
|
|
38
35
|
throw new Error("无权限")
|
|
39
36
|
}
|
|
40
37
|
|
|
@@ -65,14 +62,13 @@ export const setDesignSharePasswordFn = createServerFn({ method: 'POST' })
|
|
|
65
62
|
// 关闭密码仅置 hasPassword=false、password 列保留旧值(重开沿用旧密码)——
|
|
66
63
|
// 有意设计:shareGatePassed 以 hasPassword 为权威开关(见 @/server/design/share-access)
|
|
67
64
|
export const toggleDesignSharePasswordFn = createServerFn({ method: 'POST' })
|
|
65
|
+
.middleware([authContextMiddleware])
|
|
68
66
|
.validator(z.object({ designId: z.string(), enabled: z.boolean() }))
|
|
69
|
-
.handler(async ({ data }) => {
|
|
67
|
+
.handler(async ({ data, context }) => {
|
|
70
68
|
const prisma = await getPrisma()
|
|
71
|
-
const request = getRequest()
|
|
72
|
-
const session = await getServerSeam().requireAuth(request)
|
|
73
69
|
const { designId, enabled } = data
|
|
74
70
|
|
|
75
|
-
if (!(await verifyDesignOwner(designId,
|
|
71
|
+
if (!(await verifyDesignOwner(designId, context.user.id))) {
|
|
76
72
|
throw new Error("无权限")
|
|
77
73
|
}
|
|
78
74
|
|
|
@@ -110,11 +106,10 @@ export const toggleDesignSharePasswordFn = createServerFn({ method: 'POST' })
|
|
|
110
106
|
})
|
|
111
107
|
|
|
112
108
|
export const setDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
|
|
109
|
+
.middleware([authContextMiddleware])
|
|
113
110
|
.validator(z.object({ shareId: z.string() }))
|
|
114
|
-
.handler(async ({ data }) => {
|
|
111
|
+
.handler(async ({ data, context }) => {
|
|
115
112
|
const prisma = await getPrisma()
|
|
116
|
-
const request = getRequest()
|
|
117
|
-
const session = await getServerSeam().requireAuth(request)
|
|
118
113
|
const { shareId } = data
|
|
119
114
|
|
|
120
115
|
const share = await prisma.share.findUnique({
|
|
@@ -126,7 +121,7 @@ export const setDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
|
|
|
126
121
|
throw new Error("Share not found")
|
|
127
122
|
}
|
|
128
123
|
// IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
|
|
129
|
-
if (!(await verifyDesignOwner(share.designId,
|
|
124
|
+
if (!(await verifyDesignOwner(share.designId, context.user.id))) {
|
|
130
125
|
throw new Error("无权限")
|
|
131
126
|
}
|
|
132
127
|
|
|
@@ -156,11 +151,10 @@ export const setDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
|
|
|
156
151
|
})
|
|
157
152
|
|
|
158
153
|
export const toggleDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
|
|
154
|
+
.middleware([authContextMiddleware])
|
|
159
155
|
.validator(z.object({ shareId: z.string(), enabled: z.boolean() }))
|
|
160
|
-
.handler(async ({ data }) => {
|
|
156
|
+
.handler(async ({ data, context }) => {
|
|
161
157
|
const prisma = await getPrisma()
|
|
162
|
-
const request = getRequest()
|
|
163
|
-
const session = await getServerSeam().requireAuth(request)
|
|
164
158
|
const { shareId, enabled } = data
|
|
165
159
|
|
|
166
160
|
const share = await prisma.share.findUnique({
|
|
@@ -172,7 +166,7 @@ export const toggleDesignSingleSharePasswordFn = createServerFn({ method: 'POST'
|
|
|
172
166
|
throw new Error("Share not found")
|
|
173
167
|
}
|
|
174
168
|
// IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
|
|
175
|
-
if (!(await verifyDesignOwner(share.designId,
|
|
169
|
+
if (!(await verifyDesignOwner(share.designId, context.user.id))) {
|
|
176
170
|
throw new Error("无权限")
|
|
177
171
|
}
|
|
178
172
|
|
|
@@ -16,24 +16,21 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
22
|
import type { Prisma } from '@allbluecn/database'
|
|
23
|
-
import { getServerSeam } from '@allbluecn/kernel'
|
|
24
23
|
import { notifyClients } from '@/lib/share-events'
|
|
25
24
|
import { verifyDesignOwner } from '@allbluecn/database/lib/share-utils'
|
|
26
|
-
import { sessionUserId } from '@/server/design/access'
|
|
27
25
|
import { EXPIRY_DAYS, generateSharePassword, generateShareToken, hashSharePassword } from '@/server/design/share-generate'
|
|
28
26
|
|
|
29
27
|
export const listDesignSharesFn = createServerFn({ method: 'GET' })
|
|
28
|
+
.middleware([authContextMiddleware])
|
|
30
29
|
.validator(z.object({ designId: z.string() }))
|
|
31
|
-
.handler(async ({ data }) => {
|
|
30
|
+
.handler(async ({ data, context }) => {
|
|
32
31
|
const prisma = await getPrisma()
|
|
33
|
-
const request = getRequest()
|
|
34
|
-
const session = await getServerSeam().requireAuth(request)
|
|
35
32
|
|
|
36
|
-
if (!(await verifyDesignOwner(data.designId,
|
|
33
|
+
if (!(await verifyDesignOwner(data.designId, context.user.id))) {
|
|
37
34
|
throw new Error("无权限")
|
|
38
35
|
}
|
|
39
36
|
|
|
@@ -51,6 +48,7 @@ export const listDesignSharesFn = createServerFn({ method: 'GET' })
|
|
|
51
48
|
})
|
|
52
49
|
|
|
53
50
|
export const createDesignShareFn = createServerFn({ method: 'POST' })
|
|
51
|
+
.middleware([authContextMiddleware])
|
|
54
52
|
.validator(z.object({
|
|
55
53
|
designId: z.string(),
|
|
56
54
|
enabled: z.boolean().optional(),
|
|
@@ -58,13 +56,11 @@ export const createDesignShareFn = createServerFn({ method: 'POST' })
|
|
|
58
56
|
versionIds: z.array(z.string()).optional(),
|
|
59
57
|
expiryDays: z.string().optional(),
|
|
60
58
|
}))
|
|
61
|
-
.handler(async ({ data }) => {
|
|
59
|
+
.handler(async ({ data, context }) => {
|
|
62
60
|
const prisma = await getPrisma()
|
|
63
|
-
const request = getRequest()
|
|
64
|
-
const session = await getServerSeam().requireAuth(request)
|
|
65
61
|
const { designId, enabled, password, versionIds, expiryDays } = data
|
|
66
62
|
|
|
67
|
-
if (!(await verifyDesignOwner(designId,
|
|
63
|
+
if (!(await verifyDesignOwner(designId, context.user.id))) {
|
|
68
64
|
throw new Error("无权限")
|
|
69
65
|
}
|
|
70
66
|
|
|
@@ -147,18 +143,17 @@ export const createDesignShareFn = createServerFn({ method: 'POST' })
|
|
|
147
143
|
})
|
|
148
144
|
|
|
149
145
|
export const listDesignSingleSharesFn = createServerFn({ method: 'GET' })
|
|
146
|
+
.middleware([authContextMiddleware])
|
|
150
147
|
.validator(z.object({
|
|
151
148
|
designId: z.string(),
|
|
152
149
|
page: z.number().int().min(1).default(1),
|
|
153
150
|
pageSize: z.number().int().min(1).max(200).default(50),
|
|
154
151
|
}))
|
|
155
|
-
.handler(async ({ data }) => {
|
|
152
|
+
.handler(async ({ data, context }) => {
|
|
156
153
|
const prisma = await getPrisma()
|
|
157
|
-
const request = getRequest()
|
|
158
|
-
const session = await getServerSeam().requireAuth(request)
|
|
159
154
|
const { designId, page, pageSize } = data
|
|
160
155
|
|
|
161
|
-
if (!(await verifyDesignOwner(designId,
|
|
156
|
+
if (!(await verifyDesignOwner(designId, context.user.id))) {
|
|
162
157
|
throw new Error("无权限")
|
|
163
158
|
}
|
|
164
159
|
|
|
@@ -199,19 +194,18 @@ export const listDesignSingleSharesFn = createServerFn({ method: 'GET' })
|
|
|
199
194
|
})
|
|
200
195
|
|
|
201
196
|
export const createDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
197
|
+
.middleware([authContextMiddleware])
|
|
202
198
|
.validator(z.object({
|
|
203
199
|
designId: z.string(),
|
|
204
200
|
versionId: z.string(),
|
|
205
201
|
password: z.string().max(128).optional().nullable(),
|
|
206
202
|
expiryDays: z.string().optional(),
|
|
207
203
|
}))
|
|
208
|
-
.handler(async ({ data }) => {
|
|
204
|
+
.handler(async ({ data, context }) => {
|
|
209
205
|
const prisma = await getPrisma()
|
|
210
|
-
const request = getRequest()
|
|
211
|
-
const session = await getServerSeam().requireAuth(request)
|
|
212
206
|
const { designId, versionId, password, expiryDays } = data
|
|
213
207
|
|
|
214
|
-
if (!(await verifyDesignOwner(designId,
|
|
208
|
+
if (!(await verifyDesignOwner(designId, context.user.id))) {
|
|
215
209
|
throw new Error("无权限")
|
|
216
210
|
}
|
|
217
211
|
|
|
@@ -254,11 +248,10 @@ export const createDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
|
254
248
|
})
|
|
255
249
|
|
|
256
250
|
export const getDesignSingleShareFn = createServerFn({ method: 'GET' })
|
|
251
|
+
.middleware([authContextMiddleware])
|
|
257
252
|
.validator(z.object({ shareId: z.string() }))
|
|
258
|
-
.handler(async ({ data }) => {
|
|
253
|
+
.handler(async ({ data, context }) => {
|
|
259
254
|
const prisma = await getPrisma()
|
|
260
|
-
const request = getRequest()
|
|
261
|
-
const session = await getServerSeam().requireAuth(request)
|
|
262
255
|
const share = await prisma.share.findUnique({
|
|
263
256
|
where: { id: data.shareId },
|
|
264
257
|
})
|
|
@@ -266,7 +259,7 @@ export const getDesignSingleShareFn = createServerFn({ method: 'GET' })
|
|
|
266
259
|
throw new Error("Share not found")
|
|
267
260
|
}
|
|
268
261
|
// IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
|
|
269
|
-
if (!(await verifyDesignOwner(share.designId,
|
|
262
|
+
if (!(await verifyDesignOwner(share.designId, context.user.id))) {
|
|
270
263
|
throw new Error("无权限")
|
|
271
264
|
}
|
|
272
265
|
// 密码哈希化后不回传(见 getDesignShareFn 注)
|
|
@@ -274,15 +267,14 @@ export const getDesignSingleShareFn = createServerFn({ method: 'GET' })
|
|
|
274
267
|
})
|
|
275
268
|
|
|
276
269
|
export const updateDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
270
|
+
.middleware([authContextMiddleware])
|
|
277
271
|
.validator(z.object({
|
|
278
272
|
shareId: z.string(),
|
|
279
273
|
enabled: z.boolean().optional(),
|
|
280
274
|
expiryDays: z.string().optional(),
|
|
281
275
|
}))
|
|
282
|
-
.handler(async ({ data }) => {
|
|
276
|
+
.handler(async ({ data, context }) => {
|
|
283
277
|
const prisma = await getPrisma()
|
|
284
|
-
const request = getRequest()
|
|
285
|
-
const session = await getServerSeam().requireAuth(request)
|
|
286
278
|
const { shareId, enabled, expiryDays } = data
|
|
287
279
|
|
|
288
280
|
const share = await prisma.share.findUnique({
|
|
@@ -294,7 +286,7 @@ export const updateDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
|
294
286
|
throw new Error("Share not found")
|
|
295
287
|
}
|
|
296
288
|
// IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
|
|
297
|
-
if (!(await verifyDesignOwner(share.designId,
|
|
289
|
+
if (!(await verifyDesignOwner(share.designId, context.user.id))) {
|
|
298
290
|
throw new Error("无权限")
|
|
299
291
|
}
|
|
300
292
|
|
|
@@ -340,11 +332,10 @@ export const updateDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
|
340
332
|
})
|
|
341
333
|
|
|
342
334
|
export const deleteDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
335
|
+
.middleware([authContextMiddleware])
|
|
343
336
|
.validator(z.object({ shareId: z.string() }))
|
|
344
|
-
.handler(async ({ data }) => {
|
|
337
|
+
.handler(async ({ data, context }) => {
|
|
345
338
|
const prisma = await getPrisma()
|
|
346
|
-
const request = getRequest()
|
|
347
|
-
const session = await getServerSeam().requireAuth(request)
|
|
348
339
|
const { shareId } = data
|
|
349
340
|
|
|
350
341
|
const share = await prisma.share.findUnique({
|
|
@@ -356,7 +347,7 @@ export const deleteDesignSingleShareFn = createServerFn({ method: 'POST' })
|
|
|
356
347
|
throw new Error("Share not found")
|
|
357
348
|
}
|
|
358
349
|
// IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
|
|
359
|
-
if (!(await verifyDesignOwner(share.designId,
|
|
350
|
+
if (!(await verifyDesignOwner(share.designId, context.user.id))) {
|
|
360
351
|
throw new Error("无权限")
|
|
361
352
|
}
|
|
362
353
|
|
|
@@ -16,22 +16,21 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
|
-
import {
|
|
23
|
-
import { assertDesignOwner, sessionUserId } from '@/server/design/access'
|
|
22
|
+
import { assertDesignOwner } from '@/server/design/access'
|
|
24
23
|
import { sortSnapshotsByTree, type DesignPage } from '@/lib/design-tree-utils'
|
|
25
24
|
|
|
26
25
|
export const listDesignVersionsFn = createServerFn({ method: 'GET' })
|
|
26
|
+
.middleware([authContextMiddleware])
|
|
27
27
|
.validator(z.object({
|
|
28
28
|
designId: z.string(),
|
|
29
29
|
take: z.number().int().min(1).max(200).default(50),
|
|
30
30
|
}))
|
|
31
|
-
.handler(async ({ data }) => {
|
|
31
|
+
.handler(async ({ data, context }) => {
|
|
32
32
|
const prisma = await getPrisma()
|
|
33
|
-
const
|
|
34
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
33
|
+
const userId = context.user.id
|
|
35
34
|
await assertDesignOwner(data.designId, userId)
|
|
36
35
|
|
|
37
36
|
const versions = await prisma.designVersion.findMany({
|
|
@@ -66,6 +65,7 @@ export const listDesignVersionsFn = createServerFn({ method: 'GET' })
|
|
|
66
65
|
// 调用方(页面还原走 executeRestoreVersion → updateDesignPageFn + createDesignPageVersionFn),
|
|
67
66
|
// 且允许以自传 JSON 覆盖任意 pageId 的 canvas/content(审计 2026-10-25 🔴),整段移除。
|
|
68
67
|
export const createDesignVersionFn = createServerFn({ method: 'POST' })
|
|
68
|
+
.middleware([authContextMiddleware])
|
|
69
69
|
.validator(z.object({
|
|
70
70
|
designId: z.string(),
|
|
71
71
|
major: z.number().int().min(0),
|
|
@@ -75,10 +75,9 @@ export const createDesignVersionFn = createServerFn({ method: 'POST' })
|
|
|
75
75
|
pageIds: z.array(z.string()),
|
|
76
76
|
selectedPageVersions: z.record(z.string(), z.number().int()).optional(),
|
|
77
77
|
}))
|
|
78
|
-
.handler(async ({ data }) => {
|
|
78
|
+
.handler(async ({ data, context }) => {
|
|
79
79
|
const prisma = await getPrisma()
|
|
80
|
-
const
|
|
81
|
-
const userId = sessionUserId(await getServerSeam().requireAuth(request))
|
|
80
|
+
const userId = context.user.id
|
|
82
81
|
const { designId, major, minor, patch, notes, pageIds, selectedPageVersions } = data
|
|
83
82
|
await assertDesignOwner(designId, userId)
|
|
84
83
|
|