@blackcode_sa/metaestetics-api 1.14.14 → 1.14.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -8321,16 +8321,6 @@ declare class AuthService extends BaseService {
8321
8321
  private googleProvider;
8322
8322
  private userService;
8323
8323
  constructor(db: Firestore, auth: Auth, app: FirebaseApp, userService: UserService);
8324
- /**
8325
- * Waits for Firebase Auth state to settle after sign-in.
8326
- * In React Native with Firebase JS SDK, auth.currentUser doesn't update synchronously
8327
- * after signInWithCredential. This causes Firestore permission issues.
8328
- *
8329
- * @param expectedUid - The UID we expect to see in auth.currentUser
8330
- * @param timeoutMs - Maximum time to wait (default 10 seconds)
8331
- * @returns Promise that resolves when auth state is ready
8332
- */
8333
- private waitForAuthState;
8334
8324
  /**
8335
8325
  * Registruje novog korisnika sa email-om i lozinkom
8336
8326
  */
package/dist/index.d.ts CHANGED
@@ -8321,16 +8321,6 @@ declare class AuthService extends BaseService {
8321
8321
  private googleProvider;
8322
8322
  private userService;
8323
8323
  constructor(db: Firestore, auth: Auth, app: FirebaseApp, userService: UserService);
8324
- /**
8325
- * Waits for Firebase Auth state to settle after sign-in.
8326
- * In React Native with Firebase JS SDK, auth.currentUser doesn't update synchronously
8327
- * after signInWithCredential. This causes Firestore permission issues.
8328
- *
8329
- * @param expectedUid - The UID we expect to see in auth.currentUser
8330
- * @param timeoutMs - Maximum time to wait (default 10 seconds)
8331
- * @returns Promise that resolves when auth state is ready
8332
- */
8333
- private waitForAuthState;
8334
8324
  /**
8335
8325
  * Registruje novog korisnika sa email-om i lozinkom
8336
8326
  */
package/dist/index.js CHANGED
@@ -15388,45 +15388,19 @@ var AuthService = class extends BaseService {
15388
15388
  super(db, auth, app);
15389
15389
  this.googleProvider = new import_auth8.GoogleAuthProvider();
15390
15390
  this.userService = userService || new UserService(db, auth, app);
15391
- if (!this.auth.__authServiceId) {
15392
- this.auth.__authServiceId = "auth-service-" + Date.now();
15393
- }
15394
- console.log("[AUTH] AuthService constructor - auth ID:", this.auth.__authServiceId);
15395
- console.log("[AUTH] AuthService constructor - userService.auth ID:", ((_a = this.userService.auth) == null ? void 0 : _a.__authServiceId) || "NOT SET");
15396
- }
15397
- /**
15398
- * Waits for Firebase Auth state to settle after sign-in.
15399
- * In React Native with Firebase JS SDK, auth.currentUser doesn't update synchronously
15400
- * after signInWithCredential. This causes Firestore permission issues.
15401
- *
15402
- * @param expectedUid - The UID we expect to see in auth.currentUser
15403
- * @param timeoutMs - Maximum time to wait (default 10 seconds)
15404
- * @returns Promise that resolves when auth state is ready
15405
- */
15406
- waitForAuthState(expectedUid, timeoutMs = 1e4) {
15407
- return new Promise((resolve, reject) => {
15408
- var _a;
15409
- if (((_a = this.auth.currentUser) == null ? void 0 : _a.uid) === expectedUid) {
15410
- console.log("[AUTH] Auth state already settled for:", expectedUid);
15411
- resolve();
15412
- return;
15413
- }
15414
- console.log("[AUTH] Waiting for auth state to settle for:", expectedUid);
15415
- const timeout = setTimeout(() => {
15416
- unsubscribe();
15417
- console.error("[AUTH] Timeout waiting for auth state");
15418
- reject(new Error("Timeout waiting for auth state to settle"));
15419
- }, timeoutMs);
15420
- const unsubscribe = (0, import_auth8.onAuthStateChanged)(this.auth, (user) => {
15421
- console.log("[AUTH] Auth state changed:", (user == null ? void 0 : user.uid) || "null");
15422
- if ((user == null ? void 0 : user.uid) === expectedUid) {
15423
- clearTimeout(timeout);
15424
- unsubscribe();
15425
- console.log("[AUTH] Auth state settled successfully for:", expectedUid);
15426
- resolve();
15427
- }
15428
- });
15391
+ (0, import_auth8.onAuthStateChanged)(this.auth, (user) => {
15392
+ var _a2, _b;
15393
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
15394
+ const stackTrace = ((_a2 = new Error().stack) == null ? void 0 : _a2.split("\n").slice(2, 5).join("\n")) || "N/A";
15395
+ console.log(`[AUTH STATE CHANGE] ${timestamp}`);
15396
+ console.log(`[AUTH STATE CHANGE] User: ${(user == null ? void 0 : user.uid) || "NULL"} (email: ${(user == null ? void 0 : user.email) || "N/A"})`);
15397
+ console.log(`[AUTH STATE CHANGE] auth.currentUser: ${((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL"}`);
15398
+ console.log(`[AUTH STATE CHANGE] Stack trace (first 3 frames):
15399
+ ${stackTrace}`);
15400
+ console.log("[AUTH STATE CHANGE] ---");
15429
15401
  });
15402
+ console.log("[AUTH] AuthService initialized");
15403
+ console.log("[AUTH] Initial auth.currentUser:", ((_a = this.auth.currentUser) == null ? void 0 : _a.uid) || "NULL");
15430
15404
  }
15431
15405
  /**
15432
15406
  * Registruje novog korisnika sa email-om i lozinkom
@@ -15996,7 +15970,7 @@ var AuthService = class extends BaseService {
15996
15970
  * @returns Object containing user and claimed practitioner
15997
15971
  */
15998
15972
  async claimDraftProfilesWithGoogle(idToken, practitionerIds) {
15999
- var _a, _b, _c, _d, _e;
15973
+ var _a, _b;
16000
15974
  try {
16001
15975
  console.log("[AUTH] Starting claim draft profiles with Google", {
16002
15976
  practitionerIdsCount: practitionerIds.length,
@@ -16013,61 +15987,18 @@ var AuthService = class extends BaseService {
16013
15987
  console.log("[AUTH] currentUser IMMEDIATELY AFTER sign-in:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
16014
15988
  console.log("[AUTH] User returned from signInWithCredential:", firebaseUser.uid);
16015
15989
  const practitionerService = new PractitionerService(this.db, this.auth, this.app);
16016
- console.log("[AUTH] currentUser after intializing practitionerService:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
16017
- let user = null;
15990
+ let user;
16018
15991
  try {
16019
15992
  user = await this.userService.getUserById(firebaseUser.uid);
16020
- console.log("[AUTH] User document already exists:", user.uid);
15993
+ console.log("[AUTH] User document found:", user.uid);
16021
15994
  } catch (userError) {
16022
- console.log("[AUTH] User document does not exist, creating it...");
16023
- }
16024
- if (!user) {
16025
- console.log("[AUTH] Creating user document DIRECTLY for:", firebaseUser.uid);
16026
- console.log("[AUTH] Checking auth.currentUser BEFORE refresh:", ((_d = this.auth.currentUser) == null ? void 0 : _d.uid) || "NULL");
16027
- try {
16028
- const token = await firebaseUser.getIdToken(true);
16029
- console.log("[AUTH] Got ID token, length:", (token == null ? void 0 : token.length) || 0);
16030
- } catch (tokenError) {
16031
- console.error("[AUTH] Error getting token:", tokenError);
16032
- }
16033
- await new Promise((resolve) => setTimeout(resolve, 100));
16034
- console.log("[AUTH] Using THIS.auth.currentUser AFTER refresh:", ((_e = this.auth.currentUser) == null ? void 0 : _e.uid) || "NULL");
16035
- console.log("[AUTH] Using THIS.db:", this.db ? "EXISTS" : "NULL");
16036
- if (!this.auth.currentUser) {
16037
- console.error("[AUTH] \u26A0\uFE0F auth.currentUser is STILL NULL after refresh! This is a React Native Firebase JS SDK issue.");
16038
- console.error("[AUTH] Firestore will deny permission because request.auth will be null.");
16039
- }
16040
- const userData = {
16041
- uid: firebaseUser.uid,
16042
- email: firebaseUser.email,
16043
- roles: ["practitioner" /* PRACTITIONER */],
16044
- isAnonymous: firebaseUser.isAnonymous || false,
16045
- createdAt: (0, import_firestore40.serverTimestamp)(),
16046
- updatedAt: (0, import_firestore40.serverTimestamp)(),
16047
- lastLoginAt: (0, import_firestore40.serverTimestamp)()
16048
- };
16049
- console.log("[AUTH] Attempting setDoc directly with userData:", {
16050
- uid: userData.uid,
16051
- email: userData.email,
16052
- roles: userData.roles
16053
- });
16054
- try {
16055
- await (0, import_firestore40.setDoc)((0, import_firestore40.doc)(this.db, USERS_COLLECTION, firebaseUser.uid), userData);
16056
- console.log("[AUTH] \u2705 setDoc SUCCEEDED directly!");
16057
- const userDoc = await (0, import_firestore40.getDoc)((0, import_firestore40.doc)(this.db, USERS_COLLECTION, firebaseUser.uid));
16058
- if (!userDoc.exists()) {
16059
- throw new Error("User document was not created");
16060
- }
16061
- user = userDoc.data();
16062
- console.log("[AUTH] User document created successfully:", user.uid);
16063
- } catch (error) {
16064
- console.error("[AUTH] \u274C setDoc FAILED directly:", {
16065
- errorCode: error == null ? void 0 : error.code,
16066
- errorMessage: error == null ? void 0 : error.message,
16067
- uid: firebaseUser.uid
16068
- });
16069
- throw error;
16070
- }
15995
+ console.error("[AUTH] \u274C User document should already exist! It should have been created in signUpPractitionerWithGoogle.");
15996
+ console.error("[AUTH] This indicates a bug - User doc creation failed in the initial Google sign-in flow.");
15997
+ throw new AuthError(
15998
+ "User account not properly initialized. Please try signing in again.",
15999
+ "AUTH/USER_NOT_INITIALIZED",
16000
+ 500
16001
+ );
16071
16002
  }
16072
16003
  let practitioner;
16073
16004
  if (practitionerIds.length === 1) {
@@ -16248,7 +16179,7 @@ var AuthService = class extends BaseService {
16248
16179
  * @returns Object containing user, practitioner (if exists), and draft profiles (if any)
16249
16180
  */
16250
16181
  async signUpPractitionerWithGoogle(idToken) {
16251
- var _a, _b;
16182
+ var _a, _b, _c;
16252
16183
  try {
16253
16184
  console.log("[AUTH] Starting practitioner Google Sign-In/Sign-Up");
16254
16185
  let email;
@@ -16313,14 +16244,31 @@ var AuthService = class extends BaseService {
16313
16244
  404
16314
16245
  );
16315
16246
  }
16316
- console.log("[AUTH] Draft profiles found, returning to client for selection");
16317
- const draftProfilesFound = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
16318
- return {
16319
- user: null,
16320
- // Will be created when claiming profiles
16321
- practitioner: null,
16322
- draftProfiles: draftProfilesFound
16323
- };
16247
+ console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
16248
+ console.log("[AUTH] auth.currentUser at User creation time:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
16249
+ try {
16250
+ const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
16251
+ skipProfileCreation: true
16252
+ });
16253
+ console.log("[AUTH] \u2705 User document created successfully:", newUser.uid);
16254
+ return {
16255
+ user: newUser,
16256
+ practitioner: null,
16257
+ draftProfiles: draftProfiles3
16258
+ };
16259
+ } catch (createUserError) {
16260
+ console.error("[AUTH] \u274C Failed to create User document:", {
16261
+ errorCode: createUserError == null ? void 0 : createUserError.code,
16262
+ errorMessage: createUserError == null ? void 0 : createUserError.message,
16263
+ uid: firebaseUser2.uid
16264
+ });
16265
+ try {
16266
+ await (0, import_auth8.signOut)(this.auth);
16267
+ } catch (signOutError) {
16268
+ console.warn("[AUTH] Error signing out Firebase user (non-critical):", signOutError);
16269
+ }
16270
+ throw createUserError;
16271
+ }
16324
16272
  }
16325
16273
  if (!existingUser2) {
16326
16274
  await (0, import_auth8.signOut)(this.auth);
@@ -16434,7 +16382,7 @@ var AuthService = class extends BaseService {
16434
16382
  };
16435
16383
  } catch (error) {
16436
16384
  console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
16437
- console.error("[AUTH] Error type:", (_b = error == null ? void 0 : error.constructor) == null ? void 0 : _b.name);
16385
+ console.error("[AUTH] Error type:", (_c = error == null ? void 0 : error.constructor) == null ? void 0 : _c.name);
16438
16386
  console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
16439
16387
  console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
16440
16388
  console.error("[AUTH] Error message:", error == null ? void 0 : error.message);
package/dist/index.mjs CHANGED
@@ -7122,13 +7122,9 @@ import {
7122
7122
  } from "firebase/auth";
7123
7123
  import {
7124
7124
  collection as collection21,
7125
- doc as doc25,
7126
- getDoc as getDoc27,
7127
- setDoc as setDoc16,
7128
7125
  query as query21,
7129
7126
  getDocs as getDocs21,
7130
- runTransaction,
7131
- serverTimestamp as serverTimestamp21
7127
+ runTransaction
7132
7128
  } from "firebase/firestore";
7133
7129
 
7134
7130
  // src/types/user/index.ts
@@ -15479,45 +15475,19 @@ var AuthService = class extends BaseService {
15479
15475
  super(db, auth, app);
15480
15476
  this.googleProvider = new GoogleAuthProvider();
15481
15477
  this.userService = userService || new UserService(db, auth, app);
15482
- if (!this.auth.__authServiceId) {
15483
- this.auth.__authServiceId = "auth-service-" + Date.now();
15484
- }
15485
- console.log("[AUTH] AuthService constructor - auth ID:", this.auth.__authServiceId);
15486
- console.log("[AUTH] AuthService constructor - userService.auth ID:", ((_a = this.userService.auth) == null ? void 0 : _a.__authServiceId) || "NOT SET");
15487
- }
15488
- /**
15489
- * Waits for Firebase Auth state to settle after sign-in.
15490
- * In React Native with Firebase JS SDK, auth.currentUser doesn't update synchronously
15491
- * after signInWithCredential. This causes Firestore permission issues.
15492
- *
15493
- * @param expectedUid - The UID we expect to see in auth.currentUser
15494
- * @param timeoutMs - Maximum time to wait (default 10 seconds)
15495
- * @returns Promise that resolves when auth state is ready
15496
- */
15497
- waitForAuthState(expectedUid, timeoutMs = 1e4) {
15498
- return new Promise((resolve, reject) => {
15499
- var _a;
15500
- if (((_a = this.auth.currentUser) == null ? void 0 : _a.uid) === expectedUid) {
15501
- console.log("[AUTH] Auth state already settled for:", expectedUid);
15502
- resolve();
15503
- return;
15504
- }
15505
- console.log("[AUTH] Waiting for auth state to settle for:", expectedUid);
15506
- const timeout = setTimeout(() => {
15507
- unsubscribe();
15508
- console.error("[AUTH] Timeout waiting for auth state");
15509
- reject(new Error("Timeout waiting for auth state to settle"));
15510
- }, timeoutMs);
15511
- const unsubscribe = onAuthStateChanged(this.auth, (user) => {
15512
- console.log("[AUTH] Auth state changed:", (user == null ? void 0 : user.uid) || "null");
15513
- if ((user == null ? void 0 : user.uid) === expectedUid) {
15514
- clearTimeout(timeout);
15515
- unsubscribe();
15516
- console.log("[AUTH] Auth state settled successfully for:", expectedUid);
15517
- resolve();
15518
- }
15519
- });
15478
+ onAuthStateChanged(this.auth, (user) => {
15479
+ var _a2, _b;
15480
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
15481
+ const stackTrace = ((_a2 = new Error().stack) == null ? void 0 : _a2.split("\n").slice(2, 5).join("\n")) || "N/A";
15482
+ console.log(`[AUTH STATE CHANGE] ${timestamp}`);
15483
+ console.log(`[AUTH STATE CHANGE] User: ${(user == null ? void 0 : user.uid) || "NULL"} (email: ${(user == null ? void 0 : user.email) || "N/A"})`);
15484
+ console.log(`[AUTH STATE CHANGE] auth.currentUser: ${((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL"}`);
15485
+ console.log(`[AUTH STATE CHANGE] Stack trace (first 3 frames):
15486
+ ${stackTrace}`);
15487
+ console.log("[AUTH STATE CHANGE] ---");
15520
15488
  });
15489
+ console.log("[AUTH] AuthService initialized");
15490
+ console.log("[AUTH] Initial auth.currentUser:", ((_a = this.auth.currentUser) == null ? void 0 : _a.uid) || "NULL");
15521
15491
  }
15522
15492
  /**
15523
15493
  * Registruje novog korisnika sa email-om i lozinkom
@@ -16087,7 +16057,7 @@ var AuthService = class extends BaseService {
16087
16057
  * @returns Object containing user and claimed practitioner
16088
16058
  */
16089
16059
  async claimDraftProfilesWithGoogle(idToken, practitionerIds) {
16090
- var _a, _b, _c, _d, _e;
16060
+ var _a, _b;
16091
16061
  try {
16092
16062
  console.log("[AUTH] Starting claim draft profiles with Google", {
16093
16063
  practitionerIdsCount: practitionerIds.length,
@@ -16104,61 +16074,18 @@ var AuthService = class extends BaseService {
16104
16074
  console.log("[AUTH] currentUser IMMEDIATELY AFTER sign-in:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
16105
16075
  console.log("[AUTH] User returned from signInWithCredential:", firebaseUser.uid);
16106
16076
  const practitionerService = new PractitionerService(this.db, this.auth, this.app);
16107
- console.log("[AUTH] currentUser after intializing practitionerService:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
16108
- let user = null;
16077
+ let user;
16109
16078
  try {
16110
16079
  user = await this.userService.getUserById(firebaseUser.uid);
16111
- console.log("[AUTH] User document already exists:", user.uid);
16080
+ console.log("[AUTH] User document found:", user.uid);
16112
16081
  } catch (userError) {
16113
- console.log("[AUTH] User document does not exist, creating it...");
16114
- }
16115
- if (!user) {
16116
- console.log("[AUTH] Creating user document DIRECTLY for:", firebaseUser.uid);
16117
- console.log("[AUTH] Checking auth.currentUser BEFORE refresh:", ((_d = this.auth.currentUser) == null ? void 0 : _d.uid) || "NULL");
16118
- try {
16119
- const token = await firebaseUser.getIdToken(true);
16120
- console.log("[AUTH] Got ID token, length:", (token == null ? void 0 : token.length) || 0);
16121
- } catch (tokenError) {
16122
- console.error("[AUTH] Error getting token:", tokenError);
16123
- }
16124
- await new Promise((resolve) => setTimeout(resolve, 100));
16125
- console.log("[AUTH] Using THIS.auth.currentUser AFTER refresh:", ((_e = this.auth.currentUser) == null ? void 0 : _e.uid) || "NULL");
16126
- console.log("[AUTH] Using THIS.db:", this.db ? "EXISTS" : "NULL");
16127
- if (!this.auth.currentUser) {
16128
- console.error("[AUTH] \u26A0\uFE0F auth.currentUser is STILL NULL after refresh! This is a React Native Firebase JS SDK issue.");
16129
- console.error("[AUTH] Firestore will deny permission because request.auth will be null.");
16130
- }
16131
- const userData = {
16132
- uid: firebaseUser.uid,
16133
- email: firebaseUser.email,
16134
- roles: ["practitioner" /* PRACTITIONER */],
16135
- isAnonymous: firebaseUser.isAnonymous || false,
16136
- createdAt: serverTimestamp21(),
16137
- updatedAt: serverTimestamp21(),
16138
- lastLoginAt: serverTimestamp21()
16139
- };
16140
- console.log("[AUTH] Attempting setDoc directly with userData:", {
16141
- uid: userData.uid,
16142
- email: userData.email,
16143
- roles: userData.roles
16144
- });
16145
- try {
16146
- await setDoc16(doc25(this.db, USERS_COLLECTION, firebaseUser.uid), userData);
16147
- console.log("[AUTH] \u2705 setDoc SUCCEEDED directly!");
16148
- const userDoc = await getDoc27(doc25(this.db, USERS_COLLECTION, firebaseUser.uid));
16149
- if (!userDoc.exists()) {
16150
- throw new Error("User document was not created");
16151
- }
16152
- user = userDoc.data();
16153
- console.log("[AUTH] User document created successfully:", user.uid);
16154
- } catch (error) {
16155
- console.error("[AUTH] \u274C setDoc FAILED directly:", {
16156
- errorCode: error == null ? void 0 : error.code,
16157
- errorMessage: error == null ? void 0 : error.message,
16158
- uid: firebaseUser.uid
16159
- });
16160
- throw error;
16161
- }
16082
+ console.error("[AUTH] \u274C User document should already exist! It should have been created in signUpPractitionerWithGoogle.");
16083
+ console.error("[AUTH] This indicates a bug - User doc creation failed in the initial Google sign-in flow.");
16084
+ throw new AuthError(
16085
+ "User account not properly initialized. Please try signing in again.",
16086
+ "AUTH/USER_NOT_INITIALIZED",
16087
+ 500
16088
+ );
16162
16089
  }
16163
16090
  let practitioner;
16164
16091
  if (practitionerIds.length === 1) {
@@ -16339,7 +16266,7 @@ var AuthService = class extends BaseService {
16339
16266
  * @returns Object containing user, practitioner (if exists), and draft profiles (if any)
16340
16267
  */
16341
16268
  async signUpPractitionerWithGoogle(idToken) {
16342
- var _a, _b;
16269
+ var _a, _b, _c;
16343
16270
  try {
16344
16271
  console.log("[AUTH] Starting practitioner Google Sign-In/Sign-Up");
16345
16272
  let email;
@@ -16404,14 +16331,31 @@ var AuthService = class extends BaseService {
16404
16331
  404
16405
16332
  );
16406
16333
  }
16407
- console.log("[AUTH] Draft profiles found, returning to client for selection");
16408
- const draftProfilesFound = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
16409
- return {
16410
- user: null,
16411
- // Will be created when claiming profiles
16412
- practitioner: null,
16413
- draftProfiles: draftProfilesFound
16414
- };
16334
+ console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
16335
+ console.log("[AUTH] auth.currentUser at User creation time:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
16336
+ try {
16337
+ const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
16338
+ skipProfileCreation: true
16339
+ });
16340
+ console.log("[AUTH] \u2705 User document created successfully:", newUser.uid);
16341
+ return {
16342
+ user: newUser,
16343
+ practitioner: null,
16344
+ draftProfiles: draftProfiles3
16345
+ };
16346
+ } catch (createUserError) {
16347
+ console.error("[AUTH] \u274C Failed to create User document:", {
16348
+ errorCode: createUserError == null ? void 0 : createUserError.code,
16349
+ errorMessage: createUserError == null ? void 0 : createUserError.message,
16350
+ uid: firebaseUser2.uid
16351
+ });
16352
+ try {
16353
+ await firebaseSignOut(this.auth);
16354
+ } catch (signOutError) {
16355
+ console.warn("[AUTH] Error signing out Firebase user (non-critical):", signOutError);
16356
+ }
16357
+ throw createUserError;
16358
+ }
16415
16359
  }
16416
16360
  if (!existingUser2) {
16417
16361
  await firebaseSignOut(this.auth);
@@ -16525,7 +16469,7 @@ var AuthService = class extends BaseService {
16525
16469
  };
16526
16470
  } catch (error) {
16527
16471
  console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
16528
- console.error("[AUTH] Error type:", (_b = error == null ? void 0 : error.constructor) == null ? void 0 : _b.name);
16472
+ console.error("[AUTH] Error type:", (_c = error == null ? void 0 : error.constructor) == null ? void 0 : _c.name);
16529
16473
  console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
16530
16474
  console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
16531
16475
  console.error("[AUTH] Error message:", error == null ? void 0 : error.message);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.14.14",
4
+ "version": "1.14.16",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -92,54 +92,22 @@ export class AuthService extends BaseService {
92
92
  super(db, auth, app);
93
93
  this.userService = userService || new UserService(db, auth, app);
94
94
 
95
- // DEBUG: Tag the auth instances to track them
96
- // @ts-ignore
97
- if (!this.auth.__authServiceId) {
98
- // @ts-ignore
99
- this.auth.__authServiceId = 'auth-service-' + Date.now();
100
- }
101
- // @ts-ignore
102
- console.log('[AUTH] AuthService constructor - auth ID:', this.auth.__authServiceId);
103
- // @ts-ignore
104
- console.log('[AUTH] AuthService constructor - userService.auth ID:', (this.userService as any).auth?.__authServiceId || 'NOT SET');
105
- }
106
-
107
- /**
108
- * Waits for Firebase Auth state to settle after sign-in.
109
- * In React Native with Firebase JS SDK, auth.currentUser doesn't update synchronously
110
- * after signInWithCredential. This causes Firestore permission issues.
111
- *
112
- * @param expectedUid - The UID we expect to see in auth.currentUser
113
- * @param timeoutMs - Maximum time to wait (default 10 seconds)
114
- * @returns Promise that resolves when auth state is ready
115
- */
116
- private waitForAuthState(expectedUid: string, timeoutMs: number = 10000): Promise<void> {
117
- return new Promise((resolve, reject) => {
118
- // If already correct, resolve immediately
119
- if (this.auth.currentUser?.uid === expectedUid) {
120
- console.log('[AUTH] Auth state already settled for:', expectedUid);
121
- resolve();
122
- return;
123
- }
124
-
125
- console.log('[AUTH] Waiting for auth state to settle for:', expectedUid);
126
-
127
- const timeout = setTimeout(() => {
128
- unsubscribe();
129
- console.error('[AUTH] Timeout waiting for auth state');
130
- reject(new Error('Timeout waiting for auth state to settle'));
131
- }, timeoutMs);
132
-
133
- const unsubscribe = onAuthStateChanged(this.auth, (user) => {
134
- console.log('[AUTH] Auth state changed:', user?.uid || 'null');
135
- if (user?.uid === expectedUid) {
136
- clearTimeout(timeout);
137
- unsubscribe();
138
- console.log('[AUTH] Auth state settled successfully for:', expectedUid);
139
- resolve();
140
- }
141
- });
95
+ // Initialize auth state change listener for debugging
96
+ // This helps track when auth.currentUser changes, which is critical for debugging
97
+ // the permission-denied issue during user document creation
98
+ onAuthStateChanged(this.auth, (user) => {
99
+ const timestamp = new Date().toISOString();
100
+ const stackTrace = new Error().stack?.split('\n').slice(2, 5).join('\n') || 'N/A';
101
+ console.log(`[AUTH STATE CHANGE] ${timestamp}`);
102
+ console.log(`[AUTH STATE CHANGE] User: ${user?.uid || 'NULL'} (email: ${user?.email || 'N/A'})`);
103
+ console.log(`[AUTH STATE CHANGE] auth.currentUser: ${this.auth.currentUser?.uid || 'NULL'}`);
104
+ console.log(`[AUTH STATE CHANGE] Stack trace (first 3 frames):\n${stackTrace}`);
105
+ console.log('[AUTH STATE CHANGE] ---');
142
106
  });
107
+
108
+ // Log initial auth state
109
+ console.log('[AUTH] AuthService initialized');
110
+ console.log('[AUTH] Initial auth.currentUser:', this.auth.currentUser?.uid || 'NULL');
143
111
  }
144
112
 
145
113
  /**
@@ -900,81 +868,22 @@ export class AuthService extends BaseService {
900
868
  console.log('[AUTH] User returned from signInWithCredential:', firebaseUser.uid);
901
869
 
902
870
  const practitionerService = new PractitionerService(this.db, this.auth, this.app);
903
- console.log('[AUTH] currentUser after intializing practitionerService:', this.auth.currentUser?.uid || 'NULL');
904
871
 
905
- // Step 1: Check if User document already exists
906
- let user: User | null = null;
872
+ // Step 1: Get User document (should already exist from signUpPractitionerWithGoogle)
873
+ // The User document is created IMMEDIATELY after Google sign-in in signUpPractitionerWithGoogle
874
+ // This matches the token flow pattern - no delays between sign-in and User doc creation
875
+ let user: User;
907
876
  try {
908
877
  user = await this.userService.getUserById(firebaseUser.uid);
909
- console.log('[AUTH] User document already exists:', user.uid);
878
+ console.log('[AUTH] User document found:', user.uid);
910
879
  } catch (userError) {
911
- console.log('[AUTH] User document does not exist, creating it...');
912
- }
913
-
914
- // Step 2: Create User document directly (bypassing UserService to test auth instance issue)
915
- if (!user) {
916
- console.log('[AUTH] Creating user document DIRECTLY for:', firebaseUser.uid);
917
-
918
- // CRITICAL: Force auth state refresh right before setDoc
919
- // React Native Firebase JS SDK has issues where auth.currentUser becomes NULL
920
- // We need to ensure it's set before Firestore operations
921
- console.log('[AUTH] Checking auth.currentUser BEFORE refresh:', this.auth.currentUser?.uid || 'NULL');
922
-
923
- // Force token refresh to ensure auth state is set
924
- try {
925
- const token = await firebaseUser.getIdToken(true);
926
- console.log('[AUTH] Got ID token, length:', token?.length || 0);
927
- } catch (tokenError) {
928
- console.error('[AUTH] Error getting token:', tokenError);
929
- }
930
-
931
- // Wait a tiny bit for auth state to propagate
932
- await new Promise(resolve => setTimeout(resolve, 100));
933
-
934
- console.log('[AUTH] Using THIS.auth.currentUser AFTER refresh:', this.auth.currentUser?.uid || 'NULL');
935
- console.log('[AUTH] Using THIS.db:', this.db ? 'EXISTS' : 'NULL');
936
-
937
- // If still NULL, this is a React Native Firebase JS SDK bug
938
- if (!this.auth.currentUser) {
939
- console.error('[AUTH] ⚠️ auth.currentUser is STILL NULL after refresh! This is a React Native Firebase JS SDK issue.');
940
- console.error('[AUTH] Firestore will deny permission because request.auth will be null.');
941
- }
942
-
943
- const userData = {
944
- uid: firebaseUser.uid,
945
- email: firebaseUser.email,
946
- roles: [UserRole.PRACTITIONER],
947
- isAnonymous: firebaseUser.isAnonymous || false,
948
- createdAt: serverTimestamp(),
949
- updatedAt: serverTimestamp(),
950
- lastLoginAt: serverTimestamp(),
951
- };
952
-
953
- console.log('[AUTH] Attempting setDoc directly with userData:', {
954
- uid: userData.uid,
955
- email: userData.email,
956
- roles: userData.roles,
957
- });
958
-
959
- try {
960
- await setDoc(doc(this.db, USERS_COLLECTION, firebaseUser.uid), userData);
961
- console.log('[AUTH] ✅ setDoc SUCCEEDED directly!');
962
-
963
- // Fetch the created user
964
- const userDoc = await getDoc(doc(this.db, USERS_COLLECTION, firebaseUser.uid));
965
- if (!userDoc.exists()) {
966
- throw new Error('User document was not created');
967
- }
968
- user = userDoc.data() as User;
969
- console.log('[AUTH] User document created successfully:', user.uid);
970
- } catch (error: any) {
971
- console.error('[AUTH] ❌ setDoc FAILED directly:', {
972
- errorCode: error?.code,
973
- errorMessage: error?.message,
974
- uid: firebaseUser.uid,
975
- });
976
- throw error;
977
- }
880
+ console.error('[AUTH] User document should already exist! It should have been created in signUpPractitionerWithGoogle.');
881
+ console.error('[AUTH] This indicates a bug - User doc creation failed in the initial Google sign-in flow.');
882
+ throw new AuthError(
883
+ 'User account not properly initialized. Please try signing in again.',
884
+ 'AUTH/USER_NOT_INITIALIZED',
885
+ 500,
886
+ );
978
887
  }
979
888
 
980
889
  // Step 3: Claim the draft profiles
@@ -1308,19 +1217,38 @@ export class AuthService extends BaseService {
1308
1217
  );
1309
1218
  }
1310
1219
 
1311
- // Draft profiles exist - return them to client
1312
- // User document creation will happen server-side when claiming profiles
1313
- // This avoids permission issues with client-side User document creation
1314
- console.log('[AUTH] Draft profiles found, returning to client for selection');
1315
- const draftProfilesFound = await practitionerService.getDraftProfilesByEmail(normalizedEmail);
1220
+ // Draft profiles exist - CREATE USER DOCUMENT IMMEDIATELY (like token flow)
1221
+ // This matches the token flow pattern: create User doc right after sign-in, before any delays
1222
+ console.log('[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in');
1223
+ console.log('[AUTH] auth.currentUser at User creation time:', this.auth.currentUser?.uid || 'NULL');
1316
1224
 
1317
- // Return draft profiles without creating User document
1318
- // The User document will be created server-side via Cloud Function when claiming profiles
1319
- return {
1320
- user: null, // Will be created when claiming profiles
1321
- practitioner: null,
1322
- draftProfiles: draftProfilesFound,
1323
- };
1225
+ try {
1226
+ // Create User document immediately (same pattern as token flow)
1227
+ const newUser = await this.userService.createUser(firebaseUser, [UserRole.PRACTITIONER], {
1228
+ skipProfileCreation: true,
1229
+ });
1230
+ console.log('[AUTH] ✅ User document created successfully:', newUser.uid);
1231
+
1232
+ // Return user + draft profiles (user doc already exists, just need to claim profiles)
1233
+ return {
1234
+ user: newUser,
1235
+ practitioner: null,
1236
+ draftProfiles: draftProfiles,
1237
+ };
1238
+ } catch (createUserError: any) {
1239
+ console.error('[AUTH] ❌ Failed to create User document:', {
1240
+ errorCode: createUserError?.code,
1241
+ errorMessage: createUserError?.message,
1242
+ uid: firebaseUser.uid,
1243
+ });
1244
+ // Sign out on failure
1245
+ try {
1246
+ await firebaseSignOut(this.auth);
1247
+ } catch (signOutError) {
1248
+ console.warn('[AUTH] Error signing out Firebase user (non-critical):', signOutError);
1249
+ }
1250
+ throw createUserError;
1251
+ }
1324
1252
  }
1325
1253
 
1326
1254
  // User document exists - check for practitioner profile and draft profiles