@blackcode_sa/metaestetics-api 1.12.16 → 1.12.17

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.js CHANGED
@@ -10352,6 +10352,34 @@ var AuthService = class extends BaseService {
10352
10352
  async signInWithGoogleIdToken(idToken, initialRole = "patient" /* PATIENT */) {
10353
10353
  try {
10354
10354
  console.log("[AUTH] Signing in with Google ID Token");
10355
+ let email;
10356
+ try {
10357
+ const payloadBase64 = idToken.split(".")[1];
10358
+ const payloadJson = globalThis.atob ? globalThis.atob(payloadBase64) : Buffer.from(payloadBase64, "base64").toString("utf8");
10359
+ const payload = JSON.parse(payloadJson);
10360
+ email = payload.email;
10361
+ } catch (decodeError) {
10362
+ console.warn("[AUTH] Failed to decode email from Google ID token:", decodeError);
10363
+ }
10364
+ if (!email) {
10365
+ throw new AuthError(
10366
+ "Unable to read email from Google token. Please try again or use another sign-in method.",
10367
+ "AUTH/INVALID_GOOGLE_TOKEN",
10368
+ 400
10369
+ );
10370
+ }
10371
+ const methods = await (0, import_auth7.fetchSignInMethodsForEmail)(this.auth, email);
10372
+ console.log("[AUTH] Fetch sign in methods for email:", email, methods);
10373
+ const hasGoogleMethod = methods.includes(import_auth7.GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD);
10374
+ console.log("[AUTH] Has Google method:", hasGoogleMethod);
10375
+ if (!hasGoogleMethod) {
10376
+ console.log("[AUTH] No existing Google credential for email, aborting login:", email);
10377
+ throw new AuthError(
10378
+ "No account found for this Google user. Please complete registration first.",
10379
+ "AUTH/USER_NOT_FOUND",
10380
+ 404
10381
+ );
10382
+ }
10355
10383
  const credential = import_auth7.GoogleAuthProvider.credential(idToken);
10356
10384
  const { user: firebaseUser } = await (0, import_auth7.signInWithCredential)(this.auth, credential);
10357
10385
  console.log("[AUTH] Firebase user signed in:", firebaseUser.uid);
@@ -10360,7 +10388,7 @@ var AuthService = class extends BaseService {
10360
10388
  console.log("[AUTH] Existing user found, returning profile:", existingUser.uid);
10361
10389
  return existingUser;
10362
10390
  }
10363
- console.log("[AUTH] No existing user found for Google account:", firebaseUser.email);
10391
+ console.log("[AUTH] No existing MetaEstetics user for Google account \u2013 signing out.");
10364
10392
  await (0, import_auth7.signOut)(this.auth);
10365
10393
  throw new AuthError(
10366
10394
  'No account found. Please complete registration by starting with "Get Started".',
package/dist/index.mjs CHANGED
@@ -1798,6 +1798,7 @@ import {
1798
1798
  sendPasswordResetEmail,
1799
1799
  verifyPasswordResetCode,
1800
1800
  confirmPasswordReset,
1801
+ fetchSignInMethodsForEmail as fetchSignInMethodsForEmail2,
1801
1802
  signInWithCredential
1802
1803
  } from "firebase/auth";
1803
1804
  import {
@@ -10456,6 +10457,34 @@ var AuthService = class extends BaseService {
10456
10457
  async signInWithGoogleIdToken(idToken, initialRole = "patient" /* PATIENT */) {
10457
10458
  try {
10458
10459
  console.log("[AUTH] Signing in with Google ID Token");
10460
+ let email;
10461
+ try {
10462
+ const payloadBase64 = idToken.split(".")[1];
10463
+ const payloadJson = globalThis.atob ? globalThis.atob(payloadBase64) : Buffer.from(payloadBase64, "base64").toString("utf8");
10464
+ const payload = JSON.parse(payloadJson);
10465
+ email = payload.email;
10466
+ } catch (decodeError) {
10467
+ console.warn("[AUTH] Failed to decode email from Google ID token:", decodeError);
10468
+ }
10469
+ if (!email) {
10470
+ throw new AuthError(
10471
+ "Unable to read email from Google token. Please try again or use another sign-in method.",
10472
+ "AUTH/INVALID_GOOGLE_TOKEN",
10473
+ 400
10474
+ );
10475
+ }
10476
+ const methods = await fetchSignInMethodsForEmail2(this.auth, email);
10477
+ console.log("[AUTH] Fetch sign in methods for email:", email, methods);
10478
+ const hasGoogleMethod = methods.includes(GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD);
10479
+ console.log("[AUTH] Has Google method:", hasGoogleMethod);
10480
+ if (!hasGoogleMethod) {
10481
+ console.log("[AUTH] No existing Google credential for email, aborting login:", email);
10482
+ throw new AuthError(
10483
+ "No account found for this Google user. Please complete registration first.",
10484
+ "AUTH/USER_NOT_FOUND",
10485
+ 404
10486
+ );
10487
+ }
10459
10488
  const credential = GoogleAuthProvider.credential(idToken);
10460
10489
  const { user: firebaseUser } = await signInWithCredential(this.auth, credential);
10461
10490
  console.log("[AUTH] Firebase user signed in:", firebaseUser.uid);
@@ -10464,7 +10493,7 @@ var AuthService = class extends BaseService {
10464
10493
  console.log("[AUTH] Existing user found, returning profile:", existingUser.uid);
10465
10494
  return existingUser;
10466
10495
  }
10467
- console.log("[AUTH] No existing user found for Google account:", firebaseUser.email);
10496
+ console.log("[AUTH] No existing MetaEstetics user for Google account \u2013 signing out.");
10468
10497
  await firebaseSignOut(this.auth);
10469
10498
  throw new AuthError(
10470
10499
  'No account found. Please complete registration by starting with "Get Started".',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.12.16",
4
+ "version": "1.12.17",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -883,23 +883,58 @@ export class AuthService extends BaseService {
883
883
  ): Promise<User> {
884
884
  try {
885
885
  console.log('[AUTH] Signing in with Google ID Token');
886
+
887
+ // 1) Extract the email claim from the raw JWT so we can check Auth records *before* sign-in
888
+ let email: string | undefined;
889
+ try {
890
+ const payloadBase64 = idToken.split('.')[1];
891
+ const payloadJson = globalThis.atob
892
+ ? globalThis.atob(payloadBase64)
893
+ : Buffer.from(payloadBase64, 'base64').toString('utf8');
894
+ const payload = JSON.parse(payloadJson);
895
+ email = payload.email as string | undefined;
896
+ } catch (decodeError) {
897
+ console.warn('[AUTH] Failed to decode email from Google ID token:', decodeError);
898
+ }
899
+
900
+ if (!email) {
901
+ throw new AuthError(
902
+ 'Unable to read email from Google token. Please try again or use another sign-in method.',
903
+ 'AUTH/INVALID_GOOGLE_TOKEN',
904
+ 400,
905
+ );
906
+ }
907
+
908
+ // 2) Check if this email already has a Google credential in Firebase Auth.
909
+ // If not, abort early so we *never* create an unwanted Auth user.
910
+ const methods = await fetchSignInMethodsForEmail(this.auth, email);
911
+ console.log('[AUTH] Fetch sign in methods for email:', email, methods);
912
+ const hasGoogleMethod = methods.includes(GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD);
913
+ console.log('[AUTH] Has Google method:', hasGoogleMethod);
914
+ if (!hasGoogleMethod) {
915
+ console.log('[AUTH] No existing Google credential for email, aborting login:', email);
916
+ throw new AuthError(
917
+ 'No account found for this Google user. Please complete registration first.',
918
+ 'AUTH/USER_NOT_FOUND',
919
+ 404,
920
+ );
921
+ }
922
+
923
+ // 3) Safe to sign-in – we know the credential belongs to an existing Auth account.
886
924
  const credential = GoogleAuthProvider.credential(idToken);
887
925
  const { user: firebaseUser } = await signInWithCredential(this.auth, credential);
888
926
  console.log('[AUTH] Firebase user signed in:', firebaseUser.uid);
889
927
 
890
- // Check if the user already has a profile in our database
928
+ // 4) Load our domain user document.
891
929
  const existingUser = await this.userService.getUserById(firebaseUser.uid);
892
930
  if (existingUser) {
893
931
  console.log('[AUTH] Existing user found, returning profile:', existingUser.uid);
894
932
  return existingUser;
895
933
  }
896
934
 
897
- // If no profile exists, reject the login - user must complete onboarding first
898
- console.log('[AUTH] No existing user found for Google account:', firebaseUser.email);
899
-
900
- // Sign out the Firebase user since we don't allow auto-registration
935
+ // 5) If no profile exists we sign out immediately and error but crucially no phantom user was created.
936
+ console.log('[AUTH] No existing MetaEstetics user for Google account – signing out.');
901
937
  await firebaseSignOut(this.auth);
902
-
903
938
  throw new AuthError(
904
939
  'No account found. Please complete registration by starting with "Get Started".',
905
940
  'AUTH/USER_NOT_FOUND',