@vertesia/ui 1.5.0-dev.20260725.083715Z → 1.5.0-dev.20260806.125520Z
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/lib/core/components/ComboBox.d.ts.map +1 -1
- package/lib/core/components/ComboBox.js +4 -4
- package/lib/core/components/ComboBox.js.map +1 -1
- package/lib/core/components/FileUpload.js.map +1 -1
- package/lib/core/components/MenuList.d.ts +2 -1
- package/lib/core/components/MenuList.d.ts.map +1 -1
- package/lib/core/components/TagsInput.js +1 -1
- package/lib/core/components/popup/PopupController.d.ts.map +1 -1
- package/lib/core/components/popup/PopupController.js.map +1 -1
- package/lib/core/components/popup/position.js.map +1 -1
- package/lib/core/components/popup/utils.js.map +1 -1
- package/lib/core/components/shadcn/LanguageSwitcher.js.map +1 -1
- package/lib/core/components/shadcn/MessageBox.js.map +1 -1
- package/lib/core/components/shadcn/Panel.js +1 -1
- package/lib/core/components/shadcn/badge.d.ts +2 -2
- package/lib/core/components/shadcn/button.d.ts +2 -2
- package/lib/core/components/shadcn/button.js +1 -1
- package/lib/core/components/shadcn/command.d.ts +4 -4
- package/lib/core/components/shadcn/command.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/DynamicLabel.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/SelectCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/SelectCombobox.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/StringListCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/TextCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filter/dateFilter.js +1 -1
- package/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filters.js.map +1 -1
- package/lib/core/components/shadcn/input.d.ts +2 -2
- package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
- package/lib/core/components/shadcn/popover.d.ts +1 -1
- package/lib/core/components/shadcn/popover.d.ts.map +1 -1
- package/lib/core/components/shadcn/popover.js.map +1 -1
- package/lib/core/components/shadcn/radioGroup.d.ts.map +1 -1
- package/lib/core/components/shadcn/selectBox.js +1 -1
- package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/core/components/shadcn/tabs.js +1 -1
- package/lib/core/components/shadcn/text.d.ts +2 -2
- package/lib/core/components/shadcn/theme/ThemeSwitcher.js.map +1 -1
- package/lib/core/components/toast/ToastProvider.js +1 -1
- package/lib/core/hooks/CompositeState.d.ts +1 -1
- package/lib/core/hooks/CompositeState.d.ts.map +1 -1
- package/lib/core/hooks/CompositeState.js.map +1 -1
- package/lib/core/hooks/SharedState.d.ts.map +1 -1
- package/lib/core/hooks/useFetch.d.ts.map +1 -1
- package/lib/core/hooks/useFetch.js +2 -1
- package/lib/core/hooks/useFetch.js.map +1 -1
- package/lib/core/hooks/useFlag.d.ts.map +1 -1
- package/lib/core/hooks/useIntersectionObserver.js.map +1 -1
- package/lib/core/hooks/useSafeLayoutEffect.d.ts +2 -2
- package/lib/core/hooks/useSafeLayoutEffect.d.ts.map +1 -1
- package/lib/core/hooks/useScrollableSearch.d.ts +1 -1
- package/lib/core/hooks/useScrollableSearch.d.ts.map +1 -1
- package/lib/core/hooks/useScrollableSearch.js +15 -2
- package/lib/core/hooks/useScrollableSearch.js.map +1 -1
- package/lib/core/hooks/useSharedValue.d.ts.map +1 -1
- package/lib/core/hooks/useSharedValue.js.map +1 -1
- package/lib/core/utils/a11y.d.ts.map +1 -1
- package/lib/env/index.d.ts +4 -0
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.js +3 -8
- package/lib/features/agent/chat/AgentRequestInputOverlay.js.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.js +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +1 -1
- package/lib/features/agent/chat/DocumentEditingActionCard.js +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +8 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +79 -20
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +25 -10
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +25 -10
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +7 -0
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +40 -3
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +8 -0
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts +9 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +97 -2
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
- package/lib/features/agent/chat/SlidingThinkingIndicator.js +1 -1
- package/lib/features/agent/chat/VegaLiteChart.js +1 -1
- package/lib/features/agent/chat/VegaLiteChart.js.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.js +38 -3
- package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
- package/lib/features/agent/chat/hooks/useFileProcessing.d.ts +8 -1
- package/lib/features/agent/chat/hooks/useFileProcessing.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useFileProcessing.js +31 -2
- package/lib/features/agent/chat/hooks/useFileProcessing.js.map +1 -1
- package/lib/features/agent/chat/index.d.ts +1 -1
- package/lib/features/agent/chat/index.d.ts.map +1 -1
- package/lib/features/agent/chat/index.js.map +1 -1
- package/lib/features/agent/chat/useArtifactUrlCache.js.map +1 -1
- package/lib/features/agent/chat/workstreams.d.ts +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.d.ts +8 -6
- package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.js +8 -3
- package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
- package/lib/features/facets/RunsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
- package/lib/features/magic-pdf/GroundedExtractionView.js +1 -1
- package/lib/features/magic-pdf/MagicPdfProvider.d.ts.map +1 -1
- package/lib/features/magic-pdf/MagicPdfProvider.js.map +1 -1
- package/lib/features/oauth/McpConnectionsButton.js +1 -1
- package/lib/features/oauth/OAuthProviderConnectButton.js +1 -1
- package/lib/features/oauth/RemoteMcpConnectionButton.js +1 -1
- package/lib/features/pdf-viewer/PdfPageRenderer.js +1 -1
- package/lib/features/pdf-viewer/PdfPageSlider.js +1 -1
- package/lib/features/permissions/UserPermissionsProvider.d.ts.map +1 -1
- package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
- package/lib/features/store/collections/CollectionsTable.js +2 -2
- package/lib/features/store/collections/CollectionsTable.js.map +1 -1
- package/lib/features/store/collections/CreateCollection.js +1 -1
- package/lib/features/store/collections/EditCollectionView.js +1 -1
- package/lib/features/store/objects/DocumentQuickFilter.js +1 -1
- package/lib/features/store/objects/DocumentSelectionProvider.d.ts.map +1 -1
- package/lib/features/store/objects/DocumentSelectionProvider.js.map +1 -1
- package/lib/features/store/objects/components/ContentDispositionButton.d.ts +2 -1
- package/lib/features/store/objects/components/ContentDispositionButton.d.ts.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +5 -2
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/components/DocumentEditingPanel.js +1 -1
- package/lib/features/store/objects/components/PropertiesEditorModal.js +1 -1
- package/lib/features/store/objects/components/TextEditorPanel.js +1 -1
- package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts +31 -3
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.d.ts +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
- package/lib/features/store/objects/layout/documentLayout.js +1 -1
- package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts +129 -7
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.js.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContext.d.ts +2 -2
- package/lib/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContextClass.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContextClass.js.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionSpec.d.ts +2 -2
- package/lib/features/store/objects/selection/ObjectsActionSpec.d.ts.map +1 -1
- package/lib/features/store/objects/selection/SelectionActions.d.ts +2 -2
- package/lib/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
- package/lib/features/store/objects/selection/SelectionActions.js +1 -1
- package/lib/features/store/objects/selection/actions/ConfirmAction.js +1 -1
- package/lib/features/store/objects/selection/actions/DeleteObjectsAction.js +1 -1
- package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.js +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
- package/lib/features/store/objects/upload/useUploadHandler.d.ts.map +1 -1
- package/lib/features/store/types/ContentObjectTypesSearch.js +1 -1
- package/lib/features/store/types/IntakePolicyEditor.d.ts +2 -2
- package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.js +6 -2
- package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.js +2 -2
- package/lib/features/store/types/IntakePolicyForm.js.map +1 -1
- package/lib/features/store/types/ObjectSchemaEditor.d.ts +2 -2
- package/lib/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentType.d.ts +2 -2
- package/lib/features/store/types/SelectContentType.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentType.js.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.d.ts +2 -2
- package/lib/features/store/types/SelectContentTypeModal.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
- package/lib/features/store/types/TableLayoutEditor.d.ts +2 -2
- package/lib/features/store/types/TableLayoutEditor.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.d.ts +1267 -6
- package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.js +5 -0
- package/lib/features/store/types/TypeRegistry.js.map +1 -1
- package/lib/features/store/types/intake-policy-editor.logic.d.ts +9 -1
- package/lib/features/store/types/intake-policy-editor.logic.d.ts.map +1 -1
- package/lib/features/store/types/intake-policy-editor.logic.js +9 -1
- package/lib/features/store/types/intake-policy-editor.logic.js.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +1252 -2
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.js.map +1 -1
- package/lib/features/store/types/typeCatalogCache.d.ts +2 -2
- package/lib/features/store/types/typeCatalogCache.d.ts.map +1 -1
- package/lib/features/store/types/typeCatalogCache.js +4 -0
- package/lib/features/store/types/typeCatalogCache.js.map +1 -1
- package/lib/features/user/UserInfo.d.ts +118 -7
- package/lib/features/user/UserInfo.d.ts.map +1 -1
- package/lib/features/user/UserInfo.js +1 -1
- package/lib/features/user/UserInfo.js.map +1 -1
- package/lib/features/utils/mimeType.d.ts.map +1 -1
- package/lib/features/utils/rendition.js.map +1 -1
- package/lib/features/utils/text.js.map +1 -1
- package/lib/i18n/locales/ar.json +27 -1
- package/lib/i18n/locales/de.json +27 -1
- package/lib/i18n/locales/en.json +30 -1
- package/lib/i18n/locales/es.json +27 -1
- package/lib/i18n/locales/fr.json +27 -1
- package/lib/i18n/locales/it.json +27 -1
- package/lib/i18n/locales/ja.json +27 -1
- package/lib/i18n/locales/ko.json +27 -1
- package/lib/i18n/locales/pt.json +27 -1
- package/lib/i18n/locales/ru.json +27 -1
- package/lib/i18n/locales/tr.json +27 -1
- package/lib/i18n/locales/zh-TW.json +27 -1
- package/lib/i18n/locales/zh.json +27 -1
- package/lib/i18n/rtl.d.ts +1 -1
- package/lib/i18n/rtl.d.ts.map +1 -1
- package/lib/layout/FullHeightLayout.d.ts +7 -6
- package/lib/layout/FullHeightLayout.d.ts.map +1 -1
- package/lib/layout/Sidebar.d.ts +1 -1
- package/lib/layout/Sidebar.js +1 -1
- package/lib/rich-text/EditorToolbar.js +1 -1
- package/lib/router/HistoryNavigator.d.ts +2 -2
- package/lib/router/HistoryNavigator.d.ts.map +1 -1
- package/lib/router/HistoryNavigator.js.map +1 -1
- package/lib/router/PathMatcher.d.ts.map +1 -1
- package/lib/router/PathMatcher.js.map +1 -1
- package/lib/router/PathWithParams.d.ts.map +1 -1
- package/lib/router/Redirect.js.map +1 -1
- package/lib/router/Route404.js +1 -1
- package/lib/router/Router.d.ts.map +1 -1
- package/lib/router/Router.js.map +1 -1
- package/lib/session/UserSession.d.ts +18 -4
- package/lib/session/UserSession.d.ts.map +1 -1
- package/lib/session/UserSession.js.map +1 -1
- package/lib/session/UserSessionProvider.d.ts +2 -0
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +81 -53
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/composable.d.ts +49 -1
- package/lib/session/auth/composable.d.ts.map +1 -1
- package/lib/session/auth/composable.js +179 -53
- package/lib/session/auth/composable.js.map +1 -1
- package/lib/shell/VertesiaShell.js +1 -1
- package/lib/shell/apps/AppInstallationProvider.d.ts +230 -2
- package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
- package/lib/shell/apps/AppProjectSelector.js +1 -1
- package/lib/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/shell/login/SignInEmailStep.js +1 -1
- package/lib/shell/login/SignInPrimitives.d.ts +21 -20
- package/lib/shell/login/SignInPrimitives.d.ts.map +1 -1
- package/lib/shell/login/SignInPrimitives.js.map +1 -1
- package/lib/shell/login/SignInRecoveryStep.d.ts +22 -0
- package/lib/shell/login/SignInRecoveryStep.d.ts.map +1 -0
- package/lib/shell/login/SignInRecoveryStep.js +59 -0
- package/lib/shell/login/SignInRecoveryStep.js.map +1 -0
- package/lib/shell/login/SigninScreen.d.ts.map +1 -1
- package/lib/shell/login/SigninScreen.js +84 -11
- package/lib/shell/login/SigninScreen.js.map +1 -1
- package/lib/shell/login/SignupForm.js +1 -1
- package/lib/shell/login/TerminalLogin.js +1 -1
- package/lib/shell/login/UserSessionMenu.js +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +34 -34
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +13 -13
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js.map +1 -1
- package/lib/vertesia-ui-router.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js +1 -1
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +18 -18
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/form/FormContext.d.ts.map +1 -1
- package/lib/widgets/form/FormContext.js.map +1 -1
- package/lib/widgets/form/ManagedObject.d.ts +2 -2
- package/lib/widgets/form/ManagedObject.d.ts.map +1 -1
- package/lib/widgets/form/ManagedObject.js.map +1 -1
- package/lib/widgets/form/schema.d.ts.map +1 -1
- package/lib/widgets/form/schema.js.map +1 -1
- package/lib/widgets/json-view/JSONCode.js +1 -1
- package/lib/widgets/json-view/JSONTable.js +1 -1
- package/lib/widgets/markdown/ArtifactContentRenderer.js.map +1 -1
- package/lib/widgets/markdown/CodeBlockPlaceholder.d.ts +1 -1
- package/lib/widgets/markdown/CodeBlockPlaceholder.d.ts.map +1 -1
- package/lib/widgets/markdown/CodeBlockPlaceholder.js +1 -1
- package/lib/widgets/markdown/CodeBlockRendering.d.ts.map +1 -1
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +1 -1
- package/lib/widgets/markdown/remarkDirectiveHandler.d.ts.map +1 -1
- package/lib/widgets/markdown/textDiff.js.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts +7 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.js +62 -6
- package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
- package/lib/widgets/schema-editor/ManagedSchema.d.ts.map +1 -1
- package/lib/widgets/schema-editor/editor/PropertyEditor.js +1 -1
- package/lib/widgets/schema-editor/json-schema4-utils.js.map +1 -1
- package/lib/widgets/xml-viewer/components/Elements/index.js +1 -1
- package/lib/widgets/xml-viewer/components/Tag/index.js +1 -1
- package/lib/widgets/xml-viewer/constants/index.d.ts.map +1 -1
- package/lib/widgets/xml-viewer/helpers/index.d.ts +1 -1
- package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
- package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts.map +1 -1
- package/package.json +33 -33
- package/src/core/hooks/useFetch.ts +2 -1
- package/src/core/hooks/useScrollableSearch.test.tsx +139 -0
- package/src/core/hooks/useScrollableSearch.tsx +17 -3
- package/src/env/index.ts +2 -0
- package/src/features/agent/chat/AgentChatPlaybackControls.test.tsx +2 -0
- package/src/features/agent/chat/AgentRequestInputOverlay.test.tsx +51 -6
- package/src/features/agent/chat/AgentRequestInputOverlay.tsx +5 -7
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +208 -3
- package/src/features/agent/chat/ModernAgentConversation.tsx +130 -25
- package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +75 -20
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +112 -0
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +62 -10
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.test.ts +38 -0
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +62 -4
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +2 -2
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.test.tsx +71 -0
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +3 -1
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +18 -4
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +9 -0
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +95 -0
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +111 -1
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +21 -0
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +172 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +38 -3
- package/src/features/agent/chat/hooks/useFileProcessing.test.tsx +87 -0
- package/src/features/agent/chat/hooks/useFileProcessing.ts +32 -1
- package/src/features/agent/chat/index.ts +1 -0
- package/src/features/facets/PromptsFacetsNav.tsx +17 -9
- package/src/features/store/collections/CollectionsTable.tsx +1 -1
- package/src/features/store/objects/components/ContentOverview.tsx +4 -1
- package/src/features/store/objects/selection/ObjectsActionContext.tsx +2 -2
- package/src/features/store/objects/selection/ObjectsActionSpec.ts +2 -2
- package/src/features/store/objects/selection/SelectionActions.tsx +2 -2
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +2 -2
- package/src/features/store/types/IntakePolicyEditor.tsx +12 -4
- package/src/features/store/types/IntakePolicyForm.tsx +25 -0
- package/src/features/store/types/ObjectSchemaEditor.tsx +2 -2
- package/src/features/store/types/SelectContentType.tsx +9 -9
- package/src/features/store/types/SelectContentTypeModal.tsx +5 -5
- package/src/features/store/types/TableLayoutEditor.tsx +2 -2
- package/src/features/store/types/TypeRegistry.ts +8 -3
- package/src/features/store/types/intake-policy-editor.logic.ts +10 -2
- package/src/features/store/types/typeCatalogCache.ts +10 -3
- package/src/i18n/locales/ar.json +27 -1
- package/src/i18n/locales/de.json +27 -1
- package/src/i18n/locales/en.json +30 -1
- package/src/i18n/locales/es.json +27 -1
- package/src/i18n/locales/fr.json +27 -1
- package/src/i18n/locales/it.json +27 -1
- package/src/i18n/locales/ja.json +27 -1
- package/src/i18n/locales/ko.json +27 -1
- package/src/i18n/locales/pt.json +27 -1
- package/src/i18n/locales/ru.json +27 -1
- package/src/i18n/locales/tr.json +27 -1
- package/src/i18n/locales/zh-TW.json +27 -1
- package/src/i18n/locales/zh.json +27 -1
- package/src/session/UserSessionProvider.test.ts +69 -0
- package/src/session/UserSessionProvider.tsx +96 -60
- package/src/session/auth/composable.scope.test.ts +88 -0
- package/src/session/auth/composable.test.ts +205 -0
- package/src/session/auth/composable.ts +227 -58
- package/src/shell/login/InviteAcceptModal.tsx +4 -4
- package/src/shell/login/SignInPrimitives.tsx +1 -0
- package/src/shell/login/SignInRecoveryStep.test.tsx +112 -0
- package/src/shell/login/SignInRecoveryStep.tsx +177 -0
- package/src/shell/login/SigninScreen.tsx +145 -27
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +13 -9
- package/src/widgets/monacoEditor/MonacoEditor.tsx +83 -7
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"agent.rewind.jumpToLatest": "跳到最新訊息",
|
|
161
161
|
"agent.rewind.jumpToLive": "跳到即時",
|
|
162
162
|
"agent.rewind.jumpToStart": "跳到第一則訊息",
|
|
163
|
-
"agent.rewind.label": "
|
|
163
|
+
"agent.rewind.label": "偵錯",
|
|
164
164
|
"agent.rewind.nextMessage": "下一則訊息",
|
|
165
165
|
"agent.rewind.pause": "暫停",
|
|
166
166
|
"agent.rewind.positionInput": "播放位置",
|
|
@@ -192,6 +192,7 @@
|
|
|
192
192
|
"agent.summary": "摘要",
|
|
193
193
|
"agent.taskProgress": "任務進度",
|
|
194
194
|
"agent.tasksCompleted": "{{completed}}/{{total}} 已完成",
|
|
195
|
+
"agent.thinking": "思考中...",
|
|
195
196
|
"agent.timeout": "已逾時",
|
|
196
197
|
"agent.toggleRightSidebar": "切換右側邊欄",
|
|
197
198
|
"agent.typeYourMessage": "輸入訊息...",
|
|
@@ -243,6 +244,31 @@
|
|
|
243
244
|
"auth.providers.bodyConsumer": "請從下方提供者中選擇一個繼續。",
|
|
244
245
|
"auth.providers.eyebrow": "選擇登入方式",
|
|
245
246
|
"auth.providers.title": "再一步",
|
|
247
|
+
"auth.recovery.continue": "繼續前往 Vertesia",
|
|
248
|
+
"auth.recovery.credential.body": "無法驗證您的登入資訊。請重新登入以繼續。",
|
|
249
|
+
"auth.recovery.credential.eyebrow": "需要登入",
|
|
250
|
+
"auth.recovery.credential.title": "無法驗證您的登入資訊",
|
|
251
|
+
"auth.recovery.errorCode": "錯誤代碼",
|
|
252
|
+
"auth.recovery.errorMessage": "錯誤訊息",
|
|
253
|
+
"auth.recovery.httpStatus": "HTTP 狀態",
|
|
254
|
+
"auth.recovery.noAccessibleAccount.body": "您已登入,但此身分沒有可用的 Vertesia 帳戶。",
|
|
255
|
+
"auth.recovery.noAccessibleAccount.eyebrow": "需要帳戶",
|
|
256
|
+
"auth.recovery.noAccessibleAccount.title": "沒有可用帳戶",
|
|
257
|
+
"auth.recovery.requestedAccount": "要求的帳戶",
|
|
258
|
+
"auth.recovery.requestedProject": "要求的專案",
|
|
259
|
+
"auth.recovery.scopeAccount.body": "您已登入,但此連結中的帳戶無法使用。連結可能已過期,或您沒有存取權限。",
|
|
260
|
+
"auth.recovery.scopeAccount.eyebrow": "連結無法使用",
|
|
261
|
+
"auth.recovery.scopeAccount.title": "帳戶無法使用",
|
|
262
|
+
"auth.recovery.scopeProject.body": "您已登入,但此連結中的專案無法使用。連結可能已過期,或您沒有存取權限。",
|
|
263
|
+
"auth.recovery.scopeProject.eyebrow": "連結無法使用",
|
|
264
|
+
"auth.recovery.scopeProject.title": "專案無法使用",
|
|
265
|
+
"auth.recovery.service.body": "驗證服務暫時無法使用。請重試或使用其他帳戶。",
|
|
266
|
+
"auth.recovery.service.eyebrow": "服務無法使用",
|
|
267
|
+
"auth.recovery.service.title": "無法完成登入",
|
|
268
|
+
"auth.recovery.supportPrefix": "如需協助,請聯絡",
|
|
269
|
+
"auth.recovery.technicalDetails": "技術詳細資料",
|
|
270
|
+
"auth.recovery.tryAgain": "重試",
|
|
271
|
+
"auth.recovery.useDifferentAccount": "使用其他帳戶",
|
|
246
272
|
"auth.restricted.autoRedirect": "{{seconds}} 秒後前往主網站…",
|
|
247
273
|
"auth.restricted.body": "本網站僅限擁有新功能和修復搶先體驗權限的使用者使用。請繼續前往主網站,或就此網站的搶先體驗事宜聯絡 Vertesia。",
|
|
248
274
|
"auth.restricted.calloutMeta": "聯絡 Vertesia 取得搶先體驗權限",
|
package/src/i18n/locales/zh.json
CHANGED
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"agent.rewind.jumpToLatest": "跳到最新消息",
|
|
161
161
|
"agent.rewind.jumpToLive": "跳到实时",
|
|
162
162
|
"agent.rewind.jumpToStart": "跳到第一条消息",
|
|
163
|
-
"agent.rewind.label": "
|
|
163
|
+
"agent.rewind.label": "调试",
|
|
164
164
|
"agent.rewind.nextMessage": "下一条消息",
|
|
165
165
|
"agent.rewind.pause": "暂停",
|
|
166
166
|
"agent.rewind.positionInput": "播放位置",
|
|
@@ -192,6 +192,7 @@
|
|
|
192
192
|
"agent.summary": "摘要",
|
|
193
193
|
"agent.taskProgress": "任务进度",
|
|
194
194
|
"agent.tasksCompleted": "{{completed}}/{{total}} 已完成",
|
|
195
|
+
"agent.thinking": "思考中...",
|
|
195
196
|
"agent.timeout": "已超时",
|
|
196
197
|
"agent.toggleRightSidebar": "切换右侧边栏",
|
|
197
198
|
"agent.typeYourMessage": "输入消息...",
|
|
@@ -243,6 +244,31 @@
|
|
|
243
244
|
"auth.providers.bodyConsumer": "请从下方提供商中选择一个继续。",
|
|
244
245
|
"auth.providers.eyebrow": "选择登录方式",
|
|
245
246
|
"auth.providers.title": "再一步",
|
|
247
|
+
"auth.recovery.continue": "继续前往 Vertesia",
|
|
248
|
+
"auth.recovery.credential.body": "无法验证您的登录信息。请重新登录以继续。",
|
|
249
|
+
"auth.recovery.credential.eyebrow": "需要登录",
|
|
250
|
+
"auth.recovery.credential.title": "无法验证您的登录信息",
|
|
251
|
+
"auth.recovery.errorCode": "错误代码",
|
|
252
|
+
"auth.recovery.errorMessage": "错误消息",
|
|
253
|
+
"auth.recovery.httpStatus": "HTTP 状态",
|
|
254
|
+
"auth.recovery.noAccessibleAccount.body": "您已登录,但此身份没有可用的 Vertesia 账户。",
|
|
255
|
+
"auth.recovery.noAccessibleAccount.eyebrow": "需要账户",
|
|
256
|
+
"auth.recovery.noAccessibleAccount.title": "没有可用账户",
|
|
257
|
+
"auth.recovery.requestedAccount": "请求的账户",
|
|
258
|
+
"auth.recovery.requestedProject": "请求的项目",
|
|
259
|
+
"auth.recovery.scopeAccount.body": "您已登录,但此链接中的账户不可用。链接可能已过期,或者您没有访问权限。",
|
|
260
|
+
"auth.recovery.scopeAccount.eyebrow": "链接不可用",
|
|
261
|
+
"auth.recovery.scopeAccount.title": "账户不可用",
|
|
262
|
+
"auth.recovery.scopeProject.body": "您已登录,但此链接中的项目不可用。链接可能已过期,或者您没有访问权限。",
|
|
263
|
+
"auth.recovery.scopeProject.eyebrow": "链接不可用",
|
|
264
|
+
"auth.recovery.scopeProject.title": "项目不可用",
|
|
265
|
+
"auth.recovery.service.body": "身份验证服务暂时不可用。请重试或使用其他账户。",
|
|
266
|
+
"auth.recovery.service.eyebrow": "服务不可用",
|
|
267
|
+
"auth.recovery.service.title": "无法完成登录",
|
|
268
|
+
"auth.recovery.supportPrefix": "如需帮助,请联系",
|
|
269
|
+
"auth.recovery.technicalDetails": "技术详情",
|
|
270
|
+
"auth.recovery.tryAgain": "重试",
|
|
271
|
+
"auth.recovery.useDifferentAccount": "使用其他账户",
|
|
246
272
|
"auth.restricted.autoRedirect": "{{seconds}} 秒后前往主站点…",
|
|
247
273
|
"auth.restricted.body": "本站点仅限拥有新功能和修复抢先体验权限的用户使用。请继续前往主站点,或就此站点的抢先体验事宜联系 Vertesia。",
|
|
248
274
|
"auth.restricted.calloutMeta": "联系 Vertesia 获取抢先体验权限",
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { RequestedScopeUnavailableError } from './auth/composable';
|
|
3
|
+
import { sanitizeRejectedScopeUrl } from './UserSessionProvider';
|
|
4
|
+
|
|
5
|
+
describe('sanitizeRejectedScopeUrl', () => {
|
|
6
|
+
it.each([
|
|
7
|
+
{
|
|
8
|
+
name: 'an account/project pair',
|
|
9
|
+
input: 'https://app.example.test/studio/dashboard?a=apple&p=banana&tab=runs',
|
|
10
|
+
accountId: 'apple',
|
|
11
|
+
projectId: 'banana',
|
|
12
|
+
expected: 'https://app.example.test/studio/dashboard?tab=runs',
|
|
13
|
+
scope: 'project',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'a project-only selector',
|
|
17
|
+
input: 'https://app.example.test/studio/dashboard?p=banana&tab=runs',
|
|
18
|
+
accountId: undefined,
|
|
19
|
+
projectId: 'banana',
|
|
20
|
+
expected: 'https://app.example.test/studio/dashboard?tab=runs',
|
|
21
|
+
scope: 'project',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'an account-only selector',
|
|
25
|
+
input: 'https://app.example.test/studio/dashboard?a=apple&tab=runs',
|
|
26
|
+
accountId: 'apple',
|
|
27
|
+
projectId: undefined,
|
|
28
|
+
expected: 'https://app.example.test/studio/dashboard?tab=runs',
|
|
29
|
+
scope: 'account',
|
|
30
|
+
},
|
|
31
|
+
])('removes $name while preserving the path and unrelated parameters', (testCase) => {
|
|
32
|
+
const error = new RequestedScopeUnavailableError(
|
|
33
|
+
'https://sts.example.test',
|
|
34
|
+
testCase.accountId,
|
|
35
|
+
testCase.projectId,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const result = sanitizeRejectedScopeUrl(new URL(testCase.input), error);
|
|
39
|
+
|
|
40
|
+
expect(result.toString()).toBe(testCase.expected);
|
|
41
|
+
expect(error.recoveryUrl).toBe(testCase.expected);
|
|
42
|
+
expect(error.requestedScope).toBe(testCase.scope);
|
|
43
|
+
expect(error.selectorSource).toBe('url');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('clears central-auth state while preserving unrelated query parameters', () => {
|
|
47
|
+
const error = new RequestedScopeUnavailableError('https://sts.example.test', 'apple', 'banana');
|
|
48
|
+
|
|
49
|
+
const result = sanitizeRejectedScopeUrl(
|
|
50
|
+
new URL('https://app.example.test/deep/path?a=apple&p=banana&view=grid#token=secret&state=opaque'),
|
|
51
|
+
error,
|
|
52
|
+
true,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
expect(result.toString()).toBe('https://app.example.test/deep/path?view=grid');
|
|
56
|
+
expect(error.recoveryUrl).not.toContain('secret');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('marks a matching persisted-only selection without removing unrelated URL state', () => {
|
|
60
|
+
const error = new RequestedScopeUnavailableError('https://sts.example.test', 'stored-a', 'stored-p');
|
|
61
|
+
const input = new URL('https://app.example.test/deep/path?view=grid');
|
|
62
|
+
|
|
63
|
+
const result = sanitizeRejectedScopeUrl(input, error);
|
|
64
|
+
|
|
65
|
+
expect(result.toString()).toBe(input.toString());
|
|
66
|
+
expect(error.selectorSource).toBe('persisted');
|
|
67
|
+
expect(error.requestedScope).toBe('project');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import { REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE } from '@vertesia/common';
|
|
1
2
|
import { Env } from '@vertesia/ui/env';
|
|
2
3
|
import { onAuthStateChanged } from 'firebase/auth';
|
|
3
4
|
import { type ReactNode, useEffect, useRef, useState } from 'react';
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AuthenticationServiceError,
|
|
7
|
+
CredentialError,
|
|
8
|
+
getComposableToken,
|
|
9
|
+
NoAccessibleAccountError,
|
|
10
|
+
RequestedScopeUnavailableError,
|
|
11
|
+
RestrictedEnvironmentError,
|
|
12
|
+
resolveAuthSelection,
|
|
13
|
+
UserNotFoundError,
|
|
14
|
+
} from './auth/composable';
|
|
5
15
|
import { authReturnUrl, shouldRedirectToCentralAuth } from './auth/domainRouting';
|
|
6
16
|
import { getFirebaseAuth } from './auth/firebase';
|
|
7
17
|
import { useAuthState } from './auth/useAuthState';
|
|
8
|
-
import {
|
|
18
|
+
import { UserSession, UserSessionContext } from './UserSession';
|
|
9
19
|
|
|
10
20
|
const CENTRAL_AUTH_REDIRECT = 'https://internal-auth.vertesia.app/';
|
|
11
21
|
|
|
@@ -15,6 +25,38 @@ function clearAuthHash() {
|
|
|
15
25
|
window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}`);
|
|
16
26
|
}
|
|
17
27
|
|
|
28
|
+
export function sanitizeRejectedScopeUrl(
|
|
29
|
+
currentUrl: URL,
|
|
30
|
+
error: RequestedScopeUnavailableError,
|
|
31
|
+
clearHash = false,
|
|
32
|
+
): URL {
|
|
33
|
+
const sanitizedUrl = new URL(currentUrl);
|
|
34
|
+
const urlAccountId = sanitizedUrl.searchParams.get('a') ?? undefined;
|
|
35
|
+
const urlProjectId = sanitizedUrl.searchParams.get('p') ?? undefined;
|
|
36
|
+
|
|
37
|
+
if (urlAccountId && urlProjectId && urlAccountId === error.accountId && urlProjectId === error.projectId) {
|
|
38
|
+
sanitizedUrl.searchParams.delete('a');
|
|
39
|
+
sanitizedUrl.searchParams.delete('p');
|
|
40
|
+
error.requestedScope = 'project';
|
|
41
|
+
error.selectorSource = 'url';
|
|
42
|
+
} else if (urlProjectId && urlProjectId === error.projectId) {
|
|
43
|
+
sanitizedUrl.searchParams.delete('p');
|
|
44
|
+
error.requestedScope = 'project';
|
|
45
|
+
error.selectorSource = 'url';
|
|
46
|
+
} else if (urlAccountId && urlAccountId === error.accountId) {
|
|
47
|
+
sanitizedUrl.searchParams.delete('a');
|
|
48
|
+
error.requestedScope = 'account';
|
|
49
|
+
error.selectorSource = 'url';
|
|
50
|
+
} else {
|
|
51
|
+
error.requestedScope = error.projectId ? 'project' : 'account';
|
|
52
|
+
error.selectorSource = 'persisted';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (clearHash) sanitizedUrl.hash = '';
|
|
56
|
+
error.recoveryUrl = sanitizedUrl.toString();
|
|
57
|
+
return sanitizedUrl;
|
|
58
|
+
}
|
|
59
|
+
|
|
18
60
|
interface UserSessionProviderProps {
|
|
19
61
|
children: ReactNode | ReactNode[];
|
|
20
62
|
loadOnboardingStatus?: boolean;
|
|
@@ -28,6 +70,46 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
28
70
|
const hasInitiatedAuthRef = useRef(false);
|
|
29
71
|
const authFlowRef = useRef<(() => undefined | (() => void)) | undefined>(undefined);
|
|
30
72
|
|
|
73
|
+
const clearRejectedUrlScope = (error: RequestedScopeUnavailableError, clearHash = false) => {
|
|
74
|
+
const sanitizedUrl = sanitizeRejectedScopeUrl(new URL(window.location.href), error, clearHash);
|
|
75
|
+
window.history.replaceState(window.history.state, '', sanitizedUrl);
|
|
76
|
+
Env.logger.warn('Sanitized an unavailable authentication scope', {
|
|
77
|
+
vertesia: {
|
|
78
|
+
account_id: error.accountId,
|
|
79
|
+
project_id: error.projectId,
|
|
80
|
+
error_code: REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE,
|
|
81
|
+
selector_source: error.selectorSource,
|
|
82
|
+
requested_scope: error.requestedScope,
|
|
83
|
+
recovery_action: 'url_sanitized',
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const surfaceAuthError = (error: unknown, clearHash = false): boolean => {
|
|
89
|
+
if (
|
|
90
|
+
!(
|
|
91
|
+
error instanceof RequestedScopeUnavailableError ||
|
|
92
|
+
error instanceof NoAccessibleAccountError ||
|
|
93
|
+
error instanceof CredentialError ||
|
|
94
|
+
error instanceof AuthenticationServiceError ||
|
|
95
|
+
error instanceof UserNotFoundError ||
|
|
96
|
+
error instanceof RestrictedEnvironmentError
|
|
97
|
+
)
|
|
98
|
+
) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (error instanceof RequestedScopeUnavailableError) {
|
|
103
|
+
clearRejectedUrlScope(error, clearHash);
|
|
104
|
+
} else if (clearHash) {
|
|
105
|
+
clearAuthHash();
|
|
106
|
+
}
|
|
107
|
+
session.isLoading = false;
|
|
108
|
+
session.authError = error;
|
|
109
|
+
setSession(session.clone());
|
|
110
|
+
return true;
|
|
111
|
+
};
|
|
112
|
+
|
|
31
113
|
const redirectToCentralAuth = (projectId?: string, accountId?: string) => {
|
|
32
114
|
const url = new URL(`${CENTRAL_AUTH_REDIRECT}?sts=${Env.endpoints.sts ?? 'https://sts.vertesia.io'}`);
|
|
33
115
|
const currentUrl = authReturnUrl();
|
|
@@ -49,12 +131,7 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
49
131
|
console.log('Auth: starting auth flow');
|
|
50
132
|
Env.logger.info('Starting auth flow');
|
|
51
133
|
const currentUrl = new URL(window.location.href);
|
|
52
|
-
const selectedAccount =
|
|
53
|
-
currentUrl.searchParams.get('a') ?? localStorage.getItem(LastSelectedAccountId_KEY) ?? undefined;
|
|
54
|
-
const selectedProject =
|
|
55
|
-
currentUrl.searchParams.get('p') ??
|
|
56
|
-
localStorage.getItem(`${LastSelectedProjectId_KEY}-${selectedAccount}`) ??
|
|
57
|
-
undefined;
|
|
134
|
+
const { accountId: selectedAccount, projectId: selectedProject } = resolveAuthSelection(currentUrl);
|
|
58
135
|
console.log('Auth: selected account', selectedAccount);
|
|
59
136
|
console.log('Auth: selected project', selectedProject);
|
|
60
137
|
Env.logger.info('Selected account and project', {
|
|
@@ -71,6 +148,7 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
71
148
|
session.login(res.rawToken).then(() => setSession(session.clone()));
|
|
72
149
|
})
|
|
73
150
|
.catch((err) => {
|
|
151
|
+
if (surfaceAuthError(err)) return;
|
|
74
152
|
console.error('Failed to initialize dev auth token', err);
|
|
75
153
|
Env.logger.error('Failed to initialize dev auth token', {
|
|
76
154
|
vertesia: {
|
|
@@ -108,44 +186,7 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
108
186
|
});
|
|
109
187
|
})
|
|
110
188
|
.catch((err) => {
|
|
111
|
-
|
|
112
|
-
if (err instanceof UserNotFoundError) {
|
|
113
|
-
console.log('User not found - will trigger signup flow', err);
|
|
114
|
-
session.isLoading = false;
|
|
115
|
-
session.authError = err;
|
|
116
|
-
setSession(session.clone());
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Restricted environment (preview/preprod without early-access): surface the
|
|
121
|
-
// error so the sign-in screen shows the dedicated step. Redirecting to central
|
|
122
|
-
// auth here would loop, since the identity is valid but the environment is gated.
|
|
123
|
-
if (err instanceof RestrictedEnvironmentError) {
|
|
124
|
-
console.warn('Restricted environment - user lacks early-access', err);
|
|
125
|
-
session.isLoading = false;
|
|
126
|
-
session.authError = err;
|
|
127
|
-
setSession(session.clone());
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (err instanceof STSError) {
|
|
132
|
-
console.error('STS error during token exchange', err);
|
|
133
|
-
Env.logger.error('STS error during token exchange', {
|
|
134
|
-
vertesia: {
|
|
135
|
-
account_id: selectedAccount,
|
|
136
|
-
project_id: selectedProject,
|
|
137
|
-
sts_url: err.stsURL,
|
|
138
|
-
error: err,
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
window.alert(
|
|
142
|
-
'Authentication failed due to an issue with the authentication service. Please try again later.',
|
|
143
|
-
);
|
|
144
|
-
session.logout();
|
|
145
|
-
setSession(session.clone());
|
|
146
|
-
clearAuthHash();
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
189
|
+
if (surfaceAuthError(err, true)) return;
|
|
149
190
|
|
|
150
191
|
console.error('Failed to fetch user token from studio, redirecting to central auth', err);
|
|
151
192
|
Env.logger.error('Failed to fetch user token from studio, redirecting to central auth', {
|
|
@@ -221,20 +262,12 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
221
262
|
.then(() => setSession(session.clone()));
|
|
222
263
|
})
|
|
223
264
|
.catch((err) => {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
project_id: selectedProject,
|
|
229
|
-
error: err,
|
|
230
|
-
},
|
|
265
|
+
if (surfaceAuthError(err)) return;
|
|
266
|
+
console.error('Unexpected failure while fetching a user token', err);
|
|
267
|
+
Env.logger.error('Unexpected failure while fetching a user token', {
|
|
268
|
+
vertesia: { account_id: selectedAccount, project_id: selectedProject, error: err },
|
|
231
269
|
});
|
|
232
|
-
|
|
233
|
-
// RestrictedEnvironmentError (identity is valid; the environment is gated).
|
|
234
|
-
// Logging out would retrigger onAuthStateChanged and clear the authError.
|
|
235
|
-
if (!(err instanceof UserNotFoundError) && !(err instanceof RestrictedEnvironmentError)) {
|
|
236
|
-
session.logout();
|
|
237
|
-
}
|
|
270
|
+
session.logout();
|
|
238
271
|
session.isLoading = false;
|
|
239
272
|
session.authError = err;
|
|
240
273
|
setSession(session.clone());
|
|
@@ -274,6 +307,7 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
274
307
|
if (!cancelled) setSession(session.clone());
|
|
275
308
|
})
|
|
276
309
|
.catch((err: unknown) => {
|
|
310
|
+
if (surfaceAuthError(err)) return;
|
|
277
311
|
console.warn('Auth: failed to initialize injected auth token', err);
|
|
278
312
|
Env.logger.warn('Failed to initialize injected auth token', {
|
|
279
313
|
vertesia: {
|
|
@@ -282,7 +316,9 @@ export function UserSessionProvider({ children, loadOnboardingStatus = true }: U
|
|
|
282
316
|
error: err,
|
|
283
317
|
},
|
|
284
318
|
});
|
|
285
|
-
|
|
319
|
+
session.isLoading = false;
|
|
320
|
+
session.authError = err instanceof Error ? err : new Error(String(err));
|
|
321
|
+
setSession(session.clone());
|
|
286
322
|
});
|
|
287
323
|
return () => {
|
|
288
324
|
cancelled = true;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
const logger = { info: vi.fn(), warn: vi.fn(), error: vi.fn() };
|
|
5
|
+
|
|
6
|
+
vi.mock('@vertesia/ui/env', () => ({
|
|
7
|
+
Env: {
|
|
8
|
+
endpoints: { sts: 'https://sts.test', studio: 'https://studio.test' },
|
|
9
|
+
logger,
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
vi.mock('./firebase', () => ({
|
|
14
|
+
getFirebaseAuth: () => ({ currentUser: null }),
|
|
15
|
+
getFirebaseAuthToken: vi.fn(),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
function unsignedJwt(payload: Record<string, unknown>): string {
|
|
19
|
+
const encode = (value: string) => btoa(value).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
20
|
+
return `${encode(JSON.stringify({ alg: 'none', typ: 'JWT' }))}.${encode(JSON.stringify(payload))}.signature`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('getComposableToken scope cache', () => {
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
vi.resetModules();
|
|
27
|
+
localStorage.clear();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('does not reuse a valid token from another project', async () => {
|
|
31
|
+
const accountId = 'account-1';
|
|
32
|
+
const projectA = 'project-a';
|
|
33
|
+
const projectB = 'project-b';
|
|
34
|
+
const expiry = Math.floor(Date.now() / 1000) + 3600;
|
|
35
|
+
const token = (project: string) =>
|
|
36
|
+
unsignedJwt({ exp: expiry, account: { id: accountId }, project: { id: project } });
|
|
37
|
+
const response = (project: string) => new Response(JSON.stringify({ token: token(project) }), { status: 200 });
|
|
38
|
+
const fetchMock = vi
|
|
39
|
+
.spyOn(globalThis, 'fetch')
|
|
40
|
+
.mockResolvedValueOnce(response(projectA))
|
|
41
|
+
.mockResolvedValueOnce(response(projectB));
|
|
42
|
+
|
|
43
|
+
const { getComposableToken } = await import('./composable');
|
|
44
|
+
const first = await getComposableToken(accountId, projectA, 'central-auth-credential', true);
|
|
45
|
+
const second = await getComposableToken(accountId, projectB, 'central-auth-credential');
|
|
46
|
+
|
|
47
|
+
expect(first.token.project?.id).toBe(projectA);
|
|
48
|
+
expect(second.token.project?.id).toBe(projectB);
|
|
49
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('reuses a valid project token for an account-scoped request in the same account', async () => {
|
|
53
|
+
const accountId = 'account-1';
|
|
54
|
+
const projectId = 'project-a';
|
|
55
|
+
const expiry = Math.floor(Date.now() / 1000) + 3600;
|
|
56
|
+
const token = unsignedJwt({ exp: expiry, account: { id: accountId }, project: { id: projectId } });
|
|
57
|
+
const fetchMock = vi
|
|
58
|
+
.spyOn(globalThis, 'fetch')
|
|
59
|
+
.mockResolvedValueOnce(new Response(JSON.stringify({ token }), { status: 200 }));
|
|
60
|
+
|
|
61
|
+
const { getComposableToken } = await import('./composable');
|
|
62
|
+
await getComposableToken(accountId, projectId, 'central-auth-credential', true);
|
|
63
|
+
const accountScoped = await getComposableToken(accountId);
|
|
64
|
+
|
|
65
|
+
expect(accountScoped.token.project?.id).toBe(projectId);
|
|
66
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('reuses a valid token for a global request', async () => {
|
|
70
|
+
const expiry = Math.floor(Date.now() / 1000) + 3600;
|
|
71
|
+
const token = unsignedJwt({
|
|
72
|
+
exp: expiry,
|
|
73
|
+
account: { id: 'account-1' },
|
|
74
|
+
project: { id: 'project-a' },
|
|
75
|
+
});
|
|
76
|
+
const fetchMock = vi
|
|
77
|
+
.spyOn(globalThis, 'fetch')
|
|
78
|
+
.mockResolvedValueOnce(new Response(JSON.stringify({ token }), { status: 200 }));
|
|
79
|
+
|
|
80
|
+
const { getComposableToken } = await import('./composable');
|
|
81
|
+
await getComposableToken('account-1', 'project-a', 'central-auth-credential', true);
|
|
82
|
+
const global = await getComposableToken();
|
|
83
|
+
|
|
84
|
+
expect(global.token.account.id).toBe('account-1');
|
|
85
|
+
expect(global.token.project?.id).toBe('project-a');
|
|
86
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
87
|
+
});
|
|
88
|
+
});
|