serenity icon indicating copy to clipboard operation
serenity copied to clipboard

LibWeb: Become a supported browser on Duolingo

Open awesomekling opened this issue 2 years ago • 4 comments

We should figure out what's causing this error, and then fix it:

image

Funding

  • We're currently trying Polar.sh where you can help fund the work on this issue.
  • Contributor(s) receive the funding once the issue is completed & confirmed.
Fund with Polar

awesomekling avatar Nov 21 '23 18:11 awesomekling

Here's the (formatted) JS they use for browser support detection:

if ("/errors/not-supported.html" !== window.location.pathname) {
    for (
        var supportsAbortController =
                ("AbortController" in window) &&
                ("Request" in window) &&
                Object.hasOwnProperty.call(Request.prototype, "signal"),
            supportsElementAnimate = ("animate" in Element.prototype),
            supportsES2015 = (function () {
                if ("undefined" == typeof Symbol || "undefined" == typeof Proxy) return !1;
                try {
                    return (
                        new Function("(a = 0) => a")(),
                        new Function("class MyEvent extends Event{}")(),
                        !1 === new Function("return new Boolean(Symbol.match)")()
                            ? !1
                            : (new Function("new.target")(),
                              new Function(
                                  'class ಠ_ಠ extends Array {constructor(j = "a", ...c) {const q = (({u: e}) => {return { [`s${c}`]: Symbol(j) };})({});super(j, q, ...c);}}new Promise((f) => {const a = function* (){return "𠮷".match(/./u)[0].length === 2 || true;};for (let vre of a()) {const [uw, as, he, re] = [new Set(), new WeakSet(), new Map(), new WeakMap()];break;}f(new Proxy({}, {get: (han, h) => h in han ? han[h] : "42".repeat(0o10)}));}).then(bi => new ಠ_ಠ(bi.rd));'
                              )(),
                              !!new Function(
                                  "return (a, b,) => a.padStart(5, '0') === '0000x' && Object.values(b).length === 2"
                              )()("x", { a: 1, b: 2 }))
                    );
                } catch (e) {
                    return !1;
                }
            })(),
            supportsIntersectionObserver =
                ("IntersectionObserver" in window) &&
                ("IntersectionObserverEntry" in window) &&
                ("intersectionRatio" in window.IntersectionObserverEntry.prototype) &&
                ("isIntersecting" in window.IntersectionObserverEntry.prototype),
            supportsResizeObserver = ("ResizeObserver" in window),
            features = [
                supportsAbortController,
                supportsElementAnimate,
                supportsES2015,
                supportsIntersectionObserver,
                supportsResizeObserver,
            ],
            i = 0;
        i < features.length;
        i++
    ) {
        features[i] || (window.location.href = "/errors/not-supported.html");
    }
    (window.duo.disableMonetization = /[?&]utm_source=pwa_launch/.test(window.location.search)),
        (window.duo.l10n = { strings: {}, undeclared: {} }),
        (window.duo.uiLanguage = window.duo.uiLanguage || "en"),
        (window.duo.version = "1.195.3"),
        (window.duo.versionHash = "2a84ac2cffc51b7d784f24505baf933c63c03194");
    var isAbc = /^\/abc/.test(window.location.pathname),
        HIDE_APP_SMART_BANNER_PATH = [
            "/2022-campaigns",
            "/share/sm",
            "/share-direct/sm",
            "/super",
            "/plus",
            "/getplus",
            "/youtubeplus",
        ];
    if (HIDE_APP_SMART_BANNER_PATH.includes(window.location.pathname))
        (el = document.querySelector("[name=apple-itunes-app]")) && el.remove();
    else if (isAbc) {
        var el;
        (el = document.querySelector("[name=apple-itunes-app]")) &&
            el.setAttribute("content", "app-id=1440502568");
    }
}

Of those features, we do not implement Element.prototype.animate. So that part is #21570.

However, if I stub that out, rather than getting redirected to the error page, we get a reCAPTCHA error instead (after some timeout) :

Screenshot_20231121_220740

trflynn89 avatar Nov 22 '23 03:11 trflynn89

I believe the main roadblock is missing transfer support in window.postMessage, as IIRC it creates a MessageChannel in the reCAPTCHA iframe, then transfers one of the ports to the parent window and uses that for communication.

Lubrsi avatar Nov 25 '23 01:11 Lubrsi

After #23218, I get the same reCAPTCHA timeout failure, but it doesn't seem to be related to window.postMesage transfer support, as that should(?) work now.

90664.787 WebContent(744): ResourceLoader: Failed load of: "https://cdn.cookielaw.org/scripttemplates/otSDKStub.js", Error: URL was filtered, Duration: 1ms
90664.798 WebContent(744): HTMLScriptElement: Refusing to run script because the element's result is null.
90665.438 WebContent(744): Unhandled JavaScript exception: [ReferenceError] 'FontFace' is not defined
90665.439 WebContent(744):     at https://www.duolingo.com/:1:125
    at <unknown>
    at n (https://d35aaqx5ub95lt.cloudfront.net/js/manifest-2e205d95.js:1:157)
    at https://www.duolingo.com/:1:1196
    at a (https://d35aaqx5ub95lt.cloudfront.net/js/manifest-2e205d95.js:1:11971)
    at <unknown>
    at https://d35aaqx5ub95lt.cloudfront.net/js/manifest-2e205d95.js:1:12165
    at https://d35aaqx5ub95lt.cloudfront.net/js/manifest-2e205d95.js:1:12165
    at https://d35aaqx5ub95lt.cloudfront.net/js/manifest-2e205d95.js:1:12165

90667.153 WebContent(744): Potential FIXME: Returning from PerformanceObserver::observe() as we don't support the PerformanceEntry type 'longtask'
90667.234 WebSocket(750): Loaded 145 of 145 (100%) provided CA Certificates
90667.234 RequestServer(749): Loaded 145 of 145 (100%) provided CA Certificates
90682.154 WebContent(744): Unhandled JavaScript exception (in promise): Timeout (z)
90687.138 WebContent(744): Potential FIXME: Returning from PerformanceObserver::observe() as we don't support the PerformanceEntry type 'longtask'
90687.181 RequestServer(752): Loaded 145 of 145 (100%) provided CA Certificates
90687.181 WebSocket(754): Loaded 145 of 145 (100%) provided CA Certificates
90702.140 WebContent(744): Unhandled JavaScript exception (in promise): Timeout (z)
90706.100 WebContent(744): Unhandled JavaScript exception (in promise): Timeout

ADKaster avatar Feb 16 '24 19:02 ADKaster

IIRC reCAPTCHA requires this on MessagePort transfer: https://github.com/SerenityOS/serenity/blob/9aefc5c927be6202f49abca4d077f70657c097b2/Userland/Libraries/LibWeb/HTML/MessagePort.cpp#L68-L69 https://github.com/SerenityOS/serenity/blob/9aefc5c927be6202f49abca4d077f70657c097b2/Userland/Libraries/LibWeb/HTML/MessagePort.cpp#L101-L103

Lubrsi avatar Mar 11 '24 19:03 Lubrsi

Thank you @ADKaster and @mattco98 for contributing to close this issue! ⭐

The rewards from this issue, totalling $200, has been shared with you.

What now?

  1. Create a Polar account
  2. See incoming rewards & setup Stripe to receive them
  3. Get payouts as backers finalize their payments

If you already have a Polar account setup, you don't need to do anything.

awesomekling avatar May 08 '24 08:05 awesomekling