Spaces:
Runtime error
Runtime error
Update app/routes.py
Browse files- app/routes.py +117 -0
app/routes.py
CHANGED
|
@@ -590,3 +590,120 @@ def ping_db():
|
|
| 590 |
except Exception as e:
|
| 591 |
return f" DB Error: {e}"
|
| 592 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 590 |
except Exception as e:
|
| 591 |
return f" DB Error: {e}"
|
| 592 |
|
| 593 |
+
|
| 594 |
+
|
| 595 |
+
|
| 596 |
+
@auth.route('/settings')
|
| 597 |
+
def settings():
|
| 598 |
+
user, redirect_response = get_current_user()
|
| 599 |
+
if redirect_response:
|
| 600 |
+
return redirect_response
|
| 601 |
+
|
| 602 |
+
return render_template('settings.html', user=user)
|
| 603 |
+
|
| 604 |
+
|
| 605 |
+
@auth.route('/update_profile', methods=['POST'])
|
| 606 |
+
def update_profile():
|
| 607 |
+
user, redirect_response = get_current_user()
|
| 608 |
+
if redirect_response:
|
| 609 |
+
return redirect_response
|
| 610 |
+
|
| 611 |
+
new_email = request.form.get('email')
|
| 612 |
+
# username = request.form.get('username') # Username is read-only, not updated here
|
| 613 |
+
|
| 614 |
+
if not new_email:
|
| 615 |
+
flash('Email cannot be empty.', 'error')
|
| 616 |
+
return redirect(url_for('auth.settings'))
|
| 617 |
+
|
| 618 |
+
# Update email in Supabase. Assuming 'users' table or Supabase Auth update.
|
| 619 |
+
# For Supabase Auth, you'd use the client library or the /auth/v1/users endpoint
|
| 620 |
+
# For a custom 'users' table, it would be a PATCH request:
|
| 621 |
+
update_payload = {"email": new_email}
|
| 622 |
+
update_res = requests.patch(
|
| 623 |
+
f"{SUPABASE_URL}/rest/v1/users?id=eq.{user['id']}",
|
| 624 |
+
headers=HEADERS,
|
| 625 |
+
json=update_payload
|
| 626 |
+
)
|
| 627 |
+
|
| 628 |
+
if update_res.status_code == 200 or update_res.status_code == 204: # 200 OK or 204 No Content
|
| 629 |
+
flash('Profile updated successfully!', 'success')
|
| 630 |
+
else:
|
| 631 |
+
flash(f'Failed to update profile. Error: {update_res.text}', 'error')
|
| 632 |
+
|
| 633 |
+
return redirect(url_for('auth.settings'))
|
| 634 |
+
|
| 635 |
+
|
| 636 |
+
@auth.route('/change_password', methods=['POST'])
|
| 637 |
+
def change_password():
|
| 638 |
+
user, redirect_response = get_current_user()
|
| 639 |
+
if redirect_response:
|
| 640 |
+
return redirect_response
|
| 641 |
+
|
| 642 |
+
current_password = request.form.get('current_password')
|
| 643 |
+
new_password = request.form.get('new_password')
|
| 644 |
+
confirm_new_password = request.form.get('confirm_new_password')
|
| 645 |
+
|
| 646 |
+
if not current_password or not new_password or not confirm_new_password:
|
| 647 |
+
flash('All password fields are required.', 'error')
|
| 648 |
+
return redirect(url_for('auth.settings'))
|
| 649 |
+
|
| 650 |
+
if new_password != confirm_new_password:
|
| 651 |
+
flash('New password and confirmation do not match.', 'error')
|
| 652 |
+
return redirect(url_for('auth.settings'))
|
| 653 |
+
|
| 654 |
+
# In a real app, you would verify current_password first:
|
| 655 |
+
# 1. Fetch user from Supabase Auth based on their email or ID.
|
| 656 |
+
# 2. Use `check_password_hash(user.hashed_password, current_password)`
|
| 657 |
+
# If you're using Supabase's built-in auth, you'd typically re-authenticate
|
| 658 |
+
# or use their client's `updateUser` function which handles password changes.
|
| 659 |
+
# Direct patching to a 'users' table password field is generally insecure
|
| 660 |
+
# unless you are doing the hashing yourself.
|
| 661 |
+
|
| 662 |
+
# Example using a mock check for demonstration
|
| 663 |
+
if current_password != 'TestPass123': # Replace with actual password verification
|
| 664 |
+
flash('Incorrect current password.', 'error')
|
| 665 |
+
return redirect(url_for('auth.settings'))
|
| 666 |
+
|
| 667 |
+
# Update password in Supabase Auth (conceptual)
|
| 668 |
+
# This typically involves a call to Supabase's auth client or API endpoint for password change.
|
| 669 |
+
# E.g., `supabase.auth.updateUser({ password: new_password })`
|
| 670 |
+
# For direct database table if not using Supabase Auth for passwords:
|
| 671 |
+
hashed_new_password = generate_password_hash(new_password)
|
| 672 |
+
update_payload = {"password_hash": hashed_new_password} # Assuming a column for hashed password
|
| 673 |
+
update_res = requests.patch(
|
| 674 |
+
f"{SUPABASE_URL}/rest/v1/users?id=eq.{user['id']}",
|
| 675 |
+
headers=HEADERS,
|
| 676 |
+
json=update_payload
|
| 677 |
+
)
|
| 678 |
+
if update_res.status_code == 200 or update_res.status_code == 204:
|
| 679 |
+
flash('Password changed successfully!', 'success')
|
| 680 |
+
else:
|
| 681 |
+
flash(f'Failed to change password. Error: {update_res.text}', 'error')
|
| 682 |
+
|
| 683 |
+
flash('Password change simulated successfully!', 'success') # Placeholder
|
| 684 |
+
return redirect(url_for('auth.settings'))
|
| 685 |
+
|
| 686 |
+
|
| 687 |
+
@auth.route('/delete_account', methods=['POST'])
|
| 688 |
+
def delete_account():
|
| 689 |
+
user, redirect_response = get_current_user()
|
| 690 |
+
if redirect_response:
|
| 691 |
+
return redirect_response
|
| 692 |
+
|
| 693 |
+
# In a real app, confirm with a password or MFA
|
| 694 |
+
# Then delete the user from Supabase Auth and any related tables (via RLS or triggers)
|
| 695 |
+
# Example for deleting from a custom 'users' table:
|
| 696 |
+
delete_res = requests.delete(
|
| 697 |
+
f"{SUPABASE_URL}/rest/v1/users?id=eq.{user['id']}",
|
| 698 |
+
headers=HEADERS
|
| 699 |
+
)
|
| 700 |
+
|
| 701 |
+
if delete_res.status_code == 204: # 204 No Content for successful delete
|
| 702 |
+
session.pop('user_id', None) # Clear session after account deletion
|
| 703 |
+
flash('Your account has been successfully deleted.', 'success')
|
| 704 |
+
return redirect(url_for('auth.login'))
|
| 705 |
+
else:
|
| 706 |
+
flash(f'Failed to delete account. Error: {delete_res.text}', 'error')
|
| 707 |
+
return redirect(url_for('auth.settings'))
|
| 708 |
+
|
| 709 |
+
|