ng
Browse files
frontend/src/pages/ResetPassword.jsx
CHANGED
@@ -12,7 +12,7 @@ const ResetPassword = () => {
|
|
12 |
const { loading, error } = useSelector(state => state.auth);
|
13 |
|
14 |
const [formData, setFormData] = useState({
|
15 |
-
token: '',
|
16 |
password: '',
|
17 |
confirmPassword: ''
|
18 |
});
|
@@ -24,11 +24,34 @@ const ResetPassword = () => {
|
|
24 |
password: false,
|
25 |
confirmPassword: false
|
26 |
});
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
useEffect(() => {
|
30 |
const token = searchParams.get('token');
|
31 |
if (token) {
|
|
|
32 |
setFormData(prev => ({ ...prev, token }));
|
33 |
}
|
34 |
}, [searchParams]);
|
@@ -98,32 +121,36 @@ const ResetPassword = () => {
|
|
98 |
}
|
99 |
|
100 |
try {
|
|
|
|
|
101 |
// --- Check for existing session (recovery session) ---
|
102 |
// It's crucial to verify the session was established by the Supabase client
|
103 |
// when it processed the URL fragments on app load.
|
104 |
-
const { data: { session }, error: sessionError } = await supabase.auth.getSession();
|
|
|
|
|
105 |
if (sessionError) {
|
106 |
-
console.error('Error getting session:', sessionError);
|
107 |
alert('Failed to get session. Please try resetting your password again.');
|
108 |
-
// Optionally, redirect to /forgot-password
|
109 |
-
// navigate('/forgot-password');
|
110 |
return;
|
111 |
}
|
112 |
|
113 |
-
if (!
|
114 |
// This is the likely cause of AuthSessionMissingError
|
115 |
-
console.warn('No active session found. The URL might not have been processed correctly or the session expired.');
|
|
|
116 |
alert('Password reset link may be invalid or expired. Please request a new one.');
|
117 |
// Optionally, redirect to /forgot-password
|
118 |
// navigate('/forgot-password');
|
119 |
return;
|
120 |
}
|
121 |
|
122 |
-
console.log('Resetting password with Supabase client for user:',
|
123 |
|
124 |
const { data, error } = await supabase.auth.updateUser({
|
125 |
password: formData.password
|
126 |
});
|
|
|
127 |
|
128 |
if (error) {
|
129 |
console.error('Supabase password reset error:', error);
|
@@ -141,8 +168,7 @@ const ResetPassword = () => {
|
|
141 |
|
142 |
console.log('Password updated successfully:', data);
|
143 |
alert('Password reset successfully! You can now log in with your new password.');
|
144 |
-
// After successful reset, the
|
145 |
-
// Consider logging the user out of the recovery session.
|
146 |
await supabase.auth.signOut();
|
147 |
navigate('/login');
|
148 |
|
@@ -171,6 +197,14 @@ const ResetPassword = () => {
|
|
171 |
|
172 |
{/* Auth Card */}
|
173 |
<div className="bg-white rounded-2xl shadow-xl p-4 sm:p-8 space-y-4 sm:space-y-6 animate-slide-up animate-delay-100">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
{/* Error Message */}
|
175 |
{error && (
|
176 |
<div className="bg-red-50 border border-red-200 rounded-lg p-3 sm:p-4 animate-slide-up animate-delay-200">
|
|
|
12 |
const { loading, error } = useSelector(state => state.auth);
|
13 |
|
14 |
const [formData, setFormData] = useState({
|
15 |
+
token: '', // This is likely unused in the v2 flow, but kept for structure
|
16 |
password: '',
|
17 |
confirmPassword: ''
|
18 |
});
|
|
|
24 |
password: false,
|
25 |
confirmPassword: false
|
26 |
});
|
27 |
+
const [authState, setAuthState] = useState({ event: null, session: null });
|
28 |
+
|
29 |
+
// --- Listen for auth state changes specifically on this page ---
|
30 |
+
// This helps confirm if PASSWORD_RECOVERY was detected
|
31 |
+
useEffect(() => {
|
32 |
+
console.log("ResetPassword component mounted. Setting up auth listener.");
|
33 |
+
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
|
34 |
+
console.log('Auth state changed within ResetPassword component:', event, session ? `User: ${session.user?.id || 'N/A'}` : 'No session');
|
35 |
+
setAuthState({ event, session });
|
36 |
+
|
37 |
+
if (event === 'PASSWORD_RECOVERY') {
|
38 |
+
console.log('*** PASSWORD_RECOVERY event confirmed in ResetPassword component. ***');
|
39 |
+
// Optional: You could set some state here to indicate the recovery flow is active
|
40 |
+
}
|
41 |
+
});
|
42 |
+
|
43 |
+
// Cleanup listener on unmount
|
44 |
+
return () => {
|
45 |
+
console.log("ResetPassword component unmounting. Removing auth listener.");
|
46 |
+
authListener?.subscription.unsubscribe();
|
47 |
+
};
|
48 |
+
}, []);
|
49 |
+
|
50 |
+
// Get token from URL params (old v1 flow, kept for reference but likely not used)
|
51 |
useEffect(() => {
|
52 |
const token = searchParams.get('token');
|
53 |
if (token) {
|
54 |
+
console.warn("Token found in search params (v1 flow?). This might be unexpected in v2 flow:", token);
|
55 |
setFormData(prev => ({ ...prev, token }));
|
56 |
}
|
57 |
}, [searchParams]);
|
|
|
121 |
}
|
122 |
|
123 |
try {
|
124 |
+
console.log("Attempting to get current session before password update...");
|
125 |
+
|
126 |
// --- Check for existing session (recovery session) ---
|
127 |
// It's crucial to verify the session was established by the Supabase client
|
128 |
// when it processed the URL fragments on app load.
|
129 |
+
const { data: { session: currentSession }, error: sessionError } = await supabase.auth.getSession();
|
130 |
+
console.log("Current session check result:", currentSession ? `Session for user: ${currentSession.user?.id || 'N/A'}` : 'No session', sessionError);
|
131 |
+
|
132 |
if (sessionError) {
|
133 |
+
console.error('Error getting current session:', sessionError);
|
134 |
alert('Failed to get session. Please try resetting your password again.');
|
|
|
|
|
135 |
return;
|
136 |
}
|
137 |
|
138 |
+
if (!currentSession || !currentSession.user) {
|
139 |
// This is the likely cause of AuthSessionMissingError
|
140 |
+
console.warn('No active session found in handleSubmit. The URL might not have been processed correctly or the session expired.');
|
141 |
+
console.log("Auth state at time of submission:", authState);
|
142 |
alert('Password reset link may be invalid or expired. Please request a new one.');
|
143 |
// Optionally, redirect to /forgot-password
|
144 |
// navigate('/forgot-password');
|
145 |
return;
|
146 |
}
|
147 |
|
148 |
+
console.log('Resetting password with Supabase client for user:', currentSession.user?.email);
|
149 |
|
150 |
const { data, error } = await supabase.auth.updateUser({
|
151 |
password: formData.password
|
152 |
});
|
153 |
+
console.log("supabase.auth.updateUser result:", data, error);
|
154 |
|
155 |
if (error) {
|
156 |
console.error('Supabase password reset error:', error);
|
|
|
168 |
|
169 |
console.log('Password updated successfully:', data);
|
170 |
alert('Password reset successfully! You can now log in with your new password.');
|
171 |
+
// After successful reset, sign the user out of the temporary recovery session.
|
|
|
172 |
await supabase.auth.signOut();
|
173 |
navigate('/login');
|
174 |
|
|
|
197 |
|
198 |
{/* Auth Card */}
|
199 |
<div className="bg-white rounded-2xl shadow-xl p-4 sm:p-8 space-y-4 sm:space-y-6 animate-slide-up animate-delay-100">
|
200 |
+
{/* --- Debug Info Display (Remove in production) --- */}
|
201 |
+
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-2 text-xs">
|
202 |
+
<strong>Debug Info:</strong>
|
203 |
+
<p>Auth Event: {authState.event || 'None'}</p>
|
204 |
+
<p>Auth Session User ID: {authState.session?.user?.id || 'None'}</p>
|
205 |
+
</div>
|
206 |
+
{/* --- End Debug Info --- */}
|
207 |
+
|
208 |
{/* Error Message */}
|
209 |
{error && (
|
210 |
<div className="bg-red-50 border border-red-200 rounded-lg p-3 sm:p-4 animate-slide-up animate-delay-200">
|
frontend/src/services/supabaseClient.js
CHANGED
@@ -38,17 +38,58 @@ export const supabase = createClient(
|
|
38 |
}
|
39 |
);
|
40 |
|
41 |
-
// --- Add logging
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
console.log("Supabase client initialized with URL:", supabaseUrl);
|
|
|
|
|
43 |
supabase.auth.getSession()
|
44 |
.then(({ data: { session }, error }) => {
|
|
|
45 |
if (error) {
|
46 |
console.error("Error getting initial session:", error);
|
47 |
} else {
|
48 |
-
console.log("Initial session
|
49 |
-
//
|
50 |
-
// If session is null here when coming from a reset link, it means processing failed.
|
51 |
}
|
52 |
});
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
export default supabase;
|
|
|
38 |
}
|
39 |
);
|
40 |
|
41 |
+
// --- Add comprehensive logging for auth state changes ---
|
42 |
+
let initialSessionCheckDone = false;
|
43 |
+
|
44 |
+
// Listen for auth state changes
|
45 |
+
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
|
46 |
+
console.log('Supabase Auth State Change Event:', event);
|
47 |
+
console.log('Supabase Auth State Change Session:', session ? `User: ${session.user?.id || 'N/A'}` : 'No session');
|
48 |
+
|
49 |
+
// Handle specific events
|
50 |
+
if (event === 'PASSWORD_RECOVERY') {
|
51 |
+
console.log('*** PASSWORD_RECOVERY event detected. A password reset link was used. ***');
|
52 |
+
// The session provided here should be the temporary recovery session.
|
53 |
+
// The app should now allow the user to set a new password.
|
54 |
+
} else if (event === 'SIGNED_IN') {
|
55 |
+
console.log('User signed in.');
|
56 |
+
} else if (event === 'SIGNED_OUT') {
|
57 |
+
console.log('User signed out.');
|
58 |
+
} else if (event === 'TOKEN_REFRESHED') {
|
59 |
+
console.log('Session token refreshed.');
|
60 |
+
} else if (event === 'USER_UPDATED') {
|
61 |
+
console.log('User data updated.');
|
62 |
+
}
|
63 |
+
});
|
64 |
+
|
65 |
console.log("Supabase client initialized with URL:", supabaseUrl);
|
66 |
+
|
67 |
+
// Initial session check on app load
|
68 |
supabase.auth.getSession()
|
69 |
.then(({ data: { session }, error }) => {
|
70 |
+
initialSessionCheckDone = true;
|
71 |
if (error) {
|
72 |
console.error("Error getting initial session:", error);
|
73 |
} else {
|
74 |
+
console.log("Initial session check result (on app load):", session ? `Session exists for user: ${session.user?.id || 'N/A'}` : "No active session found");
|
75 |
+
// If session is null here when coming from a reset link, it means processing failed or the token was already used/expired.
|
|
|
76 |
}
|
77 |
});
|
78 |
|
79 |
+
// Fallback check in case the initial check happens too early or misses something
|
80 |
+
setTimeout(() => {
|
81 |
+
if (!initialSessionCheckDone) {
|
82 |
+
console.warn("Initial session check might have been missed or delayed. Checking again...");
|
83 |
+
supabase.auth.getSession()
|
84 |
+
.then(({ data: { session }, error }) => {
|
85 |
+
initialSessionCheckDone = true; // Mark as done even on retry
|
86 |
+
if (error) {
|
87 |
+
console.error("Fallback - Error getting session:", error);
|
88 |
+
} else {
|
89 |
+
console.log("Fallback - Session check result:", session ? `Session exists for user: ${session.user?.id || 'N/A'}` : "No active session found (Fallback)");
|
90 |
+
}
|
91 |
+
});
|
92 |
+
}
|
93 |
+
}, 1000); // Check again after 1 second
|
94 |
+
|
95 |
export default supabase;
|