Files
codeql-action/node_modules/@octokit/auth-app/dist-src/hook.js
2025-02-19 11:13:12 -08:00

94 lines
3.6 KiB
JavaScript

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
};