@vertesia/ui 1.5.0-dev.20260804.124748Z → 1.5.0-dev.20260807.073259Z
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.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.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/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.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +26 -3
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +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 +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 +25 -0
- 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/InlineSlidingPlanPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.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/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 +26 -0
- 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/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.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 +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 +2 -2
- 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 +25 -25
- 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/ObjectsActionContextClass.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContextClass.js.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/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.js +1 -1
- package/lib/features/store/types/TypeRegistry.d.ts +240 -180
- package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.js.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +239 -179
- 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/user/UserInfo.d.ts +14 -14
- 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 +25 -0
- package/lib/i18n/locales/de.json +25 -0
- package/lib/i18n/locales/en.json +25 -0
- package/lib/i18n/locales/es.json +25 -0
- package/lib/i18n/locales/fr.json +25 -0
- package/lib/i18n/locales/it.json +25 -0
- package/lib/i18n/locales/ja.json +25 -0
- package/lib/i18n/locales/ko.json +25 -0
- package/lib/i18n/locales/pt.json +25 -0
- package/lib/i18n/locales/ru.json +25 -0
- package/lib/i18n/locales/tr.json +25 -0
- package/lib/i18n/locales/zh-TW.json +25 -0
- package/lib/i18n/locales/zh.json +25 -0
- 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 +1 -1
- 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 +58 -50
- package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
- package/lib/shell/apps/AppProjectSelector.js +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.map +1 -1
- package/lib/vertesia-ui-features.js +26 -26
- 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.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.map +1 -1
- 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 +11 -11
- package/src/core/hooks/useFetch.ts +2 -1
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +13 -0
- package/src/features/agent/chat/ModernAgentConversation.tsx +24 -3
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.test.ts +38 -0
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +26 -0
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +9 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +21 -0
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +116 -1
- package/src/features/agent/chat/hooks/useAgentStream.ts +26 -0
- package/src/features/agent/chat/hooks/useFileProcessing.test.tsx +87 -0
- package/src/features/agent/chat/hooks/useFileProcessing.ts +32 -1
- package/src/features/store/collections/CollectionsTable.tsx +1 -1
- package/src/i18n/locales/ar.json +25 -0
- package/src/i18n/locales/de.json +25 -0
- package/src/i18n/locales/en.json +25 -0
- package/src/i18n/locales/es.json +25 -0
- package/src/i18n/locales/fr.json +25 -0
- package/src/i18n/locales/it.json +25 -0
- package/src/i18n/locales/ja.json +25 -0
- package/src/i18n/locales/ko.json +25 -0
- package/src/i18n/locales/pt.json +25 -0
- package/src/i18n/locales/ru.json +25 -0
- package/src/i18n/locales/tr.json +25 -0
- package/src/i18n/locales/zh-TW.json +25 -0
- package/src/i18n/locales/zh.json +25 -0
- 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/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
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
2
|
+
import { AlertTriangle } from 'lucide-react';
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import {
|
|
5
|
+
SignInAccountRow,
|
|
6
|
+
SignInIconBadge,
|
|
7
|
+
SignInInitialsBadge,
|
|
8
|
+
SignInStepButton,
|
|
9
|
+
SignInStepHeader,
|
|
10
|
+
SignInStepLayout,
|
|
11
|
+
} from './SignInPrimitives';
|
|
12
|
+
import { emailInitial, firstNameFromEmail } from './signInUtils';
|
|
13
|
+
|
|
14
|
+
export type SignInRecoveryKind = 'scopeProject' | 'scopeAccount' | 'noAccessibleAccount' | 'credential' | 'service';
|
|
15
|
+
|
|
16
|
+
export interface SignInRecoveryDetails {
|
|
17
|
+
accountId?: string;
|
|
18
|
+
errorCode?: string;
|
|
19
|
+
message: string;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
status?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SignInRecoveryIdentity {
|
|
25
|
+
email: string;
|
|
26
|
+
name?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface SignInRecoveryStepProps {
|
|
30
|
+
details?: SignInRecoveryDetails;
|
|
31
|
+
identity?: SignInRecoveryIdentity;
|
|
32
|
+
kind: SignInRecoveryKind;
|
|
33
|
+
onContinue?: () => void;
|
|
34
|
+
onUseDifferentAccount: () => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default function SignInRecoveryStep({
|
|
38
|
+
details,
|
|
39
|
+
identity,
|
|
40
|
+
kind,
|
|
41
|
+
onContinue,
|
|
42
|
+
onUseDifferentAccount,
|
|
43
|
+
}: SignInRecoveryStepProps) {
|
|
44
|
+
const { t } = useUITranslation();
|
|
45
|
+
const [submitting, setSubmitting] = useState(false);
|
|
46
|
+
const initialButtonRef = useRef<HTMLButtonElement>(null);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
initialButtonRef.current?.focus();
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const isScopeFailure = kind === 'scopeProject' || kind === 'scopeAccount';
|
|
53
|
+
let copy: { eyebrow: string; title: string; body: string };
|
|
54
|
+
if (kind === 'scopeProject') {
|
|
55
|
+
copy = {
|
|
56
|
+
eyebrow: t('auth.recovery.scopeProject.eyebrow'),
|
|
57
|
+
title: t('auth.recovery.scopeProject.title'),
|
|
58
|
+
body: t('auth.recovery.scopeProject.body'),
|
|
59
|
+
};
|
|
60
|
+
} else if (kind === 'scopeAccount') {
|
|
61
|
+
copy = {
|
|
62
|
+
eyebrow: t('auth.recovery.scopeAccount.eyebrow'),
|
|
63
|
+
title: t('auth.recovery.scopeAccount.title'),
|
|
64
|
+
body: t('auth.recovery.scopeAccount.body'),
|
|
65
|
+
};
|
|
66
|
+
} else if (kind === 'noAccessibleAccount') {
|
|
67
|
+
copy = {
|
|
68
|
+
eyebrow: t('auth.recovery.noAccessibleAccount.eyebrow'),
|
|
69
|
+
title: t('auth.recovery.noAccessibleAccount.title'),
|
|
70
|
+
body: t('auth.recovery.noAccessibleAccount.body'),
|
|
71
|
+
};
|
|
72
|
+
} else if (kind === 'credential') {
|
|
73
|
+
copy = {
|
|
74
|
+
eyebrow: t('auth.recovery.credential.eyebrow'),
|
|
75
|
+
title: t('auth.recovery.credential.title'),
|
|
76
|
+
body: t('auth.recovery.credential.body'),
|
|
77
|
+
};
|
|
78
|
+
} else {
|
|
79
|
+
copy = {
|
|
80
|
+
eyebrow: t('auth.recovery.service.eyebrow'),
|
|
81
|
+
title: t('auth.recovery.service.title'),
|
|
82
|
+
body: t('auth.recovery.service.body'),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const runAction = (action: () => void) => {
|
|
87
|
+
if (submitting) return;
|
|
88
|
+
setSubmitting(true);
|
|
89
|
+
action();
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<SignInStepLayout>
|
|
94
|
+
<div role="alert" aria-live="assertive">
|
|
95
|
+
<SignInIconBadge>
|
|
96
|
+
<AlertTriangle className="size-7 text-attention" aria-hidden="true" />
|
|
97
|
+
</SignInIconBadge>
|
|
98
|
+
<SignInStepHeader eyebrow={copy.eyebrow} title={copy.title} body={copy.body} />
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
{identity && (
|
|
102
|
+
<SignInAccountRow
|
|
103
|
+
badge={<SignInInitialsBadge initials={emailInitial(identity.email)} />}
|
|
104
|
+
title={identity.name || firstNameFromEmail(identity.email)}
|
|
105
|
+
subtitle={identity.email}
|
|
106
|
+
actionLabel={t('auth.returning.notYou')}
|
|
107
|
+
onAction={onUseDifferentAccount}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
110
|
+
|
|
111
|
+
<div className="flex flex-col gap-2">
|
|
112
|
+
{onContinue && (
|
|
113
|
+
<SignInStepButton
|
|
114
|
+
ref={initialButtonRef}
|
|
115
|
+
className="w-full"
|
|
116
|
+
disabled={submitting}
|
|
117
|
+
onClick={() => runAction(onContinue)}
|
|
118
|
+
>
|
|
119
|
+
{isScopeFailure ? t('auth.recovery.continue') : t('auth.recovery.tryAgain')}
|
|
120
|
+
</SignInStepButton>
|
|
121
|
+
)}
|
|
122
|
+
<SignInStepButton
|
|
123
|
+
ref={onContinue ? undefined : initialButtonRef}
|
|
124
|
+
variant={onContinue ? 'ghost' : 'primary'}
|
|
125
|
+
disabled={submitting}
|
|
126
|
+
onClick={() => runAction(onUseDifferentAccount)}
|
|
127
|
+
>
|
|
128
|
+
{t('auth.recovery.useDifferentAccount')}
|
|
129
|
+
</SignInStepButton>
|
|
130
|
+
{(kind === 'noAccessibleAccount' || kind === 'service') && (
|
|
131
|
+
<p className="text-center text-xs text-muted">
|
|
132
|
+
{t('auth.recovery.supportPrefix')}{' '}
|
|
133
|
+
<a className="text-info" href="mailto:support@vertesiahq.com">
|
|
134
|
+
support@vertesiahq.com
|
|
135
|
+
</a>
|
|
136
|
+
</p>
|
|
137
|
+
)}
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
{details && (
|
|
141
|
+
<details className="rounded-lg border border-mixer-muted/30 bg-mixer-muted/10 px-4 py-3 text-sm">
|
|
142
|
+
<summary className="cursor-pointer font-medium text-muted marker:text-muted focus-visible:outline-2 focus-visible:outline-offset-2">
|
|
143
|
+
{t('auth.recovery.technicalDetails')}
|
|
144
|
+
</summary>
|
|
145
|
+
<dl className="mt-3 grid grid-cols-[max-content_minmax(0,1fr)] gap-x-3 gap-y-2 text-xs">
|
|
146
|
+
{details.errorCode && (
|
|
147
|
+
<>
|
|
148
|
+
<dt className="text-muted">{t('auth.recovery.errorCode')}</dt>
|
|
149
|
+
<dd className="wrap-break-word font-mono">{details.errorCode}</dd>
|
|
150
|
+
</>
|
|
151
|
+
)}
|
|
152
|
+
{details.status && (
|
|
153
|
+
<>
|
|
154
|
+
<dt className="text-muted">{t('auth.recovery.httpStatus')}</dt>
|
|
155
|
+
<dd className="font-mono">{details.status}</dd>
|
|
156
|
+
</>
|
|
157
|
+
)}
|
|
158
|
+
{details.accountId && (
|
|
159
|
+
<>
|
|
160
|
+
<dt className="text-muted">{t('auth.recovery.requestedAccount')}</dt>
|
|
161
|
+
<dd className="wrap-break-word font-mono">{details.accountId}</dd>
|
|
162
|
+
</>
|
|
163
|
+
)}
|
|
164
|
+
{details.projectId && (
|
|
165
|
+
<>
|
|
166
|
+
<dt className="text-muted">{t('auth.recovery.requestedProject')}</dt>
|
|
167
|
+
<dd className="wrap-break-word font-mono">{details.projectId}</dd>
|
|
168
|
+
</>
|
|
169
|
+
)}
|
|
170
|
+
<dt className="text-muted">{t('auth.recovery.errorMessage')}</dt>
|
|
171
|
+
<dd className="wrap-break-word font-mono">{details.message}</dd>
|
|
172
|
+
</dl>
|
|
173
|
+
</details>
|
|
174
|
+
)}
|
|
175
|
+
</SignInStepLayout>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE, type SignupData, type SignupPayload } from '@vertesia/common';
|
|
2
2
|
import { Env } from '@vertesia/ui/env';
|
|
3
3
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
4
4
|
import { RegionTag } from '@vertesia/ui/layout';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AuthenticationServiceError,
|
|
7
|
+
CredentialError,
|
|
8
|
+
NoAccessibleAccountError,
|
|
9
|
+
RequestedScopeUnavailableError,
|
|
10
|
+
RestrictedEnvironmentError,
|
|
11
|
+
UserNotFoundError,
|
|
12
|
+
useUserSession,
|
|
13
|
+
useUXTracking,
|
|
14
|
+
} from '@vertesia/ui/session';
|
|
6
15
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
16
|
import SignInAuthPending from './SignInAuthPending';
|
|
8
17
|
import SignInEmailStep, { type TenantInfo } from './SignInEmailStep';
|
|
9
18
|
import SignInProvidersStep from './SignInProvidersStep';
|
|
19
|
+
import SignInRecoveryStep, { type SignInRecoveryKind } from './SignInRecoveryStep';
|
|
10
20
|
import SignInRestrictedEnvStep from './SignInRestrictedEnvStep';
|
|
11
21
|
import SignInReturningStep from './SignInReturningStep';
|
|
12
22
|
import SignInTenantBlockedStep from './SignInTenantBlockedStep';
|
|
@@ -65,7 +75,30 @@ function matchesPathPrefix(pathname: string, prefix?: string | string[]) {
|
|
|
65
75
|
});
|
|
66
76
|
}
|
|
67
77
|
|
|
68
|
-
type Mode =
|
|
78
|
+
type Mode =
|
|
79
|
+
| 'email'
|
|
80
|
+
| 'providers'
|
|
81
|
+
| 'tenant'
|
|
82
|
+
| 'blocked'
|
|
83
|
+
| 'returning'
|
|
84
|
+
| 'pending'
|
|
85
|
+
| 'signup'
|
|
86
|
+
| 'restricted'
|
|
87
|
+
| 'scopeUnavailable'
|
|
88
|
+
| 'noAccessibleAccount'
|
|
89
|
+
| 'credentialFailure'
|
|
90
|
+
| 'serviceFailure';
|
|
91
|
+
|
|
92
|
+
function isDedicatedAuthError(error: Error): boolean {
|
|
93
|
+
return (
|
|
94
|
+
error instanceof UserNotFoundError ||
|
|
95
|
+
error instanceof RestrictedEnvironmentError ||
|
|
96
|
+
error instanceof RequestedScopeUnavailableError ||
|
|
97
|
+
error instanceof NoAccessibleAccountError ||
|
|
98
|
+
error instanceof CredentialError ||
|
|
99
|
+
error instanceof AuthenticationServiceError
|
|
100
|
+
);
|
|
101
|
+
}
|
|
69
102
|
|
|
70
103
|
function SigninScreenImpl({
|
|
71
104
|
isNested = false,
|
|
@@ -87,8 +120,20 @@ function SigninScreenImpl({
|
|
|
87
120
|
const [tenant, setTenant] = useState<TenantInfo | undefined>(undefined);
|
|
88
121
|
const [pendingProvider, setPendingProvider] = useState<ProviderId | null>(null);
|
|
89
122
|
|
|
123
|
+
const recoveryIdentity =
|
|
124
|
+
authError instanceof RequestedScopeUnavailableError || authError instanceof NoAccessibleAccountError
|
|
125
|
+
? authError.identity
|
|
126
|
+
: undefined;
|
|
127
|
+
const matchingStoredIdentity =
|
|
128
|
+
recoveryIdentity && storedSession?.email.toLowerCase() === recoveryIdentity.email.toLowerCase()
|
|
129
|
+
? storedSession
|
|
130
|
+
: undefined;
|
|
131
|
+
const displayedRecoveryIdentity = recoveryIdentity
|
|
132
|
+
? { email: recoveryIdentity.email, name: recoveryIdentity.name ?? matchingStoredIdentity?.name }
|
|
133
|
+
: undefined;
|
|
134
|
+
|
|
90
135
|
useEffect(() => {
|
|
91
|
-
if (!preservePath) {
|
|
136
|
+
if (!preservePath && !isLoading && !authError) {
|
|
92
137
|
// Reset to the app's mount root, not the bare origin. A gateway-mounted app carries a
|
|
93
138
|
// served `<base href>` deep mount; collapsing to '/' drops the app off that mount (the
|
|
94
139
|
// bare origin serves no app) and the address bar can no longer be reloaded. This effect
|
|
@@ -99,7 +144,7 @@ function SigninScreenImpl({
|
|
|
99
144
|
const mountRoot = new URL(document.baseURI).pathname || '/';
|
|
100
145
|
history.replaceState({}, '', mountRoot);
|
|
101
146
|
}
|
|
102
|
-
}, [preservePath]);
|
|
147
|
+
}, [authError, isLoading, preservePath]);
|
|
103
148
|
|
|
104
149
|
// Route based on authError surfaced by the session.
|
|
105
150
|
useEffect(() => {
|
|
@@ -108,6 +153,14 @@ function SigninScreenImpl({
|
|
|
108
153
|
setMode('signup');
|
|
109
154
|
} else if (authError instanceof RestrictedEnvironmentError) {
|
|
110
155
|
setMode('restricted');
|
|
156
|
+
} else if (authError instanceof RequestedScopeUnavailableError) {
|
|
157
|
+
setMode('scopeUnavailable');
|
|
158
|
+
} else if (authError instanceof NoAccessibleAccountError) {
|
|
159
|
+
setMode('noAccessibleAccount');
|
|
160
|
+
} else if (authError instanceof CredentialError) {
|
|
161
|
+
setMode('credentialFailure');
|
|
162
|
+
} else if (authError instanceof AuthenticationServiceError) {
|
|
163
|
+
setMode('serviceFailure');
|
|
111
164
|
} else if (isInviteRequiredError(authError)) {
|
|
112
165
|
const pending = readPendingSignin();
|
|
113
166
|
if (pending) setEmail(pending.email);
|
|
@@ -176,6 +229,37 @@ function SigninScreenImpl({
|
|
|
176
229
|
void resetSignInState();
|
|
177
230
|
}, []);
|
|
178
231
|
|
|
232
|
+
const useDifferentAccount = useCallback(() => {
|
|
233
|
+
Env.logger.info('Authentication recovery action selected', {
|
|
234
|
+
vertesia: { recovery_action: 'use_different_account' },
|
|
235
|
+
});
|
|
236
|
+
setStoredSession(null);
|
|
237
|
+
setEmail('');
|
|
238
|
+
setTenant(undefined);
|
|
239
|
+
setMode('email');
|
|
240
|
+
void resetSignInState().finally(() => signOut());
|
|
241
|
+
}, [signOut]);
|
|
242
|
+
|
|
243
|
+
const continueWithSanitizedScope = useCallback(() => {
|
|
244
|
+
if (!(authError instanceof RequestedScopeUnavailableError)) return;
|
|
245
|
+
Env.logger.info('Authentication recovery action selected', {
|
|
246
|
+
vertesia: {
|
|
247
|
+
error_code: REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE,
|
|
248
|
+
selector_source: authError.selectorSource,
|
|
249
|
+
requested_scope: authError.requestedScope,
|
|
250
|
+
recovery_action: 'continue_sanitized',
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
window.location.replace(authError.recoveryUrl ?? window.location.href);
|
|
254
|
+
}, [authError]);
|
|
255
|
+
|
|
256
|
+
const retryAuthentication = useCallback(() => {
|
|
257
|
+
Env.logger.info('Authentication recovery action selected', {
|
|
258
|
+
vertesia: { recovery_action: 'retry' },
|
|
259
|
+
});
|
|
260
|
+
window.location.reload();
|
|
261
|
+
}, []);
|
|
262
|
+
|
|
179
263
|
// Submits the signup form to /auth/signup, then redirects into the app.
|
|
180
264
|
const onSignup = (data: SignupData, fbToken: string) => {
|
|
181
265
|
const payload: SignupPayload = { signupData: data, firebaseToken: fbToken };
|
|
@@ -190,10 +274,7 @@ function SigninScreenImpl({
|
|
|
190
274
|
};
|
|
191
275
|
|
|
192
276
|
const shouldHideTransientAuthError =
|
|
193
|
-
suppressAuthError &&
|
|
194
|
-
authError !== undefined &&
|
|
195
|
-
!(authError instanceof UserNotFoundError) &&
|
|
196
|
-
!(authError instanceof RestrictedEnvironmentError);
|
|
277
|
+
suppressAuthError && authError !== undefined && !isDedicatedAuthError(authError);
|
|
197
278
|
|
|
198
279
|
if (isLoading || user || shouldHideTransientAuthError) return null;
|
|
199
280
|
|
|
@@ -210,6 +291,49 @@ function SigninScreenImpl({
|
|
|
210
291
|
);
|
|
211
292
|
} else if (mode === 'restricted') {
|
|
212
293
|
content = <SignInRestrictedEnvStep onUseDifferentEmail={startOver} />;
|
|
294
|
+
} else if (mode === 'scopeUnavailable' && authError instanceof RequestedScopeUnavailableError) {
|
|
295
|
+
const kind: SignInRecoveryKind = authError.requestedScope === 'project' ? 'scopeProject' : 'scopeAccount';
|
|
296
|
+
content = (
|
|
297
|
+
<SignInRecoveryStep
|
|
298
|
+
details={{
|
|
299
|
+
accountId: authError.accountId,
|
|
300
|
+
errorCode: authError.errorCode,
|
|
301
|
+
message: authError.message,
|
|
302
|
+
projectId: authError.projectId,
|
|
303
|
+
status: authError.status,
|
|
304
|
+
}}
|
|
305
|
+
identity={displayedRecoveryIdentity}
|
|
306
|
+
kind={kind}
|
|
307
|
+
onContinue={continueWithSanitizedScope}
|
|
308
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
309
|
+
/>
|
|
310
|
+
);
|
|
311
|
+
} else if (mode === 'noAccessibleAccount' && authError instanceof NoAccessibleAccountError) {
|
|
312
|
+
content = (
|
|
313
|
+
<SignInRecoveryStep
|
|
314
|
+
details={{ errorCode: authError.errorCode, message: authError.message, status: authError.status }}
|
|
315
|
+
identity={displayedRecoveryIdentity}
|
|
316
|
+
kind="noAccessibleAccount"
|
|
317
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
318
|
+
/>
|
|
319
|
+
);
|
|
320
|
+
} else if (mode === 'credentialFailure' && authError instanceof CredentialError) {
|
|
321
|
+
content = (
|
|
322
|
+
<SignInRecoveryStep
|
|
323
|
+
details={{ errorCode: authError.errorCode, message: authError.message, status: authError.status }}
|
|
324
|
+
kind="credential"
|
|
325
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
326
|
+
/>
|
|
327
|
+
);
|
|
328
|
+
} else if (mode === 'serviceFailure' && authError instanceof AuthenticationServiceError) {
|
|
329
|
+
content = (
|
|
330
|
+
<SignInRecoveryStep
|
|
331
|
+
details={{ errorCode: authError.errorCode, message: authError.message, status: authError.status }}
|
|
332
|
+
kind="service"
|
|
333
|
+
onContinue={retryAuthentication}
|
|
334
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
335
|
+
/>
|
|
336
|
+
);
|
|
213
337
|
} else if (mode === 'signup' && !localStorage.getItem('tenantName')) {
|
|
214
338
|
content = <SignupForm onSignup={onSignup} goBack={startOver} />;
|
|
215
339
|
} else if (mode === 'tenant' && tenant) {
|
|
@@ -247,25 +371,19 @@ function SigninScreenImpl({
|
|
|
247
371
|
|
|
248
372
|
{content}
|
|
249
373
|
|
|
250
|
-
{authError &&
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
support@vertesiahq.com
|
|
261
|
-
</a>
|
|
262
|
-
{t('auth.signInErrorPersists')}
|
|
263
|
-
<pre className="mt-2 text-xs">
|
|
264
|
-
{t('auth.error', { message: authError.message })}
|
|
265
|
-
</pre>
|
|
266
|
-
</div>
|
|
374
|
+
{authError && !isDedicatedAuthError(authError) && !isInviteRequiredError(authError) && (
|
|
375
|
+
<div className="mt-6 max-w-[420px] text-center text-sm text-muted">
|
|
376
|
+
<div>
|
|
377
|
+
{t('auth.signInError')}
|
|
378
|
+
<br />
|
|
379
|
+
{t('auth.signInErrorContact')}
|
|
380
|
+
<a className="text-info mx-1" href="mailto:support@vertesiahq.com">
|
|
381
|
+
support@vertesiahq.com
|
|
382
|
+
</a>
|
|
383
|
+
{t('auth.signInErrorPersists')}
|
|
267
384
|
</div>
|
|
268
|
-
|
|
385
|
+
</div>
|
|
386
|
+
)}
|
|
269
387
|
|
|
270
388
|
<div className="flex items-center gap-5 mt-10 text-xs text-muted-foreground">
|
|
271
389
|
<a href="https://vertesiahq.com/privacy" className="hover:text-foreground transition">
|