@blackcode_sa/metaestetics-api 1.14.17 → 1.14.23

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.
@@ -11860,21 +11860,10 @@ var practitionerInvitationTemplate = `
11860
11860
 
11861
11861
  <p>This token will expire on <strong>{{expirationDate}}</strong>.</p>
11862
11862
 
11863
- <p><strong>You have two options to create your account:</strong></p>
11864
-
11865
- <p><strong>Option 1: Sign in with Google (Recommended)</strong></p>
11866
- <ol>
11867
- <li>Open the MetaEsthetics Doctor App</li>
11868
- <li>Click "Sign in with Google" on the login screen</li>
11869
- <li>Select your Google account (use the email address: {{practitionerEmail}})</li>
11870
- <li>You'll see an invitation to join {{clinicName}} - simply select it and join!</li>
11871
- </ol>
11872
-
11873
- <p><strong>Option 2: Use Email/Password with Token</strong></p>
11863
+ <p>To create your account:</p>
11874
11864
  <ol>
11875
11865
  <li>Visit {{registrationUrl}}</li>
11876
- <li>Click "Claim Existing Profile with Token"</li>
11877
- <li>Enter your email ({{practitionerEmail}}) and create a password</li>
11866
+ <li>Enter your email and create a password</li>
11878
11867
  <li>When prompted, enter the token above</li>
11879
11868
  </ol>
11880
11869
 
@@ -11787,21 +11787,10 @@ var practitionerInvitationTemplate = `
11787
11787
 
11788
11788
  <p>This token will expire on <strong>{{expirationDate}}</strong>.</p>
11789
11789
 
11790
- <p><strong>You have two options to create your account:</strong></p>
11791
-
11792
- <p><strong>Option 1: Sign in with Google (Recommended)</strong></p>
11793
- <ol>
11794
- <li>Open the MetaEsthetics Doctor App</li>
11795
- <li>Click "Sign in with Google" on the login screen</li>
11796
- <li>Select your Google account (use the email address: {{practitionerEmail}})</li>
11797
- <li>You'll see an invitation to join {{clinicName}} - simply select it and join!</li>
11798
- </ol>
11799
-
11800
- <p><strong>Option 2: Use Email/Password with Token</strong></p>
11790
+ <p>To create your account:</p>
11801
11791
  <ol>
11802
11792
  <li>Visit {{registrationUrl}}</li>
11803
- <li>Click "Claim Existing Profile with Token"</li>
11804
- <li>Enter your email ({{practitionerEmail}}) and create a password</li>
11793
+ <li>Enter your email and create a password</li>
11805
11794
  <li>When prompted, enter the token above</li>
11806
11795
  </ol>
11807
11796
 
