Release 2025-25-07 - #416
Conversation
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 problem is to apply a rate limiting middleware to the sensitive route(s) – in this case, the DELETE route at /:id. This can be done by installing and importing the popular express-rate-limit package, defining a rate limiter (for example, limiting to 10 DELETE requests per 15 minutes per IP), and applying it to the DELETE route.
To implement this:
- Add an import for
express-rate-limitat the top of the file. - Define a rate limiter instance, e.g.,
const deleteLimiter = rateLimit({...}). - Apply this rate limiter as middleware to the DELETE route.
- Only edit the shown code in
packages/server/src/routes/chatflows/index.ts.
| @@ -1,6 +1,7 @@ | ||
| import express from 'express' | ||
| import chatflowsController from '../../controllers/chatflows' | ||
| import enforceAbility from '../../middlewares/authentication/enforceAbility' | ||
| import rateLimit from 'express-rate-limit' | ||
| const router = express.Router() | ||
|
|
||
| // CREATE | ||
| @@ -16,6 +17,17 @@ | ||
| router.put(['/', '/:id'], enforceAbility('ChatFlow'), chatflowsController.updateChatflow) | ||
|
|
||
| // DELETE | ||
| router.delete('/:id', enforceAbility('ChatFlow'), chatflowsController.deleteChatflow) | ||
| // DELETE route replaced below with rate limiter | ||
|
|
||
|
|
||
| export default router | ||
|
|
||
| // Rate limiter for DELETE requests (10 per 15 minutes per IP) | ||
| const deleteLimiter = rateLimit({ | ||
| windowMs: 15 * 60 * 1000, // 15 minutes | ||
| max: 10, // limit each IP to 10 delete requests per windowMs | ||
| message: 'Too many delete requests from this IP, please try again later.' | ||
| }) | ||
|
|
||
| // Re-define DELETE route with rate limiter | ||
| router.delete('/:id', deleteLimiter, enforceAbility('ChatFlow'), chatflowsController.deleteChatflow) |
| router.get('/templates', marketplacesController.getAllTemplates) | ||
| router.get('/templates/:id', marketplacesController.getMarketplaceTemplate) | ||
|
|
||
| router.post('/custom', enforceAbility('CustomTemplate'), marketplacesController.saveCustomTemplate) | ||
| // READ - Custom templates (req authentication) | ||
| router.get('/custom', enforceAbility('Marketplace'), marketplacesController.getAllCustomTemplates) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
To fix this problem, we should add rate-limiting middleware to the affected route (and optionally to other routes handling sensitive or expensive operations). The most common and robust approach in Express is to use the express-rate-limit package. Specifically, we should:
- Import
express-rate-limitat the beginning of the file. - Define a rate limiter instance (e.g., allowing 100 requests per 15 minutes per IP).
- Plug the rate limiter into the
/customroute (and optionally similar routes) by inserting it between the route path and the controller. - Only edit the code within the file shown, adding the import and the necessary rate limiter setup within this file.
| @@ -1,14 +1,23 @@ | ||
| import express from 'express' | ||
| import marketplacesController from '../../controllers/marketplaces' | ||
| import enforceAbility from '../../middlewares/authentication/enforceAbility' | ||
| import rateLimit from 'express-rate-limit' | ||
| const router = express.Router() | ||
|
|
||
| // Rate limiter for sensitive routes | ||
| const customTemplatesLimiter = 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 | ||
| }) | ||
|
|
||
| // READ - Templates del marketplace (public) | ||
| router.get('/templates', marketplacesController.getAllTemplates) | ||
| router.get('/templates/:id', marketplacesController.getMarketplaceTemplate) | ||
|
|
||
| // READ - Custom templates (req authentication) | ||
| router.get('/custom', enforceAbility('Marketplace'), marketplacesController.getAllCustomTemplates) | ||
| router.get('/custom', customTemplatesLimiter, enforceAbility('Marketplace'), marketplacesController.getAllCustomTemplates) | ||
|
|
||
| // 🆕 Add - Organization templates | ||
| router.get('/organization', enforceAbility('Marketplace'), marketplacesController.getOrganizationTemplates) |
| // READ | ||
| router.get('/custom', marketplacesController.getAllCustomTemplates) | ||
| // 🆕 Add - Organization templates | ||
| router.get('/organization', enforceAbility('Marketplace'), marketplacesController.getOrganizationTemplates) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
To fix this issue, we should add a rate-limiting middleware to the /organization route (and, ideally, to all routes performing expensive operations unless rate limiting is already handled at a higher level). The best way is to use the express-rate-limit package, which is a well-maintained and widely used library for Express applications. We will import and configure the rate limiter and apply it specifically to the /organization route in this file. This approach avoids altering existing route logic or interfering with authentication/authorization functionality. The changes should be made at the top of the file for imports and just before the /organization route definition for the middleware application.
| @@ -1,6 +1,7 @@ | ||
| import express from 'express' | ||
| import marketplacesController from '../../controllers/marketplaces' | ||
| import enforceAbility from '../../middlewares/authentication/enforceAbility' | ||
| import rateLimit from 'express-rate-limit' | ||
| const router = express.Router() | ||
|
|
||
| // READ - Templates del marketplace (public) | ||
| @@ -11,7 +12,12 @@ | ||
| router.get('/custom', enforceAbility('Marketplace'), marketplacesController.getAllCustomTemplates) | ||
|
|
||
| // 🆕 Add - Organization templates | ||
| router.get('/organization', enforceAbility('Marketplace'), marketplacesController.getOrganizationTemplates) | ||
| router.get( | ||
| '/organization', | ||
| organizationRateLimiter, | ||
| enforceAbility('Marketplace'), | ||
| marketplacesController.getOrganizationTemplates | ||
| ) | ||
| // CREATE - Create custom template | ||
| router.post('/custom', enforceAbility('Marketplace'), marketplacesController.saveCustomTemplate) | ||
|
|
| // 🆕 Add - Organization templates | ||
| router.get('/organization', enforceAbility('Marketplace'), marketplacesController.getOrganizationTemplates) | ||
| // CREATE - Create custom template | ||
| router.post('/custom', enforceAbility('Marketplace'), marketplacesController.saveCustomTemplate) |
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 will implement rate limiting for the /custom route using the express-rate-limit package. This ensures that the creation of custom templates is protected against excessive requests. Specifically:
- Import the
express-rate-limitpackage. - Configure a rate limiter middleware with an appropriate maximum number of requests and time window.
- Apply the rate limiter to the specific
/customroute to limit the requests.
The fix will not alter the existing functionality of the route, as it only adds a middleware.
| @@ -1,8 +1,14 @@ | ||
| import express from 'express' | ||
| import marketplacesController from '../../controllers/marketplaces' | ||
| import enforceAbility from '../../middlewares/authentication/enforceAbility' | ||
| import rateLimit from 'express-rate-limit' | ||
| const router = express.Router() | ||
|
|
||
| const customTemplateRateLimiter = rateLimit({ | ||
| windowMs: 15 * 60 * 1000, // 15 minutes | ||
| max: 100, // Limit each IP to 100 requests per windowMs | ||
| }) | ||
|
|
||
| // READ - Templates del marketplace (public) | ||
| router.get('/templates', marketplacesController.getAllTemplates) | ||
| router.get('/templates/:id', marketplacesController.getMarketplaceTemplate) | ||
| @@ -13,7 +17,7 @@ | ||
| // 🆕 Add - Organization templates | ||
| router.get('/organization', enforceAbility('Marketplace'), marketplacesController.getOrganizationTemplates) | ||
| // CREATE - Create custom template | ||
| router.post('/custom', enforceAbility('Marketplace'), marketplacesController.saveCustomTemplate) | ||
| router.post('/custom', customTemplateRateLimiter, enforceAbility('Marketplace'), marketplacesController.saveCustomTemplate) | ||
|
|
||
| // DELETE - Delete custom template | ||
| router.delete('/custom/:id', enforceAbility('Marketplace'), marketplacesController.deleteCustomTemplate) |
| // DELETE | ||
| router.delete(['/', '/custom/:id'], marketplacesController.deleteCustomTemplate) | ||
| // DELETE - Delete custom template | ||
| router.delete('/custom/:id', enforceAbility('Marketplace'), marketplacesController.deleteCustomTemplate) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
To fix the problem, we need to add a rate-limiting middleware to the DELETE /custom/:id route. The best way to do this is to use a well-known package, such as express-rate-limit. We should import the package at the top of the file, define a suitable rate limiter instance (e.g., limit to 10 deletes per 15 minutes per IP), and apply it to the route in question. The fix should be made in packages/server/src/routes/marketplaces/index.ts:
- Add the import for
express-rate-limit. - Define a rate limiter instance.
- Add the rate limiter as a middleware to the route on line 19 (
router.delete(...)).
No changes to controller logic or existing authentication middleware are needed.
| @@ -1,8 +1,16 @@ | ||
| import express from 'express' | ||
| import marketplacesController from '../../controllers/marketplaces' | ||
| import enforceAbility from '../../middlewares/authentication/enforceAbility' | ||
| import rateLimit from 'express-rate-limit' | ||
| const router = express.Router() | ||
|
|
||
| // Limit DELETE requests to 10 per 15 minutes per IP | ||
| const deleteLimiter = rateLimit({ | ||
| windowMs: 15 * 60 * 1000, // 15 minutes | ||
| max: 10, // limit each IP to 10 delete requests per windowMs | ||
| standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers | ||
| legacyHeaders: false, // Disable the `X-RateLimit-*` headers | ||
| }) | ||
| // READ - Templates del marketplace (public) | ||
| router.get('/templates', marketplacesController.getAllTemplates) | ||
| router.get('/templates/:id', marketplacesController.getMarketplaceTemplate) | ||
| @@ -16,6 +22,6 @@ | ||
| router.post('/custom', enforceAbility('Marketplace'), marketplacesController.saveCustomTemplate) | ||
|
|
||
| // DELETE - Delete custom template | ||
| router.delete('/custom/:id', enforceAbility('Marketplace'), marketplacesController.deleteCustomTemplate) | ||
| router.delete('/custom/:id', enforceAbility('Marketplace'), deleteLimiter, marketplacesController.deleteCustomTemplate) | ||
|
|
||
| export default router |
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
| passport.authenticate('salesforce-dynamic', { failureRedirect: '/' }), | ||
| salesforceAuthController.salesforceAuthCallback | ||
| ) | ||
| router.get('/', salesforceAuthController.authenticate) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 year ago
To address the missing rate limiting on the / route, a rate-limiting middleware should be applied to this route within packages/server/src/routes/salesforce-auth/index.ts. The best practice is to use a well-known and maintained package such as express-rate-limit. Since the codebase uses TypeScript and ES module-style imports, and only changes within the shown file are allowed, the fix involves:
- Importing
express-rate-limit. - Creating a rate limiter instance with reasonable defaults (e.g., 100 requests per 15 minutes).
- Applying the rate limiter specifically to the
/route by passing it as middleware torouter.get('/', ...).
All changes are to be made within packages/server/src/routes/salesforce-auth/index.ts.
| @@ -1,11 +1,20 @@ | ||
| /* eslint-disable no-console */ | ||
| import express from 'express' | ||
| import salesforceAuthController from '../../controllers/salesforce-auth' | ||
| import rateLimit from 'express-rate-limit' | ||
| import passport from 'passport' | ||
|
|
||
| const router = express.Router() | ||
|
|
||
| router.get('/', salesforceAuthController.authenticate) | ||
| // Rate limiter: max 100 requests per 15 minutes per IP for auth endpoint | ||
| const authRateLimiter = 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 | ||
| }) | ||
|
|
||
| router.get('/', authRateLimiter, salesforceAuthController.authenticate) | ||
| router.get('/error', (req, res) => { | ||
| const messages = (req.session as any)?.messages || [] | ||
| const errorMessage = messages.length > 0 ? messages[messages.length - 1] : req.query.error |
| router.get('/callback', (req, res, next) => { | ||
| passport.authenticate('salesforce-dynamic', (err: any, user: any, info: any) => { | ||
| console.log('Error:', err) | ||
| console.log('User:', user) | ||
| console.log('Info:', info) | ||
|
|
||
| if (err || !user) { | ||
| const errorMsg = err?.message || info?.message || 'Authentication failed' | ||
| return res.redirect(`/api/v1/salesforce-auth/error?error=${encodeURIComponent(errorMsg)}`) | ||
| } | ||
|
|
||
| req.user = user | ||
| salesforceAuthController.salesforceAuthCallback(req, res) | ||
| })(req, res, next) | ||
| }) |
Check failure
Code scanning / CodeQL
Missing rate limiting High
- Fix JSX element return in homepage component - Remove path restriction from redirect hook - Add timeout protection and enhanced error handling - Ensure all error scenarios fallback to /chat Resolves AAI-489
- Fix JSX element return in homepage component - Remove path restriction from redirect hook - Add timeout protection and enhanced error handling - Update related page components for consistency - Ensure all error scenarios fallback to /chat Resolves AAI-489
…rovements This comprehensive update addresses GitHub issue #391 and Jira ticket AAI-487 by implementing multi-tenant template management with proper organization scoping and critical security fixes. ## 🆕 New Features ### Multi-Tenant Template System - **Organization Scoping**: Templates now belong to specific organizations - **Template Sharing**: Option to share templates within organization - **Template Lineage**: Track parent-child relationships and template origins - **Answer Agent Framework**: Added support for Answer Agent framework detection ### Enhanced UI Experience - **Organization Templates Tab**: New tab showing organization-shared templates - **Template Segregation**: Answer Agent templates filtered from Example Templates - **Share Toggle**: UI option to share templates with organization members - **Improved Template Export**: Better framework detection and metadata handling ## 🔧 Database Schema Updates ### New Migrations - `AddOrganizationToCustomTemplate`: Adds organization and user scoping - `AddParentIdToCustomTemplate`: Enables template lineage tracking - `AddTemplateIdToChatFlow`: Links chatflows to their template origins ### Enhanced Entities - **CustomTemplate**: Added userId, organizationId, shareWithOrg, parentId fields - **ChatFlow**: Added templateId field for template tracking - **Soft Delete**: Implemented for data integrity and audit trails ## 🛡️ Critical Security Fixes ### Authentication & Authorization - **Mandatory Authentication**: All marketplace endpoints now require authentication - **Ownership Validation**: Proper user/organization ownership checks - **Permission System**: Role-based access control for templates ### Chatflow Deletion Security - **Authorization Logic**: Fixed flawed permission checking in deleteChatflow - **Route Security**: Removed vulnerable DELETE pattern allowing deletion without ID - **Transaction Safety**: Wrapped deletion operations in database transactions ### Migration Resilience - **No-Organization Handling**: Migration handles environments without organizations - **System Templates**: Orphaned templates become system-wide instead of failing ## 🎯 API Improvements ### New Endpoints - `GET /marketplaces/organization`: Retrieve organization-shared templates - Enhanced marketplace endpoints with proper authentication middleware ### Enhanced Services - **Template Service**: Improved filtering, validation, and framework detection - **Chatflow Service**: Better authorization and cleanup procedures - **Error Handling**: Consistent error responses and proper status codes ## 📊 Frontend Enhancements ### Template Management - **Filtered Views**: Answer Agent templates excluded from Example Templates - **Organization Tab**: Dedicated view for organization-shared templates - **Enhanced Metadata**: Better template information display and searching ### User Experience - **Template Sharing**: Easy organization sharing toggle - **Framework Detection**: Automatic framework classification - **Improved Navigation**: Better template organization and discovery ## 🔍 Technical Details ### Framework Detection - Automatic detection of Answer Agent templates based on MCP Tools usage - Enhanced framework categorization (Langchain, LlamaIndex, Answer Agent) - Better template metadata extraction and processing ### Data Integrity - Soft delete implementation across all related entities - Proper cleanup of chatflow dependencies (messages, feedback, history) - Transaction-safe operations with rollback capabilities ### Performance Optimizations - Efficient query patterns with proper indexing - Optimized filtering and search operations - Reduced database roundtrips through better query design ## 🚀 New MCP Sidekick Templates - Answer Agent MCP Sidekick - BraveSearch MCP Sidekick - Confluence MCP Sidekick - Contentful MCP Sidekick - Jira MCP Sidekick - PostgreSQL MCP Sidekick - Salesforce MCP Sidekick - Slack MCP Sidekick - YouTube MCP Sidekick Fixes: #391 Jira: AAI-487
- Fixed orphaned object literals after commented console.log statements - Properly commented out object properties in MarketplaceCanvas.jsx - Properly commented out object properties in MarketplaceLanding.jsx - Properly commented out object properties in canvas/index.jsx - Resolves build errors while preserving debug information for future use
- Enhance clarity and structure of local development instructions - Add steps for cloning the repository, setting up environment variables, initializing git submodules, and running the application - Include optional steps for faster startup and database tool installation
- Add step for installing Docker Desktop and ensuring it is running - Reorder steps for clarity, including building and migrating the initial database - Update instructions for running the application and accessing it - Enhance guidance for development with fast reload instructions
- Removed the `update_ui_env.sh` script from the Dockerfile as it is no longer needed for application startup. - Updated the ENTRYPOINT to use the default CMD for starting the application.
* error handling in salesforce route * some better logging --------- Co-authored-by: Jaime Morales <jaime@lastrev.com>
- Removed empty PRODUCTION_URL from copilot._environment_.env.template - Set NODE_ENV in Dockerfile to production using the correct syntax - Added stickiness to the health check configuration in manifest.yml - Introduced NUMBER_OF_PROXIES variable in manifest.yml - Specified cookie domain in server index.ts for production environment
…eprecated disk configuration (#364)
… button for members
Release Notes
Bug Fixes
User Interface & Experience
Documentation & Developer Experience
DevOps & Infrastructure
Features
Security
Content