Skip to content

Instantly share code, notes, and snippets.

@Luckz
Last active May 12, 2026 11:36
Show Gist options
  • Select an option

  • Save Luckz/6bb085775941ebaca363c722cb8445e3 to your computer and use it in GitHub Desktop.

Select an option

Save Luckz/6bb085775941ebaca363c722cb8445e3 to your computer and use it in GitHub Desktop.
KinguinAntiAutoLogoutGuard.user.js
// ==UserScript==
// @name [AI] Kinguin anti-auto-logout guard
// @namespace luckz
// @author luckz
// @LLMs GPT-5.3 Codex
// @version 0001
// @description Block automatic logout on Kinguin
// @match https://www.kinguin.net/*
// @grant none
// @run-at document-start
// @downloadURL https://gist.github.com/Luckz/6bb085775941ebaca363c722cb8445e3/raw/KinguinAntiAutoLogoutGuard.user.js
// @updateURL https://gist.github.com/Luckz/6bb085775941ebaca363c722cb8445e3/raw/KinguinAntiAutoLogoutGuard.user.js
// ==/UserScript==
// ==Thoughts & Docs==
// The Point™:
// the main app bundle behavior is: one tab gets auth failure - broadcasts LOGOUT_EVENT - tabs dispatch logout - all tabs navigate to /oauth/logout.
// broadcast trigger itself is tied to 401 logic not a direct offline event
// losing internet can lead to broken auth/refresh flows, and then next auth calls can return 401, which starts the chain
// Solution attempt:
// 1. Block cross-tab logout broadcast BroadcastChannel for LOGOUT + LOGOUT_EVENT
// 2. Block/guard navigation to /oauth/logout unless it’s a deliberate user logout click
// ==/Thoughts & Docs==
'use strict';
const LOGOUT_PATH = '/oauth/logout';
const LOGOUT_CHANNEL = 'LOGOUT';
const LOGOUT_EVENT = 'LOGOUT_EVENT';
// Allow only intentional user logout clicks for a short time window.
let allowManualLogoutUntil = 0;
document.addEventListener('click', (ev) => {
const a = ev.target && ev.target.closest ? ev.target.closest('a[href]') : null;
if (!a) return;
const href = a.getAttribute('href') || '';
if (href.includes('/logout') || href.includes('/oauth/logout')) {
allowManualLogoutUntil = Date.now() + 10000;
}
}, true);
function shouldBlockLogoutUrl(urlLike) {
try {
const u = new URL(String(urlLike), location.href);
if (!u.pathname.startsWith(LOGOUT_PATH)) return false;
return Date.now() >= allowManualLogoutUntil;
} catch {
return false;
}
}
// 1) Block cross-tab forced logout broadcast.
if (window.BroadcastChannel) {
const NativeBC = window.BroadcastChannel;
window.BroadcastChannel = function (name) {
const ch = new NativeBC(name);
if (name === LOGOUT_CHANNEL) {
const origPost = ch.postMessage.bind(ch);
ch.postMessage = (msg) => {
if (msg === LOGOUT_EVENT) return;
return origPost(msg);
};
const origAdd = ch.addEventListener.bind(ch);
ch.addEventListener = (type, listener, options) => {
if (type !== 'message' || typeof listener !== 'function') {
return origAdd(type, listener, options);
}
const wrapped = function (ev) {
if (ev && ev.data === LOGOUT_EVENT) return;
return listener.call(this, ev);
};
return origAdd(type, wrapped, options);
};
let onMessageHandler = null;
Object.defineProperty(ch, 'onmessage', {
configurable: true,
enumerable: true,
get() {
return onMessageHandler;
},
set(fn) {
onMessageHandler = fn;
if (typeof fn !== 'function') return;
origAdd('message', function (ev) {
if (ev && ev.data === LOGOUT_EVENT) return;
fn.call(ch, ev);
});
}
});
}
return ch;
};
window.BroadcastChannel.prototype = NativeBC.prototype;
}
// 2) Block redirects to /oauth/logout (unless manually allowed).
const locProto = Location.prototype;
const origAssign = locProto.assign;
const origReplace = locProto.replace;
locProto.assign = function (url) {
if (shouldBlockLogoutUrl(url)) return;
return origAssign.call(this, url);
};
locProto.replace = function (url) {
if (shouldBlockLogoutUrl(url)) return;
return origReplace.call(this, url);
};
try {
const hrefDesc = Object.getOwnPropertyDescriptor(locProto, 'href');
if (hrefDesc && hrefDesc.get && hrefDesc.set) {
Object.defineProperty(locProto, 'href', {
configurable: true,
enumerable: hrefDesc.enumerable,
get() {
return hrefDesc.get.call(this);
},
set(url) {
if (shouldBlockLogoutUrl(url)) return;
return hrefDesc.set.call(this, url);
}
});
}
} catch (_) {
// Some browsers may not allow redefining Location.href
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment