mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix: Expose projectId for remaining Data Table contexts (no-changelog) (#19058)
This commit is contained in:
@@ -15,4 +15,5 @@ export class BaseDynamicParametersRequestDto extends Z.class({
|
||||
credentials: z.record(z.string(), z.any()).optional() satisfies z.ZodType<
|
||||
INodeCredentials | undefined
|
||||
>,
|
||||
projectId: z.string().optional(),
|
||||
}) {}
|
||||
|
||||
@@ -6,5 +6,4 @@ export class ResourceLocatorRequestDto extends BaseDynamicParametersRequestDto.e
|
||||
methodName: z.string(),
|
||||
filter: z.string().optional(),
|
||||
paginationToken: z.string().optional(),
|
||||
projectId: z.string().optional(),
|
||||
}) {}
|
||||
|
||||
@@ -29,10 +29,22 @@ export class DynamicNodeParametersController {
|
||||
path,
|
||||
methodName,
|
||||
loadOptions,
|
||||
projectId,
|
||||
} = payload;
|
||||
|
||||
const additionalData = await getBase(req.user.id, currentNodeParameters);
|
||||
|
||||
if (projectId) {
|
||||
if (await userHasScopes(req.user, ['dataStore:listProject'], false, { projectId })) {
|
||||
// Project ID is currently only added on the additionalData if the user
|
||||
// has data store listing permission for that project. We should consider
|
||||
// turning this into a more general check, but as of now data stores are
|
||||
// the only nodes with project specific resource locators where we want to ensure
|
||||
// that only data stores belonging to their respective projects are shown.
|
||||
additionalData.dataStoreProjectId = projectId;
|
||||
}
|
||||
}
|
||||
|
||||
if (methodName) {
|
||||
return await this.service.getOptionsViaMethodName(
|
||||
methodName,
|
||||
@@ -105,10 +117,22 @@ export class DynamicNodeParametersController {
|
||||
_res: Response,
|
||||
@Body payload: ResourceMapperFieldsRequestDto,
|
||||
) {
|
||||
const { path, methodName, credentials, currentNodeParameters, nodeTypeAndVersion } = payload;
|
||||
const { path, methodName, credentials, currentNodeParameters, nodeTypeAndVersion, projectId } =
|
||||
payload;
|
||||
|
||||
const additionalData = await getBase(req.user.id, currentNodeParameters);
|
||||
|
||||
if (projectId) {
|
||||
if (await userHasScopes(req.user, ['dataStore:listProject'], false, { projectId })) {
|
||||
// Project ID is currently only added on the additionalData if the user
|
||||
// has data store listing permission for that project. We should consider
|
||||
// turning this into a more general check, but as of now data stores are
|
||||
// the only nodes with project specific resource locators where we want to ensure
|
||||
// that only data stores belonging to their respective projects are shown.
|
||||
additionalData.dataStoreProjectId = projectId;
|
||||
}
|
||||
}
|
||||
|
||||
return await this.service.getResourceMappingFields(
|
||||
methodName,
|
||||
path,
|
||||
|
||||
@@ -87,6 +87,7 @@ import CssEditor from './CssEditor/CssEditor.vue';
|
||||
import { useFocusPanelStore } from '@/stores/focusPanel.store';
|
||||
import ExperimentalEmbeddedNdvMapper from '@/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue';
|
||||
import { useExperimentalNdvStore } from '@/components/canvas/experimental/experimentalNdv.store';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
type Picker = { $emit: (arg0: string, arg1: Date) => void };
|
||||
|
||||
@@ -152,6 +153,7 @@ const nodeTypesStore = useNodeTypesStore();
|
||||
const uiStore = useUIStore();
|
||||
const focusPanelStore = useFocusPanelStore();
|
||||
const experimentalNdvStore = useExperimentalNdvStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
|
||||
const expressionLocalResolveCtx = inject(ExpressionLocalResolveContextSymbol, undefined);
|
||||
|
||||
@@ -688,6 +690,7 @@ async function loadRemoteParameterOptions() {
|
||||
loadOptions,
|
||||
currentNodeParameters: resolvedNodeParameters,
|
||||
credentials: node.value.credentials,
|
||||
projectId: projectsStore.currentProjectId,
|
||||
});
|
||||
|
||||
remoteParameterOptions.value = remoteParameterOptions.value.concat(options);
|
||||
|
||||
@@ -4,13 +4,17 @@ import {
|
||||
UPDATED_SCHEMA,
|
||||
} from './__tests__/utils/ResourceMapper.utils';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { cleanupAppModals, createAppModals, waitAllPromises } from '@/__tests__/utils';
|
||||
import type { MockedStore } from '@/__tests__/utils';
|
||||
import { cleanupAppModals, createAppModals, mockedStore, waitAllPromises } from '@/__tests__/utils';
|
||||
import ResourceMapper from '@/components/ResourceMapper/ResourceMapper.vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import type { MockInstance } from 'vitest';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
let nodeTypeStore: ReturnType<typeof useNodeTypesStore>;
|
||||
let projectsStore: MockedStore<typeof useProjectsStore>;
|
||||
|
||||
let fetchFieldsSpy: MockInstance;
|
||||
|
||||
const renderComponent = createComponentRenderer(ResourceMapper, DEFAULT_SETUP);
|
||||
@@ -25,6 +29,8 @@ describe('ResourceMapper.vue', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
createAppModals();
|
||||
projectsStore = mockedStore(useProjectsStore);
|
||||
projectsStore.currentProjectId = 'aProjectId';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -30,6 +30,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useDocumentVisibility } from '@/composables/useDocumentVisibility';
|
||||
import { N8nButton, N8nCallout, N8nNotice } from '@n8n/design-system';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
type Props = {
|
||||
parameter: INodeProperties;
|
||||
@@ -46,6 +47,7 @@ type Props = {
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const ndvStore = useNDVStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
teleported: true,
|
||||
@@ -310,6 +312,7 @@ const createRequestParams = (methodName: string) => {
|
||||
path: props.path,
|
||||
methodName,
|
||||
credentials: props.node.credentials,
|
||||
projectId: projectsStore.currentProjectId,
|
||||
};
|
||||
|
||||
return requestParams;
|
||||
|
||||
Reference in New Issue
Block a user