package/dist/index.d.mts CHANGED
@@ -6992,9 +6992,10 @@ declare class PractitionerService extends BaseService {
6992
6992
  /**
6993
6993
  * Gets active tokens for a practitioner
6994
6994
  * @param practitionerId ID of the practitioner
6995
+ * @param clinicId Optional clinic ID to filter tokens by. If provided, only returns tokens for this clinic.
6995
6996
  * @returns Array of active tokens
6996
6997
  */
6997
- getPractitionerActiveTokens(practitionerId: string): Promise<PractitionerToken[]>;
6998
+ getPractitionerActiveTokens(practitionerId: string, clinicId?: string): Promise<PractitionerToken[]>;
6998
6999
  /**
6999
7000
  * Gets a token by its string value and validates it
7000
7001
  * @param tokenString The token string to find
@@ -7008,6 +7009,14 @@ declare class PractitionerService extends BaseService {
7008
7009
  * @param userId ID of the user using the token
7009
7010
  */
7010
7011
  markTokenAsUsed(tokenId: string, practitionerId: string, userId: string): Promise<void>;
7012
+ /**
7013
+ * Revokes a token by setting its status to REVOKED
7014
+ * @param tokenId ID of the token
7015
+ * @param practitionerId ID of the practitioner
7016
+ * @param clinicId ID of the clinic that owns the token. Used to verify ownership before revoking.
7017
+ * @throws Error if token doesn't exist or doesn't belong to the specified clinic
7018
+ */
7019
+ revokeToken(tokenId: string, practitionerId: string, clinicId: string): Promise<void>;
7011
7020
  /**
7012
7021
  * Dohvata zdravstvenog radnika po ID-u
7013
7022
  */
@@ -8323,19 +8332,7 @@ declare class AuthService extends BaseService {
8323
8332
  constructor(db: Firestore, auth: Auth, app: FirebaseApp, userService: UserService);
8324
8333
  /**
8325
8334
  * Waits for Firebase Auth state to settle after sign-in.
8326
- *
8327
- * In React Native with AsyncStorage persistence, there's a critical issue:
8328
- * 1. signInWithCredential() sets auth.currentUser in memory immediately
8329
- * 2. But AsyncStorage persistence happens asynchronously
8330
- * 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
8331
- * 4. This causes auth.currentUser to become NULL even after it was set
8332
- *
8333
- * This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
8334
- * It ensures the auth state persists through AsyncStorage operations.
8335
- *
8336
- * @param expectedUid - The UID we expect to see in auth.currentUser
8337
- * @param timeoutMs - Maximum time to wait (default 5 seconds)
8338
- * @returns Promise that resolves when auth state is ready and stable
8335
+ * In React Native with AsyncStorage persistence, auth state may not be immediately available.
8339
8336
  */
8340
8337
  private waitForAuthStateToSettle;
8341
8338
  /**
package/dist/index.d.ts CHANGED
@@ -6992,9 +6992,10 @@ declare class PractitionerService extends BaseService {
6992
6992
  /**
6993
6993
  * Gets active tokens for a practitioner
6994
6994
  * @param practitionerId ID of the practitioner
6995
+ * @param clinicId Optional clinic ID to filter tokens by. If provided, only returns tokens for this clinic.
6995
6996
  * @returns Array of active tokens
6996
6997
  */
6997
- getPractitionerActiveTokens(practitionerId: string): Promise<PractitionerToken[]>;
6998
+ getPractitionerActiveTokens(practitionerId: string, clinicId?: string): Promise<PractitionerToken[]>;
6998
6999
  /**
6999
7000
  * Gets a token by its string value and validates it
7000
7001
  * @param tokenString The token string to find
@@ -7008,6 +7009,14 @@ declare class PractitionerService extends BaseService {
7008
7009
  * @param userId ID of the user using the token
7009
7010
  */
7010
7011
  markTokenAsUsed(tokenId: string, practitionerId: string, userId: string): Promise<void>;
7012
+ /**
7013
+ * Revokes a token by setting its status to REVOKED
7014
+ * @param tokenId ID of the token
7015
+ * @param practitionerId ID of the practitioner
7016
+ * @param clinicId ID of the clinic that owns the token. Used to verify ownership before revoking.
7017
+ * @throws Error if token doesn't exist or doesn't belong to the specified clinic
7018
+ */
7019
+ revokeToken(tokenId: string, practitionerId: string, clinicId: string): Promise<void>;
7011
7020
  /**
7012
7021
  * Dohvata zdravstvenog radnika po ID-u
7013
7022
  */
@@ -8323,19 +8332,7 @@ declare class AuthService extends BaseService {
8323
8332
  constructor(db: Firestore, auth: Auth, app: FirebaseApp, userService: UserService);
8324
8333
  /**
8325
8334
  * Waits for Firebase Auth state to settle after sign-in.
8326
- *
8327
- * In React Native with AsyncStorage persistence, there's a critical issue:
8328
- * 1. signInWithCredential() sets auth.currentUser in memory immediately
8329
- * 2. But AsyncStorage persistence happens asynchronously
8330
- * 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
8331
- * 4. This causes auth.currentUser to become NULL even after it was set
8332
- *
8333
- * This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
8334
- * It ensures the auth state persists through AsyncStorage operations.
8335
- *
8336
- * @param expectedUid - The UID we expect to see in auth.currentUser
8337
- * @param timeoutMs - Maximum time to wait (default 5 seconds)
8338
- * @returns Promise that resolves when auth state is ready and stable
8335
+ * In React Native with AsyncStorage persistence, auth state may not be immediately available.
8339
8336
  */
8340
8337
  private waitForAuthStateToSettle;
8341
8338
  /**
package/dist/index.js CHANGED
@@ -11533,6 +11533,24 @@ var PractitionerService = class extends BaseService {
11533
11533
  if (!practitioner.clinics.includes(validatedData.clinicId)) {
11534
11534
  throw new Error("Practitioner is not associated with this clinic");
11535
11535
  }
11536
+ let expectedClinicGroupId = null;
11537
+ if (clinic.clinicGroupId === createdBy) {
11538
+ expectedClinicGroupId = createdBy;
11539
+ } else {
11540
+ try {
11541
+ const creatorClinic = await this.getClinicService().getClinic(createdBy);
11542
+ if (creatorClinic && creatorClinic.clinicGroupId === clinic.clinicGroupId) {
11543
+ expectedClinicGroupId = clinic.clinicGroupId;
11544
+ } else {
11545
+ throw new Error("Clinic does not belong to your clinic group");
11546
+ }
11547
+ } catch (error) {
11548
+ if (error.message === "Clinic does not belong to your clinic group") {
11549
+ throw error;
11550
+ }
11551
+ throw new Error("Clinic does not belong to your clinic group");
11552
+ }
11553
+ }
11536
11554
  const expiration = validatedData.expiresAt || new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3);
11537
11555
  const tokenString = this.generateId().slice(0, 6).toUpperCase();
11538
11556
  const token = {
@@ -11560,18 +11578,22 @@ var PractitionerService = class extends BaseService {
11560
11578
  /**
11561
11579
  * Gets active tokens for a practitioner
11562
11580
  * @param practitionerId ID of the practitioner
11581
+ * @param clinicId Optional clinic ID to filter tokens by. If provided, only returns tokens for this clinic.
11563
11582
  * @returns Array of active tokens
11564
11583
  */
11565
- async getPractitionerActiveTokens(practitionerId) {
11584
+ async getPractitionerActiveTokens(practitionerId, clinicId) {
11566
11585
  const tokensRef = (0, import_firestore32.collection)(
11567
11586
  this.db,
11568
11587
  `${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
11569
11588
  );
11570
- const q = (0, import_firestore32.query)(
11571
- tokensRef,
11589
+ const conditions = [
11572
11590
  (0, import_firestore32.where)("status", "==", "active" /* ACTIVE */),
11573
11591
  (0, import_firestore32.where)("expiresAt", ">", import_firestore32.Timestamp.now())
11574
- );
11592
+ ];
11593
+ if (clinicId) {
11594
+ conditions.push((0, import_firestore32.where)("clinicId", "==", clinicId));
11595
+ }
11596
+ const q = (0, import_firestore32.query)(tokensRef, ...conditions);
11575
11597
  const querySnapshot = await (0, import_firestore32.getDocs)(q);
11576
11598
  return querySnapshot.docs.map((doc47) => doc47.data());
11577
11599
  }
@@ -11646,6 +11668,34 @@ var PractitionerService = class extends BaseService {
11646
11668
  usedAt: import_firestore32.Timestamp.now()
11647
11669
  });
11648
11670
  }
11671
+ /**
11672
+ * Revokes a token by setting its status to REVOKED
11673
+ * @param tokenId ID of the token
11674
+ * @param practitionerId ID of the practitioner
11675
+ * @param clinicId ID of the clinic that owns the token. Used to verify ownership before revoking.
11676
+ * @throws Error if token doesn't exist or doesn't belong to the specified clinic
11677
+ */
11678
+ async revokeToken(tokenId, practitionerId, clinicId) {
11679
+ const tokenRef = (0, import_firestore32.doc)(
11680
+ this.db,
11681
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}/${tokenId}`
11682
+ );
11683
+ const tokenDoc = await (0, import_firestore32.getDoc)(tokenRef);
11684
+ if (!tokenDoc.exists()) {
11685
+ throw new Error("Token not found");
11686
+ }
11687
+ const tokenData = tokenDoc.data();
11688
+ if (tokenData.clinicId !== clinicId) {
11689
+ throw new Error("Token does not belong to the specified clinic");
11690
+ }
11691
+ if (tokenData.status !== "active" /* ACTIVE */) {
11692
+ throw new Error("Token is not active and cannot be revoked");
11693
+ }
11694
+ await (0, import_firestore32.updateDoc)(tokenRef, {
11695
+ status: "revoked" /* REVOKED */,
11696
+ updatedAt: (0, import_firestore32.serverTimestamp)()
11697
+ });
11698
+ }
11649
11699
  /**
11650
11700
  * Dohvata zdravstvenog radnika po ID-u
11651
11701
  */
@@ -12880,11 +12930,6 @@ var PractitionerService = class extends BaseService {
12880
12930
  var UserService = class extends BaseService {
12881
12931
  constructor(db, auth, app, patientService, clinicAdminService, practitionerService) {
12882
12932
  super(db, auth, app);
12883
- if (!this.auth.__userServiceId) {
12884
- this.auth.__userServiceId = "user-service-" + Date.now();
12885
- }
12886
- console.log("[USER_SERVICE] Constructor - auth ID:", this.auth.__userServiceId);
12887
- console.log("[USER_SERVICE] Constructor - auth.__authServiceId:", this.auth.__authServiceId || "NOT SET");
12888
12933
  if (!patientService) {
12889
12934
  patientService = new PatientService(db, auth, app);
12890
12935
  }
@@ -12911,25 +12956,6 @@ var UserService = class extends BaseService {
12911
12956
  * Kreira novog korisnika na osnovu Firebase korisnika
12912
12957
  */
12913
12958
  async createUser(firebaseUser, roles = ["patient" /* PATIENT */], options) {
12914
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
12915
- console.log("[USER_SERVICE] ====== CREATE USER DEBUG ======");
12916
- console.log(this.auth);
12917
- console.log("[USER_SERVICE] Auth instance ID:", ((_a = this.auth) == null ? void 0 : _a.__debugId) || "no-id");
12918
- console.log("[USER_SERVICE] Current auth state:", {
12919
- currentUser: ((_c = (_b = this.auth) == null ? void 0 : _b.currentUser) == null ? void 0 : _c.uid) || "NULL",
12920
- currentUserEmail: ((_e = (_d = this.auth) == null ? void 0 : _d.currentUser) == null ? void 0 : _e.email) || "NULL",
12921
- currentUserProvider: ((_g = (_f = this.auth) == null ? void 0 : _f.currentUser) == null ? void 0 : _g.providerId) || "NULL"
12922
- });
12923
- console.log("[USER_SERVICE] Firebase user passed to createUser:", {
12924
- uid: (firebaseUser == null ? void 0 : firebaseUser.uid) || "NULL",
12925
- email: (firebaseUser == null ? void 0 : firebaseUser.email) || "NULL",
12926
- providerId: (firebaseUser == null ? void 0 : firebaseUser.providerId) || "NULL",
12927
- isAnonymous: firebaseUser == null ? void 0 : firebaseUser.isAnonymous
12928
- });
12929
- console.log("[USER_SERVICE] Auth instances match:", ((_i = (_h = this.auth) == null ? void 0 : _h.currentUser) == null ? void 0 : _i.uid) === (firebaseUser == null ? void 0 : firebaseUser.uid));
12930
- console.log("[USER_SERVICE] Document path:", `${USERS_COLLECTION}/${firebaseUser == null ? void 0 : firebaseUser.uid}`);
12931
- console.log("[USER_SERVICE] Roles:", roles);
12932
- console.log("[USER_SERVICE] ================================");
12933
12959
  const userData = {
12934
12960
  uid: firebaseUser.uid,
12935
12961
  email: firebaseUser.email,
@@ -12939,22 +12965,7 @@ var UserService = class extends BaseService {
12939
12965
  updatedAt: (0, import_firestore33.serverTimestamp)(),
12940
12966
  lastLoginAt: (0, import_firestore33.serverTimestamp)()
12941
12967
  };
12942
- console.log("[USER_SERVICE] Attempting setDoc with userData:", {
12943
- uid: userData.uid,
12944
- email: userData.email,
12945
- roles: userData.roles
12946
- });
12947
- try {
12948
- await (0, import_firestore33.setDoc)((0, import_firestore33.doc)(this.db, USERS_COLLECTION, userData.uid), userData);
12949
- console.log("[USER_SERVICE] \u2705 setDoc SUCCEEDED for:", userData.uid);
12950
- } catch (error) {
12951
- console.error("[USER_SERVICE] \u274C setDoc FAILED:", {
12952
- errorCode: error == null ? void 0 : error.code,
12953
- errorMessage: error == null ? void 0 : error.message,
12954
- uid: userData.uid
12955
- });
12956
- throw error;
12957
- }
12968
+ await (0, import_firestore33.setDoc)((0, import_firestore33.doc)(this.db, USERS_COLLECTION, userData.uid), userData);
12958
12969
  if (options == null ? void 0 : options.skipProfileCreation) {
12959
12970
  return this.getUserById(userData.uid);
12960
12971
  }
@@ -15384,59 +15395,28 @@ var validatePractitionerProfileData = async (profileData) => {
15384
15395
  // src/services/auth/auth.service.ts
15385
15396
  var AuthService = class extends BaseService {
15386
15397
  constructor(db, auth, app, userService) {
15387
- var _a;
15388
15398
  super(db, auth, app);
15389
15399
  this.googleProvider = new import_auth8.GoogleAuthProvider();
15390
15400
  this.userService = userService || new UserService(db, auth, app);
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] ---");
15401
- });
15402
- console.log("[AUTH] AuthService initialized");
15403
- console.log("[AUTH] Initial auth.currentUser:", ((_a = this.auth.currentUser) == null ? void 0 : _a.uid) || "NULL");
15404
15401
  }
15405
15402
  /**
15406
15403
  * Waits for Firebase Auth state to settle after sign-in.
15407
- *
15408
- * In React Native with AsyncStorage persistence, there's a critical issue:
15409
- * 1. signInWithCredential() sets auth.currentUser in memory immediately
15410
- * 2. But AsyncStorage persistence happens asynchronously
15411
- * 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
15412
- * 4. This causes auth.currentUser to become NULL even after it was set
15413
- *
15414
- * This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
15415
- * It ensures the auth state persists through AsyncStorage operations.
15416
- *
15417
- * @param expectedUid - The UID we expect to see in auth.currentUser
15418
- * @param timeoutMs - Maximum time to wait (default 5 seconds)
15419
- * @returns Promise that resolves when auth state is ready and stable
15404
+ * In React Native with AsyncStorage persistence, auth state may not be immediately available.
15420
15405
  */
15421
15406
  async waitForAuthStateToSettle(expectedUid, timeoutMs = 5e3) {
15422
- var _a, _b, _c;
15407
+ var _a, _b;
15423
15408
  if (((_a = this.auth.currentUser) == null ? void 0 : _a.uid) === expectedUid) {
15424
- console.log("[AUTH] Auth state appears set, waiting for stability...");
15425
15409
  await new Promise((resolve) => setTimeout(resolve, 200));
15426
15410
  if (((_b = this.auth.currentUser) == null ? void 0 : _b.uid) === expectedUid) {
15427
- console.log("[AUTH] \u2705 Auth state stable for:", expectedUid);
15428
15411
  return;
15429
15412
  }
15430
15413
  }
15431
- console.log("[AUTH] Waiting for auth state to settle for:", expectedUid);
15432
- console.log("[AUTH] Current auth.currentUser:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
15433
15414
  return new Promise((resolve, reject) => {
15434
15415
  const startTime = Date.now();
15435
15416
  let resolved = false;
15436
15417
  const unsubscribe = (0, import_auth8.onAuthStateChanged)(this.auth, (user) => {
15437
15418
  if (resolved) return;
15438
15419
  const currentUid = (user == null ? void 0 : user.uid) || null;
15439
- console.log("[AUTH] onAuthStateChanged fired:", currentUid || "NULL");
15440
15420
  if (currentUid === expectedUid) {
15441
15421
  setTimeout(() => {
15442
15422
  var _a2;
@@ -15445,27 +15425,17 @@ ${stackTrace}`);
15445
15425
  resolved = true;
15446
15426
  unsubscribe();
15447
15427
  clearTimeout(timeout);
15448
- const elapsed = Date.now() - startTime;
15449
- console.log(`[AUTH] \u2705 Auth state settled and stable after ${elapsed}ms for:`, expectedUid);
15450
15428
  resolve();
15451
- } else {
15452
- console.warn("[AUTH] \u26A0\uFE0F Auth state became NULL after being set, waiting more...");
15453
15429
  }
15454
15430
  }, 300);
15455
- } else if (currentUid === null && Date.now() - startTime > 1e3) {
15456
- console.error("[AUTH] \u274C Auth state became NULL after being set!");
15457
- console.error("[AUTH] This indicates AsyncStorage persistence issue");
15458
15431
  }
15459
15432
  });
15460
15433
  const timeout = setTimeout(() => {
15461
- var _a2, _b2;
15434
+ var _a2;
15462
15435
  if (resolved) return;
15463
15436
  resolved = true;
15464
15437
  unsubscribe();
15465
- console.error("[AUTH] \u274C Timeout waiting for auth state to settle");
15466
- console.error("[AUTH] Expected UID:", expectedUid);
15467
- console.error("[AUTH] Actual auth.currentUser:", ((_a2 = this.auth.currentUser) == null ? void 0 : _a2.uid) || "NULL");
15468
- reject(new Error(`Timeout waiting for auth state to settle. Expected: ${expectedUid}, Got: ${((_b2 = this.auth.currentUser) == null ? void 0 : _b2.uid) || "NULL"}`));
15438
+ reject(new Error(`Timeout waiting for auth state to settle. Expected: ${expectedUid}, Got: ${((_a2 = this.auth.currentUser) == null ? void 0 : _a2.uid) || "NULL"}`));
15469
15439
  }, timeoutMs);
15470
15440
  });
15471
15441
  }
@@ -16037,7 +16007,6 @@ ${stackTrace}`);
16037
16007
  * @returns Object containing user and claimed practitioner
16038
16008
  */
16039
16009
  async claimDraftProfilesWithGoogle(idToken, practitionerIds) {
16040
- var _a, _b;
16041
16010
  try {
16042
16011
  console.log("[AUTH] Starting claim draft profiles with Google", {
16043
16012
  practitionerIdsCount: practitionerIds.length,
@@ -16046,21 +16015,14 @@ ${stackTrace}`);
16046
16015
  if (practitionerIds.length === 0) {
16047
16016
  throw new AuthError("No practitioner profiles selected to claim", "AUTH/NO_PROFILES_SELECTED", 400);
16048
16017
  }
16049
- console.log("[AUTH] currentUser BEFORE sign-in:", ((_a = this.auth.currentUser) == null ? void 0 : _a.uid) || "NULL");
16050
- console.log("[AUTH] Signing in with Google credential...");
16051
16018
  const credential = import_auth8.GoogleAuthProvider.credential(idToken);
16052
16019
  const result = await (0, import_auth8.signInWithCredential)(this.auth, credential);
16053
16020
  const firebaseUser = result.user;
16054
- console.log("[AUTH] currentUser IMMEDIATELY AFTER sign-in:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
16055
- console.log("[AUTH] User returned from signInWithCredential:", firebaseUser.uid);
16056
16021
  const practitionerService = new PractitionerService(this.db, this.auth, this.app);
16057
16022
  let user;
16058
16023
  try {
16059
16024
  user = await this.userService.getUserById(firebaseUser.uid);
16060
- console.log("[AUTH] User document found:", user.uid);
16061
16025
  } catch (userError) {
16062
- console.error("[AUTH] \u274C User document should already exist! It should have been created in signUpPractitionerWithGoogle.");
16063
- console.error("[AUTH] This indicates a bug - User doc creation failed in the initial Google sign-in flow.");
16064
16026
  throw new AuthError(
16065
16027
  "User account not properly initialized. Please try signing in again.",
16066
16028
  "AUTH/USER_NOT_INITIALIZED",
@@ -16069,30 +16031,22 @@ ${stackTrace}`);
16069
16031
  }
16070
16032
  let practitioner;
16071
16033
  if (practitionerIds.length === 1) {
16072
- console.log("[AUTH] Claiming single draft profile:", practitionerIds[0]);
16073
16034
  practitioner = await practitionerService.claimDraftProfileWithGoogle(
16074
16035
  practitionerIds[0],
16075
16036
  firebaseUser.uid
16076
16037
  );
16077
16038
  } else {
16078
- console.log("[AUTH] Claiming multiple draft profiles:", practitionerIds);
16079
16039
  practitioner = await practitionerService.claimMultipleDraftProfilesWithGoogle(
16080
16040
  practitionerIds,
16081
16041
  firebaseUser.uid
16082
16042
  );
16083
16043
  }
16084
- console.log("[AUTH] Draft profiles claimed:", practitioner.id);
16085
16044
  if (!user.practitionerProfile || user.practitionerProfile !== practitioner.id) {
16086
- console.log("[AUTH] Linking practitioner to user");
16087
16045
  await this.userService.updateUser(firebaseUser.uid, {
16088
16046
  practitionerProfile: practitioner.id
16089
16047
  });
16090
16048
  }
16091
16049
  const updatedUser = await this.userService.getUserById(firebaseUser.uid);
16092
- console.log("[AUTH] Draft profiles claimed successfully", {
16093
- userId: updatedUser.uid,
16094
- practitionerId: practitioner.id
16095
- });
16096
16050
  return {
16097
16051
  user: updatedUser,
16098
16052
  practitioner
@@ -16221,9 +16175,6 @@ ${stackTrace}`);
16221
16175
  const credential = import_auth8.GoogleAuthProvider.credential(idToken);
16222
16176
  const { user: firebaseUser } = await (0, import_auth8.signInWithCredential)(this.auth, credential);
16223
16177
  console.log("[AUTH] Firebase user signed in:", firebaseUser.uid);
16224
- console.log("[AUTH] Waiting for auth state to settle after sign-in...");
16225
- await this.waitForAuthStateToSettle(firebaseUser.uid);
16226
- console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
16227
16178
  const existingUser = await this.userService.getUserById(firebaseUser.uid);
16228
16179
  if (existingUser) {
16229
16180
  console.log("[AUTH] Existing user found, returning profile:", existingUser.uid);
@@ -16249,7 +16200,6 @@ ${stackTrace}`);
16249
16200
  * @returns Object containing user, practitioner (if exists), and draft profiles (if any)
16250
16201
  */
16251
16202
  async signUpPractitionerWithGoogle(idToken) {
16252
- var _a, _b, _c, _d;
16253
16203
  try {
16254
16204
  console.log("[AUTH] Starting practitioner Google Sign-In/Sign-Up");
16255
16205
  let email;
@@ -16274,49 +16224,30 @@ ${stackTrace}`);
16274
16224
  );
16275
16225
  }
16276
16226
  const normalizedEmail = email.toLowerCase().trim();
16277
- console.log("[AUTH] Extracted email from Google token:", normalizedEmail);
16278
16227
  const methods = await (0, import_auth8.fetchSignInMethodsForEmail)(this.auth, normalizedEmail);
16279
16228
  const hasGoogleMethod = methods.includes(import_auth8.GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD);
16280
16229
  const hasEmailMethod = methods.includes(import_auth8.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD);
16281
16230
  const practitionerService = new PractitionerService(this.db, this.auth, this.app);
16282
16231
  if (hasGoogleMethod) {
16283
- console.log("[AUTH] User exists with Google provider, signing in");
16284
16232
  const credential2 = import_auth8.GoogleAuthProvider.credential(idToken);
16285
16233
  const { user: firebaseUser2 } = await (0, import_auth8.signInWithCredential)(this.auth, credential2);
16286
- console.log("[AUTH] Waiting for auth state to settle after sign-in...");
16287
16234
  await this.waitForAuthStateToSettle(firebaseUser2.uid);
16288
- console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
16289
16235
  let existingUser2 = null;
16290
16236
  try {
16291
16237
  existingUser2 = await this.userService.getUserById(firebaseUser2.uid);
16292
- console.log("[AUTH] User document found:", existingUser2.uid);
16293
16238
  } catch (userError) {
16294
- console.log("[AUTH] User document not found in Firestore, checking for draft profiles", {
16295
- errorCode: userError == null ? void 0 : userError.code,
16296
- errorMessage: userError == null ? void 0 : userError.message,
16297
- errorType: (_a = userError == null ? void 0 : userError.constructor) == null ? void 0 : _a.name,
16298
- isAuthError: userError instanceof AuthError
16299
- });
16300
16239
  if (!this.auth.currentUser || this.auth.currentUser.uid !== firebaseUser2.uid) {
16301
- console.error("[AUTH] \u274C auth.currentUser became NULL before draft profile query!");
16302
- console.error("[AUTH] Expected UID:", firebaseUser2.uid);
16303
- console.error("[AUTH] Actual auth.currentUser:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
16304
- console.log("[AUTH] Waiting for auth state to recover...");
16240
+ const credential3 = import_auth8.GoogleAuthProvider.credential(idToken);
16241
+ await (0, import_auth8.signInWithCredential)(this.auth, credential3);
16305
16242
  await this.waitForAuthStateToSettle(firebaseUser2.uid, 2e3);
16306
16243
  }
16307
16244
  const practitionerService2 = new PractitionerService(this.db, this.auth, this.app);
16308
16245
  const draftProfiles3 = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
16309
- console.log("[AUTH] Draft profiles check result:", {
16310
- email: normalizedEmail,
16311
- draftProfilesCount: draftProfiles3.length,
16312
- draftProfileIds: draftProfiles3.map((p) => p.id)
16313
- });
16314
16246
  if (draftProfiles3.length === 0) {
16315
- console.log("[AUTH] No draft profiles found, signing out and throwing error");
16316
16247
  try {
16317
16248
  await (0, import_auth8.signOut)(this.auth);
16318
16249
  } catch (signOutError) {
16319
- console.warn("[AUTH] Error signing out Firebase user (non-critical):", signOutError);
16250
+ console.warn("[AUTH] Error signing out:", signOutError);
16320
16251
  }
16321
16252
  throw new AuthError(
16322
16253
  "No clinic invitation found for this email. Please contact your clinic administrator to receive an invitation, or use the token provided by your clinic.",
@@ -16324,28 +16255,20 @@ ${stackTrace}`);
16324
16255
  404
16325
16256
  );
16326
16257
  }
16327
- console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
16328
- console.log("[AUTH] auth.currentUser at User creation time:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
16329
16258
  try {
16330
16259
  const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
16331
16260
  skipProfileCreation: true
16332
16261
  });
16333
- console.log("[AUTH] \u2705 User document created successfully:", newUser.uid);
16334
16262
  return {
16335
16263
  user: newUser,
16336
16264
  practitioner: null,
16337
16265
  draftProfiles: draftProfiles3
16338
16266
  };
16339
16267
  } catch (createUserError) {
16340
- console.error("[AUTH] \u274C Failed to create User document:", {
16341
- errorCode: createUserError == null ? void 0 : createUserError.code,
16342
- errorMessage: createUserError == null ? void 0 : createUserError.message,
16343
- uid: firebaseUser2.uid
16344
- });
16345
16268
  try {
16346
16269
  await (0, import_auth8.signOut)(this.auth);
16347
16270
  } catch (signOutError) {
16348
- console.warn("[AUTH] Error signing out Firebase user (non-critical):", signOutError);
16271
+ console.warn("[AUTH] Error signing out:", signOutError);
16349
16272
  }
16350
16273
  throw createUserError;
16351
16274
  }
@@ -16370,14 +16293,12 @@ ${stackTrace}`);
16370
16293
  };
16371
16294
  }
16372
16295
  if (hasEmailMethod && !hasGoogleMethod) {
16373
- console.log("[AUTH] User exists with email/password only");
16374
16296
  throw new AuthError(
16375
16297
  "An account with this email already exists. Please sign in with your email and password, then link your Google account in settings.",
16376
16298
  "AUTH/EMAIL_ALREADY_EXISTS",
16377
16299
  409
16378
16300
  );
16379
16301
  }
16380
- console.log("[AUTH] Signing in with Google credential");
16381
16302
  const credential = import_auth8.GoogleAuthProvider.credential(idToken);
16382
16303
  let firebaseUser;
16383
16304
  try {
@@ -16393,30 +16314,23 @@ ${stackTrace}`);
16393
16314
  }
16394
16315
  throw error;
16395
16316
  }
16396
- console.log("[AUTH] Waiting for auth state to settle after sign-in...");
16397
16317
  await this.waitForAuthStateToSettle(firebaseUser.uid);
16398
- console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
16399
16318
  let existingUser = null;
16400
16319
  try {
16401
16320
  const existingUserDoc = await this.userService.getUserById(firebaseUser.uid);
16402
16321
  if (existingUserDoc) {
16403
16322
  existingUser = existingUserDoc;
16404
- console.log("[AUTH] Found existing User document");
16405
16323
  }
16406
16324
  } catch (error) {
16407
- console.error("[AUTH] Error checking for existing user:", error);
16408
16325
  }
16409
- console.log("[AUTH] Checking for draft profiles");
16410
16326
  let draftProfiles = [];
16411
16327
  try {
16412
16328
  draftProfiles = await practitionerService.getDraftProfilesByEmail(normalizedEmail);
16413
- console.log("[AUTH] Draft profiles check complete", { count: draftProfiles.length });
16414
16329
  } catch (draftCheckError) {
16415
- console.error("[AUTH] Error checking draft profiles:", draftCheckError);
16416
16330
  try {
16417
16331
  await (0, import_auth8.signOut)(this.auth);
16418
16332
  } catch (signOutError) {
16419
- console.warn("[AUTH] Error signing out Firebase user (non-critical):", signOutError);
16333
+ console.warn("[AUTH] Error signing out:", signOutError);
16420
16334
  }
16421
16335
  throw new AuthError(
16422
16336
  "No clinic invitation found for this email. Please contact your clinic administrator to receive an invitation, or use the token provided by your clinic.",
@@ -16427,55 +16341,38 @@ ${stackTrace}`);
16427
16341
  let user;
16428
16342
  if (existingUser) {
16429
16343
  user = existingUser;
16430
- console.log("[AUTH] Using existing user account");
16431
16344
  } else {
16432
16345
  if (draftProfiles.length === 0) {
16433
- console.log("[AUTH] No draft profiles found, signing out and throwing error");
16434
16346
  try {
16435
16347
  await (0, import_auth8.signOut)(this.auth);
16436
16348
  } catch (signOutError) {
16437
- console.warn("[AUTH] Error signing out Firebase user (non-critical):", signOutError);
16349
+ console.warn("[AUTH] Error signing out:", signOutError);
16438
16350
  }
16439
- const noDraftError = new AuthError(
16351
+ throw new AuthError(
16440
16352
  "No clinic invitation found for this email. Please contact your clinic administrator to receive an invitation, or use the token provided by your clinic.",
16441
16353
  "AUTH/NO_DRAFT_PROFILES",
16442
16354
  404
16443
16355
  );
16444
- console.log("[AUTH] Throwing NO_DRAFT_PROFILES error:", noDraftError.code);
16445
- throw noDraftError;
16446
16356
  }
16447
16357
  user = await this.userService.createUser(firebaseUser, ["practitioner" /* PRACTITIONER */], {
16448
16358
  skipProfileCreation: true
16449
16359
  });
16450
- console.log("[AUTH] Created new user account with draft profiles available");
16451
16360
  }
16452
16361
  let practitioner = null;
16453
16362
  if (user.practitionerProfile) {
16454
16363
  practitioner = await practitionerService.getPractitioner(user.practitionerProfile);
16455
16364
  }
16456
- console.log("[AUTH] Google Sign-In complete", {
16457
- userId: user.uid,
16458
- hasPractitioner: !!practitioner,
16459
- draftProfilesCount: draftProfiles.length
16460
- });
16461
16365
  return {
16462
16366
  user,
16463
16367
  practitioner,
16464
16368
  draftProfiles
16465
16369
  };
16466
16370
  } catch (error) {
16467
- console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
16468
- console.error("[AUTH] Error type:", (_d = error == null ? void 0 : error.constructor) == null ? void 0 : _d.name);
16469
- console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
16470
- console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
16471
- console.error("[AUTH] Error message:", error == null ? void 0 : error.message);
16472
16371
  if (error instanceof AuthError) {
16473
- console.log("[AUTH] Preserving AuthError:", error.code);
16474
16372
  throw error;
16475
16373
  }
16476
16374
  const errorMessage = (error == null ? void 0 : error.message) || (error == null ? void 0 : error.toString()) || "";
16477
16375
  if (errorMessage.includes("NO_DRAFT_PROFILES") || errorMessage.includes("clinic invitation")) {
16478
- console.log("[AUTH] Detected clinic invitation error in message, converting to AuthError");
16479
16376
  throw new AuthError(
16480
16377
  "No clinic invitation found for this email. Please contact your clinic administrator to receive an invitation, or use the token provided by your clinic.",
16481
16378
  "AUTH/NO_DRAFT_PROFILES",
@@ -16483,7 +16380,6 @@ ${stackTrace}`);
16483
16380
  );
16484
16381
  }
16485
16382
  const wrappedError = handleFirebaseError(error);
16486
- console.log("[AUTH] Wrapped error:", wrappedError.message);
16487
16383
  if (wrappedError.message.includes("permissions") || wrappedError.message.includes("Account creation failed")) {
16488
16384
  throw new AuthError(
16489
16385
  "No clinic invitation found for this email. Please contact your clinic administrator to receive an invitation, or use the token provided by your clinic.",