Age Verification Bypass

Skips age verification screens on AgeChecker.net, AgeVerif.com, Agego.com, AliExpress, Bluesky, Reddit, Veriff. Ported from Firefox add-on by helloyanis (https://github.com/helloyanis/age-verification-bypass).

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Age Verification Bypass
// @name:en      Age Verification Bypass
// @name:pt-BR   Age Verification Bypass
// @namespace    https://greasyfork.org/en/users/1301195-luciano-inf
// @version      1.1.3
// @description  Skips age verification screens on AgeChecker.net, AgeVerif.com, Agego.com, AliExpress, Bluesky, Reddit, Veriff. Ported from Firefox add-on by helloyanis (https://github.com/helloyanis/age-verification-bypass).
// @description:pt-BR  Pula telas de verificação de idade em AgeChecker.net, AgeVerif.com, Agego.com, AliExpress, Bluesky, Reddit, Veriff. Portado do add-on Firefox por helloyanis (https://github.com/helloyanis/age-verification-bypass).
// @author       Luciano.Oliveirals
// @license      MIT
// @run-at       document-start
// @grant        none
// @match        *://*/*
// @icon         https://raw.githubusercontent.com/LucianoSkx/age-verification-bypass/main/icon.svg
// @supportURL   https://greasyfork.org/scripts/587561-age-verification-bypass
// @homepageURL  https://github.com/LucianoSkx/age-verification-bypass
// ==/UserScript==

(function () {
    'use strict';

    function inject(fn) {
        var el = document.createElement('script');
        el.textContent = '(' + fn.toString() + ')();';
        document.documentElement.appendChild(el);
        el.remove();
    }

    /* =============================================
       Fetch Interceptor
       ============================================= */
    var origFetch = window.fetch;
    if (typeof origFetch === 'function') {
        window.fetch = function (input, init) {
            var url = (typeof input === 'string' ? input : (input && input.url)) || '';

            // --- Agego.com server-to-server redirect ---
            if (url.indexOf('myapi.agego.com/s2s/start/') !== -1) {
                try {
                    var returnto = new URL(url).searchParams.get('returnto');
                    if (returnto) window.location.href = returnto;
                } catch (e) {}
                return new Response('', { status: 204 });
            }

            // --- AgeChecker.net API ---
            if (url.indexOf('api.agechecker.net/v1/create') !== -1 || url.indexOf('sa.agechecker.net/ac_create') !== -1) {
                return new Response(JSON.stringify({ uuid: crypto.randomUUID(), status: 'accepted' }), {
                    status: 200,
                    statusText: 'OK',
                    headers: { 'Content-Type': 'application/json' }
                });
            }

            // --- Veriff session API ---
            if (url.indexOf('saas.veriff.com/api/v2/sessions') !== -1) {
                return origFetch.call(window, input, init).then(function (r) {
                    return r.clone().json().then(function (data) {
                        if (data.vendorIntegration && data.vendorIntegration.callback) {
                            window.location.href = data.vendorIntegration.callback;
                        }
                        return r;
                    });
                });
            }

            var result = origFetch.call(window, input, init);

            // --- Bluesky labeler ---
            if (url.indexOf('public.api.bsky.app/xrpc/app.bsky.labeler.getServices') !== -1) {
                return result.then(function (r) {
                    return r.clone().json().then(function (data) {
                        if (data.views) {
                            data.views.forEach(function (view) {
                                view.policies.labelValueDefinitions = (view.policies.labelValues || []).map(function (label) {
                                    return {
                                        adultOnly: false,
                                        blurs: 'media',
                                        defaultSetting: 'warn',
                                        identifier: label,
                                        locales: [{ description: 'Labeled as ' + label, lang: 'en', name: label }],
                                        severity: 'inform'
                                    };
                                });
                            });
                        }
                        return new Response(JSON.stringify(data), {
                            status: r.status,
                            statusText: r.statusText,
                            headers: r.headers
                        });
                    });
                });
            }

            // --- Bluesky age assurance ---
            if (url.indexOf('public.api.bsky.app/xrpc/app.bsky.ageassurance.getConfig') !== -1) {
                return result.then(function (r) {
                    return r.clone().json().then(function (data) {
                        data.regions = [];
                        return new Response(JSON.stringify(data), {
                            status: r.status,
                            statusText: r.statusText,
                            headers: r.headers
                        });
                    });
                });
            }

            return result;
        };
    }

    /* =============================================
       AgeChecker.net — inject auto-accept SDK
       ============================================= */
    inject(function () {
        var config = window.AgeCheckerConfig || {};

        function complete() {
            if (typeof config.onstatuschanged === 'function') {
                config.onstatuschanged({ uuid: crypto.randomUUID(), status: 'accepted' });
            }
            if (config.redirect_url) {
                window.location.href = config.redirect_url;
                return;
            }
            if (typeof config.onclose === 'function') config.onclose();
            if (typeof config.onclosed === 'function') config.onclosed();
        }

        window.AgeCheckerAPI = { show: complete, close: complete };
        if (typeof config.onready === 'function') config.onready();
    });

    /* =============================================
       AgeVerif.com — inject auto-accept SDK
       ============================================= */
    inject(function () {
        function parseQuery(url) {
            var params = {};
            var q = (url.split('?')[1] || '').split('#')[0];
            q.split('&').forEach(function (part) {
                if (!part) return;
                var kv = part.split('=');
                params[decodeURIComponent(kv[0])] = kv[1] ? decodeURIComponent(kv[1]) : true;
            });
            return params;
        }

        function safeCall(fnName, payload) {
            if (!fnName) return;
            var fn = window[fnName];
            if (typeof fn === 'function') {
                try { fn(payload); } catch (e) { console.error('[avb] callback error:', e); }
            }
        }

        function emit(eventName, detail) {
            window.dispatchEvent(new CustomEvent(eventName, { detail: detail }));
            var legacyMap = {
                'ageverif:load': window.ageverifLoaded,
                'ageverif:ready': window.ageverifReady,
                'ageverif:success': window.ageverifSuccess
            };
            if (legacyMap[eventName]) {
                try { legacyMap[eventName](detail); } catch (e) { console.error('[avb] legacy error:', e); }
            }
        }

        function randStr(n) {
            var c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', o = '';
            for (var i = 0; i < n; i++) o += c[Math.floor(Math.random() * c.length)];
            return o;
        }

        function createVerification() {
            var now = Math.floor(Date.now() / 1000);
            var expiresIn = 100 * 365 * 24 * 60 * 60;
            return {
                uid: randStr(24),
                country: 'FR',
                countrySubdivision: null,
                assuranceLevel: 'STRICT',
                ageThreshold: 0,
                reused: false,
                expiresAt: now + expiresIn,
                expiresIn: expiresIn,
                token: randStr(48)
            };
        }

        var el = document.currentScript;
        var src = el ? el.src : '';
        var params = parseQuery(src);
        var hasNoStart = Object.prototype.hasOwnProperty.call(params, 'nostart');

        var config = {
            onload: params.onload,
            onready: params.onready,
            onsuccess: params.onsuccess,
            onclose: params.onclose,
            onerror: params.onerror
        };

        var ageverif = {
            started: false,
            events: {},
            on: function (event, handler) {
                if (!this.events[event]) this.events[event] = [];
                this.events[event].push(handler);
            },
            emitLocal: function (event, payload) {
                var list = this.events[event] || [];
                list.forEach(function (fn) { try { fn(payload); } catch (e) { } });
            },
            start: function () {
                if (this.started) return;
                this.started = true;
                var verification = createVerification();
                var readyPayload = { verification: verification };
                this.emitLocal('ready', readyPayload);
                emit('ageverif:ready', readyPayload);
                safeCall(config.onready, readyPayload);
                var successPayload = { verification: verification };
                this.emitLocal('success', successPayload);
                emit('ageverif:success', successPayload);
                safeCall(config.onsuccess, successPayload);
                this.emitLocal('close', {});
                safeCall(config.onclose, {});
            }
        };

        window.ageverif = ageverif;

        var loadPayload = { verified: true, verification: createVerification() };
        emit('ageverif:load', loadPayload);
        safeCall(config.onload, loadPayload);

        if (window.ageverif && typeof window.ageverif.on === 'function') {
            try { window.ageverif.on('ready', function () { ageverif.start(); }); } catch (e) { }
        }

        if (!hasNoStart) ageverif.start();
    });

    /* =============================================
       Veriff SDK spoof
       ============================================= */
    inject(function () {
        window.Veriff = function (config) {
            config = config || {};
            return {
                setParams: function () { },
                mount: function () {
                    if (typeof config.onSession === 'function') {
                        config.onSession(null, {
                            status: 'success',
                            verification: {
                                id: crypto.randomUUID(),
                                url: '',
                                host: window.location.hostname,
                                status: 'approved',
                                sessionToken: ''
                            }
                        });
                    }
                }
            };
        };
    });

    inject(function () {
        var MESSAGES = { STARTED: 'STARTED', FINISHED: 'FINISHED', SUBMITTED: 'SUBMITTED' };
        window.veriffSDK = {
            createVeriffFrame: function (opts) {
                if (typeof opts.onEvent !== 'function') return;
                opts.onEvent(MESSAGES.STARTED);
                opts.onEvent(MESSAGES.FINISHED);
                opts.onEvent(MESSAGES.SUBMITTED);
            }
        };
    });

    /* =============================================
       Agego.com — process AGEGO verification queue
       ============================================= */
    inject(function () {
        function processQueue() {
            var queue = window.AGEGO && window.AGEGO.e;
            if (!Array.isArray(queue) || queue.length === 0) return false;

            for (var i = queue.length - 1; i >= 0; i--) {
                var args = queue[i];
                for (var j = 0; j < args.length; j++) {
                    var candidate = args[j];
                    if (candidate && typeof candidate === 'object' && candidate.events && typeof candidate.events === 'object') {
                        if (typeof candidate.events.onVerifiedBefore === 'function')
                            candidate.events.onVerifiedBefore();
                        else if (typeof candidate.events.onAPIVerify === 'function')
                            candidate.events.onAPIVerify();
                        else if (typeof candidate.events.onVerificationFlowEnd === 'function')
                            candidate.events.onVerificationFlowEnd({});
                        return true;
                    }
                }
            }
            return false;
        }

        if (!processQueue()) {
            var iv = setInterval(function () {
                if (processQueue()) clearInterval(iv);
            }, 200);
            setTimeout(function () { clearInterval(iv); }, 10000);
        }
    });

    /* =============================================
       DOM-based bypasses (AliExpress, Reddit, Bluesky sensitive media)
       ============================================= */
    document.addEventListener('DOMContentLoaded', function () {
        /* ---- AliExpress ---- */
        function cleanAliExpress() {
            document.querySelectorAll('.ls_ke, .ho_g9, .J_SAFETY_FILER_MODAL, ._1FlkA, img[src*="72x72.png"]').forEach(function (el) { el.remove(); });
            document.querySelectorAll('img.nf_bj').forEach(function (el) { el.classList.remove('nf_bj'); });
            document.querySelectorAll('.card-dsa-wrapper').forEach(function (el) { el.classList.remove('card-dsa-wrapper'); });
            document.querySelectorAll('.dsa--visible--wrapper').forEach(function (el) { el.classList.remove('dsa--visible--wrapper'); });
        }
        cleanAliExpress();
        setInterval(cleanAliExpress, 2000);

        /* ---- Reddit NSFW popup ---- */
        function cleanReddit() {
            var blockedId = 'configured-xpromo-blocking_xpromo_nsfw_blocking_desktop';
            var containerTag = 'xpromo-nsfw-blocking-container';
            var target = document.getElementById(blockedId);
            if (target) target.remove();
            var container = document.querySelector(containerTag);
            if (container && container.shadowRoot) {
                var prompt = container.shadowRoot.querySelector('.prompt');
                if (prompt) prompt.remove();
            }
            Array.from(document.querySelectorAll('style')).filter(function (s) {
                return s.innerText && s.innerText.indexOf('.rpl-scroll-lock') !== -1;
            }).forEach(function (s) { s.remove(); });
        }
        cleanReddit();

        var observer = new MutationObserver(function (mutations) {
            for (var m = 0; m < mutations.length; m++) {
                for (var n = 0; n < mutations[m].addedNodes.length; n++) {
                    var node = mutations[m].addedNodes[n];
                    if (node.nodeType !== 1) continue;
                    if (node.id === 'configured-xpromo-blocking_xpromo_nsfw_blocking_desktop') { node.remove(); continue; }
                    if (node.tagName === 'XPROMO-NSFW-BLOCKING-CONTAINER') {
                        var p = node.shadowRoot && node.shadowRoot.querySelector('.prompt');
                        if (p) p.remove();
                    }
                    var d = node.querySelector && node.querySelector('#configured-xpromo-blocking_xpromo_nsfw_blocking_desktop');
                    if (d) d.remove();
                    var d2 = node.querySelector && node.querySelector('xpromo-nsfw-blocking-container');
                    if (d2 && d2.shadowRoot) {
                        var p2 = d2.shadowRoot.querySelector('.prompt');
                        if (p2) p2.remove();
                    }
                }
            }
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });

        /* ---- Reddit CSS strip ---- */
        var TEST_IDS = ['nsfw-bypassable-modal-client-css', 'experiences-client-css'];
        var cssObserver = new MutationObserver(function () {
            document.querySelectorAll('style[data-testid]').forEach(function (el) {
                if (TEST_IDS.indexOf(el.getAttribute('data-testid')) !== -1) el.remove();
            });
        });
        cssObserver.observe(document.head || document.documentElement, { childList: true, subtree: true });

        /* ---- Bluesky sensitive media reveal ---- */
        function cleanBluesky() {
            document.querySelectorAll('div[data-testid="contentHider"], div[data-testid="contentHoor"], div[data-testid="blurred-media"]').forEach(function (el) { el.remove(); });
        }
        cleanBluesky();
        var bskyObserver = new MutationObserver(function () {
            if (window.location.hostname.indexOf('bsky') !== -1) cleanBluesky();
        });
        bskyObserver.observe(document.documentElement, { childList: true, subtree: true });
    });
})();