mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Changes after feedback
This commit is contained in:
parent
477bbbc7d8
commit
3615cd9021
|
@ -14,16 +14,6 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { ApplicationError, jsonParse, NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
/* Function which helps while developing the node */
|
||||
// ToDo: Remove before completing the pull request
|
||||
export async function presendTest(
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
console.log('requestOptions', requestOptions);
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function which stringifies the body before sending the request.
|
||||
* It is added to the routing property in the "resource" parameter thus for all requests.
|
||||
|
@ -47,31 +37,73 @@ export async function presendFilter(
|
|||
let filterType = additionalFields.filterType as string;
|
||||
const filterValue = additionalFields.filterValue as string;
|
||||
|
||||
if (filterAttribute && filterType && filterValue) {
|
||||
// Convert the filterType to the format the API expects
|
||||
const filterTypeMapping: { [key: string]: string } = {
|
||||
exactMatch: '=',
|
||||
startsWith: '^=',
|
||||
};
|
||||
filterType = filterTypeMapping[filterType] || filterType;
|
||||
console.log('Attribute', filterAttribute, 'Type', filterType, 'Value', filterValue);
|
||||
|
||||
// Parse the body if it's a string to add the new property
|
||||
let body: IDataObject;
|
||||
if (typeof requestOptions.body === 'string') {
|
||||
try {
|
||||
body = JSON.parse(requestOptions.body) as IDataObject;
|
||||
} catch (error) {
|
||||
throw new NodeOperationError(this.getNode(), 'Failed to parse requestOptions body');
|
||||
}
|
||||
} else {
|
||||
body = requestOptions.body as IDataObject;
|
||||
if (!filterAttribute || !filterType || !filterValue) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Please provide Filter Attribute, Filter Type, and Filter Value to use filtering.',
|
||||
);
|
||||
}
|
||||
|
||||
const filterTypeMapping: { [key: string]: string } = {
|
||||
exactMatch: '=',
|
||||
startsWith: '^=',
|
||||
};
|
||||
filterType = filterTypeMapping[filterType] || filterType;
|
||||
|
||||
let body: IDataObject;
|
||||
if (typeof requestOptions.body === 'string') {
|
||||
try {
|
||||
body = JSON.parse(requestOptions.body) as IDataObject;
|
||||
} catch (error) {
|
||||
throw new NodeOperationError(this.getNode(), 'Failed to parse requestOptions body');
|
||||
}
|
||||
|
||||
requestOptions.body = JSON.stringify({
|
||||
...body,
|
||||
Filter: `${filterAttribute} ${filterType} "${filterValue}"`,
|
||||
});
|
||||
} else {
|
||||
body = requestOptions.body as IDataObject;
|
||||
}
|
||||
|
||||
requestOptions.body = JSON.stringify({
|
||||
...body,
|
||||
Filter: `${filterAttribute} ${filterType} "${filterValue}"`,
|
||||
});
|
||||
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
export async function presendOptions(
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const options = this.getNodeParameter('options', {}) as IDataObject;
|
||||
|
||||
const hasOptions = options.Description || options.Precedence || options.Path || options.RoleArn;
|
||||
|
||||
if (!hasOptions) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'At least one of the options (Description, Precedence, Path, or RoleArn) must be provided to update the group.',
|
||||
);
|
||||
}
|
||||
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
export async function presendPath(
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const path = this.getNodeParameter('path', '/') as string;
|
||||
|
||||
if (path.length < 1 || path.length > 512) {
|
||||
throw new NodeOperationError(this.getNode(), 'Path must be between 1 and 512 characters.');
|
||||
}
|
||||
|
||||
if (!/^\/$|^\/[\u0021-\u007E]+\/$/.test(path)) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Path must begin and end with a forward slash and contain valid ASCII characters.',
|
||||
);
|
||||
}
|
||||
|
||||
return requestOptions;
|
||||
|
@ -176,34 +208,33 @@ export async function handleErrorPostReceive(
|
|||
const errorType = responseBody.__type ?? response.headers?.['x-amzn-errortype'];
|
||||
const errorMessage = responseBody.message ?? response.headers?.['x-amzn-errormessage'];
|
||||
|
||||
// Resource/Operation specific errors
|
||||
if (resource === 'group') {
|
||||
if (operation === 'delete') {
|
||||
if (errorType === 'ResourceNotFoundException' || errorType === 'NoSuchEntity') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required group doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'Group' and try again",
|
||||
message: 'The group you are deleting could not be found.',
|
||||
description: 'Adjust the "Group" parameter setting to delete the group correctly.',
|
||||
});
|
||||
}
|
||||
} else if (operation === 'get') {
|
||||
if (errorType === 'ResourceNotFoundException' || errorType === 'NoSuchEntity') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required group doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'Group' and try again",
|
||||
message: 'The group you are requesting could not be found.',
|
||||
description: 'Adjust the "Group" parameter setting to retrieve the group correctly.',
|
||||
});
|
||||
}
|
||||
} else if (operation === 'update') {
|
||||
if (errorType === 'ResourceNotFoundException' || errorType === 'NoSuchEntity') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required group doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'Group' and try again",
|
||||
message: 'The group you are updating could not be found.',
|
||||
description: 'Adjust the "Group" parameter setting to update the group correctly.',
|
||||
});
|
||||
}
|
||||
} else if (operation === 'create') {
|
||||
if (errorType === 'EntityAlreadyExists' || errorType === 'GroupExistsException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'The group is already created',
|
||||
description: "Double-check the value in the parameter 'Group Name' and try again",
|
||||
message: 'The group you are trying to create already exists',
|
||||
description: 'Adjust the "Group Name" parameter setting to create the group correctly.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -214,19 +245,18 @@ export async function handleErrorPostReceive(
|
|||
errorMessage === 'User account already exists'
|
||||
) {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'The user is already created',
|
||||
description: "Double-check the value in the parameter 'User Name' and try again",
|
||||
message: 'The user you are trying to create already exists',
|
||||
description: 'Adjust the "User Name" parameter setting to create the user correctly.',
|
||||
});
|
||||
}
|
||||
} else if (operation === 'addToGroup') {
|
||||
// Group or user doesn't exist
|
||||
if (errorType === 'UserNotFoundException') {
|
||||
const user = this.getNodeParameter('user.value', '') as string;
|
||||
|
||||
if (typeof errorMessage === 'string' && errorMessage.includes(user)) {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required user doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'User' and try again.",
|
||||
message: 'The user you are requesting could not be found.',
|
||||
description: 'Adjust the "User" parameter setting to retrieve the post correctly.',
|
||||
});
|
||||
}
|
||||
} else if (errorType === 'ResourceNotFoundException') {
|
||||
|
@ -234,34 +264,33 @@ export async function handleErrorPostReceive(
|
|||
|
||||
if (typeof errorMessage === 'string' && errorMessage.includes(group)) {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required group doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'Group' and try again.",
|
||||
message: 'The group you are requesting could not be found.',
|
||||
description: 'Adjust the "Group" parameter setting to retrieve the post correctly.',
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (operation === 'delete') {
|
||||
if (errorType === 'UserNotFoundException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required user doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'User' and try again",
|
||||
message: 'The user you are requesting could not be found.',
|
||||
description: 'Adjust the "User" parameter setting to retrieve the post correctly.',
|
||||
});
|
||||
}
|
||||
} else if (operation === 'get') {
|
||||
if (errorType === 'UserNotFoundException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required user doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'User' and try again",
|
||||
message: 'The user you are requesting could not be found.',
|
||||
description: 'Adjust the "User" parameter setting to retrieve the post correctly.',
|
||||
});
|
||||
}
|
||||
} else if (operation === 'removeFromGroup') {
|
||||
// Group or user doesn't exist
|
||||
if (errorType === 'UserNotFoundException') {
|
||||
const user = this.getNodeParameter('user.value', '') as string;
|
||||
|
||||
if (typeof errorMessage === 'string' && errorMessage.includes(user)) {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required user doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'User' and try again.",
|
||||
message: 'The user you are deleting could not be found.',
|
||||
description: 'Adjust the "User" parameter setting to delete the user correctly.',
|
||||
});
|
||||
}
|
||||
} else if (errorType === 'ResourceNotFoundException') {
|
||||
|
@ -269,72 +298,21 @@ export async function handleErrorPostReceive(
|
|||
|
||||
if (typeof errorMessage === 'string' && errorMessage.includes(group)) {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required group doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'Group' and try again.",
|
||||
message: 'The group you are requesting could not be found.',
|
||||
description: 'Adjust the "Group" parameter setting to delete the user correctly.',
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (operation === 'update') {
|
||||
if (errorType === 'UserNotFoundException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: "The required user doesn't match any existing one",
|
||||
description: "Double-check the value in the parameter 'User' and try again",
|
||||
message: 'The user you are updating could not be found.',
|
||||
description: 'Adjust the "User" parameter setting to update the user correctly.',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generic Error Handling
|
||||
if (errorType === 'InvalidParameterException') {
|
||||
const group = this.getNodeParameter('group.value', '') as string;
|
||||
const parameterResource =
|
||||
resource === 'group' || (typeof errorMessage === 'string' && errorMessage.includes(group))
|
||||
? 'group'
|
||||
: 'user';
|
||||
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: `The ${parameterResource} ID is invalid`,
|
||||
description: 'The ID should be in the format e.g. 02bd9fd6-8f93-4758-87c3-1fb73740a315',
|
||||
});
|
||||
}
|
||||
|
||||
if (errorType === 'InternalErrorException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'Internal Server Error',
|
||||
description: 'Amazon Cognito encountered an internal error. Try again later.',
|
||||
});
|
||||
}
|
||||
|
||||
if (errorType === 'TooManyRequestsException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'Too Many Requests',
|
||||
description: 'You have exceeded the allowed number of requests. Try again later.',
|
||||
});
|
||||
}
|
||||
|
||||
if (errorType === 'NotAuthorizedException') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'Unauthorized Access',
|
||||
description:
|
||||
'You are not authorized to perform this operation. Check your permissions and try again.',
|
||||
});
|
||||
}
|
||||
|
||||
if (errorType === 'ServiceFailure') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'Service Failure',
|
||||
description:
|
||||
'The request processing has failed because of an unknown error, exception, or failure. Try again later.',
|
||||
});
|
||||
}
|
||||
|
||||
if (errorType === 'LimitExceeded') {
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject, {
|
||||
message: 'Limit Exceeded',
|
||||
description:
|
||||
'The request was rejected because it attempted to create resources beyond the current AWS account limits. Check your AWS limits and try again.',
|
||||
});
|
||||
}
|
||||
throw new NodeApiError(this.getNode(), response as unknown as JsonObject);
|
||||
}
|
||||
|
||||
|
@ -401,13 +379,13 @@ export async function searchUserPools(
|
|||
paginationToken?: string,
|
||||
): Promise<INodeListSearchResult> {
|
||||
const opts: IHttpRequestOptions = {
|
||||
url: '', // the base url is set in "awsRequest"
|
||||
url: '',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Amz-Target': 'AWSCognitoIdentityProviderService.ListUserPools',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
MaxResults: 60, // the maximum number by documentation is 60
|
||||
MaxResults: 60,
|
||||
NextToken: paginationToken ?? undefined,
|
||||
}),
|
||||
};
|
||||
|
@ -432,7 +410,7 @@ export async function searchUserPools(
|
|||
return 0;
|
||||
});
|
||||
|
||||
return { results, paginationToken: responseData.NextToken }; // ToDo: Test if pagination for the search methods works
|
||||
return { results, paginationToken: responseData.NextToken };
|
||||
}
|
||||
|
||||
export async function searchUsers(
|
||||
|
@ -440,20 +418,16 @@ export async function searchUsers(
|
|||
filter?: string,
|
||||
paginationToken?: string,
|
||||
): Promise<INodeListSearchResult> {
|
||||
// Get the userPoolId from the input
|
||||
const userPoolIdRaw = this.getNodeParameter('userPoolId', '') as IDataObject;
|
||||
|
||||
// Extract the actual value
|
||||
const userPoolId = userPoolIdRaw.value as string;
|
||||
|
||||
// Ensure that userPoolId is provided
|
||||
if (!userPoolId) {
|
||||
throw new ApplicationError('User Pool ID is required to search users');
|
||||
}
|
||||
|
||||
// Setup the options for the AWS request
|
||||
const opts: IHttpRequestOptions = {
|
||||
url: '', // the base URL is set in "awsRequest"
|
||||
url: '',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Amz-Target': 'AWSCognitoIdentityProviderService.ListUsers',
|
||||
|
@ -465,30 +439,23 @@ export async function searchUsers(
|
|||
}),
|
||||
};
|
||||
|
||||
// Make the AWS request
|
||||
const responseData: IDataObject = await awsRequest.call(this, opts);
|
||||
|
||||
// Extract users from the response
|
||||
const users = responseData.Users as IDataObject[] | undefined;
|
||||
|
||||
// Handle cases where no users are returned
|
||||
if (!users) {
|
||||
console.warn('No users found in the response');
|
||||
return { results: [] };
|
||||
}
|
||||
|
||||
// Map and filter the response data to create results
|
||||
const results: INodeListSearchItems[] = users
|
||||
.map((user) => {
|
||||
// Extract user attributes, if any
|
||||
const attributes = user.Attributes as Array<{ Name: string; Value: string }> | undefined;
|
||||
|
||||
// Find the `email` or `sub` attribute, fallback to `Username`
|
||||
const email = attributes?.find((attr) => attr.Name === 'email')?.Value;
|
||||
const sub = attributes?.find((attr) => attr.Name === 'sub')?.Value;
|
||||
const username = user.Username as string;
|
||||
|
||||
// Use email, sub, or Username as the user name and value
|
||||
const name = email || sub || username;
|
||||
const value = username;
|
||||
|
||||
|
@ -504,7 +471,6 @@ export async function searchUsers(
|
|||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
});
|
||||
|
||||
// Return the results and the pagination token
|
||||
return { results, paginationToken: responseData.NextToken as string | undefined };
|
||||
}
|
||||
|
||||
|
@ -513,17 +479,13 @@ export async function searchGroups(
|
|||
filter?: string,
|
||||
paginationToken?: string,
|
||||
): Promise<INodeListSearchResult> {
|
||||
// Get the userPoolId from the input
|
||||
const userPoolIdRaw = this.getNodeParameter('userPoolId', '') as IDataObject;
|
||||
|
||||
// Extract the actual value
|
||||
const userPoolId = userPoolIdRaw.value as string;
|
||||
|
||||
// Ensure that userPoolId is provided
|
||||
if (!userPoolId) {
|
||||
throw new ApplicationError('User Pool ID is required to search groups');
|
||||
}
|
||||
// Setup the options for the AWS request
|
||||
const opts: IHttpRequestOptions = {
|
||||
url: '',
|
||||
method: 'POST',
|
||||
|
@ -541,12 +503,10 @@ export async function searchGroups(
|
|||
|
||||
const groups = responseData.Groups as Array<{ GroupName?: string }> | undefined;
|
||||
|
||||
// If no groups exist, return an empty list
|
||||
if (!groups) {
|
||||
return { results: [] };
|
||||
}
|
||||
|
||||
// Map and filter the response
|
||||
const results: INodeListSearchItems[] = groups
|
||||
.filter((group) => group.GroupName)
|
||||
.map((group) => ({
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { IExecuteSingleFunctions, IHttpRequestOptions, INodeProperties } from 'n8n-workflow';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
import { handleErrorPostReceive, handlePagination } from '../GenericFunctions';
|
||||
import { handleErrorPostReceive, handlePagination, presendPath } from '../GenericFunctions';
|
||||
|
||||
export const groupOperations: INodeProperties[] = [
|
||||
{
|
||||
|
@ -92,7 +91,7 @@ export const groupOperations: INodeProperties[] = [
|
|||
},
|
||||
qs: {
|
||||
pageSize:
|
||||
'={{ $parameter["limit"] ? ($parameter["limit"] < 60 ? $parameter["limit"] : 60) : 60 }}', // The API allows maximum 60 results per page
|
||||
'={{ $parameter["limit"] ? ($parameter["limit"] < 60 ? $parameter["limit"] : 60) : 60 }}',
|
||||
},
|
||||
ignoreHttpStatusErrors: true,
|
||||
},
|
||||
|
@ -257,38 +256,13 @@ const createFields: INodeProperties[] = [
|
|||
send: {
|
||||
property: 'Path',
|
||||
type: 'body',
|
||||
preSend: [
|
||||
async function (
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const path = this.getNodeParameter('path', '/') as string;
|
||||
|
||||
// Length validation
|
||||
if (path.length < 1 || path.length > 512) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Path must be between 1 and 512 characters.',
|
||||
);
|
||||
}
|
||||
|
||||
// Regex validation
|
||||
if (!/^\/$|^\/[\u0021-\u007E]+\/$/.test(path)) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Path must begin and end with a forward slash and contain valid ASCII characters.',
|
||||
);
|
||||
}
|
||||
|
||||
return requestOptions;
|
||||
},
|
||||
],
|
||||
preSend: [presendPath],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Role ARN',
|
||||
name: 'RoleArn',
|
||||
name: 'Arn',
|
||||
default: '',
|
||||
placeholder: 'e.g. arn:aws:iam::123456789012:role/GroupRole',
|
||||
description: 'The role ARN for the group, used for setting claims in tokens',
|
||||
|
@ -296,7 +270,7 @@ const createFields: INodeProperties[] = [
|
|||
routing: {
|
||||
send: {
|
||||
type: 'body',
|
||||
property: 'RoleArn',
|
||||
property: 'Arn',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -510,91 +484,9 @@ const getFields: INodeProperties[] = [
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Include Members',
|
||||
name: 'includeMembers',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether include members of the group in the result',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['group'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
send: {
|
||||
property: '$expand',
|
||||
type: 'query',
|
||||
value:
|
||||
'={{ $value ? "members($select=CreatedDate,Description,GroupName,LastModifiedDate,Precedence,UserPoolId)" : undefined }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Include Group Policy',
|
||||
name: 'includeGroupPolicy',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether include group policy details in the result',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['group'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
send: {
|
||||
property: '$expand',
|
||||
type: 'query',
|
||||
value: '={{ $value ? "groupPolicy($select=policyName,policyType)" : undefined }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Simplified',
|
||||
name: 'simplified',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether simplify the response if there are more than 10 fields',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['group'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
send: {
|
||||
property: '$select',
|
||||
type: 'query',
|
||||
value: 'CreatedDate,Description,GroupName,LastModifiedDate,Precedence,UserPoolId',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const getAllFields: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: { show: { resource: ['group'], operation: ['getAll'] } },
|
||||
type: 'boolean',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
required: true,
|
||||
type: 'number',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
},
|
||||
default: 20,
|
||||
description: 'Max number of results to return',
|
||||
displayOptions: { show: { resource: ['group'], operation: ['getAll'], returnAll: [false] } },
|
||||
routing: { send: { type: 'body', property: 'Limit' } },
|
||||
},
|
||||
{
|
||||
displayName: 'User Pool ID',
|
||||
name: 'userPoolId',
|
||||
|
@ -633,65 +525,25 @@ const getAllFields: INodeProperties[] = [
|
|||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Include Members',
|
||||
name: 'includeMembers',
|
||||
type: 'boolean',
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
default: false,
|
||||
description: 'Whether include members of the group in the result',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['group'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
send: {
|
||||
property: '$expand',
|
||||
type: 'query',
|
||||
value:
|
||||
'={{ $value ? "members($select=CreatedDate,Description,GroupName,LastModifiedDate,Precedence,UserPoolId)" : undefined }}',
|
||||
},
|
||||
},
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: { show: { resource: ['group'], operation: ['getAll'] } },
|
||||
type: 'boolean',
|
||||
},
|
||||
{
|
||||
displayName: 'Include Group Policy',
|
||||
name: 'includeGroupPolicy',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether include group policy details in the result',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['group'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
send: {
|
||||
property: '$expand',
|
||||
type: 'query',
|
||||
value: '={{ $value ? "groupPolicy($select=policyName,policyType)" : undefined }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Simplified',
|
||||
name: 'simplified',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether simplify the response if there are more than 10 fields',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['group'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
send: {
|
||||
property: '$select',
|
||||
type: 'query',
|
||||
value: 'CreatedDate,Description,GroupName,LastModifiedDate,Precedence,UserPoolId',
|
||||
},
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
required: true,
|
||||
type: 'number',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
},
|
||||
default: 20,
|
||||
description: 'Max number of results to return',
|
||||
displayOptions: { show: { resource: ['group'], operation: ['getAll'], returnAll: [false] } },
|
||||
routing: { send: { type: 'body', property: 'Limit' } },
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -848,38 +700,13 @@ const updateFields: INodeProperties[] = [
|
|||
send: {
|
||||
property: 'Path',
|
||||
type: 'body',
|
||||
preSend: [
|
||||
async function (
|
||||
this: IExecuteSingleFunctions,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const path = this.getNodeParameter('path', '/') as string;
|
||||
|
||||
// Length validation
|
||||
if (path.length < 1 || path.length > 512) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Path must be between 1 and 512 characters.',
|
||||
);
|
||||
}
|
||||
|
||||
// Regex validation
|
||||
if (!/^\/$|^\/[\u0021-\u007E]+\/$/.test(path)) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Path must begin and end with a forward slash and contain valid ASCII characters.',
|
||||
);
|
||||
}
|
||||
|
||||
return requestOptions;
|
||||
},
|
||||
],
|
||||
preSend: [presendPath],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Role ARN',
|
||||
name: 'RoleArn',
|
||||
name: 'Arn',
|
||||
default: '',
|
||||
placeholder: 'e.g. arn:aws:iam::123456789012:role/GroupRole',
|
||||
description:
|
||||
|
@ -888,7 +715,7 @@ const updateFields: INodeProperties[] = [
|
|||
routing: {
|
||||
send: {
|
||||
type: 'body',
|
||||
property: 'RoleArn',
|
||||
property: 'Arn',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -34,7 +34,15 @@ export const userOperations: INodeProperties[] = [
|
|||
ignoreHttpStatusErrors: true,
|
||||
},
|
||||
output: {
|
||||
postReceive: [handleErrorPostReceive],
|
||||
postReceive: [
|
||||
handleErrorPostReceive,
|
||||
{
|
||||
type: 'set',
|
||||
properties: {
|
||||
value: '={{ { "added": true } }}',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -114,7 +122,7 @@ export const userOperations: INodeProperties[] = [
|
|||
},
|
||||
qs: {
|
||||
pageSize:
|
||||
'={{ $parameter["limit"] ? ($parameter["limit"] < 60 ? $parameter["limit"] : 60) : 60 }}', // The API allows maximum 60 results per page
|
||||
'={{ $parameter["limit"] ? ($parameter["limit"] < 60 ? $parameter["limit"] : 60) : 60 }}',
|
||||
},
|
||||
ignoreHttpStatusErrors: true,
|
||||
},
|
||||
|
@ -138,7 +146,15 @@ export const userOperations: INodeProperties[] = [
|
|||
ignoreHttpStatusErrors: true,
|
||||
},
|
||||
output: {
|
||||
postReceive: [handleErrorPostReceive],
|
||||
postReceive: [
|
||||
handleErrorPostReceive,
|
||||
{
|
||||
type: 'set',
|
||||
properties: {
|
||||
value: '={{ { "removed": true } }}',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -262,7 +278,7 @@ const createFields: INodeProperties[] = [
|
|||
displayName: 'Client Metadata',
|
||||
name: 'clientMetadata',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Metadata Pair',
|
||||
placeholder: 'Add Metadata',
|
||||
default: { metadata: [] },
|
||||
description: 'A map of custom key-value pairs for workflows triggered by this action',
|
||||
typeOptions: {
|
||||
|
@ -318,7 +334,7 @@ const createFields: INodeProperties[] = [
|
|||
name: 'MessageAction',
|
||||
default: 'RESEND',
|
||||
description:
|
||||
"Set to RESEND to resend the invitation message to a user that already exists and reset the expiration limit on the user's account. Set to SUPPRESS to suppress sending the message. You can specify only one value.",
|
||||
"Set to RESEND to resend the invitation message to a user that already exists and reset the expiration limit on the user's account. Set to SUPPRESS to suppress sending the message.",
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
|
@ -685,7 +701,13 @@ const getAllFields: INodeProperties[] = [
|
|||
name: 'filterAttribute',
|
||||
type: 'options',
|
||||
default: 'username',
|
||||
hint: 'Make sure to select an attribute, type, and provide a value before submitting.',
|
||||
description: 'The attribute to search for',
|
||||
routing: {
|
||||
send: {
|
||||
preSend: [presendFilter],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{ name: 'Cognito User Status', value: 'cognito:user_status' },
|
||||
{ name: 'Email', value: 'email' },
|
||||
|
@ -716,11 +738,6 @@ const getAllFields: INodeProperties[] = [
|
|||
type: 'string',
|
||||
default: '',
|
||||
description: 'The value of the attribute to search for',
|
||||
routing: {
|
||||
send: {
|
||||
preSend: [presendFilter],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue