MoviePilot自动登录

因为MoviePilot每次重启都要重新登陆,而且浏览器又不能自动填充账号密码,我比较懒不想输账号密码所有我写了这个脚本。

// ==UserScript==
// @name         MoviePilot自动登录
// @version      1.2.1
// @namespace    https://www.muooy.com/
// @description  因为MoviePilot每次重启都要重新登陆,而且浏览器又不能自动填充账号密码,我比较懒不想输账号密码所有我写了这个脚本。
// @author       Daliyuer
// @match        *://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=5.2
// @grant        none
// @require      https://unpkg.com/axios/dist/axios.min.js
// @license      GPL-3.0
// ==/UserScript==

(function () {
    'use strict';
    /* 
    * 更新记录
    * v1.2(2025-04-01)
    * 修复2.3.1以后的版本无法登录的问题
    * 修复了MoviePilot的账号密码错误无法自动登录的问题(账号密码错误重新弹出配置窗口)
    * 优化登录逻辑
    * 无需修改@match配置等代码配置自动判断当前网站是否是MoviePilot,对小白更友好(新增)
    *
    * v1.1(2025-01-05)
    * 新增配置窗口,无需更改文件可直接更改MoviePilot账号密码url信息,第一次使用会弹窗
    * 修复会登录其他程序的问题
    *
    */
    if (document.title == 'MoviePilot') {
        console.log("当前网站为MoviePilot开始执行自动登录程序");
        if (localStorage.getItem('AutomaticLoginConfig') === 'true') {
            startMonitoring();
        } else {
            popUps();
        }
    }
    function startMonitoring() {
        //注意上面的注释的 @match  也要改成你的MoviePilot的IP地址不要加端口
        let uname = localStorage.getItem("auname"); //MoviePilot账号
        let upassword = localStorage.getItem("aupwd"); //MoviePilot密码
        //let MoviePilotHost = localStorage.getItem("auurl"); //MoviePilot地址ip+端口 后缀不需要加 /
        let MoviePilotHost = window.location.origin; // 获取当前域名和端口

        //不懂的不要动以下代码
        var currentUrl = window.location.href;
        let intervalId;
        let vueRouter;
        var isCloud = 0;
        function waitForVue() {
            return new Promise((resolve) => {
                const checkVue = () => {
                    if (window.Vue && window.Vue.prototype.$router) {
                        vueRouter = window.Vue.prototype.$router;
                        resolve();
                    } else {
                        setTimeout(checkVue, 1000);
                    }
                };
                checkVue();
            });
        }


        function checkUrlChange() {
            const newUrl = window.location.href;
            if (!newUrl.includes(MoviePilotHost + '/#/login')) {
                clearInterval(intervalId);
                currentUrl = newUrl;
                startMonitoring();
            } else {
                info11();
            }
        }


        function info11() {

            let formData = new FormData();
            formData.append('username', uname);
            formData.append('password', upassword);
            // 查找用户名和密码输入框
            let usernameInput = document.querySelector('input[name="username"]');
            let passwordInput = document.querySelector('input[name="current-password"]');
            let loginButton = document.querySelector('button[type="submit"], button.login-button'); // 适配不同按钮

            function setInputValue(element, value) {
                let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
                nativeInputValueSetter.call(element, value);
                element.dispatchEvent(new Event('input', { bubbles: true }));
                element.dispatchEvent(new Event('change', { bubbles: true }));
            }

            setInputValue(usernameInput, localStorage.getItem("auname"));
            setInputValue(passwordInput, localStorage.getItem("aupwd"));

            loginButton.click();

            axios.post(MoviePilotHost + '/api/v1/login/access-token', formData, {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            })
                .then(function (response) {
                })
                .catch(function (error) {
                    if (error.response && error.response.status === 401) {
                        console.log('Unauthorized: 401 Status Code');
                        localStorage.setItem('AutomaticLoginConfig', 'false');
                        alert("账号密码错误,请重新输入");
                        window.history.go(0);
                    } else {
                        console.error('Error posting data:', error);
                        window.history.go(0);
                    }
                });
        }

        // function info11() {

        //     let formData = new FormData();
        //     formData.append('username', uname);
        //     formData.append('password', upassword);




        //     axios.post(MoviePilotHost + '/api/v1/login/access-token', formData, {
        //         headers: {
        //             'Content-Type': 'multipart/form-data'
        //         }
        //     })
        //         .then(function (response) {

        //             axios.get(MoviePilotHost + '/api/v1/user/config/Layout', {
        //                 headers: {
        //                     'Authorization': 'Bearer ' + response.data.access_token
        //                 }
        //             }).then((responsea) => {


        //                 localStorage.setItem('auth', '{"token":"' + response.data.access_token + '","remember":true,"originalPath":"/dashboard"}');

        //                 axios.get(MoviePilotHost + '/api/v1/user/config/Dashboard', {
        //                     headers: {
        //                         'Authorization': 'Bearer ' + response.data.access_token
        //                     }
        //                 }).then((responsea) => {

        //                     location.rel·oad();




        //                 });
        //             });

        //         })
        //         .catch(function (error) {
        //             if (error.response && error.response.status === 401) {
        //                 console.log('Unauthorized: 401 Status Code');
        //                 localStorage.setItem('AutomaticLoginConfig', 'false');
        //                 alert("账号密码错误,请重新输入");
        //                 window.history.go(0);
        //             } else {
        //                 console.error('Error posting data:', error);
        //                 window.history.go(0);
        //             }
        //         });
        // }


        function startMonitoring() {
            intervalId = setInterval(checkUrlChange, 1000);
        }


        function setupRouteChangeListeners() {

            const pushState = history.pushState;
            history.pushState = function (state) {
                pushState.apply(history, arguments);
                checkUrlChange();
            };


            window.addEventListener('hashchange', checkUrlChange);


            window.addEventListener('popstate', checkUrlChange);
        }

        async function navigateToNewUrl() {
            await waitForVue();
            const newPath = '/dashboard';
            vueRouter.push(newPath);
        }


        window.onload = startMonitoring();
        setupRouteChangeListeners();
        console.log("本脚本出生于2024-11-20,功能原创,请勿盗版!博客:https://www.muooy.com")
        return;

    }
    function popUps() {
        const style = document.createElement('style');
        style.innerHTML = `
    .AutomaticLoginForm {
    max-width: 650px;
    margin: 50px auto;
    padding: 20px;
    background: #f2f2f2;
    border: 1px solid #ddd;
    border-radius: 10px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.AutomaticLoginForm h2 {
    text-align: center;
    color: #333;
    margin-bottom: 20px;
}

.AutomaticLoginForm input[type="text"],
.AutomaticLoginForm input[type="password"] {
    width: 100%;
    padding: 10px;
    margin: 10px 0;
    border: 1px solid #ddd;
    border-radius: 5px;
    box-sizing: border-box;
}

.AutomaticLoginForm input[type="submit"] {
    width: 100%;
    padding: 10px;
    background: rgb(145, 85, 253);
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.AutomaticLoginForm input[type="submit"]:hover {
    background: rgb(148, 91, 255);
}
    `;
        document.head.appendChild(style);

        // 创建弹窗的 HTML(包含表单)
        const modalHTML = `
        <div id="AutomaticLoginMode" style="display:none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 500px; height: auto; z-index: 9999;">
            <form id="AutomaticLoginForm"class="AutomaticLoginForm" action="#" method="post">
                   <h2>MoviePilot自动登录配置</h2>
                   <input type="text" id="ausername" name="ausername" placeholder="MoviePilot的账号" required>
                   <input type="password" id="apassword" name="apassword" placeholder="MoviePilot的密码" required>
                   <!--input type="text" id="aurls" name="aurls" placeholder="地址:ip+端口,如:http://192.168.5.10:3000" required--!>
                   <p id="message" style="display:none;text-align: center; color: red;">配置成功!</p>
                   <input type="submit" value="保存">
            </form>
             </div>
        <div id="modalBackdrop" style="display:none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 9998;"></div>
    `;


        document.body.insertAdjacentHTML('beforeend', modalHTML);


        const amodal = document.getElementById('AutomaticLoginMode');
        const backdrop = document.getElementById('modalBackdrop');
        const aform = document.getElementById('AutomaticLoginForm');
        const amessage = document.getElementById('message');


        function showModal() {
            amodal.style.display = 'block';
            backdrop.style.display = 'block';
        }


        function closeModal() {
            amodal.style.display = 'none';
            backdrop.style.display = 'none';
            startMonitoring();
            //location.reload();
        }

        // 表单提交处理
        function handleSubmit(event) {
            event.preventDefault();


            const auname = document.getElementById('ausername').value;
            const aupwd = document.getElementById('apassword').value;
            //const auurl = document.getElementById('aurls').value;
            localStorage.setItem("auname", auname);
            localStorage.setItem("aupwd", aupwd);
            // localStorage.setItem("auurl", auurl);



            amessage.style.display = 'block';
            localStorage.setItem('AutomaticLoginConfig', 'true'); // 设置提交标记

            setTimeout(closeModal, 1000); // 1秒后关闭弹窗
        }

        // 绑定表单提交事件
        aform.addEventListener('submit', handleSubmit);

        // 在页面加载完成后,显示弹窗
        window.addEventListener('load', showModal);
    }
})();