From 8b63c3c5636c28d121d055bf455e24629d4c458e Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 21 Nov 2025 19:30:09 +0000 Subject: [PATCH 1/3] Add the legacy path of /oauth back --- src/Webhooks.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Webhooks.ts b/src/Webhooks.ts index c42dfcdf1..bf99336fc 100644 --- a/src/Webhooks.ts +++ b/src/Webhooks.ts @@ -36,6 +36,8 @@ export class Webhooks extends EventEmitter { this.config.widgets?.parsedPublicUrl, ); this.expressRouter.use("/github", this.github.getRouter()); + // LEGACY PATH - Will be removed in a future release. + this.expressRouter.get("/oauth", this.github.onGetOAuth.bind(this.github)); } if (this.config.gitlab) { @@ -94,9 +96,6 @@ export class Webhooks extends EventEmitter { // LEGACY PATHS. These will be removed in a future version. this.expressRouter.post("/", this.onPayload.bind(this)); - if (this.github) { - this.expressRouter.get("/oauth", this.github.onGetOAuth.bind(this)); - } } public stop() { From f996708365e10c3da923c494bdb0b2135a6ecede Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 21 Nov 2025 19:30:50 +0000 Subject: [PATCH 2/3] changelog --- changelog.d/1105.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1105.bugfix diff --git a/changelog.d/1105.bugfix b/changelog.d/1105.bugfix new file mode 100644 index 000000000..7dffd47cd --- /dev/null +++ b/changelog.d/1105.bugfix @@ -0,0 +1 @@ +Fix /oauth responding with 405 despite GitHub being configured. From 499593cd650844fb746ad3423254f1815ded9ce6 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 21 Nov 2025 19:48:44 +0000 Subject: [PATCH 3/3] Add simple tests --- spec/github.spec.ts | 15 +++++++++++++++ src/Webhooks.ts | 5 ++++- src/github/Router.ts | 14 +++++++------- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/spec/github.spec.ts b/spec/github.spec.ts index 043474377..6fe18b3a3 100644 --- a/spec/github.spec.ts +++ b/spec/github.spec.ts @@ -43,6 +43,11 @@ describe("GitHub", () => { webhook: { secret: randomUUID(), }, + oauth: { + client_id: "GITHUB_ID", + client_secret: "GITHUB_SECRET", + redirect_uri: "http://example.org/redirectme", + }, // So we can mock out the URL enterpriseUrl: `http://localhost:${githubPort}`, auth: { @@ -168,4 +173,14 @@ describe("GitHub", () => { expect(body).toContain("My test pull request"); }, ); + + test.each(["/oauth", "/github/oauth"])( + "should redirect invalid oauth requests to oauth.html", + async (path) => { + // This simply tests that oauth requests do not end up being ignored. + const req = await fetch(`http://localhost:${webhooksPort}${path}`); + expect(req.url.startsWith(`http://localhost:${webhooksPort}/oauth.html`)) + .to.be.true; + }, + ); }); diff --git a/src/Webhooks.ts b/src/Webhooks.ts index bf99336fc..6f93d1a67 100644 --- a/src/Webhooks.ts +++ b/src/Webhooks.ts @@ -37,7 +37,10 @@ export class Webhooks extends EventEmitter { ); this.expressRouter.use("/github", this.github.getRouter()); // LEGACY PATH - Will be removed in a future release. - this.expressRouter.get("/oauth", this.github.onGetOAuth.bind(this.github)); + this.expressRouter.get( + "/oauth", + this.github.onGetOAuth.bind(this.github), + ); } if (this.config.gitlab) { diff --git a/src/github/Router.ts b/src/github/Router.ts index 77d2a2d0a..fff52a2cd 100644 --- a/src/github/Router.ts +++ b/src/github/Router.ts @@ -174,13 +174,13 @@ export class GitHubWebhooksRouter { const { setup_action: setupAction, state } = req.query; log.info("Got new oauth request", { state, setupAction }); + if (!this.config.oauth) { + throw new ApiError( + "Bridge is not configured with OAuth support", + ErrCode.DisabledFeature, + ); + } try { - if (!this.config.oauth) { - throw new ApiError( - "Bridge is not configured with OAuth support", - ErrCode.DisabledFeature, - ); - } if (req.query.error) { throw new ApiError( `GitHub Error: ${req.query.error} ${req.query.error_description}`, @@ -291,9 +291,9 @@ export class GitHubWebhooksRouter { public getRouter() { const router = Router(); + router.get("/oauth", this.onGetOAuth.bind(this)); router.use(json({ verify: this.verifyRequest.bind(this) })); router.post("/webhook", this.onWebhook.bind(this)); - router.get("/oauth", this.onGetOAuth.bind(this)); return router; } }