|
1 | 1 | import logging |
| 2 | +import os |
2 | 3 |
|
3 | 4 | import firebase_admin.auth |
| 5 | +import requests |
4 | 6 | from fastapi import HTTPException |
5 | 7 |
|
6 | 8 | from app.utilities.constants import LOGGER_NAME |
@@ -46,10 +48,29 @@ def renew_token(self, refresh_token: str) -> Token: |
46 | 48 |
|
47 | 49 | def reset_password(self, email: str) -> None: |
48 | 50 | try: |
49 | | - firebase_admin.auth.generate_password_reset_link(email) |
| 51 | + # Use Firebase REST API to send password reset email |
| 52 | + url = f"https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key={os.getenv('FIREBASE_WEB_API_KEY')}" |
| 53 | + data = { |
| 54 | + "requestType": "PASSWORD_RESET", |
| 55 | + "email": email, |
| 56 | + "continueUrl": "http://localhost:3000/set-new-password", # Custom action URL |
| 57 | + } |
| 58 | + |
| 59 | + response = requests.post(url, json=data) |
| 60 | + response_json = response.json() |
| 61 | + |
| 62 | + if response.status_code != 200: |
| 63 | + error_message = response_json.get("error", {}).get("message", "Unknown error") |
| 64 | + self.logger.error(f"Failed to send password reset email: {error_message}") |
| 65 | + # Don't raise exception for security reasons - don't reveal if email exists |
| 66 | + return |
| 67 | + |
| 68 | + self.logger.info(f"Password reset email sent successfully to {email}") |
| 69 | + |
50 | 70 | except Exception as e: |
51 | 71 | self.logger.error(f"Failed to reset password: {str(e)}") |
52 | | - raise |
| 72 | + # Don't raise exception for security reasons - don't reveal if email exists |
| 73 | + return |
53 | 74 |
|
54 | 75 | def send_email_verification_link(self, email: str) -> None: |
55 | 76 | try: |
@@ -87,3 +108,27 @@ def is_authorized_by_email(self, access_token: str, requested_email: str) -> boo |
87 | 108 | except Exception as e: |
88 | 109 | print(f"Authorization error: {str(e)}") |
89 | 110 | return False |
| 111 | + |
| 112 | + def verify_email(self, email: str): |
| 113 | + try: |
| 114 | + user = self.user_service.get_user_by_email(email) |
| 115 | + if not user: |
| 116 | + self.logger.error(f"User not found for email: {email}") |
| 117 | + raise ValueError("User not found") |
| 118 | + |
| 119 | + if not user.auth_id: |
| 120 | + self.logger.error(f"User {user.id} has no auth_id") |
| 121 | + raise ValueError("User has no auth_id") |
| 122 | + |
| 123 | + self.logger.info(f"Updating email verification for user {user.id} with auth_id {user.auth_id}") |
| 124 | + firebase_admin.auth.update_user(user.auth_id, email_verified=True) |
| 125 | + self.logger.info(f"Successfully verified email for user {user.id}") |
| 126 | + |
| 127 | + except ValueError as e: |
| 128 | + # User not found in database - this might happen if there's a timing issue |
| 129 | + # between Firebase user creation and database user creation |
| 130 | + self.logger.warning(f"User not found in database for email {email}: {str(e)}") |
| 131 | + raise |
| 132 | + except Exception as e: |
| 133 | + self.logger.error(f"Failed to verify email for {email}: {str(e)}") |
| 134 | + raise |
0 commit comments