diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 2bb1b093d4e..406cb42d9c0 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -135,6 +135,8 @@ export class App { '/api/v1/ip', '/api/v1/ping' ] + const URL_CASE_INSENSITIVE_REGEX: RegExp = /\/api\/v1\//i + const URL_CASE_SENSITIVE_REGEX: RegExp = /\/api\/v1\// if (process.env.FLOWISE_USERNAME && process.env.FLOWISE_PASSWORD) { const username = process.env.FLOWISE_USERNAME @@ -143,37 +145,55 @@ export class App { users: { [username]: password } }) this.app.use(async (req, res, next) => { - if (/\/api\/v1\//i.test(req.url)) { - if (whitelistURLs.some((url) => new RegExp(url, 'i').test(req.url))) { - next() - } else if (req.headers['x-request-from'] === 'internal') { - basicAuthMiddleware(req, res, next) - } else { - const isKeyValidated = await validateAPIKey(req) - if (!isKeyValidated) { - return res.status(401).json({ error: 'Unauthorized Access' }) + // Step 1: Check if the req path contains /api/v1 regardless of case + if (URL_CASE_INSENSITIVE_REGEX.test(req.path)) { + // Step 2: Check if the req path is case sensitive + if (URL_CASE_SENSITIVE_REGEX.test(req.path)) { + // Step 3: Check if the req path is in the whitelist + const isWhitelisted = whitelistURLs.some((url) => req.path.startsWith(url)) + if (isWhitelisted) { + next() + } else if (req.headers['x-request-from'] === 'internal') { + basicAuthMiddleware(req, res, next) + } else { + const isKeyValidated = await validateAPIKey(req) + if (!isKeyValidated) { + return res.status(401).json({ error: 'Unauthorized Access' }) + } + next() } - next() + } else { + return res.status(401).json({ error: 'Unauthorized Access' }) } } else { + // If the req path does not contain /api/v1, then allow the request to pass through, example: /assets, /canvas next() } }) } else { this.app.use(async (req, res, next) => { - if (/\/api\/v1\//i.test(req.url)) { - if (whitelistURLs.some((url) => new RegExp(url, 'i').test(req.url))) { - next() - } else if (req.headers['x-request-from'] === 'internal') { - next() - } else { - const isKeyValidated = await validateAPIKey(req) - if (!isKeyValidated) { - return res.status(401).json({ error: 'Unauthorized Access' }) + // Step 1: Check if the req path contains /api/v1 regardless of case + if (URL_CASE_INSENSITIVE_REGEX.test(req.path)) { + // Step 2: Check if the req path is case sensitive + if (URL_CASE_SENSITIVE_REGEX.test(req.path)) { + // Step 3: Check if the req path is in the whitelist + const isWhitelisted = whitelistURLs.some((url) => req.path.startsWith(url)) + if (isWhitelisted) { + next() + } else if (req.headers['x-request-from'] === 'internal') { + next() + } else { + const isKeyValidated = await validateAPIKey(req) + if (!isKeyValidated) { + return res.status(401).json({ error: 'Unauthorized Access' }) + } + next() } - next() + } else { + return res.status(401).json({ error: 'Unauthorized Access' }) } } else { + // If the req path does not contain /api/v1, then allow the request to pass through, example: /assets, /canvas next() } })