Ghost Identity Pro

Temporary mail autofill + OTP catcher

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Ghost Identity Pro
// @namespace    http://tampermonkey.net/
// @version      10.0
// @description  Temporary mail autofill + OTP catcher
// @author       Mustafa Hakan
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @connect      1secmail.com
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(() => {
    "use strict";

    //////////////////////////////////////////////////////
    // CONFIG
    //////////////////////////////////////////////////////

    const CONFIG = {
        domain: "1secmail.com",
        checkInterval: 5000,
        maxChecks: 24
    };

    //////////////////////////////////////////////////////
    // STATE
    //////////////////////////////////////////////////////

    let currentMail = null;
    let checking = false;
    let timer = null;

    //////////////////////////////////////////////////////
    // STYLE
    //////////////////////////////////////////////////////

    const style = document.createElement("style");

    style.textContent = `
        #ghost-btn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 999999999;

            background: rgba(10,10,10,.92);
            backdrop-filter: blur(10px);

            color: #00e5ff;

            border: 1px solid #00e5ff;
            border-radius: 14px;

            padding: 12px 16px;

            font-family: monospace;
            font-size: 13px;
            font-weight: bold;

            cursor: pointer;
            user-select: none;

            transition: all .25s ease;

            box-shadow:
                0 0 14px rgba(0,229,255,.25),
                inset 0 0 12px rgba(0,229,255,.05);
        }

        #ghost-btn:hover {
            transform: translateY(-2px);

            box-shadow:
                0 0 18px rgba(0,229,255,.5),
                inset 0 0 16px rgba(0,229,255,.1);
        }

        #ghost-btn.working {
            color: #ffd000;
            border-color: #ffd000;
        }

        #ghost-btn.success {
            color: #00ff88;
            border-color: #00ff88;
        }

        #ghost-toast {
            position: fixed;
            bottom: 82px;
            right: 20px;

            background: rgba(20,20,20,.95);
            color: #fff;

            border: 1px solid #222;
            border-radius: 12px;

            padding: 12px 14px;

            font-family: monospace;
            font-size: 12px;

            z-index: 999999999;

            opacity: 0;
            transform: translateY(10px);

            transition: .25s ease;

            max-width: 300px;
            word-break: break-word;
        }

        #ghost-toast.show {
            opacity: 1;
            transform: translateY(0);
        }
    `;

    document.head.appendChild(style);

    //////////////////////////////////////////////////////
    // UI
    //////////////////////////////////////////////////////

    const button = document.createElement("div");
    button.id = "ghost-btn";
    button.textContent = "GHOST ID";

    const toast = document.createElement("div");
    toast.id = "ghost-toast";

    document.body.appendChild(button);
    document.body.appendChild(toast);

    //////////////////////////////////////////////////////
    // HELPERS
    //////////////////////////////////////////////////////

    const showToast = (text) => {
        toast.textContent = text;

        toast.classList.add("show");

        setTimeout(() => {
            toast.classList.remove("show");
        }, 3000);
    };

    const generateMail = () => {
        const random = crypto.randomUUID().slice(0, 10);
        return `${random}@${CONFIG.domain}`;
    };

    const setNativeInputValue = (element, value) => {

        const prototype = Object.getPrototypeOf(element);

        const descriptor =
            Object.getOwnPropertyDescriptor(prototype, "value");

        descriptor.set.call(element, value);

        element.dispatchEvent(
            new Event("input", { bubbles: true })
        );

        element.dispatchEvent(
            new Event("change", { bubbles: true })
        );
    };

    const findEmailInput = () => {

        const selectors = [
            'input[type="email"]',
            'input[name*="mail" i]',
            'input[name*="email" i]',
            'input[placeholder*="mail" i]',
            'input[autocomplete="email"]'
        ];

        for (const selector of selectors) {

            const input = document.querySelector(selector);

            if (input && !input.disabled) {
                return input;
            }
        }

        return null;
    };

    const extractOTP = (text) => {

        const matches = text.match(/\b\d{4,8}\b/g);

        if (!matches) return null;

        return matches[0];
    };

    //////////////////////////////////////////////////////
    // REQUEST
    //////////////////////////////////////////////////////

    const request = (url) => {

        return new Promise((resolve, reject) => {

            GM_xmlhttpRequest({
                method: "GET",
                url,

                onload: (res) => {

                    try {
                        resolve(JSON.parse(res.responseText));
                    } catch (err) {
                        reject(err);
                    }
                },

                onerror: reject
            });
        });
    };

    //////////////////////////////////////////////////////
    // MAIL CHECKER
    //////////////////////////////////////////////////////

    const startChecking = async (login) => {

        if (checking) return;

        checking = true;

        let attempts = 0;

        button.classList.add("working");
        button.textContent = "WAITING OTP";

        timer = setInterval(async () => {

            attempts++;

            if (attempts >= CONFIG.maxChecks) {

                clearInterval(timer);

                checking = false;

                button.classList.remove("working");
                button.textContent = "GHOST ID";

                showToast("Timeout");

                return;
            }

            try {

                const messages = await request(
                    `https://www.1secmail.com/api/v1/?action=getMessages&login=${login}&domain=${CONFIG.domain}`
                );

                if (!messages.length) return;

                const mail = await request(
                    `https://www.1secmail.com/api/v1/?action=readMessage&login=${login}&domain=${CONFIG.domain}&id=${messages[0].id}`
                );

                const content =
                    `${mail.subject}\n${mail.body}\n${mail.textBody}`;

                const otp = extractOTP(content);

                clearInterval(timer);

                checking = false;

                button.classList.remove("working");
                button.classList.add("success");

                button.textContent = otp || "MAIL FOUND";

                try {
                    await navigator.clipboard.writeText(
                        otp || content
                    );
                } catch {}

                showToast(
                    otp
                        ? `OTP Copied: ${otp}`
                        : "Mail copied"
                );

                console.log("Ghost Mail:", mail);

                setTimeout(() => {

                    button.classList.remove("success");
                    button.textContent = "GHOST ID";

                }, 5000);

            } catch (err) {

                console.error("Ghost Identity Error:", err);
            }

        }, CONFIG.checkInterval);
    };

    //////////////////////////////////////////////////////
    // MAIN
    //////////////////////////////////////////////////////

    button.addEventListener("click", async () => {

        if (checking) {
            showToast("Already checking");
            return;
        }

        const input = findEmailInput();

        if (!input) {

            showToast("Email input not found");

            return;
        }

        currentMail = generateMail();

        setNativeInputValue(input, currentMail);

        showToast(currentMail);

        const login = currentMail.split("@")[0];

        startChecking(login);
    });

})();