Password Manager & Autofiller

Secure password manager with autofill capabilities

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Password Manager & Autofiller
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Secure password manager with autofill capabilities
// @author       voidofdarkness
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Encryption/Decryption utilities (simple XOR - for production use a proper crypto library)
    function simpleEncrypt(text, key) {
        let result = '';
        for (let i = 0; i < text.length; i++) {
            result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length));
        }
        return btoa(result);
    }

    function simpleDecrypt(encoded, key) {
        const text = atob(encoded);
        let result = '';
        for (let i = 0; i < text.length; i++) {
            result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length));
        }
        return result;
    }

    // Get master password from user
    let masterPassword = GM_getValue('master_password', '');

    // Password storage functions
    function savePassword(domain, username, password) {
        if (!masterPassword) {
            alert('Please set a master password first!');
            return;
        }
        const encrypted = simpleEncrypt(password, masterPassword);
        const key = `pwd_${domain}`;
        const data = GM_getValue(key, {});
        data[username] = encrypted;
        GM_setValue(key, data);
    }

    function getPasswords(domain) {
        if (!masterPassword) return {};
        const key = `pwd_${domain}`;
        const data = GM_getValue(key, {});
        const decrypted = {};
        for (let username in data) {
            try {
                decrypted[username] = simpleDecrypt(data[username], masterPassword);
            } catch (e) {
                console.error('Decryption failed for', username);
            }
        }
        return decrypted;
    }

    function deletePassword(domain, username) {
        const key = `pwd_${domain}`;
        const data = GM_getValue(key, {});
        delete data[username];
        GM_setValue(key, data);
    }

    // Get current domain
    const currentDomain = window.location.hostname;

    // Create UI
    function createUI() {
        const panel = document.createElement('div');
        panel.id = 'pwd-manager-panel';
        panel.style.cssText = `
            position: fixed;
            top: 10px;
            right: 10px;
            width: 320px;
            background: #2c3e50;
            color: #ecf0f1;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            z-index: 999999;
            font-family: Arial, sans-serif;
            display: none;
        `;

        panel.innerHTML = `
            <div style="padding: 15px; border-bottom: 1px solid #34495e;">
                <h3 style="margin: 0; font-size: 16px;">🔐 Password Manager</h3>
                <button id="close-panel" style="position: absolute; top: 15px; right: 15px; background: none; border: none; color: #ecf0f1; font-size: 20px; cursor: pointer;">×</button>
            </div>
            <div style="padding: 15px;">
                <div id="master-pwd-section" style="margin-bottom: 15px;">
                    <input type="password" id="master-pwd-input" placeholder="Master Password" style="width: 100%; padding: 8px; border: 1px solid #34495e; border-radius: 4px; background: #34495e; color: #ecf0f1; box-sizing: border-box;">
                    <button id="set-master-pwd" style="width: 100%; margin-top: 8px; padding: 8px; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer;">Set Master Password</button>
                </div>
                <div id="password-section" style="display: none;">
                    <div style="margin-bottom: 15px;">
                        <strong>Domain:</strong> ${currentDomain}
                    </div>
                    <input type="text" id="username-input" placeholder="Username" style="width: 100%; padding: 8px; margin-bottom: 8px; border: 1px solid #34495e; border-radius: 4px; background: #34495e; color: #ecf0f1; box-sizing: border-box;">
                    <input type="password" id="password-input" placeholder="Password" style="width: 100%; padding: 8px; margin-bottom: 8px; border: 1px solid #34495e; border-radius: 4px; background: #34495e; color: #ecf0f1; box-sizing: border-box;">
                    <button id="save-pwd" style="width: 100%; padding: 8px; background: #27ae60; color: white; border: none; border-radius: 4px; cursor: pointer; margin-bottom: 15px;">Save Password</button>
                    <div id="saved-passwords" style="max-height: 200px; overflow-y: auto;">
                        <strong>Saved Accounts:</strong>
                        <div id="password-list" style="margin-top: 8px;"></div>
                    </div>
                </div>
            </div>
        `;

        document.body.appendChild(panel);

        // Toggle button
        const toggleBtn = document.createElement('button');
        toggleBtn.id = 'pwd-manager-toggle';
        toggleBtn.innerHTML = '🔐';
        toggleBtn.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            background: #3498db;
            color: white;
            border: none;
            font-size: 24px;
            cursor: pointer;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            z-index: 999998;
        `;
        document.body.appendChild(toggleBtn);

        // Event listeners
        toggleBtn.onclick = () => {
            panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
        };

        document.getElementById('close-panel').onclick = () => {
            panel.style.display = 'none';
        };

        document.getElementById('set-master-pwd').onclick = () => {
            const pwd = document.getElementById('master-pwd-input').value;
            if (pwd.length < 4) {
                alert('Master password must be at least 4 characters!');
                return;
            }
            masterPassword = pwd;
            GM_setValue('master_password', pwd);
            document.getElementById('master-pwd-section').style.display = 'none';
            document.getElementById('password-section').style.display = 'block';
            updatePasswordList();
        };

        document.getElementById('save-pwd').onclick = () => {
            const username = document.getElementById('username-input').value;
            const password = document.getElementById('password-input').value;
            if (!username || !password) {
                alert('Please enter both username and password!');
                return;
            }
            savePassword(currentDomain, username, password);
            document.getElementById('username-input').value = '';
            document.getElementById('password-input').value = '';
            updatePasswordList();
            alert('Password saved!');
        };

        if (masterPassword) {
            document.getElementById('master-pwd-section').style.display = 'none';
            document.getElementById('password-section').style.display = 'block';
            updatePasswordList();
        }
    }

    function updatePasswordList() {
        const passwords = getPasswords(currentDomain);
        const listDiv = document.getElementById('password-list');
        listDiv.innerHTML = '';

        if (Object.keys(passwords).length === 0) {
            listDiv.innerHTML = '<div style="color: #95a5a6; font-size: 12px;">No saved passwords for this site</div>';
            return;
        }

        for (let username in passwords) {
            const itemDiv = document.createElement('div');
            itemDiv.style.cssText = 'padding: 8px; background: #34495e; margin-bottom: 8px; border-radius: 4px; display: flex; justify-content: space-between; align-items: center;';
            itemDiv.innerHTML = `
                <span style="flex: 1;">${username}</span>
                <button class="autofill-btn" data-username="${username}" style="padding: 4px 8px; background: #3498db; color: white; border: none; border-radius: 3px; cursor: pointer; margin-right: 5px; font-size: 12px;">Fill</button>
                <button class="delete-btn" data-username="${username}" style="padding: 4px 8px; background: #e74c3c; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;">Delete</button>
            `;
            listDiv.appendChild(itemDiv);
        }

        // Autofill buttons
        document.querySelectorAll('.autofill-btn').forEach(btn => {
            btn.onclick = () => {
                const username = btn.dataset.username;
                const password = passwords[username];
                autofillCredentials(username, password);
            };
        });

        // Delete buttons
        document.querySelectorAll('.delete-btn').forEach(btn => {
            btn.onclick = () => {
                const username = btn.dataset.username;
                if (confirm(`Delete password for ${username}?`)) {
                    deletePassword(currentDomain, username);
                    updatePasswordList();
                }
            };
        });
    }

    function autofillCredentials(username, password) {
        // Find username/email fields
        const usernameFields = document.querySelectorAll('input[type="text"], input[type="email"], input[name*="user"], input[name*="email"], input[id*="user"], input[id*="email"]');
        const passwordFields = document.querySelectorAll('input[type="password"]');

        if (usernameFields.length > 0) {
            usernameFields[0].value = username;
            usernameFields[0].dispatchEvent(new Event('input', { bubbles: true }));
            usernameFields[0].dispatchEvent(new Event('change', { bubbles: true }));
        }

        if (passwordFields.length > 0) {
            passwordFields[0].value = password;
            passwordFields[0].dispatchEvent(new Event('input', { bubbles: true }));
            passwordFields[0].dispatchEvent(new Event('change', { bubbles: true }));
        }

        alert('Credentials autofilled!');
    }

    // Initialize
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', createUI);
    } else {
        createUI();
    }
})();