feat: Atlassian MCP OAuth - #499
Conversation
## Summary Enhances the build process for the documentation package by adding a script to fix the sitemap after building. ## Changes - Updated the `build` script in `packages/docs/package.json` to include `&& node scripts/fix-sitemap.js` after the Docusaurus build command. This change ensures that the sitemap is properly fixed as part of the build process, improving the documentation deployment workflow.
…efresh (AAI-530) (#443) ## Summary Complete implementation of Atlassian MCP OAuth integration with seamless automatic token refresh functionality for JIRA and Confluence access through Model Context Protocol. ### Key Features - **Atlassian MCP OAuth Integration**: Full OAuth 2.0 flow with dynamic client registration - **Automatic Token Refresh**: Seamless server-side token refresh before node execution (5-minute buffer) - **MCP Server Support**: Integration with Atlassian's remote MCP server at https://mcp.atlassian.com/v1/sse - **Clean Architecture**: No circular imports, proper database access patterns - **User Transparency**: Token refresh happens behind the scenes - users are "none the wiser" ### Components Added - `AtlassianOauth.credential.ts`: OAuth credential definition with MCP client fields - `AtlassianMcp.ts`: MCP node for JIRA/Confluence tool integration - `checkAndRefreshCredentialsBeforeInit()`: Server-side pre-initialization token refresh hook - OAuth controllers and routes for authentication flow - MCP metadata utilities with discovery support ### Technical Implementation - **Pre-initialization Hook**: Automatically refreshes tokens before node execution in buildFlow - **Proper Content-Type**: Uses `application/x-www-form-urlencoded` for MCP token endpoints - **Database Integration**: Persists refreshed tokens using TypeORM repositories - **Error Handling**: Graceful fallbacks that don't break flow execution - **Clean Dependencies**: Uses function parameters to avoid circular imports ### Testing - ✅ Token refresh logic tested and verified working - ✅ MCP server connection established successfully - ✅ OAuth flow completed end-to-end - ✅ TypeScript compilation clean - ✅ Server starts without errors Fixes AAI-530: Enable MCP server authentication for Atlassian integration ## Test Plan - [x] OAuth authentication flow works end-to-end - [x] Token refresh triggers automatically when needed - [x] MCP tools load and execute successfully - [x] Tokens persist correctly to database - [x] Error handling works gracefully - [x] TypeScript compiles without errors - [x] Server starts and runs without issues
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const router = express.Router() | ||
|
|
||
| // GET /api/v1/atlassian-auth/ | ||
| router.get('/', atlassianAuthController.authenticate) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
To resolve this issue, rate-limiting middleware should be added to the affected route(s), specifically the /api/v1/atlassian-auth/ GET handler. The preferred approach is to use a well-established package such as express-rate-limit. You will need to:
- Install the
express-rate-limitpackage. - Import
express-rate-limitin the file. - Create a rate limiter instance (e.g., allowing a reasonable number of authentication requests per IP per time window).
- Apply the rate limiter as middleware to the route for
atlassianAuthController.authenticate. - Make minimal changes that avoid altering any existing route logic or structure.
This fix should be made directly in packages/server/src/routes/atlassian-auth/index.ts near the affected route.
| @@ -1,11 +1,18 @@ | ||
| import express from 'express' | ||
| import passport from 'passport' | ||
| import atlassianAuthController from '../../controllers/atlassian-auth' | ||
| import rateLimit from 'express-rate-limit' | ||
|
|
||
| const authRateLimiter = rateLimit({ | ||
| windowMs: 15 * 60 * 1000, // 15 minutes | ||
| max: 100, // Limit each IP to 100 requests per windowMs | ||
| message: 'Too many authentication attempts from this IP, please try again later.' | ||
| }) | ||
|
|
||
| const router = express.Router() | ||
|
|
||
| // GET /api/v1/atlassian-auth/ | ||
| router.get('/', atlassianAuthController.authenticate) | ||
| router.get('/', authRateLimiter, atlassianAuthController.authenticate) | ||
|
|
||
| // GET /api/v1/atlassian-auth/callback | ||
| router.get('/callback', passport.authenticate('atlassian-dynamic', { session: false }), atlassianAuthController.atlassianAuthCallback) |
| router.get('/callback', passport.authenticate('atlassian-dynamic', { session: false }), atlassianAuthController.atlassianAuthCallback) | ||
|
|
||
| // GET /api/v1/atlassian-auth/mcp-initialize | ||
| router.get('/mcp-initialize', atlassianAuthController.mcpInitialize) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
To address this issue, we should apply rate-limiting middleware to the /mcp-initialize route to prevent abuse. The standard approach in an Express app is to use a middleware like express-rate-limit. This involves:
- Importing
express-rate-limitat the top of the file. - Creating a new rate limiter instance with appropriate configuration (e.g., 100 requests per 15 minutes per IP).
- Applying this rate limiter only to the
/mcp-initializeroute in the router.
All the modifications will be isolated to packages/server/src/routes/atlassian-auth/index.ts. No other files are modified.
| @@ -1,9 +1,16 @@ | ||
| import express from 'express' | ||
| import passport from 'passport' | ||
| import atlassianAuthController from '../../controllers/atlassian-auth' | ||
|
|
||
| import rateLimit from 'express-rate-limit' | ||
| const router = express.Router() | ||
|
|
||
| // Rate limiter for mcp-initialize route (e.g., max 100 requests per 15 minutes per IP) | ||
| const mcpInitializeLimiter = rateLimit({ | ||
| windowMs: 15 * 60 * 1000, // 15 minutes | ||
| max: 100, // limit each IP to 100 requests per windowMs | ||
| standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers | ||
| legacyHeaders: false, // Disable the `X-RateLimit-*` headers | ||
| }) | ||
| // GET /api/v1/atlassian-auth/ | ||
| router.get('/', atlassianAuthController.authenticate) | ||
|
|
||
| @@ -11,6 +16,6 @@ | ||
| router.get('/callback', passport.authenticate('atlassian-dynamic', { session: false }), atlassianAuthController.atlassianAuthCallback) | ||
|
|
||
| // GET /api/v1/atlassian-auth/mcp-initialize | ||
| router.get('/mcp-initialize', atlassianAuthController.mcpInitialize) | ||
| router.get('/mcp-initialize', mcpInitializeLimiter, atlassianAuthController.mcpInitialize) | ||
|
|
||
| export default router |
| router.post('/refresh-token', enforceAbility('Credential'), credentialsController.updateAndRefreshToken) | ||
|
|
||
| // UPDATE REFRESH ATLASSIAN TOKEN | ||
| router.post('/refresh-atlassian-token', enforceAbility('Credential'), credentialsController.updateAndRefreshAtlassianToken) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
The best way to fix this issue is to add a rate limiting middleware to sensitive routes such as /refresh-atlassian-token. A widely accepted solution is to use the express-rate-limit package, which fits Express applications and can be configured per route as needed. We should:
- Import
express-rate-limit. - Define a rate limiter instance with sensible defaults (e.g., max requests per time window for this endpoint).
- Apply this rate limiter as the first middleware for the route
/refresh-atlassian-token.
All changes must be in packages/server/src/routes/credentials/index.ts. We will need to:
- Import
express-rate-limit. - Add the rate limiter definition.
- Add it as middleware for the
/refresh-atlassian-tokenroute.
| @@ -1,9 +1,17 @@ | ||
| import express from 'express' | ||
| import credentialsController from '../../controllers/credentials' | ||
| import enforceAbility from '../../middlewares/authentication/enforceAbility' | ||
| import rateLimit from 'express-rate-limit' | ||
|
|
||
| const router = express.Router() | ||
|
|
||
| // Rate limiter for sensitive routes | ||
| const refreshAtlassianTokenRateLimiter = rateLimit({ | ||
| windowMs: 15 * 60 * 1000, // 15 minutes | ||
| max: 20, // limit each IP to 20 requests per windowMs (adjust as reasonable) | ||
| message: 'Too many requests, please try again later.', | ||
| }) | ||
|
|
||
| // CREATE | ||
| router.post('/', enforceAbility('Credential'), credentialsController.createCredential) | ||
|
|
||
| @@ -21,6 +26,11 @@ | ||
| router.post('/refresh-token', enforceAbility('Credential'), credentialsController.updateAndRefreshToken) | ||
|
|
||
| // UPDATE REFRESH ATLASSIAN TOKEN | ||
| router.post('/refresh-atlassian-token', enforceAbility('Credential'), credentialsController.updateAndRefreshAtlassianToken) | ||
| router.post( | ||
| '/refresh-atlassian-token', | ||
| refreshAtlassianTokenRateLimiter, | ||
| enforceAbility('Credential'), | ||
| credentialsController.updateAndRefreshAtlassianToken | ||
| ) | ||
|
|
||
| export default router |
# feat: add automated staging reset workflow ## Summary Implements a GitHub Action that automatically resets staging to match production after staging-to-production releases, preventing the 90+ file change issue that occurs when staging accumulates commits. ## Changes - **Smart Staging Reset Action**: Automatically resets staging only when staging→production PRs are merged - **Simplified Logic**: Removes complex safety checks that would prevent the action from working - **Hotfix Protection**: Does not trigger on hotfix PRs (feature→production) - **Documentation**: Added comments explaining the workflow purpose ## Technical Details - Triggers on PR close events targeting production branch - Only executes when source branch is 'staging' - Resets staging when it has commits ahead of production - Uses --force-with-lease for safe force pushing - Provides detailed logging and status messages ## Benefits - Eliminates manual staging resets - Prevents 90+ file change issues in future PRs - Maintains clean git workflow - Safe for hotfixes and normal development - Works with active test branch workflow ## Testing This workflow will be tested when this PR is merged to staging, and will activate on the next staging→production release. --------- Co-authored-by: Bradley Taylor <bradtaylorsf@gmail.com>
## Summary Introduces a new `robots.txt` file to enhance SEO by allowing all crawlers to access the site's content and specifying the sitemap location. ## Changes - Created `robots.txt` in `packages/docs/static/` with rules for web crawlers. - Added directives to allow all user agents and provide the sitemap URL. This addition aims to improve search engine indexing and visibility for the site.
|



No description provided.