Skip to content

Commit 932adad

Browse files
committed
feat: Add GitHub token retrieval and user fetching services
1 parent 31319d5 commit 932adad

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import consola from "consola"
2+
3+
import { ENV } from "~/config/env"
4+
import { _github } from "~/services/api-instance"
5+
6+
interface DeviceCodeResponse {
7+
device_code: string
8+
user_code: string
9+
verification_uri: string
10+
expires_in: number
11+
interval: number
12+
}
13+
14+
interface AccessTokenResponse {
15+
access_token: string
16+
token_type: string
17+
scope: string
18+
}
19+
20+
export async function getGitHubToken() {
21+
const response = await _github<DeviceCodeResponse>("/login/device/code", {
22+
method: "POST",
23+
body: {
24+
client_id: ENV.GITHUB_CLIENT_ID,
25+
scope: ENV.GITHUB_OAUTH_SCOPES,
26+
},
27+
})
28+
29+
consola.info(
30+
`Please enter the code "${response.user_code}" in ${response.verification_uri}`,
31+
)
32+
33+
while (true) {
34+
const pollResponse = await _github<AccessTokenResponse>(
35+
"/login/oauth/access_token",
36+
{
37+
method: "POST",
38+
body: {
39+
client_id: ENV.GITHUB_CLIENT_ID,
40+
device_code: response.device_code,
41+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
42+
},
43+
},
44+
)
45+
46+
if (pollResponse.access_token) {
47+
consola.info(`Got token ${pollResponse.access_token.replace(/./g, "*")}`)
48+
return pollResponse
49+
} else {
50+
// Interval is in seconds, we need to multiply by 1000 to get milliseconds
51+
// I'm also adding another second, just to be safe
52+
await new Promise((resolve) =>
53+
setTimeout(resolve, (response.interval + 1) * 1000),
54+
)
55+
}
56+
}
57+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { github } from "~/services/api-instance"
2+
3+
export async function getGitHubUser() {
4+
return github<GithubUser>("/user", {
5+
method: "GET",
6+
})
7+
}
8+
9+
interface GithubUser {
10+
login: string
11+
id: number
12+
node_id: string
13+
avatar_url: string
14+
gravatar_id: string
15+
url: string
16+
html_url: string
17+
followers_url: string
18+
following_url: string
19+
gists_url: string
20+
starred_url: string
21+
subscriptions_url: string
22+
organizations_url: string
23+
repos_url: string
24+
events_url: string
25+
received_events_url: string
26+
type: "User"
27+
user_view_type: "private"
28+
site_admin: boolean
29+
name: string
30+
company: string | null
31+
blog: string
32+
location: string
33+
email: null
34+
hireable: null
35+
bio: string
36+
twitter_username: string | null
37+
notification_email: null
38+
public_repos: number
39+
public_gists: number
40+
followers: number
41+
following: number
42+
created_at: string
43+
updated_at: string
44+
private_gists: number
45+
total_private_repos: number
46+
owned_private_repos: number
47+
disk_usage: number
48+
collaborators: number
49+
two_factor_authentication: boolean
50+
plan: {
51+
name: "pro"
52+
space: number
53+
collaborators: number
54+
private_repos: number
55+
}
56+
}

0 commit comments

Comments
 (0)