NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Google Drive Authuser Redirector
// @name:tr Google Drive Authuser Yönlendirici
// @namespace https://github.com/moetwa/userscripts
// @version 1.0.1
// @description Forces Google Drive file links to open with the selected account index.
// @description:tr Google Drive bağlantılarının seçilen hesap dizini ile açılmasını sağlar.
// @author moetwa
// @match *://*/*
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const currentHost = window.location.hostname;
const currentPath = window.location.pathname;
// load saved auth index dynamically
// always fetch the freshest setting directly from db to avoid stale tab issues
function getAuthUser() {
return GM_getValue('defaultAuthUser', '0');
}
// Early redirect
// catches direct url pastes and google's server-side access denied redirects
const isDriveFilePage = currentPath.includes('/file/d/') || currentPath.includes('/drivesharing/');
if (currentHost === 'drive.google.com' && isDriveFilePage) {
const currentUrl = new URL(window.location.href);
const currentAuthUser = currentUrl.searchParams.get('authuser');
const targetAuth = getAuthUser();
// bounce to the correct account immediately
if (currentAuthUser !== targetAuth) {
currentUrl.searchParams.set('pli', '1');
currentUrl.searchParams.set('authuser', targetAuth);
// use replace() so we don't trap the user in a back-button loop
window.location.replace(currentUrl.toString());
return; // halt execution until the new page renders
}
}
// External Link Interceptor
// intercept clicks on external sites. doing this inside drive breaks their SPA routing.
if (currentHost !== 'drive.google.com') {
const targetPattern = 'drive.google.com/';
// function to modify links with the absolute latest auth value
const updateLinkHref = (link) => {
if (link.href.includes('/file/d/') || link.href.includes('id=')) {
try {
const targetAuth = getAuthUser();
let url = new URL(link.href);
if (url.searchParams.get('authuser') !== targetAuth) {
url.searchParams.set('pli', '1');
url.searchParams.set('authuser', targetAuth);
link.href = url.toString();
}
} catch (e) {
// sssshh!
}
}
};
// exact-millisecond interception
// fires right before browser navigation (covers clicks and middle clicks)
const interactionHandler = (event) => {
const link = event.target.closest('a');
if (link && link.href && link.href.includes(targetPattern)) {
updateLinkHref(link);
}
};
document.addEventListener('click', interactionHandler, true);
document.addEventListener('auxclick', interactionHandler, true);
// modify links for right click copying
const scanDOM = () => {
document.querySelectorAll(`a[href*="${targetPattern}"]`).forEach(updateLinkHref);
};
// wait for DOM before parsing links
document.addEventListener('DOMContentLoaded', () => {
scanDOM();
// disabled MutationObserver here to save cpu on all web pages
// click interception handles dynamic links anyway.
});
}
// Settings UI
if (currentHost === 'drive.google.com') {
document.addEventListener('DOMContentLoaded', () => {
injectSettingsPanel();
});
}
function injectSettingsPanel() {
// base styling for the floating panel
GM_addStyle(`
#gd-auth-panel { position: fixed; top: 50%; right: -250px; width: 250px; background: #ffffff; border: 1px solid #dadce0; border-radius: 8px 0 0 8px; box-shadow: -2px 0 8px rgba(0,0,0,0.1); transition: right 0.3s ease; z-index: 999999; font-family: Arial, sans-serif; color: #202124; transform: translateY(-50%); }
#gd-auth-panel.open { right: 0; }
#gd-auth-toggle { position: absolute; left: -40px; top: 20px; width: 40px; height: 40px; background: #1a73e8; color: white; border-radius: 8px 0 0 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 12px; box-shadow: -2px 0 5px rgba(0,0,0,0.1); }
#gd-auth-content { padding: 16px; }
#gd-auth-content h3 { margin: 0 0 12px 0; font-size: 15px; color: #1a73e8; }
.gd-radio-group { margin-bottom: 10px; }
.gd-radio-group label { cursor: pointer; font-size: 14px; display: flex; align-items: center; gap: 8px; }
#gd-auth-save { margin-top: 15px; background: #1a73e8; color: white; border: none; padding: 10px 12px; border-radius: 4px; cursor: pointer; width: 100%; font-weight: bold; }
#gd-auth-save:hover { background: #1557b0; }
`);
// build DOM manually to respect Google's strict CSP (no innerHTML allowed)
const container = document.createElement('div');
container.id = 'gd-auth-panel';
const toggleBtn = document.createElement('div');
toggleBtn.id = 'gd-auth-toggle';
toggleBtn.textContent = 'ACC';
const content = document.createElement('div');
content.id = 'gd-auth-content';
const header = document.createElement('h3');
header.textContent = 'Select Default Account';
content.appendChild(header);
const currentSavedAuth = getAuthUser();
// generate radio inputs for standard account indexes (0-4)
for (let i = 0; i <= 4; i++) {
const group = document.createElement('div');
group.className = 'gd-radio-group';
const label = document.createElement('label');
const radioInput = document.createElement('input');
radioInput.type = 'radio';
radioInput.name = 'authuser_index';
radioInput.value = i.toString();
if (parseInt(currentSavedAuth) === i) radioInput.checked = true;
const labelText = document.createTextNode(' Account Index ' + i);
label.appendChild(radioInput);
label.appendChild(labelText);
group.appendChild(label);
content.appendChild(group);
}
const saveBtn = document.createElement('button');
saveBtn.id = 'gd-auth-save';
saveBtn.textContent = 'Save Selection';
content.appendChild(saveBtn);
container.appendChild(toggleBtn);
container.appendChild(content);
document.body.appendChild(container);
// interactions
toggleBtn.addEventListener('click', () => {
container.classList.toggle('open');
});
saveBtn.addEventListener('click', () => {
const selectedRadio = document.querySelector('input[name="authuser_index"]:checked');
if (selectedRadio) {
const targetValue = selectedRadio.value;
GM_setValue('defaultAuthUser', targetValue);
// instantly force the current tab to navigate to the new account
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set('pli', '1');
currentUrl.searchParams.set('authuser', targetValue);
window.location.replace(currentUrl.toString());
}
});
}
})();