Skip to content

Refactor auth routes to use controller functions#1374

Merged
alexanmtz merged 3 commits intomasterfrom
copilot/refactor-auth-route-controller
Feb 4, 2026
Merged

Refactor auth routes to use controller functions#1374
alexanmtz merged 3 commits intomasterfrom
copilot/refactor-auth-route-controller

Conversation

Copy link
Contributor

Copilot AI commented Feb 3, 2026

Description

Inline route handlers in providers.ts violated the established pattern of delegating logic to controllers. Four routes (/callback/github, /connect/github, /callback/bitbucket, /authorize/local) implemented business logic directly in route definitions.

Changes:

  • Extracted inline handlers to controller functions in src/app/controllers/auth.ts:
    • callbackGithub - handles GitHub OAuth callback with login strategy routing
    • connectGithub - initiates GitHub authentication for account linking
    • callbackBitbucket - handles Bitbucket OAuth callback
    • authorizeLocal - handles local auth with header injection
  • Added null guards for req.user and req.user.token to prevent silent failures

Before:

router.get('/connect/github', secure, (req: any, res: any, next: any) => {
  const user = req.user
  if (user) {
    passport.authenticate('github', {
      scope: ['user:email'],
      state: req.user.email
    })(req, res, next)
  } else {
    res.redirect(`${process.env.FRONTEND_HOST}/#/signin/invalid`)
  }
})

After:

router.get('/connect/github', secure, controllers.connectGithub)

Routes now follow the same pattern as /callback/github/private and /authorize/github/disconnect.

Thank you for your contribution!


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: alexanmtz <88840+alexanmtz@users.noreply.github.com>
res.redirect(`${process.env.FRONTEND_HOST}/#/signin/invalid`)
}
})
router.get('/connect/github', secure, controllers.connectGithub)

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.

Copilot Autofix

AI 1 day ago

To fix the problem, introduce a rate-limiting middleware in this router and apply it to the sensitive authorization/connection routes, including /connect/github (the one using secure). The most straightforward approach in an Express-based codebase is to use the widely adopted express-rate-limit package. This avoids changing the business logic or existing behavior beyond rejecting or slowing excessive requests.

