Age Verification Bypass

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

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 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.2
// @description  Skips age verification screens on AgeChecker.net, AgeVerif.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, 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)) || '';

            // --- 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);
            }
        };
    });

    /* =============================================
       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 });
    });
})();