summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatt korwel <[email protected]>2025-06-20 10:46:41 -0700
committerGitHub <[email protected]>2025-06-20 10:46:41 -0700
commit7c8a1da8fe0856e7ebedcd543f82e20f09816222 (patch)
tree28e597e682bad94d7799028d73449209df1866cb
parent7c4af82da4ee4322daeb0ab78acafda4a73dc7e9 (diff)
Auth blocking (#1261)
-rw-r--r--packages/cli/src/ui/App.tsx11
-rw-r--r--packages/cli/src/ui/components/AuthInProgress.tsx51
-rw-r--r--packages/cli/src/ui/hooks/useAuthCommand.ts11
3 files changed, 73 insertions, 0 deletions
diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx
index b89a20ed..ad65adc6 100644
--- a/packages/cli/src/ui/App.tsx
+++ b/packages/cli/src/ui/App.tsx
@@ -33,6 +33,7 @@ import { InputPrompt } from './components/InputPrompt.js';
import { Footer } from './components/Footer.js';
import { ThemeDialog } from './components/ThemeDialog.js';
import { AuthDialog } from './components/AuthDialog.js';
+import { AuthInProgress } from './components/AuthInProgress.js';
import { EditorSettingsDialog } from './components/EditorSettingsDialog.js';
import { Colors } from './colors.js';
import { Help } from './components/Help.js';
@@ -138,6 +139,8 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
openAuthDialog,
handleAuthSelect,
handleAuthHighlight,
+ isAuthenticating,
+ cancelAuthentication,
} = useAuthCommand(settings, setAuthError, config);
useEffect(() => {
@@ -585,6 +588,14 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
terminalWidth={mainAreaWidth}
/>
</Box>
+ ) : isAuthenticating ? (
+ <AuthInProgress
+ onTimeout={() => {
+ setAuthError('Authentication timed out. Please try again.');
+ cancelAuthentication();
+ openAuthDialog();
+ }}
+ />
) : isAuthDialogOpen ? (
<Box flexDirection="column">
<AuthDialog
diff --git a/packages/cli/src/ui/components/AuthInProgress.tsx b/packages/cli/src/ui/components/AuthInProgress.tsx
new file mode 100644
index 00000000..804e2ff8
--- /dev/null
+++ b/packages/cli/src/ui/components/AuthInProgress.tsx
@@ -0,0 +1,51 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState, useEffect } from 'react';
+import { Box, Text } from 'ink';
+import Spinner from 'ink-spinner';
+import { Colors } from '../colors.js';
+
+interface AuthInProgressProps {
+ onTimeout: () => void;
+}
+
+export function AuthInProgress({
+ onTimeout,
+}: AuthInProgressProps): React.JSX.Element {
+ const [timedOut, setTimedOut] = useState(false);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setTimedOut(true);
+ onTimeout();
+ }, 30000);
+
+ return () => clearTimeout(timer);
+ }, [onTimeout]);
+
+ return (
+ <Box
+ borderStyle="round"
+ borderColor={Colors.Gray}
+ flexDirection="column"
+ padding={1}
+ width="100%"
+ >
+ {timedOut ? (
+ <Text color={Colors.AccentRed}>
+ Authentication timed out. Please try again.
+ </Text>
+ ) : (
+ <Box>
+ <Text>
+ <Spinner type="dots" /> Waiting for auth...
+ </Text>
+ </Box>
+ )}
+ </Box>
+ );
+}
diff --git a/packages/cli/src/ui/hooks/useAuthCommand.ts b/packages/cli/src/ui/hooks/useAuthCommand.ts
index 2c2b5f93..5cc67a07 100644
--- a/packages/cli/src/ui/hooks/useAuthCommand.ts
+++ b/packages/cli/src/ui/hooks/useAuthCommand.ts
@@ -31,6 +31,8 @@ export const useAuthCommand = (
setIsAuthDialogOpen(true);
}, []);
+ const [isAuthenticating, setIsAuthenticating] = useState(false);
+
useEffect(() => {
const authFlow = async () => {
if (isAuthDialogOpen || !settings.merged.selectedAuthType) {
@@ -38,6 +40,7 @@ export const useAuthCommand = (
}
try {
+ setIsAuthenticating(true);
await performAuthFlow(
settings.merged.selectedAuthType as AuthType,
config,
@@ -51,6 +54,8 @@ Message: ${getErrorMessage(e)}`
: `Failed to login. Message: ${getErrorMessage(e)}`;
setAuthError(errorMessage);
openAuthDialog();
+ } finally {
+ setIsAuthenticating(false);
}
};
@@ -73,10 +78,16 @@ Message: ${getErrorMessage(e)}`
// For now, we don't do anything on highlight.
}, []);
+ const cancelAuthentication = useCallback(() => {
+ setIsAuthenticating(false);
+ }, []);
+
return {
isAuthDialogOpen,
openAuthDialog,
handleAuthSelect,
handleAuthHighlight,
+ isAuthenticating,
+ cancelAuthentication,
};
};