mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(API): Exclude pinned data from workflows (#12261)
This commit is contained in:
@@ -80,7 +80,7 @@ export class WorkflowEntity extends WithTimestampsAndStringId implements IWorkfl
|
||||
nullable: true,
|
||||
transformer: sqlite.jsonColumn,
|
||||
})
|
||||
pinData: ISimplifiedPinData;
|
||||
pinData?: ISimplifiedPinData;
|
||||
|
||||
@Column({ length: 36 })
|
||||
versionId: string;
|
||||
|
||||
@@ -74,11 +74,12 @@ export declare namespace WorkflowRequest {
|
||||
active: boolean;
|
||||
name?: string;
|
||||
projectId?: string;
|
||||
excludePinnedData?: boolean;
|
||||
}
|
||||
>;
|
||||
|
||||
type Create = AuthenticatedRequest<{}, {}, WorkflowEntity, {}>;
|
||||
type Get = AuthenticatedRequest<{ id: string }, {}, {}, {}>;
|
||||
type Get = AuthenticatedRequest<{ id: string }, {}, {}, { excludePinnedData?: boolean }>;
|
||||
type Delete = Get;
|
||||
type Update = AuthenticatedRequest<{ id: string }, {}, WorkflowEntity, {}>;
|
||||
type Activate = Get;
|
||||
|
||||
@@ -6,6 +6,13 @@ get:
|
||||
summary: Retrieves a workflow
|
||||
description: Retrieves a workflow.
|
||||
parameters:
|
||||
- name: excludePinnedData
|
||||
in: query
|
||||
required: false
|
||||
description: Set this to avoid retrieving pinned data
|
||||
schema:
|
||||
type: boolean
|
||||
example: true
|
||||
- $ref: '../schemas/parameters/workflowId.yml'
|
||||
responses:
|
||||
'200':
|
||||
|
||||
@@ -60,6 +60,13 @@ get:
|
||||
schema:
|
||||
type: string
|
||||
example: VmwOO9HeTEj20kxM
|
||||
- name: excludePinnedData
|
||||
in: query
|
||||
required: false
|
||||
description: Set this to avoid retrieving pinned data
|
||||
schema:
|
||||
type: boolean
|
||||
example: true
|
||||
- $ref: '../../../../shared/spec/parameters/limit.yml'
|
||||
- $ref: '../../../../shared/spec/parameters/cursor.yml'
|
||||
responses:
|
||||
|
||||
@@ -105,6 +105,7 @@ export = {
|
||||
projectScope('workflow:read', 'workflow'),
|
||||
async (req: WorkflowRequest.Get, res: express.Response): Promise<express.Response> => {
|
||||
const { id } = req.params;
|
||||
const { excludePinnedData = false } = req.query;
|
||||
|
||||
const workflow = await Container.get(SharedWorkflowRepository).findWorkflowForUser(
|
||||
id,
|
||||
@@ -120,6 +121,10 @@ export = {
|
||||
return res.status(404).json({ message: 'Not Found' });
|
||||
}
|
||||
|
||||
if (excludePinnedData) {
|
||||
delete workflow.pinData;
|
||||
}
|
||||
|
||||
Container.get(EventService).emit('user-retrieved-workflow', {
|
||||
userId: req.user.id,
|
||||
publicApi: true,
|
||||
@@ -131,7 +136,15 @@ export = {
|
||||
getWorkflows: [
|
||||
validCursor,
|
||||
async (req: WorkflowRequest.GetAll, res: express.Response): Promise<express.Response> => {
|
||||
const { offset = 0, limit = 100, active, tags, name, projectId } = req.query;
|
||||
const {
|
||||
offset = 0,
|
||||
limit = 100,
|
||||
excludePinnedData = false,
|
||||
active,
|
||||
tags,
|
||||
name,
|
||||
projectId,
|
||||
} = req.query;
|
||||
|
||||
const where: FindOptionsWhere<WorkflowEntity> = {
|
||||
...(active !== undefined && { active }),
|
||||
@@ -199,6 +212,12 @@ export = {
|
||||
...(!config.getEnv('workflowTagsDisabled') && { relations: ['tags'] }),
|
||||
});
|
||||
|
||||
if (excludePinnedData) {
|
||||
workflows.forEach((workflow) => {
|
||||
delete workflow.pinData;
|
||||
});
|
||||
}
|
||||
|
||||
Container.get(EventService).emit('user-retrieved-all-workflows', {
|
||||
userId: req.user.id,
|
||||
publicApi: true,
|
||||
|
||||
@@ -378,6 +378,47 @@ describe('GET /workflows', () => {
|
||||
expect(updatedAt).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
test('should return all owned workflows without pinned data', async () => {
|
||||
await Promise.all([
|
||||
createWorkflow(
|
||||
{
|
||||
pinData: {
|
||||
Webhook1: [{ json: { first: 'first' } }],
|
||||
},
|
||||
},
|
||||
member,
|
||||
),
|
||||
createWorkflow(
|
||||
{
|
||||
pinData: {
|
||||
Webhook2: [{ json: { second: 'second' } }],
|
||||
},
|
||||
},
|
||||
member,
|
||||
),
|
||||
createWorkflow(
|
||||
{
|
||||
pinData: {
|
||||
Webhook3: [{ json: { third: 'third' } }],
|
||||
},
|
||||
},
|
||||
member,
|
||||
),
|
||||
]);
|
||||
|
||||
const response = await authMemberAgent.get('/workflows?excludePinnedData=true');
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.data.length).toBe(3);
|
||||
expect(response.body.nextCursor).toBeNull();
|
||||
|
||||
for (const workflow of response.body.data) {
|
||||
const { pinData } = workflow;
|
||||
|
||||
expect(pinData).not.toBeDefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /workflows/:id', () => {
|
||||
@@ -444,6 +485,26 @@ describe('GET /workflows/:id', () => {
|
||||
expect(createdAt).toEqual(workflow.createdAt.toISOString());
|
||||
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
|
||||
});
|
||||
|
||||
test('should retrieve workflow without pinned data', async () => {
|
||||
// create and assign workflow to owner
|
||||
const workflow = await createWorkflow(
|
||||
{
|
||||
pinData: {
|
||||
Webhook1: [{ json: { first: 'first' } }],
|
||||
},
|
||||
},
|
||||
member,
|
||||
);
|
||||
|
||||
const response = await authMemberAgent.get(`/workflows/${workflow.id}?excludePinnedData=true`);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
|
||||
const { pinData } = response.body;
|
||||
|
||||
expect(pinData).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /workflows/:id', () => {
|
||||
|
||||
Reference in New Issue
Block a user