mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
Clear stale ChatGPT OAuth fallback links
Manual authorization links now behave as transient recovery state: a fresh login clears older URLs, a successful copy clears the exposed URL before polling, and logged-in status defensively drops any stale manual link. Constraint: OAuth authorization URLs should not survive beyond the active recovery action. Rejected: Keep the copy button after a successful copy | that leaves an expired authorization URL visible after later auth state changes. Confidence: high Scope-risk: narrow Tested: cd desktop && bun run test -- src/components/settings/ChatGPTOfficialLogin.test.tsx src/stores/hahaOpenAIOAuthStore.test.ts Tested: cd desktop && bun run test -- src/components/settings/ChatGPTOfficialLogin.test.tsx src/stores/hahaOpenAIOAuthStore.test.ts src/__tests__/generalSettings.test.tsx --testNamePattern "ChatGPT|OpenAI OAuth|Providers tab|ChatGPTOfficialLogin|hahaOpenAIOAuthStore" Tested: cd desktop && bun run lint Tested: git diff --check
This commit is contained in:
parent
d2ff9d0c00
commit
f497a08453
@ -90,7 +90,34 @@ describe('ChatGPTOfficialLogin', () => {
|
||||
})
|
||||
|
||||
expect(copyTextToClipboardMock).toHaveBeenCalledWith(authorizeUrl)
|
||||
expect(useHahaOpenAIOAuthStore.getState().error).toBeNull()
|
||||
expect(useHahaOpenAIOAuthStore.getState().isPolling).toBe(true)
|
||||
consoleErrorSpy.mockRestore()
|
||||
expect(screen.queryByText(/Unable to open browser/)).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('button', { name: 'Copy authorization link' })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('keeps the authorization link available when copy fails', async () => {
|
||||
const authorizeUrl = 'https://chatgpt.com/oauth/authorize?state=openai-state'
|
||||
statusMock.mockResolvedValue({ loggedIn: false })
|
||||
startMock.mockResolvedValue({ authorizeUrl, state: 'openai-state' })
|
||||
shellOpenMock.mockRejectedValue(new Error('shell unavailable'))
|
||||
copyTextToClipboardMock.mockResolvedValue(false)
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
|
||||
render(<ChatGPTOfficialLogin />)
|
||||
|
||||
await screen.findByRole('button', { name: 'Sign in with ChatGPT' })
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Sign in with ChatGPT' }))
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Copy authorization link' }))
|
||||
})
|
||||
|
||||
expect(copyTextToClipboardMock).toHaveBeenCalledWith(authorizeUrl)
|
||||
expect(useHahaOpenAIOAuthStore.getState().isPolling).toBe(false)
|
||||
expect(screen.getByText(/Unable to copy authorization link/)).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'Copy authorization link' })).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@ -26,7 +26,14 @@ export function ChatGPTOfficialLogin() {
|
||||
return () => stopPolling()
|
||||
}, [fetchStatus, stopPolling])
|
||||
|
||||
useEffect(() => {
|
||||
if (status?.loggedIn) {
|
||||
setManualAuthorizeUrl(null)
|
||||
}
|
||||
}, [status?.loggedIn])
|
||||
|
||||
const handleLogin = async () => {
|
||||
setManualAuthorizeUrl(null)
|
||||
try {
|
||||
const { authorizeUrl } = await login()
|
||||
setManualAuthorizeUrl(authorizeUrl)
|
||||
@ -49,6 +56,7 @@ export function ChatGPTOfficialLogin() {
|
||||
if (!manualAuthorizeUrl) return
|
||||
const copied = await copyTextToClipboard(manualAuthorizeUrl)
|
||||
if (copied) {
|
||||
setManualAuthorizeUrl(null)
|
||||
useHahaOpenAIOAuthStore.setState({ error: null })
|
||||
startPolling()
|
||||
return
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user