iOS 公益站L站登录跳转修复小脚本

在iphone和ipad上很多公益站点击"使用 LinuxDO 继续"后不会跳转登录。用codex排查了一下写了个小脚本,ios可以下个stay或者类似的软件。测试了几个网站结果都OK。 刚看到有类似的讨论 为什么ios的safari浏览器用不了linuxdo的第三方登录? - #10,来自 plu...
iOS 公益站L站登录跳转修复小脚本
iOS 公益站L站登录跳转修复小脚本

在iphone和ipad上很多公益站点击"使用 LinuxDO 继续"后不会跳转登录。用codex排查了一下写了个小脚本,ios可以下个stay或者类似的软件。测试了几个网站结果都OK。

刚看到有类似的讨论 为什么ios的safari浏览器用不了linuxdo的第三方登录? - #10,来自 pluto233
不过之前的解决方案需要更改Safari设置,这个脚本可以保留原来的设置。

// ==UserScript==
// @name         LinuxDO OAuth Popup Fix for iOS
// @namespace    https://linux.do/
// @version      1.0.0
// @description  修复 iOS/Safari 上 LinuxDO OAuth 因异步 window.open 被拦截而无法跳转的问题
// @author       Codex
// @match        http://*/*
// @match        https://*/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  const ONLY_IOS = true;
  const MAX_GESTURE_AGE_MS = 3000;
  const DEBUG = false;
  let lastGesture = { matched: false, at: 0, text: '', href: '' };

  function log(...args) {
    if (DEBUG) console.info('[LinuxDO OAuth Popup Fix]', ...args);
  }

  function isIOSWebKit() {
    const ua = navigator.userAgent || '';
    const platform = navigator.platform || '';
    const touchMac = platform === 'MacIntel' && navigator.maxTouchPoints > 1;
    const appleMobile = /iPhone|iPad|iPod/i.test(ua) || touchMac;
    return appleMobile && /AppleWebKit/i.test(ua);
  }

  function normalize(value) {
    return String(value || '')
      .toLowerCase()
      .replace(/\s+/g, '')
      .trim();
  }

  function isLinuxDOAuthUrl(rawUrl) {
    if (!rawUrl) return false;

    try {
      const url = new URL(rawUrl, location.href);
      const host = url.hostname.toLowerCase();
      const path = url.pathname.toLowerCase();
      if (host !== 'connect.linux.do' && host !== 'linux.do') return false;
      if (host === 'connect.linux.do' && path.startsWith('/oauth2/authorize')) return true;
      if (host === 'linux.do' && path.includes('/auth/')) return true;
      return false;
    } catch {
      return false;
    }
  }

  function classifyLinuxDOTrigger(target) {
    if (!target) return { matched: false, text: '', href: '' };

    const text = target.textContent || '';
    const href =
      target.getAttribute?.('href') ||
      target.dataset?.href ||
      target.getAttribute?.('data-href') ||
      '';
    const ariaLabel = target.getAttribute?.('aria-label') || '';
    const title = target.getAttribute?.('title') || '';
    const className = typeof target.className === 'string' ? target.className : '';

    const combined = normalize([text, href, ariaLabel, title, className].filter(Boolean).join(' '));
    const mentionsLinuxDO =
      combined.includes('linuxdo') ||
      combined.includes('linux.do') ||
      isLinuxDOAuthUrl(href);
    const actionWords = [
      '继续',
      '登录',
      '登入',
      '授权',
      '绑定',
      'continue',
      'login',
      'signin',
      'sign-in',
      'oauth',
      'authorize',
      'connect',
      'bind',
      'auth',
    ];
    const hasActionWord =
      actionWords.some((word) => combined.includes(normalize(word))) || isLinuxDOAuthUrl(href);

    return { matched: Boolean(mentionsLinuxDO && hasActionWord), text, href };
  }

  function captureGesture(event) {
    const el = event.target?.closest?.('button, a, [role="button"], [onclick], input[type="button"], input[type="submit"]');
    const result = classifyLinuxDOTrigger(el);
    lastGesture = {
      ...result,
      at: Date.now(),
    };
    if (result.matched) log('captured gesture', result);
  }

  function shouldConvertPopupToRedirect(rawUrl) {
    if (!isLinuxDOAuthUrl(rawUrl)) return false;
    if (!lastGesture.matched) return false;
    return Date.now() - lastGesture.at <= MAX_GESTURE_AGE_MS;
  }

  if (ONLY_IOS && !isIOSWebKit()) {
    return;
  }

  document.addEventListener('pointerdown', captureGesture, true);
  document.addEventListener('touchstart', captureGesture, true);
  document.addEventListener('click', captureGesture, true);

  const realOpen = window.open.bind(window);
  window.open = function patchedOpen(url, target, features) {
    if (shouldConvertPopupToRedirect(url)) {
      log('convert popup to same-tab redirect', { url, target, features, lastGesture });
      location.assign(String(url));
      return window;
    }
    return realOpen(url, target, features);
  };
})();

linuxdo-oauth-popup-fix.user.js.zip (1.7 KB)

1 个帖子 - 1 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文