Automatically fill and submit GitHub device authorization code, and handle confirmation page by form submission after fully loaded.
As of
- // ==UserScript==
- // @name GitHub Copilot automatically obtains GHU
- // @namespace http://tampermonkey.net/
- // @version 1.1
- // @description Automatically fill and submit GitHub device authorization code, and handle confirmation page by form submission after fully loaded.
- // @author NingMengGuoRou
- // @match https://github.com/login/device*
- // @grant GM_xmlhttpRequest
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- // const fetchTokenUrl = '改成你自己的http(s)://ip:端口';
- const fetchTokenUrl = 'https://xxxx:9191';
- async function getUserCode() {
- return new Promise((resolve, reject) => {
- GM_xmlhttpRequest({
- method: "GET",
- url: fetchTokenUrl+"/get_user_code",
- onload: function(response) {
- try {
- const data = JSON.parse(response.responseText);
- if (data.user_code) {
- resolve(data.user_code);
- } else {
- reject("Failed to get user code");
- }
- } catch (e) {
- reject(e.toString());
- }
- },
- onerror: function(error) {
- reject(error.toString());
- }
- });
- });
- }
- function waitForElement(selector, delay = 50, maxAttempts = 20) {
- return new Promise((resolve, reject) => {
- let attempts = 0;
- const interval = setInterval(() => {
- const element = document.querySelector(selector);
- attempts++;
- if (element) {
- clearInterval(interval);
- resolve(element);
- } else if (attempts >= maxAttempts) {
- clearInterval(interval);
- reject(new Error(`Element ${selector} not found`));
- }
- }, delay);
- });
- }
- async function fillAndSubmitCode() {
- try {
- const userCode = await getUserCode();
- const codeParts = userCode.split('-');
- if (codeParts.length !== 2) {
- console.error("Invalid user code format.");
- return;
- }
- for (let i = 0; i < codeParts[0].length; i++) {
- waitForElement(`#user-code-${i}`).then(el => el.value = codeParts[0][i]);
- }
- for (let i = 0; i < codeParts[1].length; i++) {
- waitForElement(`#user-code-${i + 5}`).then(el => el.value = codeParts[1][i]);
- }
- waitForElement('input[type="submit"][name="commit"]').then(button => setTimeout(() => button.click(), 1000));
- } catch (error) {
- console.error(error);
- }
- }
- // function autoSubmitFormOnConfirmation() {
- // const observer = new MutationObserver((mutations, obs) => {
- // const form = document.querySelector('form');
- // if (form) {
- // const authorizeButton = form.querySelector('button[name="authorize"][value="1"]');
- // if (authorizeButton) {
- // setTimeout(() => {
- // form.submit();
- // obs.disconnect();
- // }, 1000);
- // }
- // }
- // });
- // observer.observe(document.body, { childList: true, subtree: true });
- // }
- function autoSubmitFormOnConfirmation() {
- console.log("--------------------------------------------------------")
- window.addEventListener('load', () => {
- waitForElement('form[action="/login/device/authorize"] button[name="authorize"][value="1"]')
- .then(button => setTimeout(() => button.click(), 1000))
- .catch(error => console.error(error));
- });
- }
- if (window.location.pathname.includes('/login/device')) {
- fillAndSubmitCode();
- }
- if (window.location.pathname.includes('/login/device/confirmation')) {
- autoSubmitFormOnConfirmation();
- }
- if (window.location.pathname.includes('/login/device/success')) {
- // Add a delay before executing the GM_xmlhttpRequest call
- setTimeout(function() {
- GM_xmlhttpRequest({
- method: 'GET',
- url: fetchTokenUrl+"/success",
- onload: function(response) {
- try {
- const data = JSON.parse(response.responseText);
- console.log(data);
- if (data.token) {
- const message = document.createElement('div');
- message.style.position = 'fixed';
- message.style.left = '0';
- message.style.top = '0'; // Changed from bottom to top
- message.style.width = '100%';
- message.style.backgroundColor = 'green';
- message.style.color = 'white';
- message.style.textAlign = 'center';
- message.style.padding = '10px';
- message.style.fontSize = '20px';
- message.style.zIndex = '1000'; // Ensure it's on top of other elements
- message.innerText = 'Authorization successful! You can now close this window GHU:'+data.token;
- document.body.appendChild(message);
- } else {
- console.error("Token fetch error: ", data.error);
- }
- } catch (e) {
- console.error("Response parsing error: ", e);
- }
- },
- onerror: function(error) {
- console.error("Request failed: ", error);
- }
- });
- }, 1000); // Delay set to 5000 milliseconds (5 seconds)
- }
- })();