ultimate-jekyll-manager 1.3.6 → 1.3.8

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/CHANGELOG.md CHANGED
@@ -14,6 +14,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
14
14
  - `Fixed` for any bug fixes.
15
15
  - `Security` in case of vulnerabilities.
16
16
 
17
+ ---
18
+ ## [1.3.8] - 2026-05-24
19
+
20
+ ### Fixed
21
+
22
+ - **Reverse-signup now keeps the user on `/signin` so they actually see the inline error.** v1.3.7 fixed `isNewUser` detection, but a follow-on race appeared: when Firebase's `getRedirectResult()` returns a fresh-signup user, the auth-state-change listener in `core/auth.js` fires `state.user = <about-to-be-deleted>` BEFORE `reverseAccidentalSignup`'s `await newUser.delete() → signOut()` chain completes. The listener's `policy === 'unauthenticated'` branch then redirects to `/account` (or `authReturnUrl`), and by the time the inline `showError()` call fires, the user is already off the page. Fixed with a `window.__UJM_REVERSING_SIGNUP` flag set synchronously before the delete + cleared after signOut's followup state-change. The listener checks the flag at the top and short-circuits the entire callback — no redirect, no metadata POST, no consent guard, nothing — until the reversal completes and the user lands on `user = null` with the inline error visible on `/signin`.
23
+
24
+ ---
25
+ ## [1.3.7] - 2026-05-24
26
+
27
+ ### Fixed
28
+
29
+ - **Reverse-signup detection on `/signin` was completely broken.** The reverse-signup-on-/signin flow in `src/assets/js/libs/auth.js` (lines 289 and 664) was reading `result.additionalUserInfo?.isNewUser` directly off the `UserCredential` returned by `getRedirectResult()` and `signInWithPopup()`. That property does NOT exist on the v9+ modular SDK — verified against `@firebase/auth`'s `auth-public.d.ts`, which declares `UserCredential` as exactly `{ user, providerId, operationType }`. The legacy compat SDK exposed `additionalUserInfo` as a direct property, hence the v9 migration footgun. On the modular SDK you must call the standalone helper `getAdditionalUserInfo(userCredential): AdditionalUserInfo | null` to access `isNewUser`. Result: `isNewUser` was always `undefined` → always falsy → the `if (isNewUser && !isSignupPage)` reverse gate at line 296 never fired in production. New Google accounts on `/signin` got signed in straight to `/account` with no consent on record, despite the reverse-signup code existing in the bundle since multiple versions ago. Confirmed live on Somiibo (Test 4 of `TODO-CONSENT-LIVETEST.md` failed 3× in a row with `operationType: 'signIn'` and no `[Auth] Reversing accidental signup` log line). Now both sites import `getAdditionalUserInfo` and call it on the result. Added two `console.warn` diagnostic logs (one per site) so future regressions surface immediately — can be removed once we're confident the fix sticks.
30
+
17
31
  ---
18
32
  ## [1.3.6] - 2026-05-24
19
33
 
