forked from LOVECHEN/raycast-unblock
-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_copilot_token.mjs
126 lines (112 loc) · 3.19 KB
/
get_copilot_token.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* @reference https://raw.githubusercontent.com/aaamoon/copilot-gpt4-service/master/shells/get_copilot_token.py
*/
import { ofetch } from 'ofetch'
const request = ofetch.create({
baseURL: 'https://github.com',
headers: {
'accept': 'application/json',
'content-type': 'application/json',
},
})
const ClientID = 'Iv1.b507a08c87ecfe98'
const Scope = 'read:user'
const LoginInfoAPI = '/login/device/code'
const AuthAPI = '/login/oauth/access_token'
const GrantType = 'urn:ietf:params:oauth:grant-type:device_code'
const loginError = {
AUTH_PENDING: 1,
EXPIRED_TOKEN: 2,
NETWORK_ERROR: 3,
OTHER_ERROR: 4,
}
async function getLoginInfo() {
const body = {
client_id: ClientID,
scope: Scope,
}
const res = await request(LoginInfoAPI, {
method: 'POST',
body,
timeout: 10000,
}).then((v) => {
return [null, v]
}).catch((e) => {
if (e.code === 'ECONNREFUSED')
return [loginError.NETWORK_ERROR, null]
else
return [loginError.OTHER_ERROR, e]
})
return res
}
async function getAccessToken(device_code) {
const body = {
client_id: ClientID,
device_code,
grant_type: GrantType,
}
const res = await request(AuthAPI, {
method: 'POST',
body,
timeout: 10000,
}).then((v) => {
if (v.error === 'authorization_pending')
return [loginError.AUTH_PENDING, null]
else if (v.error === 'expired_token')
return [loginError.EXPIRED_TOKEN, null]
else if ('access_token' in v)
return [null, v]
else
return [loginError.OTHER_ERROR, v]
}).catch((e) => {
if (e.code === 'ECONNREFUSED')
return [loginError.NETWORK_ERROR, null]
else
return [loginError.OTHER_ERROR, e]
})
return res
}
async function main() {
const [err, loginInfo] = await getLoginInfo()
if (err !== null) {
if (err === loginError.NETWORK_ERROR) {
console.log('network error, please check your network.')
}
else if (err === loginError.OTHER_ERROR) {
console.log('unknown error occurred when getting login info.')
console.log('error message:', loginInfo)
}
return [err, null]
}
const interval = loginInfo.interval
console.log(`Please open ${loginInfo.verification_uri} in browser and enter ${loginInfo.user_code} to login.`)
while (true) {
const [err, accessToken] = await getAccessToken(loginInfo.device_code)
if (err === null) {
return [null, accessToken]
}
else if (err === loginError.AUTH_PENDING) {
console.log('waiting for authorization...')
}
else if (err === loginError.EXPIRED_TOKEN) {
console.log('session expired, please try again.')
return [err, null]
}
else if (err === loginError.NETWORK_ERROR) {
console.log('network error, please check your network.')
return [err, null]
}
else if (err === loginError.OTHER_ERROR) {
console.log('unknown error occurred when pulling auth info.')
console.log('error message:', accessToken)
return [err, null]
}
await new Promise(resolve => setTimeout(resolve, interval * 1000))
}
}
main().then(([err, accessToken]) => {
if (err === null)
console.log('Your access token:', accessToken.access_token)
else
console.log('error:', err)
})