Implement /token page

GitHub Copilot Token Generator
robots: https://developers.google.com/search/docs/crawling-indexing/block-indexing

Memo just in case: there were more alternative static serving possibilities:
- https://developers.cloudflare.com/workers/configuration/sites/start-from-worker/
- wrangler deploy --assets ./public
This commit is contained in:
johnd0e
2024-03-07 02:24:28 +01:00
parent 5059cffa15
commit 547d38240a
3 changed files with 133 additions and 1 deletions

120
src/get_copilot_token.html Normal file
View File

@@ -0,0 +1,120 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<style>
input { font-family: monospace; }
.large { font-size: large; }
.noborder { border: none; }
.copied::after { margin-left:3px; content:"copied!"; font-style:italic; background-color:silver; padding:3px; border-radius:4px; }
.hidden { display: none; }
#notice { font-style: italic; }
.error { color: red; }
</style>
</head>
<body>
<h2>GitHub Copilot token Generator</h2>
<p id="message"><em>Loading...</em>
<div id="info" class="hidden">
<p>Waiting login: <code id="time"></code>
<p id="notice">
Your token remains secure within your browser.<br>
You are welcome to press <kbd>Ctrl+U</kbd> to view the complete source code of the script.<br>
Or visit the following URL:
</div>
<script>
const message = document.getElementById("message");
const makeCopyable = (text, classes) => {
const el = document.createElement("input");
el.setAttribute("title", "Click to copy");
el.setAttribute("value", text);
el.setAttribute("size", text.length);
el.setAttribute("readonly", "");
el.setAttribute("class", classes);
el.addEventListener("click", async () => {
await navigator.clipboard.writeText(text);
const copied = document.createElement("span");
copied.classList.add("copied");
el.after(copied);
setTimeout(() => copied.remove(), 1000);
});
return el;
};
document.getElementById("notice")
.append(makeCopyable("view-source:" + window.location.href, "noborder"));
const safeFetch = async (url, options) => {
let data;
try {
const response = await fetch("/corsproxy?" + url, options);
if (response.ok) {
data = await response.json();
} else {
console.error(await response.text());
data = { error: `${url}: ${response.status} ${response.statusText}` };
}
} catch (error) {
data = { error: `${url}: ${error}` };
}
return data;
};
document.addEventListener("DOMContentLoaded", async () => {
let url = "https://github.com/login/device/code";
const clientId = "Iv1.b507a08c87ecfe98"; // GitHub Copilot Plugin by GitHub
let body = JSON.stringify({
client_id: clientId,
scope: "read:user"
});
const headers = {
"Accept": "application/json",
"Content-Type": "application/json"
};
let data = await safeFetch(url, { method: "POST", headers, body });
if (data.error) {
message.textContent = "Error: " + data.error;
message.classList.add("error");
return;
}
message.innerHTML = `Please open <a href="${data.verification_uri}" target="_blank">${data.verification_uri}</a> and enter `;
message.append(makeCopyable(data.user_code, "large"));
const info = document.getElementById("info");
info.classList.remove("hidden");
url = "https://github.com/login/oauth/access_token";
body = JSON.stringify({
client_id: clientId,
device_code: data.device_code,
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
});
const time = document.getElementById("time");
const timeout = Date.now() + data.expires_in * 1000;
const countdown = setInterval(() => {
const left = timeout - Date.now();
const date = new Date(left > 0 ? left : 0);
time.textContent = date.toLocaleTimeString().substring(3);
}, 1000);
const interval = data.interval;
setTimeout(async function poll () {
data = await safeFetch(url, { method: "POST", headers, body });
if (data.error === "authorization_pending" || data.error === "slow_down") {
setTimeout(poll, (data.interval || interval) * 1000);
return;
}
if (data.access_token) {
message.textContent = "Your token is: ";
message.append(makeCopyable(data.access_token, "noborder large"));
} else {
console.error(data);
message.textContent = "Error: " + (data.error_description || data.error);
message.classList.add("error");
}
clearInterval(countdown);
info.classList.add("hidden");
}, interval * 1000);
});
</script>
</body>
</html>

View File

@@ -1,3 +1,5 @@
import token_html from "./get_copilot_token.html";
export default {
async fetch (request, env) {
if (request.method === "OPTIONS") {
@@ -7,6 +9,17 @@ export default {
if (url.pathname === "/v1/models") {
return handleModels(request);
}
if (url.pathname === "/token") {
return new Response(token_html, {
headers: { "Content-Type": "text/html" }
});
}
if (url.pathname === "/corsproxy" && url.search.startsWith("?https://")) {
let resp = await fetch(url.search.substring(1), request);
resp = new Response(resp.body, resp);
resp.headers.set("Access-Control-Allow-Origin", "*");
return resp;
}
const auth = request.headers.get("Authorization");
let authKey = auth && auth.split(" ")[1];
if (!authKey) {

View File

@@ -1,7 +1,6 @@
name = "copilot"
main = "src/worker.mjs"
compatibility_date = "2024-01-17"
no_bundle = true
[[kv_namespaces]]
binding = "KV"