(
flow: GithubDeviceFlow
)
| 698 | } |
| 699 | |
| 700 | private async pollGithubAccessToken( |
| 701 | flow: GithubDeviceFlow |
| 702 | ): Promise< |
| 703 | Result< |
| 704 | | { type: "pending" } |
| 705 | | { type: "slow_down"; intervalSeconds: number } |
| 706 | | { type: "authorized"; accessToken: string }, |
| 707 | string |
| 708 | > |
| 709 | > { |
| 710 | const response = await fetch(GITHUB_ACCESS_TOKEN_URL, { |
| 711 | method: "POST", |
| 712 | headers: { |
| 713 | Accept: "application/json", |
| 714 | "Content-Type": "application/x-www-form-urlencoded", |
| 715 | }, |
| 716 | body: new URLSearchParams({ |
| 717 | client_id: MUX_SERVER_GITHUB_CLIENT_ID, |
| 718 | device_code: flow.deviceCode, |
| 719 | grant_type: "urn:ietf:params:oauth:grant-type:device_code", |
| 720 | }), |
| 721 | }); |
| 722 | |
| 723 | if (!response.ok) { |
| 724 | const body = await response.text().catch(() => ""); |
| 725 | return Err(`GitHub token polling failed (${response.status})${body ? `: ${body}` : ""}`); |
| 726 | } |
| 727 | |
| 728 | const json = (await response.json()) as unknown; |
| 729 | const payload = parseGithubAccessTokenResponse(json); |
| 730 | |
| 731 | if (payload.access_token) { |
| 732 | return Ok({ type: "authorized", accessToken: payload.access_token }); |
| 733 | } |
| 734 | |
| 735 | if (payload.error === "authorization_pending") { |
| 736 | return Ok({ type: "pending" }); |
| 737 | } |
| 738 | |
| 739 | if (payload.error === "slow_down") { |
| 740 | const nextInterval = payload.interval ?? flow.intervalSeconds + 5; |
| 741 | return Ok({ type: "slow_down", intervalSeconds: Math.max(1, nextInterval) }); |
| 742 | } |
| 743 | |
| 744 | if (payload.error === "expired_token") { |
| 745 | return Err("GitHub device code expired. Start login again."); |
| 746 | } |
| 747 | |
| 748 | if (payload.error === "access_denied") { |
| 749 | return Err("GitHub authorization was denied."); |
| 750 | } |
| 751 | |
| 752 | if (payload.error) { |
| 753 | const descriptionSuffix = payload.error_description ? `: ${payload.error_description}` : ""; |
| 754 | return Err(`GitHub OAuth error: ${payload.error}${descriptionSuffix}`); |
| 755 | } |
| 756 | |
| 757 | return Err("GitHub token polling returned an unexpected response"); |
no test coverage detected