Auth blocking (#1261)

This commit is contained in:
matt korwel 2025-06-20 10:46:41 -07:00 committed by GitHub
parent 7c4af82da4
commit 7c8a1da8fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 0 deletions

View File

@ -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

View File

@ -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>
);
}

View File

@ -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,
};
};