mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat: Allow sharing to and from team projects (no-changelog) (#10144)
This commit is contained in:
@@ -48,6 +48,7 @@ let memberPersonalProject: Project;
|
||||
let anotherMember: User;
|
||||
let anotherMemberPersonalProject: Project;
|
||||
let authOwnerAgent: SuperAgentTest;
|
||||
let authMemberAgent: SuperAgentTest;
|
||||
let authAnotherMemberAgent: SuperAgentTest;
|
||||
let saveCredential: SaveCredentialFunction;
|
||||
const mailer = mockInstance(UserManagementMailer);
|
||||
@@ -73,6 +74,7 @@ beforeEach(async () => {
|
||||
);
|
||||
|
||||
authOwnerAgent = testServer.authAgentFor(owner);
|
||||
authMemberAgent = testServer.authAgentFor(member);
|
||||
authAnotherMemberAgent = testServer.authAgentFor(anotherMember);
|
||||
|
||||
saveCredential = affixRoleToSaveCredential('credential:owner');
|
||||
@@ -978,6 +980,128 @@ describe('PUT /credentials/:id/share', () => {
|
||||
|
||||
config.set('userManagement.emails.mode', 'smtp');
|
||||
});
|
||||
|
||||
test('member should be able to share from personal project to team project that member has access to', async () => {
|
||||
const savedCredential = await saveCredential(randomCredentialPayload(), { user: member });
|
||||
|
||||
const testProject = await createTeamProject();
|
||||
await linkUserToProject(member, testProject, 'project:editor');
|
||||
|
||||
const response = await authMemberAgent
|
||||
.put(`/credentials/${savedCredential.id}/share`)
|
||||
.send({ shareWithIds: [testProject.id] });
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data).toBeUndefined();
|
||||
|
||||
const shares = await getCredentialSharings(savedCredential);
|
||||
const testShare = shares.find((s) => s.projectId === testProject.id);
|
||||
expect(testShare).not.toBeUndefined();
|
||||
expect(testShare?.role).toBe('credential:user');
|
||||
});
|
||||
|
||||
test('member should be able to share from team project to personal project', async () => {
|
||||
const testProject = await createTeamProject(undefined, member);
|
||||
|
||||
const savedCredential = await saveCredential(randomCredentialPayload(), {
|
||||
project: testProject,
|
||||
});
|
||||
|
||||
const response = await authMemberAgent
|
||||
.put(`/credentials/${savedCredential.id}/share`)
|
||||
.send({ shareWithIds: [anotherMemberPersonalProject.id] });
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data).toBeUndefined();
|
||||
|
||||
const shares = await getCredentialSharings(savedCredential);
|
||||
const testShare = shares.find((s) => s.projectId === anotherMemberPersonalProject.id);
|
||||
expect(testShare).not.toBeUndefined();
|
||||
expect(testShare?.role).toBe('credential:user');
|
||||
});
|
||||
|
||||
test('member should be able to share from team project to team project that member has access to', async () => {
|
||||
const testProject = await createTeamProject(undefined, member);
|
||||
const testProject2 = await createTeamProject();
|
||||
await linkUserToProject(member, testProject2, 'project:editor');
|
||||
|
||||
const savedCredential = await saveCredential(randomCredentialPayload(), {
|
||||
project: testProject,
|
||||
});
|
||||
|
||||
const response = await authMemberAgent
|
||||
.put(`/credentials/${savedCredential.id}/share`)
|
||||
.send({ shareWithIds: [testProject2.id] });
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data).toBeUndefined();
|
||||
|
||||
const shares = await getCredentialSharings(savedCredential);
|
||||
const testShare = shares.find((s) => s.projectId === testProject2.id);
|
||||
expect(testShare).not.toBeUndefined();
|
||||
expect(testShare?.role).toBe('credential:user');
|
||||
});
|
||||
|
||||
test('admins should be able to share from any team project to any team project ', async () => {
|
||||
const testProject = await createTeamProject();
|
||||
const testProject2 = await createTeamProject();
|
||||
|
||||
const savedCredential = await saveCredential(randomCredentialPayload(), {
|
||||
project: testProject,
|
||||
});
|
||||
|
||||
const response = await authOwnerAgent
|
||||
.put(`/credentials/${savedCredential.id}/share`)
|
||||
.send({ shareWithIds: [testProject2.id] });
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data).toBeUndefined();
|
||||
|
||||
const shares = await getCredentialSharings(savedCredential);
|
||||
const testShare = shares.find((s) => s.projectId === testProject2.id);
|
||||
expect(testShare).not.toBeUndefined();
|
||||
expect(testShare?.role).toBe('credential:user');
|
||||
});
|
||||
|
||||
test("admins should be able to share from any team project to any user's personal project ", async () => {
|
||||
const testProject = await createTeamProject();
|
||||
|
||||
const savedCredential = await saveCredential(randomCredentialPayload(), {
|
||||
project: testProject,
|
||||
});
|
||||
|
||||
const response = await authOwnerAgent
|
||||
.put(`/credentials/${savedCredential.id}/share`)
|
||||
.send({ shareWithIds: [memberPersonalProject.id] });
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data).toBeUndefined();
|
||||
|
||||
const shares = await getCredentialSharings(savedCredential);
|
||||
const testShare = shares.find((s) => s.projectId === memberPersonalProject.id);
|
||||
expect(testShare).not.toBeUndefined();
|
||||
expect(testShare?.role).toBe('credential:user');
|
||||
});
|
||||
|
||||
test('admins should be able to share from any personal project to any team project ', async () => {
|
||||
const testProject = await createTeamProject();
|
||||
|
||||
const savedCredential = await saveCredential(randomCredentialPayload(), {
|
||||
user: member,
|
||||
});
|
||||
|
||||
const response = await authOwnerAgent
|
||||
.put(`/credentials/${savedCredential.id}/share`)
|
||||
.send({ shareWithIds: [testProject.id] });
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data).toBeUndefined();
|
||||
|
||||
const shares = await getCredentialSharings(savedCredential);
|
||||
const testShare = shares.find((s) => s.projectId === testProject.id);
|
||||
expect(testShare).not.toBeUndefined();
|
||||
expect(testShare?.role).toBe('credential:user');
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /:credentialId/transfer', () => {
|
||||
|
||||
@@ -142,7 +142,13 @@ describe('GET /credentials', () => {
|
||||
// Team cred
|
||||
expect(cred1.id).toBe(savedCredential1.id);
|
||||
expect(cred1.scopes).toEqual(
|
||||
['credential:move', 'credential:read', 'credential:update', 'credential:delete'].sort(),
|
||||
[
|
||||
'credential:move',
|
||||
'credential:read',
|
||||
'credential:update',
|
||||
'credential:share',
|
||||
'credential:delete',
|
||||
].sort(),
|
||||
);
|
||||
|
||||
// Shared cred
|
||||
@@ -389,6 +395,21 @@ describe('GET /credentials', () => {
|
||||
expect(response2.body.data).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('should return homeProject when filtering credentials by projectId', async () => {
|
||||
const project = await createTeamProject(undefined, member);
|
||||
const credential = await saveCredential(payload(), { user: owner, role: 'credential:owner' });
|
||||
await shareCredentialWithProjects(credential, [project]);
|
||||
|
||||
const response: GetAllResponse = await testServer
|
||||
.authAgentFor(member)
|
||||
.get('/credentials')
|
||||
.query(`filter={ "projectId": "${project.id}" }`)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data).toHaveLength(1);
|
||||
expect(response.body.data[0].homeProject).not.toBeNull();
|
||||
});
|
||||
|
||||
test('should return all credentials in a team project that member is part of', async () => {
|
||||
const teamProjectWithMember = await createTeamProject('Team Project With member', owner);
|
||||
void (await linkUserToProject(member, teamProjectWithMember, 'project:editor'));
|
||||
|
||||
Reference in New Issue
Block a user