Chore/refractor (#4454)

* markdown files and env examples cleanup

* components update

* update jsonlines description

* server refractor

* update telemetry

* add execute custom node

* add ui refractor

* add username and password authenticate

* correctly retrieve past images in agentflowv2

* disable e2e temporarily

* add existing username and password authenticate

* update migration to default workspace

* update todo

* blob storage migrating

* throw error on agent tool call error

* add missing execution import

* add referral

* chore: add error message when importData is undefined

* migrate api keys to db

* fix: data too long for column executionData

* migrate api keys from json to db at init

* add info on account setup

* update docstore missing fields

---------

Co-authored-by: chungyau97 <chungyau97@gmail.com>
This commit is contained in:
Henry Heng
2025-05-27 14:29:42 +08:00
committed by GitHub
parent e35a126b46
commit 5a37227d14
560 changed files with 62127 additions and 4100 deletions
+28
View File
@@ -0,0 +1,28 @@
import * as Server from '../src'
import { getRunningExpressApp } from '../src/utils/getRunningExpressApp'
import { organizationUserRouteTest } from './routes/v1/organization-user.route.test'
import { userRouteTest } from './routes/v1/user.route.test'
import { apiKeyTest } from './utils/api-key.util.test'
// ⏱️ Extend test timeout to 6 minutes for long setups (increase as tests grow)
jest.setTimeout(360000)
beforeAll(async () => {
await Server.start()
// ⏳ Wait 3 minutes for full server and database init (esp. on lower end hardware)
await new Promise((resolve) => setTimeout(resolve, 3 * 60 * 1000))
})
afterAll(async () => {
await getRunningExpressApp().stopApp()
})
describe('Routes Test', () => {
userRouteTest()
organizationUserRouteTest()
})
describe('Utils Test', () => {
apiKeyTest()
})
@@ -0,0 +1,39 @@
import { StatusCodes } from 'http-status-codes'
import supertest from 'supertest'
import { getRunningExpressApp } from '../../../src/utils/getRunningExpressApp'
export function organizationUserRouteTest() {
describe('Organization User Route', () => {
const route = '/api/v1/user'
describe(`GET ${route}/test successful without user status`, () => {
const statusCode = StatusCodes.OK
const message = 'Hello World'
it(`should return a ${statusCode} status and message of ${message}`, async () => {
await supertest(getRunningExpressApp().app)
.get(`${route + '/test'}`)
.expect(statusCode)
.then((response) => {
const body = response.body
expect(body.message).toEqual(message)
})
})
})
describe(`POST ${route}/test successful without user status`, () => {
const statusCode = StatusCodes.OK
const message = 'Hello World'
it(`should return a ${statusCode} status and message of ${message}`, async () => {
await supertest(getRunningExpressApp().app)
.get(`${route + '/test'}`)
.expect(statusCode)
.then((response) => {
const body = response.body
expect(body.message).toEqual(message)
})
})
})
})
}
@@ -0,0 +1,54 @@
import { StatusCodes } from 'http-status-codes'
import supertest from 'supertest'
import { getRunningExpressApp } from '../../../src/utils/getRunningExpressApp'
export function userRouteTest() {
describe('User Route', () => {
const route = '/api/v1/user'
describe(`GET ${route}/test successful without user status`, () => {
const statusCode = StatusCodes.OK
const message = 'Hello World'
it(`should return a ${statusCode} status and message of ${message}`, async () => {
await supertest(getRunningExpressApp().app)
.get(`${route + '/test'}`)
.expect(statusCode)
.then((response) => {
const body = response.body
expect(body.message).toEqual(message)
})
})
})
describe(`POST ${route}/test successful without user status`, () => {
const statusCode = StatusCodes.OK
const message = 'Hello World'
it(`should return a ${statusCode} status and message of ${message}`, async () => {
await supertest(getRunningExpressApp().app)
.get(`${route + '/test'}`)
.expect(statusCode)
.then((response) => {
const body = response.body
expect(body.message).toEqual(message)
})
})
})
describe(`PUT ${route}/test successful without user status`, () => {
const statusCode = StatusCodes.OK
const message = 'Hello World'
it(`should return a ${statusCode} status and message of ${message}`, async () => {
await supertest(getRunningExpressApp().app)
.get(`${route + '/test'}`)
.expect(statusCode)
.then((response) => {
const body = response.body
expect(body.message).toEqual(message)
})
})
})
})
}
@@ -0,0 +1,10 @@
import { generateAPIKey } from '../../src/utils/apiKey'
export function apiKeyTest() {
describe('Api Key', () => {
it('should be able to generate a new api key', () => {
const apiKey = generateAPIKey()
expect(typeof apiKey === 'string').toEqual(true)
})
})
}
@@ -1,41 +0,0 @@
import { Request } from 'express'
import { ChatFlow } from '../../src/database/entities/ChatFlow'
import { validateChatflowAPIKey } from '../../src/utils/validateKey'
import { compareKeys, getAPIKeys } from '../../src/utils/apiKey'
jest.mock('../../src/utils/apiKey')
describe('validateChatflowAPIKey', () => {
let req: Partial<Request>
let chatflow: ChatFlow
beforeEach(() => {
req = {
headers: {}
}
chatflow = {
apikeyid: null
} as ChatFlow
})
it('should return true if chatflow.apikeyid is not set', async () => {
const result = await validateChatflowAPIKey(req as Request, chatflow)
expect(result).toBe(true)
})
it('should return false if chatflow.apikeyid is set but authorization header is missing', async () => {
chatflow.apikeyid = 'some-api-key-id'
const result = await validateChatflowAPIKey(req as Request, chatflow)
expect(result).toBe(false)
})
it('should return false if supplied key does not match the expected key', async () => {
chatflow.apikeyid = 'some-api-key-id'
req.headers['authorization'] = 'Bearer invalid-key'
;(getAPIKeys as jest.Mock).mockResolvedValue([{ id: 'some-api-key-id', apiSecret: 'expected-secret-key' }])
;(compareKeys as jest.Mock).mockImplementation((expected, supplied) => expected === supplied)
const result = await validateChatflowAPIKey(req as Request, chatflow)
expect(result).toBe(false)
})
})