// ==UserScript== // @name PDS CORS Reload Workaround // @namespace Violentmonkey Scripts // @match https://pds-nd.whey.party/oauth/authorize* // @grant none // @version 1.3 // @author - // @description Reliably bypasses the 'sec-fetch-site' error by using a MutationObserver to wait for the error message and then triggering a cross-site reload via a hidden iframe. // ==/UserScript== (function () { 'use strict'; // Use a session storage flag to prevent an infinite redirect loop. const retryKey = '__cors_workaround_attempted__'; // 1. ABORT if we've already tried the fix in this session. // This is the most important check to prevent loops. if (sessionStorage.getItem(retryKey)) { console.log("[Workaround] Already attempted a fix in this session. Aborting."); // The page has reloaded. We now assume it's either fixed or has a different error. // We clear the key so that a manual refresh by the user can trigger the script again. sessionStorage.removeItem(retryKey); return; } // 2. Define the keywords that identify the specific error message. const TARGET_KEYWORDS = [ 'Forbidden sec-fetch-site header', 'same-site', 'expected cross-site', ]; // The function that performs the fix. function triggerFix() { console.log("[Workaround] Error detected in DOM. Initiating cross-site reload via hidden iframe."); // Set the flag BEFORE navigating to prevent a loop if the fix fails. sessionStorage.setItem(retryKey, '1'); const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = `data:text/html,`; document.body.appendChild(iframe); } // 3. The CORE LOGIC: Use a MutationObserver to watch for the error. // This solves the race condition where the error message is added dynamically. const observer = new MutationObserver((mutations, obs) => { const bodyText = document.body.textContent || ''; const isErrorPage = TARGET_KEYWORDS.every(k => bodyText.includes(k)); if (isErrorPage) { // Error found! Trigger the fix. triggerFix(); // IMPORTANT: Stop observing once we've acted. obs.disconnect(); } }); // 4. Start observing. // We need to wait for the to exist before we can observe it. function startObserver() { if (document.body) { console.log("[Workaround] Observer started. Waiting for 'same-site' error to appear..."); // Also do an initial check, in case the error is already present. const initialBodyText = document.body.textContent || ''; if (TARGET_KEYWORDS.every(k => initialBodyText.includes(k))) { triggerFix(); return; // No need to observe if we fix it instantly. } observer.observe(document.body, { childList: true, // Watch for added/removed nodes (like the error
) subtree: true, // Watch all descendants of the body }); } else { // If body isn't ready, wait for DOMContentLoaded. window.addEventListener("DOMContentLoaded", startObserver, { once: true }); } } startObserver(); // Safety net: Stop observing after 10 seconds if nothing happens, // to prevent it from running forever on a page that is just slow to load. setTimeout(() => { observer.disconnect(); console.log("[Workaround] Observer timed out after 10 seconds. Assuming no error or a different issue."); }, 10000); })();