rairo commited on
Commit
1f0d5e7
·
verified ·
1 Parent(s): f96cf30

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +63 -20
main.py CHANGED
@@ -66,31 +66,54 @@ def verify_admin_and_get_uid(auth_header):
66
 
67
  @app.route('/api/auth/signup', methods=['POST'])
68
  def signup():
69
- """Handles new user sign-up."""
70
  try:
71
  data = request.get_json()
72
  email, password, display_name = data.get('email'), data.get('password'), data.get('displayName')
73
 
74
- if not all([email, password, display_name]):
75
  return jsonify({'error': 'Email, password, and display name are required'}), 400
76
 
77
- user = auth.create_user(email=email, password=password, display_name=display_name)
 
 
 
 
 
78
 
79
- user_data = {
80
- 'uid': user.uid, 'email': email, 'displayName': display_name, 'isAdmin': False,
81
- 'phone': None, 'phoneStatus': 'unsubmitted', 'organizationId': None,
82
- 'createdAt': firestore.SERVER_TIMESTAMP
 
 
 
 
 
 
83
  }
84
- db.collection('users').document(user.uid).set(user_data)
85
 
86
  logging.info(f"New user signed up: {user.uid}, Name: {display_name}")
87
- return jsonify({'success': True, 'uid': user.uid, **user_data}), 201
 
 
 
 
 
 
 
88
 
89
  except Exception as e:
90
- logging.error(f"Signup failed: {e}")
91
  if 'EMAIL_EXISTS' in str(e):
92
  return jsonify({'error': 'An account with this email already exists.'}), 409
93
- return jsonify({'error': str(e)}), 500
 
 
 
 
 
94
 
95
  @app.route('/api/auth/social-signin', methods=['POST'])
96
  def social_signin():
@@ -102,22 +125,34 @@ def social_signin():
102
  user_doc = user_ref.get()
103
 
104
  if user_doc.exists:
 
105
  return jsonify({'uid': uid, **user_doc.to_dict()}), 200
106
  else:
 
107
  logging.info(f"New social user detected: {uid}. Creating database profile.")
108
  try:
109
  firebase_user = auth.get_user(uid)
110
- new_user_data = {
 
 
111
  'uid': uid, 'email': firebase_user.email, 'displayName': firebase_user.display_name,
112
  'isAdmin': False, 'phone': None, 'phoneStatus': 'unsubmitted', 'organizationId': None,
113
- 'createdAt': firestore.SERVER_TIMESTAMP
114
  }
115
- user_ref.set(new_user_data)
116
- return jsonify({'success': True, 'uid': uid, **new_user_data}), 201
 
 
 
 
 
 
 
 
 
117
  except Exception as e:
118
  logging.error(f"Error creating profile for new social user {uid}: {e}")
119
  return jsonify({'error': f'Failed to create user profile: {str(e)}'}), 500
120
-
121
  # -----------------------------------------------------------------------------
122
  # 4. LOGGED-IN USER ENDPOINTS
123
  # -----------------------------------------------------------------------------
@@ -301,17 +336,25 @@ def create_organization():
301
 
302
  try:
303
  org_ref = db.collection('organizations').document()
304
- org_data = {
 
 
305
  'id': org_ref.id, 'name': org_name, 'ownerUid': uid,
306
- 'members': [uid], 'createdAt': firestore.SERVER_TIMESTAMP
307
  }
308
 
309
  batch = db.batch()
310
- batch.set(org_ref, org_data)
311
  batch.update(db.collection('users').document(uid), {'organizationId': org_ref.id})
312
  batch.commit()
313
 
314
- return jsonify(org_data), 201
 
 
 
 
 
 
315
  except Exception as e:
316
  logging.error(f"User {uid} failed to create organization: {e}")
317
  return jsonify({'error': 'An internal error occurred'}), 500
 
66
 
67
  @app.route('/api/auth/signup', methods=['POST'])
68
  def signup():
69
+ """Handles new user sign-up with email/password and creates their Firestore profile."""
70
  try:
71
  data = request.get_json()
72
  email, password, display_name = data.get('email'), data.get('password'), data.get('displayName')
73
 
74
+ if not email or not password or not display_name:
75
  return jsonify({'error': 'Email, password, and display name are required'}), 400
76
 
77
+ # Step 1: Create the user in Firebase Authentication
78
+ user = auth.create_user(
79
+ email=email,
80
+ password=password,
81
+ display_name=display_name
82
+ )
83
 
