-
-
Notifications
You must be signed in to change notification settings - Fork 376
Expand file tree
/
Copy pathgithubAppSupport.ts
More file actions
53 lines (43 loc) · 1.75 KB
/
githubAppSupport.ts
File metadata and controls
53 lines (43 loc) · 1.75 KB
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
import { SignJWT, importPKCS8 } from "jose"
import fetch from "node-fetch"
const ALG = "RS256" as const
// Step 1
/** App ID + Signing Key = initial JWT to start auth process */
export const jwtForGitHubAuth = async (appID: string, privateKeyPEM: string) => {
const key = await importPKCS8(privateKeyPEM, ALG)
const now = Math.floor(Date.now() / 1000)
const token = await new SignJWT({})
.setProtectedHeader({ alg: ALG })
.setIssuedAt(now)
.setExpirationTime(now + 300)
.setIssuer(appID)
.sign(key)
return token
}
// Step 2 - Use App signed JWT to grab a per-installation
const requestAccessTokenForInstallation = async (appID: string, installationID: number, privateKeyPEM: string) => {
const apiUrl = process.env["DANGER_GITHUB_API_BASE_URL"] ?? "https://api.github.com"
const url = `${apiUrl}/app/installations/${installationID}/access_tokens`
const jwt = await jwtForGitHubAuth(appID, privateKeyPEM)
const res = await fetch(url, {
method: "POST",
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${jwt}`,
"X-GitHub-Api-Version": "2022-11-28",
},
body: JSON.stringify({}),
})
return res
}
/** Generates a temporary access token for an app's installation, 5m long */
export const getAccessTokenForInstallation = async (appID: string, installationID: number, privateKeyPEM: string) => {
const res = await requestAccessTokenForInstallation(appID, installationID, privateKeyPEM)
const json = await res.json()
if (!res.ok) {
console.error(`Could not get an access token for installation ${installationID}`)
console.error(`GitHub returned: ${JSON.stringify(json)}`)
throw new Error(`GitHub API error: ${res.status} ${res.statusText}`)
}
return json.token as string
}