@@ -51,6 +51,16 @@ export default function () {
51
51
  // Log
52
52
  console.log('[Auth] state changed:', state);
53
53
 
54
+ // Short-circuit if a reverse-signup is in progress (libs/auth.js#reverseAccidentalSignup
55
+ // sets this synchronously before .delete() + signOut()). Without this, the brief
56
+ // window where Firebase shows user=<about-to-be-deleted-account> would trigger the
57
+ // policy-based redirect to /account (or authReturnUrl) BEFORE the user sees the
58
+ // inline error on /signin. Flag is cleared at the end of reverseAccidentalSignup.
59
+ if (window.__UJM_REVERSING_SIGNUP) {
60
+ console.warn('[Auth] Skipping state-change processing — reverse-signup in progress');
61
+ return;
62
+ }
63
+
54
64
  // Set user ID for analytics tracking
55
65
  setAnalyticsUserId(user);
56
66
 
@@ -125,6 +125,16 @@ export default function () {
125
125
  async function reverseAccidentalSignup(newUser) {
126
126
  console.warn('[Auth] Reversing accidental signup from /signin (new Google account created with no consent on record)');
127
127
 
128
+ // SYNCHRONOUSLY flag the reversal so the auth-state-change listener in
129
+ // core/auth.js short-circuits its policy-based redirect for this user.
130
+ // Without this, Firebase's redirect-result-success path triggers an auth
131
+ // state change with user=<the-about-to-be-deleted-account> BEFORE we
132
+ // finish .delete() + signOut(), and the listener redirects to /account
133
+ // (or authReturnUrl) before the user ever sees the inline error.
134
+ // Cleared in the finally block after signOut() has fired the followup
135
+ // auth-state-change with user=null.
136
+ window.__UJM_REVERSING_SIGNUP = true;
137
+
128
138
  try {
129
139
  await newUser.delete();
130
140
  } catch (e) {
@@ -152,6 +162,11 @@ export default function () {
152
162
  formManager.showError(`This account doesn't exist. Try signing up first or use a different account.`);
153
163
  formManager.ready();
154
164
  }
165
+
166
+ // Clear the flag now that signOut() has fired its auth-state-change
167
+ // with user=null. Future state changes (e.g. user re-clicks Continue
168
+ // with Google after seeing the error) get normal listener processing.
169
+ window.__UJM_REVERSING_SIGNUP = false;
155
170
  }
156
171
 
157
172
  // Validate that the user has agreed to the legal terms. Instead of highlighting the
@@ -266,7 +281,7 @@ export default function () {
266
281
  async function handleRedirectResult() {
267
282
  try {
268
283
  // Import Firebase auth functions
269
- const { getAuth, getRedirectResult } = await import('@firebase/auth');
284
+ const { getAuth, getRedirectResult, getAdditionalUserInfo } = await import('@firebase/auth');
270
285
  const auth = getAuth();
271
286
 
272
287
  // Check for redirect result
@@ -285,10 +300,17 @@ export default function () {
285
300
  // Determine the provider from the result
286
301
  const providerId = result.providerId || result.user.providerData?.[0]?.providerId || 'unknown';
287
302
 
288
- // Track based on whether this is a new user
289
- const isNewUser = result.additionalUserInfo?.isNewUser;
303
+ // Track based on whether this is a new user. Firebase Auth v9+ modular SDK
304
+ // does NOT expose additionalUserInfo as a direct property on UserCredential —
305
+ // you must call getAdditionalUserInfo(result) to get it. The legacy compat SDK
306
+ // exposed it as a direct property, hence the v9 migration footgun. Verified
307
+ // against @firebase/auth's auth-public.d.ts: UserCredential only declares
308
+ // { user, providerId, operationType }.
309
+ const additionalUserInfo = getAdditionalUserInfo(result);
310
+ const isNewUser = additionalUserInfo?.isNewUser;
290
311
  const pagePath = document.documentElement.getAttribute('data-page-path');
291
312
  const isSignupPage = pagePath === '/signup';
313
+ console.warn('[Auth] redirect additionalUserInfo:', additionalUserInfo, 'isNewUser:', isNewUser, 'pagePath:', pagePath, 'isSignupPage:', isSignupPage, 'operationType:', result.operationType);
292
314
 
293
315
  // Google quirk: if a new account was auto-created during a signin attempt
294
316
  // (user came back from OAuth via the redirect path on /signin, not /signup),
@@ -598,6 +620,7 @@ export default function () {
598
620
  getAuth,
599
621
  signInWithPopup,
600
622
  signInWithRedirect,
623
+ getAdditionalUserInfo,
601
624
  GoogleAuthProvider,
602
625
  FacebookAuthProvider,
603
626
  TwitterAuthProvider,
@@ -660,8 +683,12 @@ export default function () {
660
683
  const result = await signInWithPopup(auth, provider);
661
684
  console.log('[Auth] Successfully authenticated via popup:', result.user.email);
662
685
 
663
- // Track based on whether this is a new user
664
- const isNewUser = result.additionalUserInfo?.isNewUser;
686
+ // Track based on whether this is a new user. v9 modular SDK requires
687
+ // getAdditionalUserInfo(result) the legacy `result.additionalUserInfo`
688
+ // direct property does NOT exist on UserCredential in v9+.
689
+ const additionalUserInfoPopup = getAdditionalUserInfo(result);
690
+ const isNewUser = additionalUserInfoPopup?.isNewUser;
691
+ console.warn('[Auth] popup additionalUserInfo:', additionalUserInfoPopup, 'isNewUser:', isNewUser, 'action:', action);
665
692
 
666
693
  // Google quirk: signInWithPopup auto-creates accounts. If a brand-new visitor
667
694
  // clicks "Sign in with Google" on the SIGNIN page (not signup), reverse the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "1.3.6",
3
+ "version": "1.3.8",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "exports": {