Skip to content

Commit 917dfa1

Browse files
committed
feat: [wip] change to oauth
1 parent 24dc93e commit 917dfa1

1 file changed

Lines changed: 52 additions & 53 deletions

File tree

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,59 @@
1-
import { execa } from "execa"
1+
import consola from "consola"
22

3-
// @ts-expect-error TypeScript can't analyze timeout
4-
export async function getGitHubToken(): Promise<string> {
5-
// Kill any existing vscode processes
6-
// otherwise, no token call will be made
7-
await killVSCodeProcesses()
8-
9-
const mitmdump = createMitmdumpProcess()
10-
void createVSCodeProcess()
11-
12-
const timeout = setTimeout(() => {
13-
throw new Error("Timed out waiting for token")
14-
}, 30_000)
3+
import { ENV } from "~/lib/env"
4+
import { _github } from "~/services/api-instance"
155

16-
for await (const line of mitmdump.stdout) {
17-
if (typeof line !== "string") continue
18-
if (!line.includes("authorization: token")) continue
19-
20-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
21-
const token = line
22-
.split("\n")
23-
.map((line) => line.trim())
24-
.filter(Boolean)
25-
.find((line) => line.includes("authorization: token"))!
26-
.split("authorization: token ")
27-
.at(1)!
28-
.trim()
6+
interface DeviceCodeResponse {
7+
device_code: string
8+
user_code: string
9+
verification_uri: string
10+
expires_in: number
11+
interval: number
12+
}
2913

30-
clearTimeout(timeout)
14+
interface AccessTokenResponse {
15+
access_token: string
16+
token_type: string
17+
scope: string
18+
}
3119

32-
await killVSCodeProcesses()
33-
mitmdump.kill()
20+
export async function getGitHubToken(): Promise<string> {
21+
consola.start("Getting GitHub device code")
3422

35-
return token
23+
const response = await _github<DeviceCodeResponse>("/login/device/code", {
24+
method: "POST",
25+
body: {
26+
client_id: ENV.GITHUB_CLIENT_ID,
27+
scope: ENV.GITHUB_OAUTH_SCOPES,
28+
},
29+
})
30+
31+
consola.info(
32+
`Please enter the code "${response.user_code}" in ${response.verification_uri}`,
33+
)
34+
35+
while (true) {
36+
const pollResponse = await _github<AccessTokenResponse>(
37+
"/login/oauth/access_token",
38+
{
39+
method: "POST",
40+
body: {
41+
client_id: ENV.GITHUB_CLIENT_ID,
42+
device_code: response.device_code,
43+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
44+
},
45+
},
46+
)
47+
48+
if (pollResponse.access_token) {
49+
consola.info(`Got token ${pollResponse.access_token.replace(/./g, "*")}`)
50+
return pollResponse.access_token
51+
} else {
52+
// Interval is in seconds, we need to multiply by 1000 to get milliseconds
53+
// I'm also adding another second, just to be safe
54+
await new Promise((resolve) =>
55+
setTimeout(resolve, (response.interval + 1) * 1000),
56+
)
57+
}
3658
}
3759
}
38-
39-
const createMitmdumpProcess = () =>
40-
execa({ reject: false })("mitmdump", [
41-
"--flow-detail",
42-
"4",
43-
"~m GET & ~u https://api.github.com/copilot_internal/v2/token",
44-
])
45-
46-
const createVSCodeProcess = () =>
47-
execa({
48-
reject: false,
49-
env: {
50-
http_proxy: "http://127.0.0.1:8080",
51-
https_proxy: "http://127.0.0.1:8080",
52-
},
53-
})("code", [
54-
"--ignore-certificate-errors",
55-
// Can be whatever folder, as long as it's trusted by vscode
56-
// https://code.visualstudio.com/docs/editor/workspace-trust
57-
"/home/erick/Documents/sides/playground/",
58-
])
59-
60-
const killVSCodeProcesses = () => execa({ reject: false })("pkill", ["code"])

0 commit comments

Comments
 (0)