import { requiresBasicAuth } from "@octokit/auth-oauth-user"; import { RequestError } from "@octokit/request-error"; import { getAppAuthentication } from "./get-app-authentication.js"; import { getInstallationAuthentication } from "./get-installation-authentication.js"; import { requiresAppAuth } from "./requires-app-auth.js"; const FIVE_SECONDS_IN_MS = 5 * 1e3; function isNotTimeSkewError(error) { return !(error.message.match( /'Expiration time' claim \('exp'\) must be a numeric value representing the future time at which the assertion expires/ ) || error.message.match( /'Issued at' claim \('iat'\) must be an Integer representing the time that the assertion was issued/ )); } async function hook(state, request, route, parameters) { const endpoint = request.endpoint.merge(route, parameters); const url = endpoint.url; if (/\/login\/oauth\/access_token$/.test(url)) { return request(endpoint); } if (requiresAppAuth(url.replace(request.endpoint.DEFAULTS.baseUrl, ""))) { const { token: token2 } = await getAppAuthentication(state); endpoint.headers.authorization = `bearer ${token2}`; let response; try { response = await request(endpoint); } catch (error) { if (isNotTimeSkewError(error)) { throw error; } if (typeof error.response.headers.date === "undefined") { throw error; } const diff = Math.floor( (Date.parse(error.response.headers.date) - Date.parse((/* @__PURE__ */ new Date()).toString())) / 1e3 ); state.log.warn(error.message); state.log.warn( `[@octokit/auth-app] GitHub API time and system time are different by ${diff} seconds. Retrying request with the difference accounted for.` ); const { token: token3 } = await getAppAuthentication({ ...state, timeDifference: diff }); endpoint.headers.authorization = `bearer ${token3}`; return request(endpoint); } return response; } if (requiresBasicAuth(url)) { const authentication = await state.oauthApp({ type: "oauth-app" }); endpoint.headers.authorization = authentication.headers.authorization; return request(endpoint); } const { token, createdAt } = await getInstallationAuthentication( state, // @ts-expect-error TBD {}, request.defaults({ baseUrl: endpoint.baseUrl }) ); endpoint.headers.authorization = `token ${token}`; return sendRequestWithRetries( state, request, endpoint, createdAt ); } async function sendRequestWithRetries(state, request, options, createdAt, retries = 0) { const timeSinceTokenCreationInMs = +/* @__PURE__ */ new Date() - +new Date(createdAt); try { return await request(options); } catch (error) { if (error.status !== 401) { throw error; } if (timeSinceTokenCreationInMs >= FIVE_SECONDS_IN_MS) { if (retries > 0) { error.message = `After ${retries} retries within ${timeSinceTokenCreationInMs / 1e3}s of creating the installation access token, the response remains 401. At this point, the cause may be an authentication problem or a system outage. Please check https://www.githubstatus.com for status information`; } throw error; } ++retries; const awaitTime = retries * 1e3; state.log.warn( `[@octokit/auth-app] Retrying after 401 response to account for token replication delay (retry: ${retries}, wait: ${awaitTime / 1e3}s)` ); await new Promise((resolve) => setTimeout(resolve, awaitTime)); return sendRequestWithRetries(state, request, options, createdAt, retries); } } export { hook };