Skip to content

Commit bed2e09

Browse files
fix: guard against undefined user in getAllPermissions handler
The GET /api/v1/auth/:type route matches /api/v1/auth/resolve, which is whitelisted and skips authentication. When an unauthenticated request hits this route, req.user is undefined and accessing user.isOrganizationAdmin throws a TypeError, returning a 500 error. Added a null check for req.user that returns 401 before accessing any user properties. This fixes the login page hang on fresh Flowise 3.x installs where the UI calls /api/v1/auth/resolve to determine auth state. Fixes #6105
1 parent 4c0223a commit bed2e09

2 files changed

Lines changed: 82 additions & 1 deletion

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { describe, expect, it, beforeEach } from '@jest/globals'
2+
import { Request, Response, NextFunction } from 'express'
3+
4+
// Mock logger before importing the module under test
5+
jest.mock('../../../utils/logger', () => ({
6+
__esModule: true,
7+
default: { warn: jest.fn(), info: jest.fn(), error: jest.fn(), debug: jest.fn() }
8+
}))
9+
10+
// Mock getRunningExpressApp
11+
const mockGetRunningExpressApp = jest.fn()
12+
jest.mock('../../../utils/getRunningExpressApp', () => ({
13+
getRunningExpressApp: () => mockGetRunningExpressApp()
14+
}))
15+
16+
import authController from './index'
17+
18+
describe('auth controller', () => {
19+
describe('getAllPermissions', () => {
20+
it('should return 401 when req.user is undefined', async () => {
21+
const req = {
22+
params: { type: 'resolve' },
23+
user: undefined
24+
} as unknown as Request
25+
26+
const json = jest.fn()
27+
const status = jest.fn().mockReturnValue({ json })
28+
const res = { status } as unknown as Response
29+
const next = jest.fn() as unknown as NextFunction
30+
31+
// Mock the running app with identity manager
32+
mockGetRunningExpressApp.mockReturnValue({
33+
identityManager: {
34+
getPermissions: () => ({ toJSON: () => ({}) }),
35+
getPlatformType: () => 'OPEN_SOURCE'
36+
}
37+
})
38+
39+
await authController.getAllPermissions(req, res, next)
40+
41+
expect(status).toHaveBeenCalledWith(401)
42+
expect(json).toHaveBeenCalledWith({ error: 'Unauthorized Access' })
43+
expect(next).not.toHaveBeenCalled()
44+
})
45+
46+
it('should return permissions when req.user is present', async () => {
47+
const req = {
48+
params: { type: 'ROLE' },
49+
user: {
50+
isOrganizationAdmin: true,
51+
permissions: [],
52+
features: {}
53+
}
54+
} as unknown as Request
55+
56+
const json = jest.fn()
57+
const status = jest.fn().mockReturnValue({ json })
58+
const res = { status } as unknown as Response
59+
const next = jest.fn() as unknown as NextFunction
60+
61+
const mockPermissions = {
62+
chatflows: [{ key: 'chatflows:read', value: 'Read Chatflows' }]
63+
}
64+
65+
mockGetRunningExpressApp.mockReturnValue({
66+
identityManager: {
67+
getPermissions: () => ({ toJSON: () => mockPermissions }),
68+
getPlatformType: () => 'OPEN_SOURCE'
69+
}
70+
})
71+
72+
await authController.getAllPermissions(req, res, next)
73+
74+
expect(status).toHaveBeenCalledWith(200)
75+
expect(json).toHaveBeenCalledWith(mockPermissions)
76+
})
77+
})
78+
})

packages/server/src/enterprise/controllers/auth/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ const getAllPermissions = async (req: Request, res: Response, next: NextFunction
99
const appServer = getRunningExpressApp()
1010
const type = req.params.type as string
1111
const allPermissions = appServer.identityManager.getPermissions().toJSON()
12-
const user = req.user as LoggedInUser
12+
const user = req.user as LoggedInUser | undefined
13+
if (!user) {
14+
return res.status(StatusCodes.UNAUTHORIZED).json({ error: 'Unauthorized Access' })
15+
}
1316

1417
let permissions: { [key: string]: { key: string; value: string }[] } = allPermissions
1518

0 commit comments

Comments
 (0)