After some battle we got a deal with chatgpt..
Seems the code you share is not working because App Connect uses XMLHttpRequest
instead of fetch
This is what I got working:
(function() {
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;
let isRefreshing = false;
let refreshQueue = [];
function retryQueue() {
refreshQueue.forEach(cb => cb());
refreshQueue = [];
}
XMLHttpRequest.prototype.open = function(method, url) {
this._url = url;
return originalOpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function() {
const xhr = this;
const originalOnReadyStateChange = xhr.onreadystatechange;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 401) {
console.log('Interceptado 401 en XHR desde:', xhr._url);
if (!isRefreshing) {
isRefreshing = true;
fetch('/api/refresh-token', {
method: 'POST',
credentials: 'include'
}).then(res => {
if (res.ok) {
console.log('Refresh OK. Reintentando peticiones fallidas...');
retryQueue();
} else {
console.warn('Refresh FAIL. Redirigiendo al login...');
window.location.href = '/login';
}
}).catch(err => {
console.error('Error durante refresh:', err);
window.location.href = '/login';
}).finally(() => {
isRefreshing = false;
});
}
// Guardamos la función para que se reintente luego
refreshQueue.push(() => {
const retryXhr = new XMLHttpRequest();
retryXhr.open(xhr._method, xhr._url, true);
retryXhr.withCredentials = true;
retryXhr.setRequestHeader('Content-Type', 'application/json');
retryXhr.onload = xhr.onload;
retryXhr.send(xhr._body);
});
}
if (originalOnReadyStateChange) {
return originalOnReadyStateChange.apply(this, arguments);
}
};
// Guardamos los datos para reintentar después
this._method = this._method || this.method || 'GET';
this._body = arguments[0];
return originalSend.apply(this, arguments);
};
})();
API's are called again, but values are not printed on DOM..
Trying to avoid window.location.reload();
but I think I got no other solution..
EDIT: Asked: Can you reload all dmx-serverconnect/dmx-api-action after re-authenticate?
(function() {
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;
let isRefreshing = false;
let refreshQueue = [];
function retryQueue() {
refreshQueue.forEach(cb => cb());
refreshQueue = [];
}
XMLHttpRequest.prototype.open = function(method, url) {
this._url = url;
return originalOpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function() {
const xhr = this;
const originalOnReadyStateChange = xhr.onreadystatechange;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 401) {
console.warn('Interceptado 401 desde:', xhr._url);
const wapplerComponent = findWapplerComponent(xhr._url);
if (!isRefreshing) {
isRefreshing = true;
fetch('/api/refresh-token', {
method: 'POST',
credentials: 'include'
}).then(res => {
if (res.ok) {
console.log('Refresh OK. Reintentando cargas...');
retryQueue();
// Fallback: si en 1.5s no hay cambio visual, recargamos la página
setTimeout(() => {
console.warn('No se actualizó el DOM. Recargando...');
window.location.reload();
}, 1500);
} else {
console.warn('Refresh FAIL. Redirigiendo al login...');
window.location.href = '/login';
}
}).catch(err => {
console.error('Error durante refresh:', err);
window.location.href = '/login';
}).finally(() => {
isRefreshing = false;
});
}
refreshQueue.push(() => {
if (wapplerComponent) {
console.log('Reintentando:', wapplerComponent.id);
wapplerComponent.load();
} else {
console.warn('No se encontró componente Wappler para:', xhr._url);
}
});
}
if (originalOnReadyStateChange) {
return originalOnReadyStateChange.apply(this, arguments);
}
};
return originalSend.apply(this, arguments);
};
// Detecta tanto dmx-api-action como dmx-serverconnect
function findWapplerComponent(url) {
const components = document.querySelectorAll('dmx-api-action, dmx-serverconnect');
for (const comp of components) {
const actualUrl = comp.dmxConnect?.settings?.url;
if (actualUrl && url.startsWith(actualUrl)) {
return comp;
}
}
return null;
}
})();
And all is working now
Amazing...
I really keep some distance with AI, but I have to say it would have taken me a long time without that..
Thanks @Mozzi again