Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: RBAC #8922

Merged
merged 212 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
212 commits
Select commit Hold shift + click to select a range
54ac2df
feat: Add AND mask to hasScope (#8379)
valya Jan 22, 2024
36bd53a
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Jan 22, 2024
be99072
Merge remote-tracking branch 'origin/master' into feature/rbac
netroy Jan 24, 2024
c85bdc4
feat: Add project and project relations entities (#8421)
valya Jan 24, 2024
1c7784a
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Jan 29, 2024
5d370f3
feat: Add project ID column to shared_* tables (#8476)
valya Jan 31, 2024
1e7a2c4
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Jan 31, 2024
de3940b
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Feb 5, 2024
ed1b9d2
Merge branch 'master' into feature/rbac
despairblue Feb 7, 2024
4d0b00d
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Feb 8, 2024
fb667ed
feat(core): Link all shared credentials to the personal project of th…
despairblue Feb 8, 2024
2c416e5
feat(core): Link all shared workflows to the personal project of the …
despairblue Feb 8, 2024
dc689b0
feat: Create personal project when inviting a user (#8550)
valya Feb 9, 2024
a9edfca
fix: Fix MFA end to end tests (#8605)
despairblue Feb 12, 2024
2753800
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Feb 12, 2024
ac8b392
fix: Import name change for typeorm fork
valya Feb 14, 2024
ec56d32
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Feb 15, 2024
42ce5fa
fix: Broken migration for create project (no-changelog) (#8645)
valya Feb 15, 2024
daca181
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Feb 16, 2024
94f909c
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Feb 17, 2024
bc1aa30
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Feb 19, 2024
674abd8
refactor(core): Introduce `@GlobalScope()` and `@ProjectScope()` deco…
ivov Feb 19, 2024
655ada8
fix: ProjectRepository.getPersonalProjectForUser[OrFail] not taking t…
despairblue Feb 20, 2024
49c378f
feat: Projects API (#8649)
valya Feb 20, 2024
c56a63f
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Feb 20, 2024
bd541ec
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Feb 21, 2024
ba394f7
feat: Change routes for RBAC (#8623)
cstuncsik Feb 21, 2024
da217e4
feat(editor): Add projects menu (#8688)
cstuncsik Feb 21, 2024
c657bc0
feat(editor): Add projects store and API (#8692)
cstuncsik Feb 21, 2024
70e6231
feat(core): Allow creating workflows in other projects than the perso…
despairblue Feb 21, 2024
1fd7b1e
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Feb 22, 2024
37aed15
feat(editor): Add project page tab navigation (#8712)
cstuncsik Feb 23, 2024
323a685
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Feb 23, 2024
7665213
feat: Allow editing team project (#8727)
krynble Feb 23, 2024
f1d0347
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Feb 27, 2024
d2c217c
feat: Add get project API and merge project patch APIs (#8748)
valya Feb 27, 2024
d22f205
feat: Add role API (no-changelog) (#8718)
valya Feb 27, 2024
5694fc3
test: Update fix test that broke due to the global:owner having the c…
despairblue Feb 27, 2024
7e9daa2
feat(editor): Filter and create workflows and credentials by projectI…
cstuncsik Feb 27, 2024
8a71a67
fix: Project API GET (no-changelog) (#8753)
valya Feb 27, 2024
830f386
feat: Allow filtering credentials and workflows by project ID (#8740)
despairblue Feb 28, 2024
33b37e0
feat: Return project related information from `GET /workflows` and `G…
despairblue Feb 28, 2024
e38aa6c
Merge remote-tracking branch 'origin/master' into feature/rbac
netroy Feb 28, 2024
04fdc9e
Merge remote-tracking branch 'origin/master' into feature/rbac
netroy Feb 28, 2024
d52ff24
feat(core): Allow creating credentials in other projects than the per…
despairblue Feb 29, 2024
bcd6dc9
fix: Fix E2E test
cstuncsik Feb 29, 2024
00a891f
Merge branch 'feature/rbac' of github.com:n8n-io/n8n into feature/rbac
cstuncsik Feb 29, 2024
33c049d
feat(editor): Add project settings page (#8695)
cstuncsik Mar 1, 2024
93a0f81
feat: Make `GET /workflows` return all workflows the user is allowed …
despairblue Mar 1, 2024
baa208e
feat(editor): Show home project in card components (#8785)
cstuncsik Mar 1, 2024
6d69595
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Mar 5, 2024
6eefa0c
feat: Make `GET /credentials` return all credentials the user is allo…
despairblue Mar 6, 2024
418a683
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Mar 6, 2024
c9e1fc9
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Mar 6, 2024
a6ae83f
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Mar 8, 2024
05c7a70
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Mar 11, 2024
a0657ac
feat: Remove user from SharedCredentials and update most credential r…
despairblue Mar 12, 2024
d7d2ba4
feat(editor): Add project sharing (#8814)
cstuncsik Mar 13, 2024
e54c147
feat(editor): Add simple project deletion (#8890)
cstuncsik Mar 14, 2024
c110191
refactor(core): Ensure runtime checks rely on roles and scopes (#8589)
ivov Mar 15, 2024
372a9fd
feat(core): Make sure that `SharedWorkflow.userId` is not used anymor…
despairblue Mar 15, 2024
add6bf3
fix(editor): Get projectId properly
cstuncsik Mar 18, 2024
52ca3d3
fix(editor): Get projectId properly
cstuncsik Mar 18, 2024
75d7d15
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Mar 18, 2024
5dcea13
fix: Fix lock file after conflict
cstuncsik Mar 18, 2024
5567067
fix: Fix unit test after conflict
cstuncsik Mar 18, 2024
a71994b
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Mar 19, 2024
7cd65de
fix(editor): Fix MenuItem after conflicts
cstuncsik Mar 19, 2024
0dcc22a
fix: Fix project settings unit test
cstuncsik Mar 19, 2024
e0cc72e
fix: Fix workflows store unit test
cstuncsik Mar 19, 2024
e7165fe
fix: Fix type error
cstuncsik Mar 19, 2024
928e48d
feat(core): Implement project deletion (#8904)
despairblue Mar 19, 2024
c114536
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Mar 20, 2024
8af7fef
fix(core): Work around flaky unit tests when using sqlite with a conn…
despairblue Mar 20, 2024
e28ddae
feat(core): Allow migrating workflows and credentials when deleting p…
despairblue Mar 21, 2024
7b6b0af
test(core): Add test that makes sure the api returns a 403 when tryin…
despairblue Mar 21, 2024
c8f7c2f
fix(editor): Decouple project sharing component from project type (#8…
cstuncsik Mar 21, 2024
3077d53
feat(core): Change api for deleting team projects to match FE expecta…
despairblue Mar 21, 2024
71341f7
fix(editor): Add projects select to project delete dialog (#8937)
cstuncsik Mar 21, 2024
998c841
fix(editor): Reset selected project is wipe is selected
cstuncsik Mar 22, 2024
7a4c5eb
feat: Add includeScopes query param to credentials, workflows, and pr…
valya Mar 25, 2024
79eec50
feat(core): Refactor user deletion to support projects (#8958)
despairblue Mar 25, 2024
fcfdcd6
fix(editor): Load credentials after workflow is loaded (#8974)
cstuncsik Mar 27, 2024
0782726
fix(editor): Use projects instead of users in resource filter (#8964)
cstuncsik Mar 27, 2024
01502ae
fix(editor): Transfer data to personal project instead of user when d…
cstuncsik Mar 27, 2024
1591081
fix(editor): Add scopes to resources (#8977)
cstuncsik Mar 27, 2024
0b7526a
feat(core): Create and keep names of personal projects up to date (#8…
despairblue Mar 27, 2024
f1da02b
feat(core): Return all team projects if the user has global `project:…
despairblue Mar 28, 2024
2334a8b
fix(core): Fail correctly when trying to transfer resources to the us…
despairblue Mar 28, 2024
9fe88fc
fix(editor): Make only projects scrollable in the sidebar (#8984)
cstuncsik Mar 28, 2024
5bbbd41
fix(editor): Remove share button in when resource is in team project
cstuncsik Mar 28, 2024
1663cf6
fix(editor): Fix sharing permission for workflow
cstuncsik Mar 28, 2024
cb5b1f1
fix(editor): No need to augment workflow with 'ownedBy'
cstuncsik Mar 28, 2024
2d06623
fix(editor): Remove share button from workflow editor
cstuncsik Mar 28, 2024
f1bc68d
fix(editor): Some cleanup of old `ownedBy` settings
cstuncsik Mar 28, 2024
396f72b
fix(editor): Fix updating project in navigation when edited in settings
cstuncsik Mar 28, 2024
4921184
fix: Front end fixes to permissions, project sharing, and layout (#8998)
valya Mar 28, 2024
021bd89
feat: Use scopes on the public API (#8969)
valya Apr 1, 2024
79eb17a
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Apr 1, 2024
cca7d74
merge master into rbac
despairblue Apr 8, 2024
c187630
fix unit test
despairblue Apr 8, 2024
64e0f58
fix(editor): Resolve conflicts
cstuncsik Apr 8, 2024
1d52253
Merge branch 'feature/rbac' of github.com:n8n-io/n8n into feature/rbac
cstuncsik Apr 8, 2024
e9b6f37
fix lint issues
despairblue Apr 8, 2024
a88789f
fix(editor): Lint fix
cstuncsik Apr 8, 2024
2102b3b
Revert "fix(editor): Lint fix"
cstuncsik Apr 8, 2024
bae6f0c
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 8, 2024
fc9d59a
fix(editor): Lintfix
cstuncsik Apr 8, 2024
170b07f
feat(core): Create names for personal projects in one place and resus…
despairblue Apr 8, 2024
72689a5
fix(core): Don't fail when asking for an execution with sharing enabl…
despairblue Apr 9, 2024
145dd59
fix(core): Create personal project when a user is created via LDAP (#…
despairblue Apr 9, 2024
37af3a0
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 9, 2024
4fb67a3
fix(editor): Fix projects navigation element layout
cstuncsik Apr 9, 2024
af7a3c5
fix(editor): Fix project API (use 'makeRestApiRequest')
cstuncsik Apr 9, 2024
f7cc4c8
fix(editor): Show project navigation separator elements only if feasible
cstuncsik Apr 9, 2024
a664e27
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 9, 2024
a250586
fix: Remove scope filter on projects APIs (#9106)
valya Apr 10, 2024
48d7ffd
Merge remote-tracking branch 'origin/master' into feature/rbac
valya Apr 10, 2024
afb38c6
feat: Enable External Secrets for team projects with an instance owne…
valya Apr 10, 2024
3a489ff
Merge remote-tracking branch 'origin/master' into feature/rbac
despairblue Apr 18, 2024
045cf43
fix tests
despairblue Apr 18, 2024
18df8f1
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 19, 2024
b558a7e
fix(cli): Fix executions controller after conflict
cstuncsik Apr 19, 2024
f59941d
fix(editor): Fix E2E tests
cstuncsik Apr 19, 2024
1462360
fix(editor): Make E2E work with closed main sidebar
cstuncsik Apr 22, 2024
c2c2dce
fix(editor): Reenable all tests in user management
cstuncsik Apr 22, 2024
b50a419
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 23, 2024
1456948
fix(editor): Remove 'only' from e2e test
cstuncsik Apr 23, 2024
6c9018e
feat(core): Allow assigning imported credentials and workflows to pro…
despairblue Apr 23, 2024
3ef293c
fix(core): Truncate project and project relation table inbetween e2e …
despairblue Apr 23, 2024
b5d9078
fix(editor): Remove loading credentials in workflows list page
cstuncsik Apr 23, 2024
2d39f74
fix(editor): Fix projects e2e test
cstuncsik Apr 23, 2024
b01aad0
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 23, 2024
e4269c4
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik Apr 24, 2024
693b7dc
fix(editor): Fix variable search
cstuncsik Apr 24, 2024
cf164fe
fix(editor): Fix type error in e2e test
cstuncsik Apr 24, 2024
a010f19
test(core): Re-enable and amend test for `n8n user-management:reset` …
despairblue Apr 24, 2024
f1beffd
fix(editor): Fix variables e2e test
cstuncsik Apr 24, 2024
32ee6f4
Merge branch 'feature/rbac' of github.com:n8n-io/n8n into feature/rbac
cstuncsik Apr 24, 2024
2c784c8
fix(editor): Wait for login in e2e test
cstuncsik Apr 24, 2024
437f8f3
fix(editor): Fix getting variable permissions
cstuncsik Apr 24, 2024
4aed020
feat: Update source control to work with projects (#9202)
valya Apr 24, 2024
3df6b80
fix(editor): Take project permissions into account when checking reso…
cstuncsik Apr 25, 2024
ac7bd64
feat(core): Make `project.name` required (#9214)
despairblue Apr 25, 2024
d78892c
fix: Get workflow API sending shared data to the frontend (#9219)
valya Apr 25, 2024
b7e050d
fix(editor): RBAC FE fixes (#9216)
cstuncsik Apr 25, 2024
68b6e7b
fix: Return scopes on the personal the project endpoint (#9218)
valya Apr 25, 2024
269b16f
feat(core): Return `homeProject` from `POST /workflow` (#9242)
despairblue Apr 29, 2024
70fb5f4
fix(editor): Check also personal project scopes when adding credential
cstuncsik Apr 29, 2024
4558303
fix(core): Fix regression, `POST /workflows` not returning tags anymo…
despairblue Apr 29, 2024
69d8988
fix(editor): RBAC FE fixes 2 (#9226)
cstuncsik Apr 29, 2024
0f75ebf
fix(core): Create personal projects for users created via LDAP (#9256)
despairblue Apr 30, 2024
aa01dee
feat(core): Down migration for RBAC (#9235)
despairblue Apr 30, 2024
80445cd
Merge remote-tracking branch 'origin/master' into feature/rbac
valya May 1, 2024
da1ce5b
fix: Sharing credentials and workflows with pending users (#9272)
valya May 2, 2024
b2ab861
fix: Members not being able to test credentials with external secrets…
valya May 2, 2024
1076cbe
fix: Source Control import creating project without specifying type (…
valya May 2, 2024
4667957
fix(editor): RBAC FE fixes and UI/UX tweaks (#9278)
cstuncsik May 2, 2024
6949989
fix: Return scopes on more resource APIs (#9128)
valya May 3, 2024
916a0aa
remove stray debugger statement
despairblue May 3, 2024
9b673f7
feat(core): Allow transfering/deleting workflows and credentials when…
despairblue May 3, 2024
1581dc2
feat: RBAC UX tweaks (#9303)
cstuncsik May 6, 2024
3db25dd
feat: Add backend license checks for RBAC (#9271)
valya May 6, 2024
afffa36
fix(core): Create a personal project if a user signs up via SAML (#9310)
despairblue May 6, 2024
8295160
--wip--
despairblue May 8, 2024
d231e16
Merge remote-tracking branch 'origin/master' into feature/rbac
despairblue May 8, 2024
bef3b07
Revert "--wip--"
despairblue May 8, 2024
3138cfc
fix remaining merge issues
despairblue May 8, 2024
b57abb1
feat: Add a project count API (#9333)
valya May 8, 2024
9183af8
fix(core): Make `project.type` type match in migration and entity (#9…
despairblue May 8, 2024
2fa8df1
fix(core): Fix `RangeError: Maximum call stack size exceeded` under c…
despairblue May 8, 2024
13fde49
fix(core): Deadlock when sharing credentials and workflows when using…
despairblue May 8, 2024
8ee3bab
refactor: Remove unused roles (#9347)
krynble May 8, 2024
e2408ce
fix(core): Fix MySQL tests timeout issues (#9331)
despairblue May 8, 2024
c91d46a
fix: Source Control import failing due to creating multiple of a proj…
valya May 9, 2024
4c2ef5f
fix(editor): Update FE telemetry for RBAC (#9343)
cstuncsik May 9, 2024
b304665
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik May 9, 2024
e66d22c
Merge branch 'feature/rbac' of github.com:n8n-io/n8n into feature/rbac
cstuncsik May 9, 2024
4eb51be
fix(editor): Fix workflows.store after conflict
cstuncsik May 9, 2024
53d812f
fix(editor): Fix workflows.store after conflict
cstuncsik May 9, 2024
920868f
fix(editor): Fix workflows.store after conflict
cstuncsik May 9, 2024
c1eb8e1
fix(editor): Fix workflows.store after conflict
cstuncsik May 9, 2024
0b5446e
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik May 9, 2024
fa17987
feat: RBAC backend Telemetry (#9351)
valya May 10, 2024
e76193f
fix: Refactor source control import to run workflow by workflow (#9354)
krynble May 10, 2024
d9d2133
fix(editor): Update paywall states for RBAC (#9335)
cstuncsik May 10, 2024
f1310bd
Merge branch 'master' into feature/rbac
krynble May 10, 2024
5cd481c
feat(core): Extract UserSubscriber into it's own module breaking depe…
despairblue May 13, 2024
1485806
fix(core): Fix project quota not being applied correctly (#9376)
despairblue May 13, 2024
3c7fd06
refactor: Require project admin role for project creation (#9381)
krynble May 13, 2024
be4360d
fix(editor): RBAC Frontend fixes (#9364)
cstuncsik May 14, 2024
4361ea1
Merge remote-tracking branch 'origin/master' into feature/rbac
netroy May 14, 2024
7b704a3
Merge remote-tracking branch 'origin/master' into feature/rbac
netroy May 14, 2024
3bd984b
fix(editor): Add project settings change telemetry events (#9389)
cstuncsik May 14, 2024
85be084
fix(editor): RBAC frontend fixes next round (#9393)
cstuncsik May 14, 2024
14d4f24
fix(editor): Update caller policy select (#9404)
cstuncsik May 15, 2024
e1f98e1
fix(editor): Fetching credentials by correct project id (#9407)
cstuncsik May 15, 2024
e3709f5
fix(editor): Fix sharing when new credential is created
cstuncsik May 15, 2024
a640de4
fix(core): Return tags from `GET /workflows/:id` (#9408)
despairblue May 15, 2024
681c2bf
test(editor): Fix failing sharing e2e tests partially (#9417)
despairblue May 15, 2024
0f9fca6
fix(editor): RBAC frontend fixes (#9416)
cstuncsik May 16, 2024
c546127
fix(editor): Update user filtering on user deletion
cstuncsik May 16, 2024
3137dd3
fix(editor): Remove new credential creation success toast message if …
cstuncsik May 16, 2024
808d30a
refactor: Allow admins and instance owners to use any credentials in …
krynble May 16, 2024
b571162
fix(editor): Fix tags visibility in workflow header
cstuncsik May 16, 2024
f6f967c
fix(editor): Fix sharing e2e test
cstuncsik May 16, 2024
fd4d268
Merge branch 'feature/rbac' of github.com:n8n-io/n8n into feature/rbac
cstuncsik May 16, 2024
2073285
fix(core): Send email again when a workflow or credential is shared (…
despairblue May 16, 2024
fec50d3
fix(editor): Load credentials before workflow
cstuncsik May 17, 2024
8c3ef82
Merge branch 'feature/rbac' of github.com:n8n-io/n8n into feature/rbac
cstuncsik May 17, 2024
dd6f125
Merge remote-tracking branch 'origin/master' into feature/rbac
cstuncsik May 17, 2024
14b2b0f
fix: Credential testing for sharees (#9426)
krynble May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions cypress/composables/projects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const getHomeButton = () => cy.getByTestId('project-home-menu-item');
export const getMenuItems = () => cy.getByTestId('project-menu-item');
export const getAddProjectButton = () => cy.getByTestId('add-project-menu-item');
export const getProjectTabs = () => cy.getByTestId('project-tabs').find('a');
export const getProjectTabWorkflows = () => getProjectTabs().filter('a[href$="/workflows"]');
export const getProjectTabCredentials = () => getProjectTabs().filter('a[href$="/credentials"]');
export const getProjectTabSettings = () => getProjectTabs().filter('a[href$="/settings"]');
export const getProjectSettingsSaveButton = () => cy.getByTestId('project-settings-save-button');
export const getProjectSettingsCancelButton = () =>
cy.getByTestId('project-settings-cancel-button');
export const getProjectSettingsDeleteButton = () =>
cy.getByTestId('project-settings-delete-button');
export const getProjectMembersSelect = () => cy.getByTestId('project-members-select');

export const addProjectMember = (email: string) => {
getProjectMembersSelect().click();
getProjectMembersSelect().get('.el-select-dropdown__item').contains(email.toLowerCase()).click();
};
6 changes: 3 additions & 3 deletions cypress/e2e/17-sharing.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const workflowSharingModal = new WorkflowSharingModal();
const ndv = new NDV();

describe('Sharing', { disableAutoLogin: true }, () => {
before(() => cy.enableFeature('sharing', true));
before(() => cy.enableFeature('sharing'));

let workflowW2Url = '';
it('should create C1, W1, W2, share W1 with U3, as U2', () => {
Expand Down Expand Up @@ -171,11 +171,11 @@ describe('Sharing', { disableAutoLogin: true }, () => {
cy.get('input').should('not.have.length');
credentialsModal.actions.changeTab('Sharing');
cy.contains(
'You can view this credential because you have permission to read and share',
'Sharing a credential allows people to use it in their workflows. They cannot access credential details.',
).should('be.visible');

credentialsModal.getters.usersSelect().click();
cy.getByTestId('user-email')
cy.getByTestId('project-sharing-info')
.filter(':visible')
.should('have.length', 3)
.contains(INSTANCE_ADMIN.email)
Expand Down
10 changes: 5 additions & 5 deletions cypress/e2e/19-execution.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ describe('Execution', () => {

workflowPage.getters.clearExecutionDataButton().should('be.visible');

cy.intercept('POST', '/rest/workflows/run').as('workflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');

workflowPage.getters
.canvasNodeByName('do something with them')
Expand All @@ -525,7 +525,7 @@ describe('Execution', () => {

workflowPage.getters.zoomToFitButton().click();

cy.intercept('POST', '/rest/workflows/run').as('workflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');

workflowPage.getters
.canvasNodeByName('If')
Expand All @@ -545,7 +545,7 @@ describe('Execution', () => {

workflowPage.getters.clearExecutionDataButton().should('be.visible');

cy.intercept('POST', '/rest/workflows/run').as('workflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');

workflowPage.getters
.canvasNodeByName('NoOp2')
Expand Down Expand Up @@ -576,7 +576,7 @@ describe('Execution', () => {
'My test workflow',
);

cy.intercept('POST', '/rest/workflows/run').as('workflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');

workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
Expand All @@ -599,7 +599,7 @@ describe('Execution', () => {
'My test workflow',
);

cy.intercept('POST', '/rest/workflows/run').as('workflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');

workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
Expand Down
7 changes: 4 additions & 3 deletions cypress/e2e/23-variables.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const variablesPage = new VariablesPage();

describe('Variables', () => {
it('should show the unlicensed action box when the feature is disabled', () => {
cy.disableFeature('variables', false);
cy.disableFeature('variables');
cy.visit(variablesPage.url);

variablesPage.getters.unavailableResourcesList().should('be.visible');
Expand All @@ -18,14 +18,15 @@ describe('Variables', () => {

beforeEach(() => {
cy.intercept('GET', '/rest/variables').as('loadVariables');
cy.intercept('GET', '/rest/login').as('login');

cy.visit(variablesPage.url);
cy.wait(['@loadVariables', '@loadSettings']);
cy.wait(['@loadVariables', '@loadSettings', '@login']);
});

it('should show the licensed action box when the feature is enabled', () => {
variablesPage.getters.emptyResourcesList().should('be.visible');
variablesPage.getters.createVariableButton().should('be.visible');
variablesPage.getters.emptyResourcesListNewVariableButton().should('be.visible');
});

it('should create a new variable using empty state row', () => {
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/28-debug.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('Debug', () => {
it('should be able to debug executions', () => {
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');
cy.intercept('GET', '/rest/executions/*').as('getExecution');
cy.intercept('POST', '/rest/workflows/run').as('postWorkflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('postWorkflowRun');

cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password });

Expand Down
33 changes: 21 additions & 12 deletions cypress/e2e/29-templates.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('Workflow templates', () => {
beforeEach(() => {
cy.intercept('GET', '**/rest/settings', (req) => {
// Disable cache
delete req.headers['if-none-match']
delete req.headers['if-none-match'];
req.reply((res) => {
if (res.body.data) {
// Disable custom templates host if it has been overridden by another intercept
Expand All @@ -22,25 +22,34 @@ describe('Workflow templates', () => {

it('Opens website when clicking templates sidebar link', () => {
cy.visit(workflowsPage.url);
mainSidebar.getters.menuItem('Templates').should('be.visible');
mainSidebar.getters.templates().should('be.visible');
// Templates should be a link to the website
mainSidebar.getters.templates().parent('a').should('have.attr', 'href').and('include', 'https://n8n.io/workflows');
mainSidebar.getters
.templates()
.parent('a')
.should('have.attr', 'href')
.and('include', 'https://n8n.io/workflows');
// Link should contain instance address and n8n version
mainSidebar.getters.templates().parent('a').then(($a) => {
const href = $a.attr('href');
const params = new URLSearchParams(href);
// Link should have all mandatory parameters expected on the website
expect(decodeURIComponent(`${params.get('utm_instance')}`)).to.include(window.location.origin);
expect(params.get('utm_n8n_version')).to.match(/[0-9]+\.[0-9]+\.[0-9]+/);
expect(params.get('utm_awc')).to.match(/[0-9]+/);
});
mainSidebar.getters
.templates()
.parent('a')
.then(($a) => {
const href = $a.attr('href');
const params = new URLSearchParams(href);
// Link should have all mandatory parameters expected on the website
expect(decodeURIComponent(`${params.get('utm_instance')}`)).to.include(
window.location.origin,
);
expect(params.get('utm_n8n_version')).to.match(/[0-9]+\.[0-9]+\.[0-9]+/);
expect(params.get('utm_awc')).to.match(/[0-9]+/);
});
mainSidebar.getters.templates().parent('a').should('have.attr', 'target', '_blank');
});

it('Redirects to website when visiting templates page directly', () => {
cy.visit(templatesPage.url);
cy.origin('https://n8n.io', () => {
cy.url().should('include', 'https://n8n.io/workflows');
})
});
});
});
6 changes: 3 additions & 3 deletions cypress/e2e/30-editor-after-route-changes.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ describe('Editor actions should work', () => {
it('after switching between Editor and Debug', () => {
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');
cy.intercept('GET', '/rest/executions/*').as('getExecution');
cy.intercept('POST', '/rest/workflows/run').as('postWorkflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('postWorkflowRun');

editWorkflowAndDeactivate();
workflowPage.actions.executeWorkflow();
Expand Down Expand Up @@ -196,9 +196,9 @@ describe('Editor zoom should work after route changes', () => {
cy.intercept('GET', '/rest/workflow-history/workflow/*/version/*').as('getVersion');
cy.intercept('GET', '/rest/workflow-history/workflow/*').as('getHistory');
cy.intercept('GET', '/rest/users').as('getUsers');
cy.intercept('GET', '/rest/workflows').as('getWorkflows');
cy.intercept('GET', '/rest/workflows?*').as('getWorkflows');
cy.intercept('GET', '/rest/active-workflows').as('getActiveWorkflows');
cy.intercept('GET', '/rest/credentials').as('getCredentials');
cy.intercept('GET', '/rest/credentials?*').as('getCredentials');

switchBetweenEditorAndHistory();
zoomInAndCheckNodes();
Expand Down
151 changes: 151 additions & 0 deletions cypress/e2e/39-projects.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { INSTANCE_ADMIN, INSTANCE_MEMBERS } from '../constants';
import { WorkflowsPage, WorkflowPage, CredentialsModal, CredentialsPage } from '../pages';
import * as projects from '../composables/projects';

const workflowsPage = new WorkflowsPage();
const workflowPage = new WorkflowPage();
const credentialsPage = new CredentialsPage();
const credentialsModal = new CredentialsModal();

describe('Projects', () => {
beforeEach(() => {
cy.resetDatabase();
cy.enableFeature('advancedPermissions');
cy.enableFeature('projectRole:admin');
cy.enableFeature('projectRole:editor');
cy.changeQuota('maxTeamProjects', -1);
});

it('should handle workflows and credentials', () => {
cy.signin(INSTANCE_ADMIN);
cy.visit(workflowsPage.url);
workflowsPage.getters.workflowCards().should('not.have.length');

workflowsPage.getters.newWorkflowButtonCard().click();

cy.intercept('POST', '/rest/workflows').as('workflowSave');
workflowPage.actions.saveWorkflowOnButtonClick();

cy.wait('@workflowSave').then((interception) => {
expect(interception.request.body).not.to.have.property('projectId');
});

projects.getHomeButton().click();
projects.getProjectTabs().should('have.length', 2);

projects.getProjectTabCredentials().click();
credentialsPage.getters.credentialCards().should('not.have.length');

credentialsPage.getters.emptyListCreateCredentialButton().click();
credentialsModal.getters.newCredentialModal().should('be.visible');
credentialsModal.getters.newCredentialTypeSelect().should('be.visible');
credentialsModal.getters.newCredentialTypeOption('Notion API').click();
credentialsModal.getters.newCredentialTypeButton().click();
credentialsModal.getters.connectionParameter('Internal Integration Secret').type('1234567890');
credentialsModal.actions.setName('My awesome Notion account');

cy.intercept('POST', '/rest/credentials').as('credentialSave');
credentialsModal.actions.save();
cy.wait('@credentialSave').then((interception) => {
expect(interception.request.body).not.to.have.property('projectId');
});

credentialsModal.actions.close();
credentialsPage.getters.credentialCards().should('have.length', 1);

projects.getProjectTabWorkflows().click();
workflowsPage.getters.workflowCards().should('have.length', 1);

projects.getMenuItems().should('not.have.length');

cy.intercept('POST', '/rest/projects').as('projectCreate');
projects.getAddProjectButton().click();
cy.wait('@projectCreate');
projects.getMenuItems().should('have.length', 1);
projects.getProjectTabs().should('have.length', 3);

cy.get('input[name="name"]').type('Development');
projects.addProjectMember(INSTANCE_MEMBERS[0].email);

cy.intercept('PATCH', '/rest/projects/*').as('projectSettingsSave');
projects.getProjectSettingsSaveButton().click();
cy.wait('@projectSettingsSave').then((interception) => {
expect(interception.request.body).to.have.property('name').and.to.equal('Development');
expect(interception.request.body).to.have.property('relations').to.have.lengthOf(2);
});

projects.getMenuItems().first().click();
workflowsPage.getters.workflowCards().should('not.have.length');
projects.getProjectTabs().should('have.length', 3);

workflowsPage.getters.newWorkflowButtonCard().click();

cy.intercept('POST', '/rest/workflows').as('workflowSave');
workflowPage.actions.saveWorkflowOnButtonClick();

cy.wait('@workflowSave').then((interception) => {
expect(interception.request.body).to.have.property('projectId');
});

projects.getMenuItems().first().click();

projects.getProjectTabCredentials().click();
credentialsPage.getters.credentialCards().should('not.have.length');

credentialsPage.getters.emptyListCreateCredentialButton().click();
credentialsModal.getters.newCredentialModal().should('be.visible');
credentialsModal.getters.newCredentialTypeSelect().should('be.visible');
credentialsModal.getters.newCredentialTypeOption('Notion API').click();
credentialsModal.getters.newCredentialTypeButton().click();
credentialsModal.getters.connectionParameter('Internal Integration Secret').type('1234567890');
credentialsModal.actions.setName('My awesome Notion account');

cy.intercept('POST', '/rest/credentials').as('credentialSave');
credentialsModal.actions.save();
cy.wait('@credentialSave').then((interception) => {
expect(interception.request.body).to.have.property('projectId');
});
credentialsModal.actions.close();

projects.getAddProjectButton().click();
projects.getMenuItems().should('have.length', 2);

let projectId: string;
projects.getMenuItems().first().click();
cy.intercept('GET', '/rest/credentials*').as('credentialsList');
projects.getProjectTabCredentials().click();
cy.wait('@credentialsList').then((interception) => {
const url = new URL(interception.request.url);
const queryParams = new URLSearchParams(url.search);
const filter = queryParams.get('filter');
expect(filter).to.be.a('string').and.to.contain('projectId');

if (filter) {
projectId = JSON.parse(filter).projectId;
}
});

projects.getMenuItems().last().click();
cy.intercept('GET', '/rest/credentials*').as('credentialsList');
projects.getProjectTabCredentials().click();
cy.wait('@credentialsList').then((interception) => {
const url = new URL(interception.request.url);
const queryParams = new URLSearchParams(url.search);
const filter = queryParams.get('filter');
expect(filter).to.be.a('string').and.to.contain('projectId');

if (filter) {
expect(JSON.parse(filter).projectId).not.to.equal(projectId);
}
});

projects.getHomeButton().click();
workflowsPage.getters.workflowCards().should('have.length', 2);

cy.intercept('GET', '/rest/credentials*').as('credentialsList');
projects.getProjectTabCredentials().click();
cy.wait('@credentialsList').then((interception) => {
expect(interception.request.url).not.to.contain('filter');
});
});
});
2 changes: 1 addition & 1 deletion cypress/e2e/5-ndv.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ describe('NDV', () => {
});

it('Stop listening for trigger event from NDV', () => {
cy.intercept('POST', '/rest/workflows/run').as('workflowRun');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');
workflowPage.actions.addInitialNodeToCanvas('Local File Trigger', {
keepNdvOpen: true,
action: 'On Changes To A Specific File',
Expand Down
2 changes: 1 addition & 1 deletion cypress/pages/credentials.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BasePage } from './base';

export class CredentialsPage extends BasePage {
url = '/credentials';
url = '/home/credentials';
getters = {
emptyListCreateCredentialButton: () => cy.getByTestId('empty-resources-list').find('button'),
createCredentialButton: () => cy.getByTestId('resources-list-add'),
Expand Down
2 changes: 1 addition & 1 deletion cypress/pages/modals/credentials-modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class CredentialsModal extends BasePage {
credentialInputs: () => cy.getByTestId('credential-connection-parameter'),
menu: () => this.getters.editCredentialModal().get('.menu-container'),
menuItem: (name: string) => this.getters.menu().get('.n8n-menu-item').contains(name),
usersSelect: () => cy.getByTestId('credential-sharing-modal-users-select'),
usersSelect: () => cy.getByTestId('project-sharing-select').filter(':visible'),
testSuccessTag: () => cy.getByTestId('credentials-config-container-test-success'),
};
actions = {
Expand Down
2 changes: 1 addition & 1 deletion cypress/pages/modals/workflow-sharing-modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BasePage } from '../base';
export class WorkflowSharingModal extends BasePage {
getters = {
modal: () => cy.getByTestId('workflowShare-modal', { timeout: 5000 }),
usersSelect: () => cy.getByTestId('workflow-sharing-modal-users-select'),
usersSelect: () => cy.getByTestId('project-sharing-select'),
saveButton: () => cy.getByTestId('workflow-sharing-modal-save-button'),
closeButton: () => this.getters.modal().find('.el-dialog__close').first(),
};
Expand Down
4 changes: 2 additions & 2 deletions cypress/pages/settings-users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export class SettingsUsersPage extends BasePage {
workflowPage.actions.visit();
mainSidebar.actions.goToSettings();
if (isOwner) {
settingsSidebar.getters.menuItem('Users').click();
settingsSidebar.getters.users().click();
cy.url().should('match', new RegExp(this.url));
} else {
settingsSidebar.getters.menuItem('Users').should('not.exist');
settingsSidebar.getters.users().should('not.exist');
// Should be redirected to workflows page if trying to access UM url
cy.visit('/settings/users');
cy.url().should('match', new RegExp(workflowsPage.url));
Expand Down
Loading
Loading