MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / pollForDeviceTokens

Function pollForDeviceTokens

apps/cli/src/device-login.ts:220–280  ·  view source on GitHub ↗
(
  discovery: CliLoginDiscovery,
  grant: DeviceCodeGrant,
  options: { readonly now?: () => number } = {},
)

Source from the content-addressed store, hash-verified

218 * `access_denied` / `expired_token` are terminal).
219 */
220export const pollForDeviceTokens = async (
221 discovery: CliLoginDiscovery,
222 grant: DeviceCodeGrant,
223 options: { readonly now?: () => number } = {},
224): Promise<DeviceTokens> => {
225 const now = options.now ?? (() => Date.now());
226 const deadline = now() + grant.expiresInSeconds * 1000;
227 let intervalMs = Math.max(1, grant.intervalSeconds) * 1000;
228
229 for (;;) {
230 if (now() >= deadline) {
231 throw new DeviceLoginError("Login timed out before it was approved.");
232 }
233 await sleep(intervalMs);
234
235 const response = await post(
236 discovery.tokenEndpoint,
237 {
238 grant_type: DEVICE_CODE_GRANT_TYPE,
239 device_code: grant.deviceCode,
240 client_id: discovery.clientId,
241 },
242 discovery.requestFormat,
243 );
244 const body = await readJson(response);
245
246 if (response.ok) {
247 const accessToken = asString(body.access_token);
248 if (!accessToken) {
249 throw new DeviceLoginError("Token response was missing an access token.");
250 }
251 const claims = decodeAccessTokenClaims(accessToken);
252 return {
253 accessToken,
254 refreshToken: asString(body.refresh_token),
255 expiresAt: deriveExpiresAt({ accessToken, expiresIn: asNumber(body.expires_in) }),
256 email:
257 readUserEmail(body) ?? (typeof claims?.email === "string" ? claims.email : undefined),
258 organizationId:
259 asString(body.organization_id) ??
260 (typeof claims?.org_id === "string" ? claims.org_id : undefined),
261 };
262 }
263
264 const error = asString(body.error);
265 if (error === "authorization_pending") continue;
266 if (error === "slow_down") {
267 intervalMs += 5000;
268 continue;
269 }
270 if (error === "access_denied") {
271 throw new DeviceLoginError("Login was denied.");
272 }
273 if (error === "expired_token") {
274 throw new DeviceLoginError("The login request expired before it was approved.");
275 }
276 throw new DeviceLoginError(
277 `Login failed: ${asString(body.error_description) ?? error ?? `HTTP ${response.status}`}`,

Callers 1

main.tsFile · 0.90

Calls 9

nowFunction · 0.85
readJsonFunction · 0.85
asStringFunction · 0.85
decodeAccessTokenClaimsFunction · 0.85
deriveExpiresAtFunction · 0.85
asNumberFunction · 0.85
readUserEmailFunction · 0.85
sleepFunction · 0.70
postFunction · 0.70

Tested by

no test coverage detected