Increase stdout maxBuffer length to prevent overflow
Browse filesThe buffer size for stdout has been increased to handle larger outputs and prevent the "stdout maxBuffer length exceeded" error. This change ensures that the application can process and display large amounts of data without encountering buffer overflow issues.
- backend/README.md +2 -0
- backend/services/auth_service.py +14 -38
- frontend/README.md +12 -0
- frontend/package.json +1 -0
- frontend/src/pages/ResetPassword.jsx +36 -6
- frontend/src/services/supabaseClient.js +36 -0
backend/README.md
CHANGED
@@ -77,6 +77,8 @@ backend/
|
|
77 |
- `POST /api/auth/login` - Login user
|
78 |
- `POST /api/auth/logout` - Logout user
|
79 |
- `GET /api/auth/user` - Get current user
|
|
|
|
|
80 |
|
81 |
### Sources
|
82 |
- `GET /api/sources` - Get all sources for current user
|
|
|
77 |
- `POST /api/auth/login` - Login user
|
78 |
- `POST /api/auth/logout` - Logout user
|
79 |
- `GET /api/auth/user` - Get current user
|
80 |
+
- `POST /api/auth/forgot-password` - Request password reset (Deprecated - Use Supabase client directly in frontend)
|
81 |
+
- `POST /api/auth/reset-password` - Reset password (Deprecated - Use Supabase client directly in frontend)
|
82 |
|
83 |
### Sources
|
84 |
- `GET /api/sources` - Get all sources for current user
|
backend/services/auth_service.py
CHANGED
@@ -275,47 +275,23 @@ def request_password_reset(supabase: Client, email: str) -> dict:
|
|
275 |
|
276 |
def reset_user_password(supabase: Client, token: str, new_password: str) -> dict:
|
277 |
"""
|
278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
|
280 |
Args:
|
281 |
supabase (Client): Supabase client instance
|
282 |
-
token (str): Password reset token (not
|
283 |
-
new_password (str): New password
|
284 |
|
285 |
Returns:
|
286 |
-
dict:
|
287 |
"""
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
'password': new_password
|
293 |
-
})
|
294 |
-
|
295 |
-
if response.user:
|
296 |
-
return {
|
297 |
-
'success': True,
|
298 |
-
'message': 'Password reset successfully! You can now log in with your new password.'
|
299 |
-
}
|
300 |
-
else:
|
301 |
-
return {
|
302 |
-
'success': False,
|
303 |
-
'message': 'Failed to reset password. Please try again.'
|
304 |
-
}
|
305 |
-
except Exception as e:
|
306 |
-
error_str = str(e).lower()
|
307 |
-
if 'invalid token' in error_str or 'expired' in error_str:
|
308 |
-
return {
|
309 |
-
'success': False,
|
310 |
-
'message': 'Invalid or expired reset token. Please request a new password reset.'
|
311 |
-
}
|
312 |
-
elif 'password' in error_str:
|
313 |
-
return {
|
314 |
-
'success': False,
|
315 |
-
'message': 'Password does not meet requirements. Please use at least 8 characters.'
|
316 |
-
}
|
317 |
-
else:
|
318 |
-
return {
|
319 |
-
'success': False,
|
320 |
-
'message': f'Failed to reset password: {str(e)}'
|
321 |
-
}
|
|
|
275 |
|
276 |
def reset_user_password(supabase: Client, token: str, new_password: str) -> dict:
|
277 |
"""
|
278 |
+
This function is deprecated. Password reset should be handled directly by the frontend
|
279 |
+
using the Supabase JavaScript client after the user is redirected from the reset email.
|
280 |
+
|
281 |
+
The standard Supabase v2 flow is:
|
282 |
+
1. User clicks reset link -> Supabase verifies token and establishes a recovery session.
|
283 |
+
2. User is redirected to the app (e.g., /reset-password).
|
284 |
+
3. Frontend uses supabase.auth.updateUser({ password: newPassword }) directly.
|
285 |
|
286 |
Args:
|
287 |
supabase (Client): Supabase client instance
|
288 |
+
token (str): Password reset token (not used in this implementation)
|
289 |
+
new_password (str): New password (not used in this implementation)
|
290 |
|
291 |
Returns:
|
292 |
+
dict: Message indicating this endpoint is deprecated
|
293 |
"""
|
294 |
+
return {
|
295 |
+
'success': False,
|
296 |
+
'message': 'Password reset should be handled by the frontend. Please update your frontend code to use the Supabase JavaScript client directly.'
|
297 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend/README.md
CHANGED
@@ -112,6 +112,18 @@ The frontend will be available at `http://localhost:3000` and the backend at `ht
|
|
112 |
- `npm run install:all` - Install both frontend and backend dependencies
|
113 |
- `npm run test` - Run linting and build tests
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
## Environment Variables
|
116 |
|
117 |
### Development
|
|
|
112 |
- `npm run install:all` - Install both frontend and backend dependencies
|
113 |
- `npm run test` - Run linting and build tests
|
114 |
|
115 |
+
## Installing New Dependencies
|
116 |
+
|
117 |
+
When new dependencies are added to `package.json`, you need to install them:
|
118 |
+
|
119 |
+
```bash
|
120 |
+
# Install all dependencies (including new ones)
|
121 |
+
npm install
|
122 |
+
|
123 |
+
# Or install only new dependencies
|
124 |
+
npm install @supabase/supabase-js
|
125 |
+
```
|
126 |
+
|
127 |
## Environment Variables
|
128 |
|
129 |
### Development
|
frontend/package.json
CHANGED
@@ -21,6 +21,7 @@
|
|
21 |
"@headlessui/react": "^1.7.17",
|
22 |
"@heroicons/react": "^2.0.18",
|
23 |
"@reduxjs/toolkit": "^1.8.5",
|
|
|
24 |
"axios": "^1.3.4",
|
25 |
"crypto-js": "^4.2.0",
|
26 |
"localforage": "^1.10.0",
|
|
|
21 |
"@headlessui/react": "^1.7.17",
|
22 |
"@heroicons/react": "^2.0.18",
|
23 |
"@reduxjs/toolkit": "^1.8.5",
|
24 |
+
"@supabase/supabase-js": "^2.39.3",
|
25 |
"axios": "^1.3.4",
|
26 |
"crypto-js": "^4.2.0",
|
27 |
"localforage": "^1.10.0",
|
frontend/src/pages/ResetPassword.jsx
CHANGED
@@ -1,7 +1,9 @@
|
|
1 |
import React, { useState, useEffect } from 'react';
|
2 |
import { useDispatch, useSelector } from 'react-redux';
|
3 |
import { useNavigate, useSearchParams } from 'react-router-dom';
|
4 |
-
import {
|
|
|
|
|
5 |
|
6 |
const ResetPassword = () => {
|
7 |
const dispatch = useDispatch();
|
@@ -97,13 +99,40 @@ const ResetPassword = () => {
|
|
97 |
}
|
98 |
|
99 |
try {
|
100 |
-
|
101 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
alert('Password reset successfully! You can now log in with your new password.');
|
103 |
navigate('/login');
|
|
|
104 |
} catch (err) {
|
105 |
-
|
106 |
-
|
107 |
}
|
108 |
};
|
109 |
|
@@ -195,7 +224,8 @@ const ResetPassword = () => {
|
|
195 |
}`}>
|
196 |
{passwordStrength <= 2 ? 'Weak' :
|
197 |
passwordStrength <= 4 ? 'Fair' :
|
198 |
-
passwordStrength === 5 ? 'Good' :
|
|
|
199 |
</span>
|
200 |
</div>
|
201 |
<div className="w-full bg-gray-200 rounded-full h-1.5 sm:h-2">
|
|
|
1 |
import React, { useState, useEffect } from 'react';
|
2 |
import { useDispatch, useSelector } from 'react-redux';
|
3 |
import { useNavigate, useSearchParams } from 'react-router-dom';
|
4 |
+
import { clearError } from '../store/reducers/authSlice';
|
5 |
+
// Import the Supabase client
|
6 |
+
import { supabase } from '../services/supabaseClient';
|
7 |
|
8 |
const ResetPassword = () => {
|
9 |
const dispatch = useDispatch();
|
|
|
99 |
}
|
100 |
|
101 |
try {
|
102 |
+
// --- This is the key change ---
|
103 |
+
// Instead of dispatching to your Redux thunk which calls the backend,
|
104 |
+
// call the Supabase client directly.
|
105 |
+
|
106 |
+
console.log('Resetting password with Supabase client');
|
107 |
+
|
108 |
+
const { data, error } = await supabase.auth.updateUser({
|
109 |
+
password: formData.password
|
110 |
+
});
|
111 |
+
|
112 |
+
if (error) {
|
113 |
+
// Handle specific Supabase errors
|
114 |
+
console.error('Supabase password reset error:', error);
|
115 |
+
let message = 'Failed to reset password.';
|
116 |
+
if (error.message.toLowerCase().includes('password')) {
|
117 |
+
message = 'Password does not meet requirements. Please use at least 8 characters.';
|
118 |
+
} else if (error.message.toLowerCase().includes('session')) {
|
119 |
+
message = 'Password reset session expired. Please request a new reset link.';
|
120 |
+
} else {
|
121 |
+
message = error.message;
|
122 |
+
}
|
123 |
+
// Show error to user
|
124 |
+
alert(message);
|
125 |
+
return;
|
126 |
+
}
|
127 |
+
|
128 |
+
// If successful
|
129 |
+
console.log('Password updated successfully:', data);
|
130 |
alert('Password reset successfully! You can now log in with your new password.');
|
131 |
navigate('/login');
|
132 |
+
|
133 |
} catch (err) {
|
134 |
+
console.error('Unexpected error during password reset:', err);
|
135 |
+
alert('An unexpected error occurred. Please try again.');
|
136 |
}
|
137 |
};
|
138 |
|
|
|
224 |
}`}>
|
225 |
{passwordStrength <= 2 ? 'Weak' :
|
226 |
passwordStrength <= 4 ? 'Fair' :
|
227 |
+
passwordStrength === 5 ? 'Good' :
|
228 |
+
'Strong'}
|
229 |
</span>
|
230 |
</div>
|
231 |
<div className="w-full bg-gray-200 rounded-full h-1.5 sm:h-2">
|
frontend/src/services/supabaseClient.js
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { createClient } from '@supabase/supabase-js';
|
2 |
+
|
3 |
+
// Supabase configuration from environment variables
|
4 |
+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
|
5 |
+
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
|
6 |
+
|
7 |
+
// Validate configuration
|
8 |
+
if (!supabaseUrl) {
|
9 |
+
console.error('Missing VITE_SUPABASE_URL environment variable');
|
10 |
+
}
|
11 |
+
|
12 |
+
if (!supabaseAnonKey) {
|
13 |
+
console.error('Missing VITE_SUPABASE_ANON_KEY environment variable');
|
14 |
+
}
|
15 |
+
|
16 |
+
// Create Supabase client instance
|
17 |
+
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
|
18 |
+
// Optional: Add any additional configuration options here
|
19 |
+
auth: {
|
20 |
+
// Automatically refresh the session if it's close to expiring
|
21 |
+
autoRefreshToken: true,
|
22 |
+
// Persist the session in local storage
|
23 |
+
persistSession: true,
|
24 |
+
// Detect changes to the session (e.g., token refresh)
|
25 |
+
detectSessionInUrl: true
|
26 |
+
},
|
27 |
+
// Global fetch options
|
28 |
+
global: {
|
29 |
+
// Set a default timeout for requests (in milliseconds)
|
30 |
+
headers: {
|
31 |
+
'X-Client-Info': 'lin-app/1.0'
|
32 |
+
}
|
33 |
+
}
|
34 |
+
});
|
35 |
+
|
36 |
+
export default supabase;
|