From ac444cba221832c012c0435fdc8339fe9f37febb Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 11 May 2026 18:35:04 +0000
Subject: [PATCH] =Some changes to the CRUD.js editing, timeline post configuration

---
 assets/js/concise/AuthManager.js |   71 +++++++++++++++++++++++++++++------
 1 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/assets/js/concise/AuthManager.js b/assets/js/concise/AuthManager.js
index dfad8bf..760934f 100644
--- a/assets/js/concise/AuthManager.js
+++ b/assets/js/concise/AuthManager.js
@@ -17,8 +17,8 @@
 		this.nonces = {};
 
 		this.subscribers = new Set();
-		this.storageKey = 'jvb_auth_state';
-		this.cacheMetaKey = 'jvb_auth_meta';
+		this.storageKey = `${jvbBase.base}auth_state`;
+		this.cacheMetaKey = `${jvbBase.base}auth_meta`;
 		this.cacheExpiry = 5 * 60 * 1000; // 5 minutes
 
 		this.init();
@@ -29,21 +29,12 @@
 	 */
 	async init() {
 		if (this.isAuthenticating) {
-			// Wait for existing auth to complete
-			return new Promise(resolve => {
-				const checkAuth = setInterval(() => {
-					if (this.initialized) {
-						clearInterval(checkAuth);
-						resolve();
-					}
-				}, 50);
-			});
+			return this.ready();
 		}
 
 		this.isAuthenticating = true;
 
 		try {
-			// Check if we have cached auth and cookie hasn't changed
 			const cached = this.getCachedAuth();
 			if (cached) {
 				this.setAuthData(cached);
@@ -53,7 +44,6 @@
 				return;
 			}
 
-			// Fetch fresh auth data
 			await this.fetchAuth();
 
 		} catch (error) {
@@ -66,6 +56,54 @@
 	}
 
 	/**
+	 * Refresh nonce if authentication fails
+	 */
+	async refreshNonce(action = 'wp_rest') {
+		try {
+			await this.fetchAuth();
+			return this.getNonce(action);
+		} catch (error) {
+			console.error('Failed to refresh nonce:', error);
+			return null;
+		}
+	}
+
+	/**
+	 * Fetch with automatic nonce refresh on auth failure
+	 * Use this for all authenticated API requests
+	 */
+	async fetch(url, options = {}) {
+		const attempt = async (retryCount = 0) => {
+			const isFormData = options.body instanceof FormData;
+
+			const headers = {
+				...(!isFormData && { 'Content-Type': 'application/json' }),
+				...options.headers,
+				'X-WP-Nonce': this.getNonce()
+			};
+
+			const response = await fetch(url, {
+				...options,
+				credentials: 'same-origin',
+				headers
+			});
+
+			if ((response.status === 403 || response.status === 401) && retryCount === 0) {
+				const result = await response.clone().json();
+				if (result.code === 'rest_cookie_invalid_nonce' || result.message?.includes('Cookie check')) {
+					console.log('Nonce invalid, refreshing auth...');
+					await this.refresh();
+					return attempt(retryCount + 1);
+				}
+			}
+
+			return response;
+		};
+
+		return attempt();
+	}
+
+	/**
 	 * Fetch authentication status from API
 	 */
 	async fetchAuth() {
@@ -104,9 +142,16 @@
 	 * Set authentication data
 	 */
 	setAuthData(authData) {
+		const wasAuthenticated = this.initialized && this.authenticated;
+
 		this.authenticated = authData.authenticated || false;
 		this.user = authData.user || false;
 		this.nonces = authData.nonces || {};
+
+		// Session expired — was logged in, now isn't
+		if (wasAuthenticated && !this.authenticated) {
+			window.location.href = `/login?redirect_to=${encodeURIComponent(window.location.href)}`;
+		}
 	}
 
 	/**

--
Gitblit v1.10.0