Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
||
| // Module-level flag to persist sign-in loading state across component remounts | ||
| // This prevents the flash of normal state when OAuth triggers session refresh | ||
| let singleProviderSignInInitiated = false; |
There was a problem hiding this comment.
The module-level singleProviderSignInInitiated flag is set to true when the user clicks to sign in but is never reset, causing the button to remain permanently in the loading state after any sign-in attempt (successful, failed, or cancelled).
View Details
📝 Patch Details
diff --git a/components/auth/dialog.tsx b/components/auth/dialog.tsx
index 4a971b0..a242bd1 100644
--- a/components/auth/dialog.tsx
+++ b/components/auth/dialog.tsx
@@ -1,6 +1,6 @@
"use client";
-import { type ReactNode, useState } from "react";
+import { type ReactNode, useEffect, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import {
@@ -408,6 +408,10 @@ let singleProviderSignInInitiated = false;
export const isSingleProviderSignInInitiated = () =>
singleProviderSignInInitiated;
+const resetSingleProviderSignInInitiated = () => {
+ singleProviderSignInInitiated = false;
+};
+
const SingleProviderButton = ({
provider,
loadingProvider,
@@ -417,6 +421,14 @@ const SingleProviderButton = ({
const [isInitiated, setIsInitiated] = useState(singleProviderSignInInitiated);
const isLoading = loadingProvider === provider || isInitiated;
+ // Reset the initiated state when loading completes (either success redirects or failure)
+ useEffect(() => {
+ if (isInitiated && loadingProvider === null) {
+ setIsInitiated(false);
+ resetSingleProviderSignInInitiated();
+ }
+ }, [isInitiated, loadingProvider]);
+
const handleClick = () => {
singleProviderSignInInitiated = true;
setIsInitiated(true);
Analysis
Module-level flag never reset causes SingleProviderButton to remain in loading state after OAuth failure
What fails: The module-level singleProviderSignInInitiated flag in SingleProviderButton (line 406-407) is set to true when the user initiates OAuth sign-in but is never reset to false, causing the button to remain permanently disabled with a loading spinner if OAuth fails or is cancelled.
How to reproduce:
- Configure the application with a single OAuth provider (e.g., GitHub only)
- Click the "Sign In" button
- Complete the OAuth flow but cancel or let it fail (e.g., deny permissions, network error)
- The error toast appears, but the button remains disabled with a loading spinner
- Clicking again does nothing - the button is permanently in loading state
Result: Button is stuck in loading state (isLoading = true), preventing user from retrying authentication. The isInitiated state (initialized from the module-level flag) is set to true and never reset, and since the component is not unmounted after OAuth failure, the state persists.
Expected: After OAuth fails, handleSocialSignIn sets setLoadingProvider(null) in the catch block, but the module-level flag and component state remain true. The button should be re-enabled so users can retry.
Fix: Added a useEffect hook in SingleProviderButton that watches for loadingProvider becoming null and resets both the local isInitiated state and the module-level flag via a new resetSingleProviderSignInInitiated() function. This ensures the button returns to its normal, clickable state when OAuth fails.
* fix sign in glitch * fix stars glitch
No description provided.