Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion metrics/prometheus/prometheus.config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ scrape_configs:
- targets: ["localhost:8080","localhost:3000"]

metrics_path: /api/v1/metrics/
scheme: http
scheme: http

authorization:
type: Bearer
credentials_file: '/etc/prometheus/api_key.txt'
1 change: 0 additions & 1 deletion packages/server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
# REDIS_KEEP_ALIVE=
# ENABLE_BULLMQ_DASHBOARD=


############################################################################################################
############################################## SECURITY ####################################################
############################################################################################################
Expand Down
40 changes: 39 additions & 1 deletion packages/server/src/controllers/export-import/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,45 @@ const importData = async (req: Request, res: Response, next: NextFunction) => {
}
}

const exportChatflowMessages = async (req: Request, res: Response, next: NextFunction) => {
try {
const workspaceId = req.user?.activeWorkspaceId
if (!workspaceId) {
throw new InternalFlowiseError(
StatusCodes.NOT_FOUND,
`Error: exportImportController.exportChatflowMessages - workspace ${workspaceId} not found!`
)
}

const { chatflowId, chatType, feedbackType, startDate, endDate } = req.body
if (!chatflowId) {
throw new InternalFlowiseError(
StatusCodes.BAD_REQUEST,
'Error: exportImportController.exportChatflowMessages - chatflowId is required!'
)
}

const apiResponse = await exportImportService.exportChatflowMessages(
chatflowId,
chatType,
feedbackType,
startDate,
endDate,
workspaceId
)

// Set headers for file download
res.setHeader('Content-Type', 'application/json')
res.setHeader('Content-Disposition', `attachment; filename="${chatflowId}-Message.json"`)

return res.json(apiResponse)
} catch (error) {
next(error)
}
}

export default {
exportData,
importData
importData,
exportChatflowMessages
}
17 changes: 0 additions & 17 deletions packages/server/src/controllers/get-upload-path/index.ts

This file was deleted.

28 changes: 28 additions & 0 deletions packages/server/src/enterprise/middleware/passport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,34 @@ export const verifyToken = (req: Request, res: Response, next: NextFunction) =>
})(req, res, next)
}

export const verifyTokenForBullMQDashboard = (req: Request, res: Response, next: NextFunction) => {
passport.authenticate('jwt', { session: true }, (err: any, user: LoggedInUser, info: object) => {
if (err) {
return next(err)
}

// @ts-ignore
if (info && info.name === 'TokenExpiredError') {
if (req.cookies && req.cookies.refreshToken) {
return res.redirect('/signin?retry=true')
}
return res.redirect('/signin')
}

if (!user) {
return res.redirect('/signin')
}

const identityManager = getRunningExpressApp().identityManager
if (identityManager.isEnterprise() && !identityManager.isLicenseValid()) {
return res.redirect('/license-expired')
}

req.user = user
next()
})(req, res, next)
}

const storeSSOUserPayload = (ssoToken: string, returnUser: any) => {
const app = getRunningExpressApp()
app.cachePool.addSSOTokenCache(ssoToken, returnUser)
Expand Down
14 changes: 12 additions & 2 deletions packages/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Telemetry } from './utils/telemetry'
import flowiseApiV1Router from './routes'
import errorHandlerMiddleware from './middlewares/errors'
import { WHITELIST_URLS } from './utils/constants'
import { initializeJwtCookieMiddleware, verifyToken } from './enterprise/middleware/passport'
import { initializeJwtCookieMiddleware, verifyToken, verifyTokenForBullMQDashboard } from './enterprise/middleware/passport'
import { IdentityManager } from './IdentityManager'
import { SSEStreamer } from './utils/SSEStreamer'
import { validateAPIKey } from './utils/validateKey'
Expand Down Expand Up @@ -331,7 +331,17 @@ export class App {
})

if (process.env.MODE === MODE.QUEUE && process.env.ENABLE_BULLMQ_DASHBOARD === 'true' && !this.identityManager.isCloud()) {
this.app.use('/admin/queues', this.queueManager.getBullBoardRouter())
// Initialize admin queues rate limiter
const id = 'bullmq_admin_dashboard'
await this.rateLimiterManager.addRateLimiter(
id,
60,
100,
process.env.ADMIN_RATE_LIMIT_MESSAGE || 'Too many requests to admin dashboard, please try again later.'
)

const rateLimiter = this.rateLimiterManager.getRateLimiterById(id)
this.app.use('/admin/queues', rateLimiter, verifyTokenForBullMQDashboard, this.queueManager.getBullBoardRouter())
}

// ----------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions packages/server/src/routes/export-import/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const router = express.Router()

router.post('/export', checkPermission('workspace:export'), exportImportController.exportData)

router.post('/chatflow-messages', checkPermission('workspace:export'), exportImportController.exportChatflowMessages)

router.post('/import', checkPermission('workspace:import'), exportImportController.importData)

export default router
8 changes: 0 additions & 8 deletions packages/server/src/routes/get-upload-path/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/server/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import fetchLinksRouter from './fetch-links'
import filesRouter from './files'
import flowConfigRouter from './flow-config'
import getUploadFileRouter from './get-upload-file'
import getUploadPathRouter from './get-upload-path'
import internalChatmessagesRouter from './internal-chat-messages'
import internalPredictionRouter from './internal-predictions'
import leadsRouter from './leads'
Expand Down Expand Up @@ -93,7 +92,6 @@ router.use('/flow-config', flowConfigRouter)
router.use('/internal-chatmessage', internalChatmessagesRouter)
router.use('/internal-prediction', internalPredictionRouter)
router.use('/get-upload-file', getUploadFileRouter)
router.use('/get-upload-path', getUploadPathRouter)
router.use('/leads', leadsRouter)
router.use('/load-prompt', loadPromptRouter)
router.use('/marketplaces', marketplacesRouter)
Expand Down
Loading