您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Auto-fills roll number and Base64-encoded password with an overlay for managing multiple credentials
// ==UserScript== // @name Auto-fill JEE Form with Multiple Credentials // @namespace http://tampermonkey.net/ // @version 5.1 // @description Auto-fills roll number and Base64-encoded password with an overlay for managing multiple credentials // @match https://josaa.admissions.nic.in/Applicant/Root/CandidateLogin.aspx* // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_deleteValue // ==/UserScript== (function() { 'use strict'; // Encode and decode Base64 string function encode(str) { return btoa(str); } function decode(str) { return atob(str); } // Get saved credentials let credentialsList = GM_getValue('jeeCredentialsList', []); if (credentialsList.length === 0) { // Add default credentials if none exist credentialsList.push({ name: 'Default', rollNumber: '250310617863', encodedPassword: 'U2l0amVlQDg4', timestamp: new Date().toISOString().replace('T', ' ').substr(0, 19) }); GM_setValue('jeeCredentialsList', credentialsList); } // Get last used profile index or default to 0 let lastUsedProfileIndex = GM_getValue('jeeLastUsedProfileIndex', 0); // Make sure index is valid (in case profiles were deleted) if (lastUsedProfileIndex >= credentialsList.length) { lastUsedProfileIndex = 0; GM_setValue('jeeLastUsedProfileIndex', 0); } // Set active credentials to last used profile let activeCredentials = credentialsList[lastUsedProfileIndex]; window.addEventListener('load', function() { applyCredentials(activeCredentials); createCredentialsOverlay(); }); function applyCredentials(creds) { const rollInput = document.getElementById('ctl00_ContentPlaceHolder1_rollno'); const passInput = document.getElementById('ctl00_ContentPlaceHolder1_Password1'); if (rollInput) { rollInput.value = creds.rollNumber; } if (passInput) { passInput.value = decode(creds.encodedPassword); } } function createCredentialsOverlay() { // Create overlay container const overlay = document.createElement('div'); overlay.style.position = 'fixed'; overlay.style.bottom = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; overlay.style.color = 'white'; overlay.style.padding = '15px'; overlay.style.zIndex = '9999'; overlay.style.display = 'flex'; overlay.style.flexDirection = 'column'; overlay.style.alignItems = 'center'; overlay.style.maxHeight = '70vh'; overlay.style.overflowY = 'auto'; // Create profile management section const profileSection = document.createElement('div'); profileSection.style.width = '100%'; profileSection.style.marginBottom = '10px'; profileSection.style.display = 'flex'; profileSection.style.flexWrap = 'wrap'; profileSection.style.justifyContent = 'center'; profileSection.style.alignItems = 'center'; // Profile selector const profileSelect = document.createElement('select'); profileSelect.style.padding = '5px'; profileSelect.style.marginRight = '10px'; // Populate profile selector credentialsList.forEach((cred, index) => { const option = document.createElement('option'); option.value = index; option.textContent = cred.name + ' (' + cred.rollNumber + ')'; if (index === lastUsedProfileIndex) { option.selected = true; } profileSelect.appendChild(option); }); // Profile selector change handler profileSelect.addEventListener('change', function() { const selectedIndex = parseInt(this.value); activeCredentials = credentialsList[selectedIndex]; // Save the last used profile index lastUsedProfileIndex = selectedIndex; GM_setValue('jeeLastUsedProfileIndex', lastUsedProfileIndex); // Update form fields nameInput.value = activeCredentials.name; rollInput.value = activeCredentials.rollNumber; passInput.value = decode(activeCredentials.encodedPassword); // Update status updateStatusMessage('Profile "' + activeCredentials.name + '" selected'); }); // Delete profile button const deleteBtn = document.createElement('button'); deleteBtn.textContent = '🗑️ Delete'; deleteBtn.style.padding = '5px 10px'; deleteBtn.style.backgroundColor = '#f44336'; deleteBtn.style.border = 'none'; deleteBtn.style.color = 'white'; deleteBtn.style.cursor = 'pointer'; deleteBtn.style.marginRight = '10px'; deleteBtn.addEventListener('click', function() { const selectedIndex = parseInt(profileSelect.value); // Can't delete if only one profile exists if (credentialsList.length <= 1) { updateStatusMessage('Cannot delete the only profile', 'error'); return; } // Confirm deletion if (!confirm('Delete profile "' + credentialsList[selectedIndex].name + '"?')) { return; } // Delete profile credentialsList.splice(selectedIndex, 1); GM_setValue('jeeCredentialsList', credentialsList); // Adjust last used index if needed if (lastUsedProfileIndex >= credentialsList.length) { lastUsedProfileIndex = credentialsList.length - 1; } if (selectedIndex === lastUsedProfileIndex) { lastUsedProfileIndex = 0; // Reset to first profile if we're deleting the active one } GM_setValue('jeeLastUsedProfileIndex', lastUsedProfileIndex); // Set active credentials to the new last used profile activeCredentials = credentialsList[lastUsedProfileIndex]; // Rebuild dropdown while (profileSelect.firstChild) { profileSelect.removeChild(profileSelect.firstChild); } // Repopulate dropdown credentialsList.forEach((cred, index) => { const option = document.createElement('option'); option.value = index; option.textContent = cred.name + ' (' + cred.rollNumber + ')'; if (index === lastUsedProfileIndex) { option.selected = true; } profileSelect.appendChild(option); }); // Update form fields nameInput.value = activeCredentials.name; rollInput.value = activeCredentials.rollNumber; passInput.value = decode(activeCredentials.encodedPassword); updateStatusMessage('Profile deleted successfully'); }); // Create form section const formSection = document.createElement('div'); formSection.style.width = '100%'; formSection.style.display = 'flex'; formSection.style.flexWrap = 'wrap'; formSection.style.justifyContent = 'center'; formSection.style.alignItems = 'center'; formSection.style.marginBottom = '10px'; // Profile name input const nameLabel = document.createElement('label'); nameLabel.textContent = 'Profile Name: '; nameLabel.style.marginRight = '5px'; const nameInput = document.createElement('input'); nameInput.type = 'text'; nameInput.placeholder = 'Profile Name'; nameInput.value = activeCredentials.name; nameInput.style.marginRight = '15px'; nameInput.style.padding = '5px'; // Create roll number input const rollLabel = document.createElement('label'); rollLabel.textContent = 'Roll Number: '; rollLabel.style.marginRight = '5px'; const rollInput = document.createElement('input'); rollInput.type = 'text'; rollInput.placeholder = 'Enter Roll Number'; rollInput.value = activeCredentials.rollNumber; rollInput.style.marginRight = '15px'; rollInput.style.padding = '5px'; // Create password input const passLabel = document.createElement('label'); passLabel.textContent = 'Password: '; passLabel.style.marginRight = '5px'; const passInput = document.createElement('input'); passInput.type = 'password'; passInput.placeholder = 'Enter Password'; passInput.value = decode(activeCredentials.encodedPassword); passInput.style.marginRight = '15px'; passInput.style.padding = '5px'; // Toggle password visibility button const togglePassBtn = document.createElement('button'); togglePassBtn.textContent = '👁️'; togglePassBtn.style.padding = '5px'; togglePassBtn.style.marginRight = '15px'; togglePassBtn.style.cursor = 'pointer'; togglePassBtn.title = 'Toggle Password Visibility'; togglePassBtn.addEventListener('click', function() { if (passInput.type === 'password') { passInput.type = 'text'; } else { passInput.type = 'password'; } }); // Button section const buttonSection = document.createElement('div'); buttonSection.style.width = '100%'; buttonSection.style.display = 'flex'; buttonSection.style.justifyContent = 'center'; buttonSection.style.marginTop = '10px'; // Create apply button const applyButton = document.createElement('button'); applyButton.textContent = '✓ Apply'; applyButton.style.padding = '5px 10px'; applyButton.style.backgroundColor = '#4CAF50'; applyButton.style.border = 'none'; applyButton.style.color = 'white'; applyButton.style.cursor = 'pointer'; applyButton.style.marginRight = '10px'; // Create save as new button const saveNewButton = document.createElement('button'); saveNewButton.textContent = '💾 Save as New'; saveNewButton.style.padding = '5px 10px'; saveNewButton.style.backgroundColor = '#2196F3'; saveNewButton.style.border = 'none'; saveNewButton.style.color = 'white'; saveNewButton.style.cursor = 'pointer'; saveNewButton.style.marginRight = '10px'; // Create update button const updateButton = document.createElement('button'); updateButton.textContent = '🔄 Update Profile'; updateButton.style.padding = '5px 10px'; updateButton.style.backgroundColor = '#FF9800'; updateButton.style.border = 'none'; updateButton.style.color = 'white'; updateButton.style.cursor = 'pointer'; updateButton.style.marginRight = '10px'; // Create close button const closeButton = document.createElement('button'); closeButton.textContent = 'X'; closeButton.style.padding = '5px 10px'; closeButton.style.backgroundColor = '#f44336'; closeButton.style.border = 'none'; closeButton.style.color = 'white'; closeButton.style.cursor = 'pointer'; // Status message const statusMsg = document.createElement('div'); statusMsg.style.width = '100%'; statusMsg.style.textAlign = 'center'; statusMsg.style.marginTop = '8px'; statusMsg.style.fontSize = '0.9em'; statusMsg.textContent = 'Select a profile or create a new one'; // Update status message function function updateStatusMessage(message, type = 'info') { statusMsg.textContent = message; if (type === 'error') { statusMsg.style.color = '#f44336'; } else if (type === 'success') { statusMsg.style.color = '#4CAF50'; } else { statusMsg.style.color = 'white'; } // Reset color after 3 seconds setTimeout(function() { statusMsg.style.color = 'white'; statusMsg.textContent = 'Select a profile or create a new one'; }, 3000); } // Add event listeners applyButton.addEventListener('click', function() { // Apply the current values and remember as last used const selectedIndex = parseInt(profileSelect.value); lastUsedProfileIndex = selectedIndex; GM_setValue('jeeLastUsedProfileIndex', lastUsedProfileIndex); const formRollInput = document.getElementById('ctl00_ContentPlaceHolder1_rollno'); const formPassInput = document.getElementById('ctl00_ContentPlaceHolder1_Password1'); if (formRollInput) { formRollInput.value = rollInput.value; } if (formPassInput) { formPassInput.value = passInput.value; } updateStatusMessage('Credentials applied successfully', 'success'); }); saveNewButton.addEventListener('click', function() { // Create a new profile const now = new Date(); const timestamp = now.toISOString().replace('T', ' ').substr(0, 19); const newProfile = { name: nameInput.value || 'Profile ' + (credentialsList.length + 1), rollNumber: rollInput.value, encodedPassword: encode(passInput.value), timestamp: timestamp }; // Add to list and save credentialsList.push(newProfile); GM_setValue('jeeCredentialsList', credentialsList); // Set as active and remember lastUsedProfileIndex = credentialsList.length - 1; GM_setValue('jeeLastUsedProfileIndex', lastUsedProfileIndex); activeCredentials = newProfile; // Add to dropdown const option = document.createElement('option'); option.value = lastUsedProfileIndex; option.textContent = newProfile.name + ' (' + newProfile.rollNumber + ')'; option.selected = true; profileSelect.appendChild(option); updateStatusMessage('New profile "' + newProfile.name + '" created', 'success'); }); updateButton.addEventListener('click', function() { const selectedIndex = parseInt(profileSelect.value); const now = new Date(); const timestamp = now.toISOString().replace('T', ' ').substr(0, 19); // Update the profile credentialsList[selectedIndex] = { name: nameInput.value || credentialsList[selectedIndex].name, rollNumber: rollInput.value, encodedPassword: encode(passInput.value), timestamp: timestamp }; // Update active credentials and remember activeCredentials = credentialsList[selectedIndex]; lastUsedProfileIndex = selectedIndex; GM_setValue('jeeLastUsedProfileIndex', lastUsedProfileIndex); // Save changes GM_setValue('jeeCredentialsList', credentialsList); // Update dropdown profileSelect.options[selectedIndex].textContent = activeCredentials.name + ' (' + activeCredentials.rollNumber + ')'; updateStatusMessage('Profile "' + activeCredentials.name + '" updated', 'success'); }); closeButton.addEventListener('click', function() { overlay.style.display = 'none'; // Create a small button to show overlay again const showButton = document.createElement('button'); showButton.textContent = 'Show Form'; showButton.style.position = 'fixed'; showButton.style.bottom = '10px'; showButton.style.right = '10px'; showButton.style.padding = '5px'; showButton.style.backgroundColor = '#555'; showButton.style.color = 'white'; showButton.style.border = 'none'; showButton.style.borderRadius = '5px'; showButton.style.cursor = 'pointer'; showButton.style.zIndex = '9998'; showButton.addEventListener('click', function() { overlay.style.display = 'flex'; showButton.remove(); }); document.body.appendChild(showButton); }); // Append elements to profile section profileSection.appendChild(document.createTextNode('Select Profile: ')); profileSection.appendChild(profileSelect); profileSection.appendChild(deleteBtn); // Append elements to form section formSection.appendChild(nameLabel); formSection.appendChild(nameInput); formSection.appendChild(document.createElement('br')); formSection.appendChild(document.createElement('br')); formSection.appendChild(rollLabel); formSection.appendChild(rollInput); formSection.appendChild(passLabel); formSection.appendChild(passInput); formSection.appendChild(togglePassBtn); // Append elements to button section buttonSection.appendChild(applyButton); buttonSection.appendChild(saveNewButton); buttonSection.appendChild(updateButton); buttonSection.appendChild(closeButton); // Append sections to overlay overlay.appendChild(profileSection); overlay.appendChild(document.createElement('hr')); overlay.appendChild(formSection); overlay.appendChild(buttonSection); overlay.appendChild(statusMsg); // Append overlay to body document.body.appendChild(overlay); } })();