( session: DeviceFlowSession, )
| 126 | * @returns The access token when granted, or `null` when still pending. |
| 127 | */ |
| 128 | export async function pollGitHubDeviceFlow( |
| 129 | session: DeviceFlowSession, |
| 130 | ): Promise<Token | null> { |
| 131 | try { |
| 132 | const { authentication } = await exchangeDeviceCode({ |
| 133 | clientType: 'oauth-app' as const, |
| 134 | clientId: session.clientId, |
| 135 | code: session.deviceCode, |
| 136 | request: request.defaults({ |
| 137 | baseUrl: getGitHubAuthBaseUrl(session.hostname).toString(), |
| 138 | }), |
| 139 | }); |
| 140 | |
| 141 | return authentication.token as Token; |
| 142 | } catch (err) { |
| 143 | if (err instanceof RequestError) { |
| 144 | const response = err.response?.data as DeviceFlowErrorResponse; |
| 145 | const errorCode = response.error; |
| 146 | |
| 147 | if (errorCode === 'authorization_pending' || errorCode === 'slow_down') { |
| 148 | return null; |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | rendererLogError( |
| 153 | 'pollGitHubDeviceFlow', |
| 154 | 'Error exchanging device code', |
| 155 | toError(err), |
| 156 | ); |
| 157 | |
| 158 | throw err; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | /** |
| 163 | * Exchange an OAuth authorization code for an access token. |
no test coverage detected