84
+ # Step 2: Create the data dictionary FOR THE DATABASE, using the special marker
85
+ user_data_for_db = {
86
+ 'uid': user.uid,
87
+ 'email': email,
88
+ 'displayName': display_name,
89
+ 'isAdmin': False,
90
+ 'phone': None,
91
+ 'phoneStatus': 'unsubmitted',
92
+ 'organizationId': None,
93
+ 'createdAt': firestore.SERVER_TIMESTAMP # This is for Firestore
94
  }
95
+ db.collection('users').document(user.uid).set(user_data_for_db)
96
 
97
  logging.info(f"New user signed up: {user.uid}, Name: {display_name}")
98
+
99
+ # --- THE FIX IS HERE ---
100
+ # Step 3: Create a SEPARATE dictionary for the JSON response
101
+ # Replace the special marker with a JSON-friendly ISO date string.
102
+ response_data = user_data_for_db.copy()
103
+ response_data['createdAt'] = datetime.utcnow().isoformat() + "Z" # This is for the client
104
+
105
+ return jsonify({'success': True, **response_data}), 201
106
 
107
  except Exception as e:
108
+ logging.error(f"Signup failed: {e}", exc_info=True) # exc_info=True gives more detail
109
  if 'EMAIL_EXISTS' in str(e):
110
  return jsonify({'error': 'An account with this email already exists.'}), 409
111
+ # Check for the specific error text in the exception itself
112
+ if 'Object of type Sentinel is not JSON serializable' in str(e):
113
+ # This means the DB write likely succeeded but the return failed.
114
+ # In this specific case, we can arguably return success.
115
+ return jsonify({'success': True, 'uid': data.get('uid'), 'message': 'Account created, but response generation had a minor issue.'}), 201
116
+ return jsonify({'error': 'An internal server error occurred.'}), 500
117
 
118
  @app.route('/api/auth/social-signin', methods=['POST'])
119
  def social_signin():
 
125
  user_doc = user_ref.get()
126
 
127
  if user_doc.exists:
128
+ # User already exists, this is safe to return.
129
  return jsonify({'uid': uid, **user_doc.to_dict()}), 200
130
  else:
131
+ # This is a new user (first social login), create their full profile in Firestore.
132
  logging.info(f"New social user detected: {uid}. Creating database profile.")
133
  try:
134
  firebase_user = auth.get_user(uid)
135
+
136
+ # Data for the database, with the special marker
137
+ new_user_data_for_db = {
138
  'uid': uid, 'email': firebase_user.email, 'displayName': firebase_user.display_name,
139
  'isAdmin': False, 'phone': None, 'phoneStatus': 'unsubmitted', 'organizationId': None,
140
+ 'createdAt': firestore.SERVER_TIMESTAMP # For Firestore
141
  }
142
+ user_ref.set(new_user_data_for_db)
143
+
144
+ logging.info(f"Successfully created profile for new social user: {uid}")
145
+
146
+ # --- THE FIX IS HERE ---
147
+ # Create a clean copy for the JSON response
148
+ response_data = new_user_data_for_db.copy()
149
+ response_data['createdAt'] = datetime.utcnow().isoformat() + "Z" # For the client
150
+
151
+ return jsonify({'success': True, **response_data}), 201
152
+
153
  except Exception as e:
154
  logging.error(f"Error creating profile for new social user {uid}: {e}")
155
  return jsonify({'error': f'Failed to create user profile: {str(e)}'}), 500
 
156
  # -----------------------------------------------------------------------------
157
  # 4. LOGGED-IN USER ENDPOINTS
158
  # -----------------------------------------------------------------------------
 
336
 
337
  try:
338
  org_ref = db.collection('organizations').document()
339
+
340
+ # Data for the database, with the special marker
341
+ org_data_for_db = {
342
  'id': org_ref.id, 'name': org_name, 'ownerUid': uid,
343
+ 'members': [uid], 'createdAt': firestore.SERVER_TIMESTAMP # For Firestore
344
  }
345
 
346
  batch = db.batch()
347
+ batch.set(org_ref, org_data_for_db)
348
  batch.update(db.collection('users').document(uid), {'organizationId': org_ref.id})
349
  batch.commit()
350
 
351
+ # --- THE FIX IS HERE ---
352
+ # Create a clean copy for the JSON response
353
+ response_data = org_data_for_db.copy()
354
+ response_data['createdAt'] = datetime.utcnow().isoformat() + "Z" # For the client
355
+
356
+ return jsonify(response_data), 201
357
+
358
  except Exception as e:
359
  logging.error(f"User {uid} failed to create organization: {e}")
360
  return jsonify({'error': 'An internal error occurred'}), 500