Concretely, in src/app/routes/auth/providers.ts:

  1. Add an import for express-rate-limit.
  2. Define a rateLimiter instance with sensible defaults (e.g., a window and max number of requests) near the router initialization.
  3. Apply rateLimiter as middleware to the routes that perform authorization: at minimum the /connect/github route where secure is used, and optionally other /authorize/* and /callback/* routes if you want broader coverage. To minimally satisfy the CodeQL finding, we will wrap only /connect/github with the limiter while leaving existing logic intact: router.get('/connect/github', rateLimiter, secure, controllers.connectGithub).

No existing imports are modified or removed; we only add a new import and a small configuration block plus the extra middleware parameter on the specific route definition.

Suggested changeset 2
src/app/routes/auth/providers.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/app/routes/auth/providers.ts b/src/app/routes/auth/providers.ts
--- a/src/app/routes/auth/providers.ts
+++ b/src/app/routes/auth/providers.ts
@@ -3,9 +3,15 @@
 import * as authenticationHelpers from '../../../modules/authenticationHelpers'
 import * as controllers from '../../controllers/auth'
 import secure from '../secure'
+import rateLimit from 'express-rate-limit'
 
 const router = express.Router()
 
+const rateLimiter = rateLimit({
+  windowMs: 15 * 60 * 1000,
+  max: 100
+})
+
 router.get('/authenticated', authenticationHelpers.isAuth)
 
 router.get('/authorize/google', passport.authenticate('google', { scope: ['email'] }))
@@ -36,7 +39,7 @@
 
 router.get('/callback/github/private', controllers.createPrivateTask)
 
-router.get('/connect/github', secure, controllers.connectGithub)
+router.get('/connect/github', rateLimiter, secure, controllers.connectGithub)
 
 router.get('/authorize/github/private', controllers.authorizeGithubPrivateIssue)
 router.get('/authorize/github/disconnect', secure, controllers.disconnectGithub)
EOF
@@ -3,9 +3,15 @@
import * as authenticationHelpers from '../../../modules/authenticationHelpers'
import * as controllers from '../../controllers/auth'
import secure from '../secure'
import rateLimit from 'express-rate-limit'

const router = express.Router()

const rateLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
})

router.get('/authenticated', authenticationHelpers.isAuth)

router.get('/authorize/google', passport.authenticate('google', { scope: ['email'] }))
@@ -36,7 +39,7 @@

router.get('/callback/github/private', controllers.createPrivateTask)

router.get('/connect/github', secure, controllers.connectGithub)
router.get('/connect/github', rateLimiter, secure, controllers.connectGithub)

router.get('/authorize/github/private', controllers.authorizeGithubPrivateIssue)
router.get('/authorize/github/disconnect', secure, controllers.disconnectGithub)
package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -128,7 +128,8 @@
     "url": "^0.11.0",
     "url-search-params": "^1.0.2",
     "x-frame-options": "^1.0.0",
-    "zone.js": "^0.8.4"
+    "zone.js": "^0.8.4",
+    "express-rate-limit": "^8.2.1"
   },
   "devDependencies": {
     "@playwright/test": "^1.53.0",
EOF
@@ -128,7 +128,8 @@
"url": "^0.11.0",
"url-search-params": "^1.0.2",
"x-frame-options": "^1.0.0",
"zone.js": "^0.8.4"
"zone.js": "^0.8.4",
"express-rate-limit": "^8.2.1"
},
"devDependencies": {
"@playwright/test": "^1.53.0",
This fix introduces these dependencies
Package Version Security advisories
express-rate-limit (npm) 8.2.1 None
Copilot is powered by AI and may make mistakes. Always verify output.
res.redirect(`${process.env.FRONTEND_HOST}/#/signin/invalid`)
}
})
router.get('/connect/github', secure, controllers.connectGithub)

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.

Copilot Autofix

AI 1 day ago

In general, this should be fixed by applying rate limiting middleware to routes that perform authentication or authorization, especially those that can trigger expensive work (external API calls, DB writes, etc.). In an Express app, this is typically done by importing a rate limiting library such as express-rate-limit, configuring a limiter instance, and applying it to the specific routes that need protection (instead of globally if we want minimal behavioral change).

For this file, the minimal-change fix is to: (1) import express-rate-limit; (2) define a limiter configured for auth-related routes (e.g., a modest number of requests per IP per time window); and (3) apply that limiter to the /connect/github route (and potentially other similar authorization routes, but CodeQL’s complaint is specifically about controllers.connectGithub). We will add the import at the top of src/app/routes/auth/providers.ts, define the limiter just below the router initialization, and then include the limiter as middleware in the route definition before secure and controllers.connectGithub so that rate limiting occurs before other logic executes. This preserves existing behavior for requests that are under the limit and only changes behavior when a client exceeds the configured rate.

Concretely:

  • Add import rateLimit from 'express-rate-limit' at the top.
  • After const router = express.Router(), add a constant such as const authRateLimiter = rateLimit({ windowMs: ..., max: ... }).
  • Change line 39 from router.get('/connect/github', secure, controllers.connectGithub) to router.get('/connect/github', authRateLimiter, secure, controllers.connectGithub).
Suggested changeset 2
src/app/routes/auth/providers.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/app/routes/auth/providers.ts b/src/app/routes/auth/providers.ts
--- a/src/app/routes/auth/providers.ts
+++ b/src/app/routes/auth/providers.ts
@@ -3,9 +3,15 @@
 import * as authenticationHelpers from '../../../modules/authenticationHelpers'
 import * as controllers from '../../controllers/auth'
 import secure from '../secure'
+import rateLimit from 'express-rate-limit'
 
 const router = express.Router()
 
+const authRateLimiter = rateLimit({
+  windowMs: 15 * 60 * 1000, // 15 minutes
+  max: 100 // limit each IP to 100 auth requests per windowMs
+})
+
 router.get('/authenticated', authenticationHelpers.isAuth)
 
 router.get('/authorize/google', passport.authenticate('google', { scope: ['email'] }))
@@ -36,7 +39,7 @@
 
 router.get('/callback/github/private', controllers.createPrivateTask)
 
-router.get('/connect/github', secure, controllers.connectGithub)
+router.get('/connect/github', authRateLimiter, secure, controllers.connectGithub)
 
 router.get('/authorize/github/private', controllers.authorizeGithubPrivateIssue)
 router.get('/authorize/github/disconnect', secure, controllers.disconnectGithub)
EOF
@@ -3,9 +3,15 @@
import * as authenticationHelpers from '../../../modules/authenticationHelpers'
import * as controllers from '../../controllers/auth'
import secure from '../secure'
import rateLimit from 'express-rate-limit'

const router = express.Router()

const authRateLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 auth requests per windowMs
})

router.get('/authenticated', authenticationHelpers.isAuth)

router.get('/authorize/google', passport.authenticate('google', { scope: ['email'] }))
@@ -36,7 +39,7 @@

router.get('/callback/github/private', controllers.createPrivateTask)

router.get('/connect/github', secure, controllers.connectGithub)
router.get('/connect/github', authRateLimiter, secure, controllers.connectGithub)

router.get('/authorize/github/private', controllers.authorizeGithubPrivateIssue)
router.get('/authorize/github/disconnect', secure, controllers.disconnectGithub)
package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -128,7 +128,8 @@
     "url": "^0.11.0",
     "url-search-params": "^1.0.2",
     "x-frame-options": "^1.0.0",
-    "zone.js": "^0.8.4"
+    "zone.js": "^0.8.4",
+    "express-rate-limit": "^8.2.1"
   },
   "devDependencies": {
     "@playwright/test": "^1.53.0",
EOF
@@ -128,7 +128,8 @@
"url": "^0.11.0",
"url-search-params": "^1.0.2",
"x-frame-options": "^1.0.0",
"zone.js": "^0.8.4"
"zone.js": "^0.8.4",
"express-rate-limit": "^8.2.1"
},
"devDependencies": {
"@playwright/test": "^1.53.0",
This fix introduces these dependencies
Package Version Security advisories
express-rate-limit (npm) 8.2.1 None
Copilot is powered by AI and may make mistakes. Always verify output.
Co-authored-by: alexanmtz <88840+alexanmtz@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor auth routes to call controllers consistently Refactor auth routes to use controller functions Feb 3, 2026
Copilot AI requested a review from alexanmtz February 3, 2026 13:17
@alexanmtz alexanmtz marked this pull request as ready for review February 3, 2026 13:18
@dosubot dosubot bot added the refactoring label Feb 3, 2026
@alexanmtz alexanmtz merged commit 644aeea into master Feb 4, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants