fix: Check license in folder controller (no-changelog) (#16937)

This commit is contained in:
Ricardo Espinoza
2025-07-22 08:56:52 -04:00
committed by GitHub
parent 9f45c284db
commit c80688b3f9
2 changed files with 185 additions and 0 deletions

View File

@@ -49,6 +49,8 @@ let workflowRepository: WorkflowRepository;
const activeWorkflowManager = mockInstance(ActiveWorkflowManager);
beforeEach(async () => {
testServer.license.enable('feat:folders');
await testDb.truncate(['Folder', 'SharedWorkflow', 'TagEntity', 'Project', 'ProjectRelation']);
projectRepository = Container.get(ProjectRepository);
@@ -66,6 +68,18 @@ beforeEach(async () => {
});
describe('POST /projects/:projectId/folders', () => {
test('should now create folder if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject(undefined, owner);
await linkUserToProject(member, project, 'project:viewer');
const payload = {
name: 'Test Folder',
};
await authMemberAgent.post(`/projects/${project.id}/folders`).send(payload).expect(403);
});
test('should not create folder when project does not exist', async () => {
const payload = {
name: 'Test Folder',
@@ -235,6 +249,32 @@ describe('POST /projects/:projectId/folders', () => {
});
describe('GET /projects/:projectId/folders/:folderId/tree', () => {
test('should not retrieve folder tree if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject('test', owner);
const rootFolder = await createFolder(project, { name: 'Root' });
const childFolder1 = await createFolder(project, {
name: 'Child 1',
parentFolder: rootFolder,
});
await createFolder(project, {
name: 'Child 2',
parentFolder: rootFolder,
});
const grandchildFolder = await createFolder(project, {
name: 'Grandchild',
parentFolder: childFolder1,
});
await authOwnerAgent
.get(`/projects/${project.id}/folders/${grandchildFolder.id}/tree`)
.expect(403);
});
test('should not get folder tree when project does not exist', async () => {
await authOwnerAgent.get('/projects/non-existing-id/folders/some-folder-id/tree').expect(403);
});
@@ -311,6 +351,68 @@ describe('GET /projects/:projectId/folders/:folderId/tree', () => {
});
describe('GET /projects/:projectId/folders/:folderId/credentials', () => {
test('should not retrieve folder tree if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject('test', owner);
const rootFolder = await createFolder(project, { name: 'Root' });
const childFolder1 = await createFolder(project, {
name: 'Child 1',
parentFolder: rootFolder,
});
await createFolder(project, {
name: 'Child 2',
parentFolder: rootFolder,
});
const grandchildFolder = await createFolder(project, {
name: 'Grandchild',
parentFolder: childFolder1,
});
for (const folder of [rootFolder, childFolder1, grandchildFolder]) {
const credential = await createCredentials(
{
name: `Test credential ${folder.name}`,
data: '',
type: 'test',
},
project,
);
await createWorkflow(
{
name: 'Test Workflow',
parentFolder: folder,
active: false,
nodes: [
{
parameters: {},
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
typeVersion: 1.2,
position: [0, 0],
id: faker.string.uuid(),
name: 'OpenAI Chat Model',
credentials: {
openAiApi: {
id: credential.id,
name: credential.name,
},
},
},
],
},
owner,
);
}
await authOwnerAgent
.get(`/projects/${project.id}/folders/${childFolder1.id}/credentials`)
.expect(403);
});
test('should not get folder credentials when project does not exist', async () => {
await authOwnerAgent
.get('/projects/non-existing-id/folders/some-folder-id/credentials')
@@ -416,6 +518,23 @@ describe('GET /projects/:projectId/folders/:folderId/credentials', () => {
});
describe('PATCH /projects/:projectId/folders/:folderId', () => {
test('should not update folder if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject(undefined, owner);
const folder = await createFolder(project, { name: 'Original Name' });
await linkUserToProject(member, project, 'project:editor');
const payload = {
name: 'Updated Folder Name',
};
await authMemberAgent
.patch(`/projects/${project.id}/folders/${folder.id}`)
.send(payload)
.expect(403);
});
test('should not update folder when project does not exist', async () => {
const payload = {
name: 'Updated Folder Name',
@@ -868,6 +987,18 @@ describe('PATCH /projects/:projectId/folders/:folderId', () => {
});
describe('DELETE /projects/:projectId/folders/:folderId', () => {
test('should not delete folder if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject(undefined, owner);
const folder = await createFolder(project);
await authOwnerAgent
.delete(`/projects/${project.id}/folders/${folder.id}`)
.send({})
.expect(403);
});
test('should not delete folder when project does not exist', async () => {
await authOwnerAgent
.delete('/projects/non-existing-id/folders/some-folder-id')
@@ -1159,6 +1290,16 @@ describe('DELETE /projects/:projectId/folders/:folderId', () => {
});
describe('GET /projects/:projectId/folders', () => {
test('should not retrieve folder if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject('test project', owner);
await linkUserToProject(member, project, 'project:viewer');
await createFolder(project, { name: 'Test Folder' });
await authMemberAgent.get(`/projects/${project.id}/folders`).expect(403);
});
test('should not list folders when project does not exist', async () => {
await authOwnerAgent.get('/projects/non-existing-id/folders').expect(403);
});
@@ -1570,6 +1711,16 @@ describe('GET /projects/:projectId/folders', () => {
});
describe('GET /projects/:projectId/folders/content', () => {
test('should not retrieve folder content if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const project = await createTeamProject('test project', owner);
await linkUserToProject(member, project, 'project:viewer');
const folder = await createFolder(project, { name: 'Test Folder' });
await authMemberAgent.get(`/projects/${project.id}/folders/${folder.id}/content`).expect(403);
});
test('should not list folders when project does not exist', async () => {
await authOwnerAgent
.get('/projects/non-existing-id/folders/no-existing-id/content')
@@ -1634,6 +1785,31 @@ describe('GET /projects/:projectId/folders/content', () => {
});
describe('PUT /projects/:projectId/folders/:folderId/transfer', () => {
test('should not transfer folder if license does not allow it', async () => {
testServer.license.disable('feat:folders');
const admin = await createUser({ role: 'global:admin' });
const sourceProject = await createTeamProject('source project', admin);
const destinationProject = await createTeamProject('destination project', member);
const sourceFolder1 = await createFolder(sourceProject, { name: 'Source Folder 1' });
const credential = await saveCredential(randomCredentialPayload(), {
project: sourceProject,
role: 'credential:owner',
});
// ACT
await testServer
.authAgentFor(owner)
.put(`/projects/${sourceProject.id}/folders/${sourceFolder1.id}/transfer`)
.send({
destinationProjectId: destinationProject.id,
destinationParentFolderId: '0',
shareCredentials: [credential.id],
})
.expect(403);
});
test('cannot transfer into the same project', async () => {
const sourceProject = await createTeamProject('source project', member);
const destinationProject = await createTeamProject('Team Project', member);