Skip to content

Commit c770fee

Browse files
authored
Add proxy support for the github webhook (#1083)
* Add proxy support for the github webhook - Introduced `PROXY_SECRET` in gitbook-manifest.yaml for proxy authentication. - Updated createAppInstallationAccessToken to conditionally include proxy headers. - Modified getRepositoryAuth to accept isProxied parameter. - Enhanced triggerImport and triggerExport to pass isProxied flag. - Implemented logic to determine proxy status in handleImportDispatchForSpaces. * linting * Remove PROXY_SECRET from secrets and update proxy token header to enable proxy * changeset
1 parent 0a644ad commit c770fee

File tree

5 files changed

+44
-4
lines changed

5 files changed

+44
-4
lines changed

.changeset/big-needles-know.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@gitbook/integration-github': patch
3+
---
4+
5+
Fix proxy for the webhook endpoint

integrations/github/src/api.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,19 @@ export async function createAppInstallationAccessToken(
165165
context: GithubRuntimeContext,
166166
appJWT: string,
167167
installationId: number,
168+
isProxied?: boolean,
168169
): Promise<string> {
169170
const { token } = await githubAPI<{ token: string; expires_at: string }>(
170171
context,
171172
{ access_token: appJWT, expires_at: 0 },
172173
{
173174
method: 'POST',
174175
path: `/app/installations/${installationId}/access_tokens`,
176+
additionalHeaders: isProxied
177+
? {
178+
'X-Gitbook-Proxy-Enabled': 'true',
179+
}
180+
: {},
175181
},
176182
);
177183

@@ -220,6 +226,10 @@ async function githubAPI<T>(
220226
* @default true
221227
*/
222228
walkPagination?: boolean;
229+
/**
230+
* Additional headers to add to the request
231+
*/
232+
additionalHeaders?: Record<string, string>;
223233
},
224234
): Promise<T> {
225235
const {
@@ -229,6 +239,7 @@ async function githubAPI<T>(
229239
params,
230240
listProperty = '',
231241
walkPagination = true,
242+
additionalHeaders = {},
232243
} = request;
233244

234245
const credentials = tokenCredentials || extractTokenCredentialsOrThrow(context);
@@ -240,6 +251,7 @@ async function githubAPI<T>(
240251
const options = {
241252
method,
242253
body: body ? JSON.stringify(body) : undefined,
254+
headers: additionalHeaders,
243255
};
244256

245257
const response = await requestGitHubAPI(context, credentials, url, options);

integrations/github/src/provider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function getRepositoryUrl(config: GitHubSpaceConfiguration, withExtension
5353
export async function getRepositoryAuth(
5454
context: GithubRuntimeContext,
5555
config: GitHubSpaceConfiguration,
56+
isProxied: boolean,
5657
) {
5758
assertIsDefined(config.installation, { label: 'config.installation', statusCode: 400 });
5859

@@ -61,6 +62,7 @@ export async function getRepositoryAuth(
6162
context,
6263
appJWT,
6364
config.installation,
65+
isProxied,
6466
);
6567

6668
return {

integrations/github/src/sync.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,18 @@ export async function triggerImport(
5151
* in the same order on GitBook and on the remote repository.
5252
*/
5353
eventTimestamp?: Date;
54+
55+
isProxied?: boolean;
5456
} = {},
5557
) {
5658
const { api } = context;
57-
const { force = false, updateGitInfo = false, standalone, eventTimestamp } = options;
58-
59+
const {
60+
force = false,
61+
updateGitInfo = false,
62+
standalone,
63+
eventTimestamp,
64+
isProxied = false,
65+
} = options;
5966
const spaceId =
6067
typeof spaceInstallation.space === 'string'
6168
? spaceInstallation.space
@@ -72,7 +79,7 @@ export async function triggerImport(
7279

7380
logger.info(`Initiating an import from GitHub to GitBook space ${spaceId}`);
7481

75-
const auth = await getRepositoryAuth(context, config);
82+
const auth = await getRepositoryAuth(context, config, isProxied);
7683
const repoTreeURL = getGitTreeURL(config);
7784

7885
const urlWithAuth = new URL(getRepositoryUrl(config, true));
@@ -136,7 +143,7 @@ export async function triggerExport(
136143

137144
const { data: revision } = await api.spaces.getCurrentRevision(spaceId);
138145

139-
const auth = await getRepositoryAuth(context, config);
146+
const auth = await getRepositoryAuth(context, config, false);
140147
const repoTreeURL = getGitTreeURL(config);
141148

142149
const urlWithAuth = new URL(getRepositoryUrl(config, true));

integrations/github/src/tasks.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@ export async function handleImportDispatchForSpaces(
7171
spaceInstallation.integration,
7272
spaceInstallation.installation,
7373
);
74+
let isProxied = context.environment.installation?.network?.proxy || false;
75+
76+
// The webhook is under the root of the integration, so we don't have access to the installation
77+
// We need to fetch it to know if we need to proxy the requests
78+
if (!context.environment.installation) {
79+
const { data: installation } =
80+
await context.api.integrations.getIntegrationInstallationById(
81+
spaceInstallation.integration,
82+
spaceInstallation.installation,
83+
);
84+
85+
isProxied = installation.network?.proxy || false;
86+
}
7487

7588
// Set the token in the duplicated context to be used by the API client
7689
const installationContext: GithubRuntimeContext = {
@@ -93,6 +106,7 @@ export async function handleImportDispatchForSpaces(
93106
}
94107
: undefined,
95108
eventTimestamp,
109+
isProxied,
96110
});
97111
} catch (error) {
98112
logger.error(

0 commit comments

Comments
 (0)