Blackboard Chrome Spoof (UPC)

Forzar Brave a parecer Chrome en Blackboard UPC (UA + CH actualizados)

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @license MIT
// @name         Blackboard Chrome Spoof (UPC)
// @namespace    https://upc.blackboard.com
// @version      1.3
// @description  Forzar Brave a parecer Chrome en Blackboard UPC (UA + CH actualizados)
// @match        *://*.upc.blackboard.com/*    
// @match        *://*.upc.class.com/*    
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
  'use strict';

  // Chrome estable (Windows) a 2025-09-30
  const CHROME_MAJOR = "141";
  const CHROME_FULL = "141.0.7390.55";

  const fakeUA = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${CHROME_FULL} Safari/537.36`;

  const brands = [
    { brand: 'Not.A/Brand', version: '99' },
    { brand: 'Google Chrome', version: CHROME_MAJOR },
    { brand: 'Chromium', version: CHROME_MAJOR }
  ];

  const fullVersionList = [
    { brand: 'Not.A/Brand', version: '99.0.0.0' },
    { brand: 'Google Chrome', version: CHROME_FULL },
    { brand: 'Chromium', version: CHROME_FULL }
  ];

  const uaDataBase = {
    brands,
    fullVersionList,
    mobile: false,
    platform: 'Windows',
    toJSON() { return { brands, mobile: false, platform: 'Windows' }; },
    getHighEntropyValues: async (hints = []) => {
      const base = {
        architecture: 'x86',
        bitness: '64',
        fullVersionList,
        model: '',
        platform: 'Windows',
        platformVersion: '10.0.0',
        uaFullVersion: CHROME_FULL,
        wow64: false
      };
      // Devuelve solo lo solicitado (pero acepta cualquiera)
      const out = {};
      for (const k of hints) out[k] = base[k];
      // Asegura claves comunes aunque no se pidan
      return Object.assign({ platform: 'Windows', platformVersion: '10.0.0' }, out);
    }
  };

  const define = (obj, prop, getFn) => {
    try {
      Object.defineProperty(obj, prop, { get: getFn, configurable: true });
    } catch (_) {}
  };

  // Sobrescribe en el prototipo para afectar a todos los accessos
  const navProto = Object.getPrototypeOf(navigator);

  define(navProto, 'userAgent', () => fakeUA);
  define(navProto, 'vendor', () => 'Google Inc.');
  define(navProto, 'platform', () => 'Win32'); // típico en Chrome en Windows
  define(navProto, 'userAgentData', () => uaDataBase);

  // Ocultar rastro de Brave
  define(navProto, 'brave', () => undefined);

  // Opcional: algunas detecciones esperan window.chrome presente
  if (!('chrome' in window)) {
    try {
      Object.defineProperty(window, 'chrome', {
        get: () => ({ runtime: {}, app: {}, webstore: {} }),
        configurable: true
      });
    } catch (_) {}
  }

  // Congela objetos para dar apariencia más realista
  try { Object.freeze(navigator.userAgentData); } catch (_) {}
})();