mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Fixed some issues after feedback
This commit is contained in:
parent
f3bcf18ce5
commit
abdd1521c0
|
@ -14,6 +14,14 @@ import type {
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { ApplicationError, jsonParse, NodeApiError, NodeOperationError } from 'n8n-workflow';
|
import { ApplicationError, jsonParse, NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||||
|
|
||||||
|
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.
|
* 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.
|
* It is added to the routing property in the "resource" parameter thus for all requests.
|
||||||
|
@ -33,14 +41,20 @@ export async function presendFilter(
|
||||||
requestOptions: IHttpRequestOptions,
|
requestOptions: IHttpRequestOptions,
|
||||||
): Promise<IHttpRequestOptions> {
|
): Promise<IHttpRequestOptions> {
|
||||||
const additionalFields = this.getNodeParameter('additionalFields', {}) as IDataObject;
|
const additionalFields = this.getNodeParameter('additionalFields', {}) as IDataObject;
|
||||||
const filterAttribute = additionalFields.filterAttribute as string;
|
const filterAttribute = additionalFields.filters as string;
|
||||||
let filterType = additionalFields.filterType as string;
|
let filterType = additionalFields.filterType as string;
|
||||||
const filterValue = additionalFields.filterValue as string;
|
const filterValue = additionalFields.filterValue as string;
|
||||||
|
|
||||||
if (!filterAttribute || !filterType || !filterValue) {
|
const hasAnyFilter = filterAttribute || filterType || filterValue;
|
||||||
|
|
||||||
|
if (!hasAnyFilter) {
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAnyFilter && (!filterAttribute || !filterType || !filterValue)) {
|
||||||
throw new NodeOperationError(
|
throw new NodeOperationError(
|
||||||
this.getNode(),
|
this.getNode(),
|
||||||
'Please provide Filter Attribute, Filter Type, and Filter Value to use filtering.',
|
'If filtering is used, please provide Filter Attribute, Filter Type, and Filter Value.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,25 +83,25 @@ export async function presendFilter(
|
||||||
return requestOptions;
|
return requestOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function presendOptions(
|
export async function presendAdditionalFields(
|
||||||
this: IExecuteSingleFunctions,
|
this: IExecuteSingleFunctions,
|
||||||
requestOptions: IHttpRequestOptions,
|
requestOptions: IHttpRequestOptions,
|
||||||
): Promise<IHttpRequestOptions> {
|
): Promise<IHttpRequestOptions> {
|
||||||
const options = this.getNodeParameter('options', {}) as IDataObject;
|
const additionalFields = this.getNodeParameter('additionalFields', {}) as IDataObject;
|
||||||
|
|
||||||
const hasOptions = options.Description || options.Precedence || options.Path || options.RoleArn;
|
const hasOptions = Object.keys(additionalFields).length > 0;
|
||||||
|
|
||||||
if (!hasOptions) {
|
if (!hasOptions) {
|
||||||
throw new NodeOperationError(
|
throw new NodeOperationError(
|
||||||
this.getNode(),
|
this.getNode(),
|
||||||
'At least one of the options (Description, Precedence, Path, or RoleArn) must be provided to update the group.',
|
'At least one of the additional fields must be provided to update the group.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestOptions;
|
return requestOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function presendPath(
|
export async function presendVerifyPath(
|
||||||
this: IExecuteSingleFunctions,
|
this: IExecuteSingleFunctions,
|
||||||
requestOptions: IHttpRequestOptions,
|
requestOptions: IHttpRequestOptions,
|
||||||
): Promise<IHttpRequestOptions> {
|
): Promise<IHttpRequestOptions> {
|
||||||
|
@ -325,7 +339,7 @@ export async function handleErrorPostReceive(
|
||||||
|
|
||||||
/* Helper function used in listSearch methods */
|
/* Helper function used in listSearch methods */
|
||||||
export async function awsRequest(
|
export async function awsRequest(
|
||||||
this: ILoadOptionsFunctions | IPollFunctions,
|
this: ILoadOptionsFunctions | IPollFunctions | IExecuteSingleFunctions,
|
||||||
opts: IHttpRequestOptions,
|
opts: IHttpRequestOptions,
|
||||||
): Promise<IDataObject> {
|
): Promise<IDataObject> {
|
||||||
const region = (await this.getCredentials('aws')).region as string;
|
const region = (await this.getCredentials('aws')).region as string;
|
||||||
|
@ -376,7 +390,6 @@ export async function awsRequest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* listSearch methods */
|
|
||||||
export async function searchUserPools(
|
export async function searchUserPools(
|
||||||
this: ILoadOptionsFunctions,
|
this: ILoadOptionsFunctions,
|
||||||
filter?: string,
|
filter?: string,
|
||||||
|
@ -448,7 +461,6 @@ export async function searchUsers(
|
||||||
const users = responseData.Users as IDataObject[] | undefined;
|
const users = responseData.Users as IDataObject[] | undefined;
|
||||||
|
|
||||||
if (!users) {
|
if (!users) {
|
||||||
console.warn('No users found in the response');
|
|
||||||
return { results: [] };
|
return { results: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,3 +541,283 @@ export async function searchGroups(
|
||||||
|
|
||||||
return { results, paginationToken: responseData.NextToken };
|
return { results, paginationToken: responseData.NextToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function simplifyData(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
items: INodeExecutionData[],
|
||||||
|
response: IN8nHttpFullResponse,
|
||||||
|
): Promise<INodeExecutionData[]> {
|
||||||
|
const simple = this.getNodeParameter('simple') as boolean;
|
||||||
|
|
||||||
|
type UserPool = {
|
||||||
|
Arn: string;
|
||||||
|
CreationDate: number;
|
||||||
|
DeletionProtection: string;
|
||||||
|
Domain: string;
|
||||||
|
EstimatedNumberOfUsers: number;
|
||||||
|
Id: string;
|
||||||
|
LastModifiedDate: number;
|
||||||
|
MfaConfiguration: string;
|
||||||
|
Name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type User = {
|
||||||
|
Enabled: boolean;
|
||||||
|
UserAttributes?: Array<{ Name: string; Value: string }>;
|
||||||
|
Attributes?: Array<{ Name: string; Value: string }>;
|
||||||
|
UserCreateDate: number;
|
||||||
|
UserLastModifiedDate: number;
|
||||||
|
UserStatus: string;
|
||||||
|
Username: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapUserAttributes(userAttributes: Array<{ Name: string; Value: string }>): {
|
||||||
|
[key: string]: string;
|
||||||
|
} {
|
||||||
|
return userAttributes?.reduce(
|
||||||
|
(acc, { Name, Value }) => {
|
||||||
|
if (Name !== 'sub') {
|
||||||
|
acc[Name] = Value;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as { [key: string]: string },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!simple) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resource = this.getNodeParameter('resource');
|
||||||
|
const operation = this.getNodeParameter('operation');
|
||||||
|
|
||||||
|
const simplifiedItems = items
|
||||||
|
.map((item) => {
|
||||||
|
const data = item.json?.UserPool as UserPool | undefined;
|
||||||
|
const userData = item.json as User | undefined;
|
||||||
|
const users = item.json?.Users as User[] | undefined;
|
||||||
|
|
||||||
|
switch (resource) {
|
||||||
|
case 'userPool':
|
||||||
|
if (data) {
|
||||||
|
return {
|
||||||
|
json: {
|
||||||
|
UserPool: {
|
||||||
|
Arn: data.Arn,
|
||||||
|
CreationDate: data.CreationDate,
|
||||||
|
DeletionProtection: data.DeletionProtection,
|
||||||
|
Domain: data.Domain,
|
||||||
|
EstimatedNumberOfUsers: data.EstimatedNumberOfUsers,
|
||||||
|
Id: data.Id,
|
||||||
|
LastModifiedDate: data.LastModifiedDate,
|
||||||
|
MfaConfiguration: data.MfaConfiguration,
|
||||||
|
Name: data.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'user':
|
||||||
|
if (userData) {
|
||||||
|
if (operation === 'get') {
|
||||||
|
const userAttributes = userData.UserAttributes
|
||||||
|
? mapUserAttributes(userData.UserAttributes)
|
||||||
|
: {};
|
||||||
|
return {
|
||||||
|
json: {
|
||||||
|
User: {
|
||||||
|
Enabled: userData.Enabled,
|
||||||
|
...Object.fromEntries(Object.entries(userAttributes).slice(0, 6)),
|
||||||
|
UserCreateDate: userData.UserCreateDate,
|
||||||
|
UserLastModifiedDate: userData.UserLastModifiedDate,
|
||||||
|
UserStatus: userData.UserStatus,
|
||||||
|
Username: userData.Username,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else if (operation === 'getAll') {
|
||||||
|
if (users && Array.isArray(users)) {
|
||||||
|
const processedUsers: User[] = [];
|
||||||
|
users.forEach((user) => {
|
||||||
|
const userAttributes = user.Attributes ? mapUserAttributes(user.Attributes) : {};
|
||||||
|
processedUsers.push({
|
||||||
|
Enabled: userData.Enabled,
|
||||||
|
...Object.fromEntries(Object.entries(userAttributes).slice(0, 6)),
|
||||||
|
UserCreateDate: userData.UserCreateDate,
|
||||||
|
UserLastModifiedDate: userData.UserLastModifiedDate,
|
||||||
|
UserStatus: userData.UserStatus,
|
||||||
|
Username: userData.Username,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
json: {
|
||||||
|
Users: processedUsers,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
})
|
||||||
|
.filter((item) => item !== undefined)
|
||||||
|
.flat();
|
||||||
|
|
||||||
|
return simplifiedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listUsersInGroup(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
groupName: string,
|
||||||
|
userPoolId: string,
|
||||||
|
): Promise<IDataObject> {
|
||||||
|
if (!userPoolId) {
|
||||||
|
throw new ApplicationError('User Pool ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const opts: IHttpRequestOptions = {
|
||||||
|
url: '',
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-Amz-Target': 'AWSCognitoIdentityProviderService.ListUsersInGroup',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
UserPoolId: userPoolId,
|
||||||
|
GroupName: groupName,
|
||||||
|
MaxResults: 60,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const responseData: IDataObject = await awsRequest.call(this, opts);
|
||||||
|
|
||||||
|
const users = responseData.Users as IDataObject[] | undefined;
|
||||||
|
|
||||||
|
if (!users) {
|
||||||
|
return { results: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
const results: INodeListSearchItems[] = users
|
||||||
|
.map((user) => {
|
||||||
|
const attributes = user.Attributes as Array<{ Name: string; Value: string }> | undefined;
|
||||||
|
|
||||||
|
const email = attributes?.find((attr) => attr.Name === 'email')?.Value;
|
||||||
|
const sub = attributes?.find((attr) => attr.Name === 'sub')?.Value;
|
||||||
|
const username = user.Username as string;
|
||||||
|
|
||||||
|
const name = email || sub || username;
|
||||||
|
const value = username;
|
||||||
|
|
||||||
|
return { name, value };
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
return { results, paginationToken: responseData.NextToken as string | undefined };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getUsersForGroup(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
groupName: string,
|
||||||
|
userPoolId: string,
|
||||||
|
): Promise<IDataObject[]> {
|
||||||
|
const users = await listUsersInGroup.call(this, groupName, userPoolId);
|
||||||
|
|
||||||
|
if (users && users.results && Array.isArray(users.results) && users.results.length > 0) {
|
||||||
|
return users.results as IDataObject[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [] as IDataObject[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function processUsersForGroups(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
items: INodeExecutionData[],
|
||||||
|
response: IN8nHttpFullResponse,
|
||||||
|
): Promise<INodeExecutionData[]> {
|
||||||
|
const userPoolIdRaw = this.getNodeParameter('userPoolId') as IDataObject;
|
||||||
|
const userPoolId = userPoolIdRaw.value as string;
|
||||||
|
const include = this.getNodeParameter('includeUsers', 0) as boolean;
|
||||||
|
|
||||||
|
if (!include) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
const processedGroups: IDataObject[] = [];
|
||||||
|
|
||||||
|
if (response.body && typeof response.body === 'object') {
|
||||||
|
if ('Group' in response.body) {
|
||||||
|
const group = (response.body as { Group: IDataObject }).Group;
|
||||||
|
const usersResponse = await getUsersForGroup.call(
|
||||||
|
this,
|
||||||
|
group.GroupName as string,
|
||||||
|
userPoolId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (usersResponse.length > 0) {
|
||||||
|
return items.map((item) => ({
|
||||||
|
json: { ...item.json, Users: usersResponse },
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return items.map((item) => ({
|
||||||
|
json: { ...item.json },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const groups = (response.body as { Groups: IDataObject[] }).Groups;
|
||||||
|
|
||||||
|
for (const group of groups) {
|
||||||
|
const usersResponse = await getUsersForGroup.call(
|
||||||
|
this,
|
||||||
|
group.GroupName as string,
|
||||||
|
userPoolId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (usersResponse.length > 0) {
|
||||||
|
processedGroups.push({
|
||||||
|
...group,
|
||||||
|
Users: usersResponse,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
processedGroups.push(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items.map((item) => ({
|
||||||
|
json: { ...item.json, Groups: processedGroups },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if needed
|
||||||
|
export async function fetchUserPoolConfig(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
requestOptions: IHttpRequestOptions,
|
||||||
|
): Promise<IHttpRequestOptions> {
|
||||||
|
const userPoolIdRaw = this.getNodeParameter('userPoolId') as IDataObject;
|
||||||
|
const userPoolId = userPoolIdRaw.value as string;
|
||||||
|
|
||||||
|
if (!userPoolId) {
|
||||||
|
throw new ApplicationError('User Pool ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const opts: IHttpRequestOptions = {
|
||||||
|
url: '',
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
UserPoolId: userPoolId,
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'X-Amz-Target': 'AWSCognitoIdentityProviderService.DescribeUserPool',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const responseData: IDataObject = await awsRequest.call(this, opts);
|
||||||
|
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@ import type { INodeProperties } from 'n8n-workflow';
|
||||||
import {
|
import {
|
||||||
handleErrorPostReceive,
|
handleErrorPostReceive,
|
||||||
handlePagination,
|
handlePagination,
|
||||||
presendOptions,
|
presendAdditionalFields,
|
||||||
presendPath,
|
presendVerifyPath,
|
||||||
|
processUsersForGroups,
|
||||||
} from '../GenericFunctions';
|
} from '../GenericFunctions';
|
||||||
|
|
||||||
export const groupOperations: INodeProperties[] = [
|
export const groupOperations: INodeProperties[] = [
|
||||||
|
@ -77,7 +78,7 @@ export const groupOperations: INodeProperties[] = [
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
postReceive: [handleErrorPostReceive],
|
postReceive: [processUsersForGroups, handleErrorPostReceive],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
action: 'Get group',
|
action: 'Get group',
|
||||||
|
@ -101,7 +102,7 @@ export const groupOperations: INodeProperties[] = [
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
postReceive: [handleErrorPostReceive],
|
postReceive: [processUsersForGroups, handleErrorPostReceive],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
action: 'Get many groups',
|
action: 'Get many groups',
|
||||||
|
@ -112,7 +113,7 @@ export const groupOperations: INodeProperties[] = [
|
||||||
description: 'Update an existing group',
|
description: 'Update an existing group',
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
send: {
|
||||||
preSend: [presendOptions],
|
preSend: [presendAdditionalFields],
|
||||||
},
|
},
|
||||||
request: {
|
request: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -264,7 +265,7 @@ const createFields: INodeProperties[] = [
|
||||||
send: {
|
send: {
|
||||||
property: 'Path',
|
property: 'Path',
|
||||||
type: 'body',
|
type: 'body',
|
||||||
preSend: [presendPath],
|
preSend: [presendVerifyPath],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -492,6 +493,19 @@ const getFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Include User List',
|
||||||
|
name: 'includeUsers',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['group'],
|
||||||
|
operation: ['get'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
description: 'Whether to include a list of users in the group',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const getAllFields: INodeProperties[] = [
|
const getAllFields: INodeProperties[] = [
|
||||||
|
@ -553,6 +567,19 @@ const getAllFields: INodeProperties[] = [
|
||||||
displayOptions: { show: { resource: ['group'], operation: ['getAll'], returnAll: [false] } },
|
displayOptions: { show: { resource: ['group'], operation: ['getAll'], returnAll: [false] } },
|
||||||
routing: { send: { type: 'body', property: 'Limit' } },
|
routing: { send: { type: 'body', property: 'Limit' } },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Include User List',
|
||||||
|
name: 'includeUsers',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['group'],
|
||||||
|
operation: ['getAll'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
description: 'Whether to include a list of users in the group',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const updateFields: INodeProperties[] = [
|
const updateFields: INodeProperties[] = [
|
||||||
|
@ -657,8 +684,8 @@ const updateFields: INodeProperties[] = [
|
||||||
type: 'resourceLocator',
|
type: 'resourceLocator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Options',
|
displayName: 'Additional Fields',
|
||||||
name: 'options',
|
name: 'additionalFields',
|
||||||
default: {},
|
default: {},
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
|
@ -708,7 +735,7 @@ const updateFields: INodeProperties[] = [
|
||||||
send: {
|
send: {
|
||||||
property: 'Path',
|
property: 'Path',
|
||||||
type: 'body',
|
type: 'body',
|
||||||
preSend: [presendPath],
|
preSend: [presendVerifyPath],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import type { INodeProperties } from 'n8n-workflow';
|
import type { INodeProperties } from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
fetchUserPoolConfig,
|
||||||
handleErrorPostReceive,
|
handleErrorPostReceive,
|
||||||
handlePagination,
|
handlePagination,
|
||||||
presendFilter,
|
presendFilter,
|
||||||
|
presendTest,
|
||||||
processAttributes,
|
processAttributes,
|
||||||
|
simplifyData,
|
||||||
} from '../GenericFunctions';
|
} from '../GenericFunctions';
|
||||||
|
|
||||||
export const userOperations: INodeProperties[] = [
|
export const userOperations: INodeProperties[] = [
|
||||||
|
@ -52,6 +55,9 @@ export const userOperations: INodeProperties[] = [
|
||||||
description: 'Create a new user',
|
description: 'Create a new user',
|
||||||
action: 'Create user',
|
action: 'Create user',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: {
|
||||||
|
preSend: [presendTest, fetchUserPoolConfig],
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -104,7 +110,7 @@ export const userOperations: INodeProperties[] = [
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
postReceive: [handleErrorPostReceive],
|
postReceive: [simplifyData, handleErrorPostReceive],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -130,7 +136,7 @@ export const userOperations: INodeProperties[] = [
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
postReceive: [handleErrorPostReceive],
|
postReceive: [simplifyData, handleErrorPostReceive],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
action: 'Get many users',
|
action: 'Get many users',
|
||||||
|
@ -167,6 +173,7 @@ export const userOperations: INodeProperties[] = [
|
||||||
description: 'Update a user',
|
description: 'Update a user',
|
||||||
action: 'Update user',
|
action: 'Update user',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: { preSend: [presendTest] },
|
||||||
request: {
|
request: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -246,7 +253,7 @@ const createFields: INodeProperties[] = [
|
||||||
displayName: 'User Name',
|
displayName: 'User Name',
|
||||||
name: 'Username',
|
name: 'Username',
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The username of the new user to create',
|
description: 'The username of the new user to create. No whitespace is allowed.',
|
||||||
placeholder: 'e.g. JohnSmith',
|
placeholder: 'e.g. JohnSmith',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
|
@ -277,61 +284,51 @@ const createFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
|
//doesn't work
|
||||||
{
|
{
|
||||||
displayName: 'Client Metadata',
|
displayName: 'User Attributes',
|
||||||
name: 'clientMetadata',
|
name: 'UserAttributes',
|
||||||
type: 'fixedCollection',
|
type: 'fixedCollection',
|
||||||
placeholder: 'Add Metadata',
|
placeholder: 'Add Attribute',
|
||||||
default: { metadata: [] },
|
default: {
|
||||||
description: 'A map of custom key-value pairs for workflows triggered by this action',
|
attributes: [],
|
||||||
|
},
|
||||||
|
description: 'Attributes to add for the user',
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
multipleValues: true,
|
multipleValues: true,
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
displayName: 'Metadata',
|
displayName: 'Attributes',
|
||||||
name: 'metadata',
|
name: 'attributes',
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
displayName: 'Key',
|
displayName: 'Name',
|
||||||
name: 'key',
|
name: 'Name',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The key of the metadata attribute',
|
description: 'The name of the attribute (e.g., custom:deliverables)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Value',
|
displayName: 'Value',
|
||||||
name: 'value',
|
name: 'Value',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The value of the metadata attribute',
|
description: 'The value of the attribute',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
send: {
|
||||||
|
preSend: [processAttributes],
|
||||||
type: 'body',
|
type: 'body',
|
||||||
property: 'ClientMetadata',
|
property: 'UserAttributes',
|
||||||
value:
|
value:
|
||||||
'={{ $value.metadata && $value.metadata.length > 0 ? Object.fromEntries($value.metadata.map(attribute => [attribute.Name, attribute.Value])) : {} }}',
|
'={{ $value.attributes?.map(attribute => ({ Name: attribute.Name, Value: attribute.Value })) || [] }}',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
displayName: 'Temporary Password',
|
|
||||||
name: 'TemporaryPassword',
|
|
||||||
default: '',
|
|
||||||
description: "The user's temporary password",
|
|
||||||
routing: {
|
|
||||||
send: {
|
|
||||||
property: 'TemporaryPassword',
|
|
||||||
type: 'body',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: 'string',
|
|
||||||
typeOptions: { password: true },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
displayName: 'Message Action',
|
displayName: 'Message Action',
|
||||||
name: 'MessageAction',
|
name: 'MessageAction',
|
||||||
|
@ -396,88 +393,45 @@ const createFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'User Attributes',
|
displayName: 'Temporary Password',
|
||||||
name: 'UserAttributes',
|
name: 'temporaryPasswordOptions',
|
||||||
type: 'fixedCollection',
|
type: 'options',
|
||||||
placeholder: 'Add Attribute',
|
default: 'generatePassword',
|
||||||
default: {
|
description: 'Choose to set a password manually or one will be automatically generated',
|
||||||
attributes: [],
|
|
||||||
},
|
|
||||||
description: 'Attributes to add for the user',
|
|
||||||
typeOptions: {
|
|
||||||
multipleValues: true,
|
|
||||||
},
|
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
displayName: 'Attributes',
|
name: 'Set a Password',
|
||||||
name: 'attributes',
|
value: 'setPassword',
|
||||||
values: [
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Name',
|
name: 'Generate a Password',
|
||||||
name: 'Name',
|
value: 'generatePassword',
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The name of the attribute (e.g., custom:deliverables)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Value',
|
|
||||||
name: 'Value',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The value of the attribute',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
send: {
|
||||||
preSend: [processAttributes],
|
property: 'TemporaryPassword',
|
||||||
type: 'body',
|
type: 'body',
|
||||||
property: 'UserAttributes',
|
|
||||||
value:
|
|
||||||
'={{ $value.attributes?.map(attribute => ({ Name: attribute.Name, Value: attribute.Value })) || [] }}',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Validation Data',
|
displayName: 'Password',
|
||||||
name: 'ValidationData',
|
name: 'password',
|
||||||
type: 'fixedCollection',
|
type: 'string',
|
||||||
placeholder: 'Add Attribute',
|
typeOptions: { password: true },
|
||||||
default: {
|
default: '',
|
||||||
attributes: [],
|
placeholder: 'Enter a temporary password',
|
||||||
},
|
description: "The user's temporary password",
|
||||||
description: 'Validation data to add for the user',
|
displayOptions: {
|
||||||
typeOptions: {
|
show: {
|
||||||
multipleValues: true,
|
temporaryPasswordOptions: ['setPassword'],
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
displayName: 'Data',
|
|
||||||
name: 'data',
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
displayName: 'Key',
|
|
||||||
name: 'Key',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The name of the data (e.g., custom:deliverables)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Value',
|
|
||||||
name: 'Value',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The value of the data',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
},
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
send: {
|
||||||
|
property: 'TemporaryPassword',
|
||||||
type: 'body',
|
type: 'body',
|
||||||
property: 'ValidationData',
|
|
||||||
value: '={{ $value.data?.map(data => ({ Name: data.Key, Value: data.Value })) || [] }}',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -586,6 +540,19 @@ const getFields: INodeProperties[] = [
|
||||||
required: true,
|
required: true,
|
||||||
type: 'resourceLocator',
|
type: 'resourceLocator',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Simplify',
|
||||||
|
name: 'simple',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['user'],
|
||||||
|
operation: ['get'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const getAllFields: INodeProperties[] = [
|
const getAllFields: INodeProperties[] = [
|
||||||
|
@ -660,48 +627,35 @@ const getAllFields: INodeProperties[] = [
|
||||||
displayOptions: { show: { resource: ['user'], operation: ['getAll'], returnAll: [false] } },
|
displayOptions: { show: { resource: ['user'], operation: ['getAll'], returnAll: [false] } },
|
||||||
routing: { send: { type: 'body', property: 'Limit' } },
|
routing: { send: { type: 'body', property: 'Limit' } },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Simplify',
|
||||||
|
name: 'simple',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['user'],
|
||||||
|
operation: ['getAll'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Additional Fields',
|
displayName: 'Additional Fields',
|
||||||
name: 'additionalFields',
|
name: 'additionalFields',
|
||||||
type: 'collection',
|
type: 'collection',
|
||||||
placeholder: 'Add Field',
|
placeholder: 'Add Field',
|
||||||
default: {},
|
default: {},
|
||||||
displayOptions: { show: { resource: ['user'], operation: ['getAll'] } },
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['user'],
|
||||||
|
operation: ['getAll'],
|
||||||
|
},
|
||||||
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
displayName: 'Attributes To Get',
|
displayName: 'Filters',
|
||||||
name: 'attributesToGet',
|
name: 'filters',
|
||||||
type: 'fixedCollection',
|
|
||||||
typeOptions: { multipleValues: true },
|
|
||||||
default: {},
|
|
||||||
placeholder: 'Add Attribute',
|
|
||||||
description: 'The attributes to return in the response',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: 'metadataValues',
|
|
||||||
displayName: 'Metadata',
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
displayName: 'Attribute',
|
|
||||||
name: 'attribute',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The attribute name to return',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
routing: {
|
|
||||||
send: {
|
|
||||||
type: 'body',
|
|
||||||
property: 'AttributesToGet',
|
|
||||||
value: '={{ $value.metadataValues.map(attribute => attribute.attribute) }}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Filter Attribute',
|
|
||||||
name: 'filterAttribute',
|
|
||||||
type: 'options',
|
type: 'options',
|
||||||
default: 'username',
|
default: 'username',
|
||||||
hint: 'Make sure to select an attribute, type, and provide a value before submitting.',
|
hint: 'Make sure to select an attribute, type, and provide a value before submitting.',
|
||||||
|
@ -896,7 +850,7 @@ const updateFields: INodeProperties[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'User',
|
displayName: 'User Name',
|
||||||
name: 'Username',
|
name: 'Username',
|
||||||
default: {
|
default: {
|
||||||
mode: 'list',
|
mode: 'list',
|
||||||
|
@ -988,6 +942,7 @@ const updateFields: INodeProperties[] = [
|
||||||
],
|
],
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
send: {
|
||||||
|
preSend: [processAttributes],
|
||||||
type: 'body',
|
type: 'body',
|
||||||
property: 'UserAttributes',
|
property: 'UserAttributes',
|
||||||
value:
|
value:
|
||||||
|
@ -995,62 +950,6 @@ const updateFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
displayName: 'Additional Fields',
|
|
||||||
name: 'additionalFields',
|
|
||||||
type: 'collection',
|
|
||||||
placeholder: 'Add Field',
|
|
||||||
default: {},
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
resource: ['user'],
|
|
||||||
operation: ['update'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
displayName: 'Client Metadata',
|
|
||||||
name: 'clientMetadata',
|
|
||||||
type: 'fixedCollection',
|
|
||||||
placeholder: 'Add Metadata Pair',
|
|
||||||
default: { metadata: [] },
|
|
||||||
description: 'A map of custom key-value pairs for workflows triggered by this action',
|
|
||||||
typeOptions: {
|
|
||||||
multipleValues: true,
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
displayName: 'Metadata',
|
|
||||||
name: 'metadata',
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
displayName: 'Key',
|
|
||||||
name: 'key',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The key of the metadata attribute',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Value',
|
|
||||||
name: 'value',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The value of the metadata attribute',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
routing: {
|
|
||||||
send: {
|
|
||||||
type: 'body',
|
|
||||||
property: 'ClientMetadata',
|
|
||||||
value:
|
|
||||||
'={{ $value.metadata && $value.metadata.length > 0 ? Object.fromEntries($value.metadata.map(attribute => [attribute.Name, attribute.Value])) : {} }}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const addToGroupFields: INodeProperties[] = [
|
const addToGroupFields: INodeProperties[] = [
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { INodeProperties } from 'n8n-workflow';
|
import type { INodeProperties } from 'n8n-workflow';
|
||||||
|
import { presendTest, simplifyData } from '../GenericFunctions';
|
||||||
|
|
||||||
export const userPoolOperations: INodeProperties[] = [
|
export const userPoolOperations: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
|
@ -13,12 +14,26 @@ export const userPoolOperations: INodeProperties[] = [
|
||||||
value: 'get',
|
value: 'get',
|
||||||
action: 'Describe the configuration of a user pool',
|
action: 'Describe the configuration of a user pool',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: {
|
||||||
|
preSend: [presendTest],
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'X-Amz-Target': 'AWSCognitoIdentityProviderService.DescribeUserPool',
|
'X-Amz-Target': 'AWSCognitoIdentityProviderService.DescribeUserPool',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
output: {
|
||||||
|
postReceive: [
|
||||||
|
simplifyData,
|
||||||
|
{
|
||||||
|
type: 'rootProperty',
|
||||||
|
properties: {
|
||||||
|
property: 'UserPool',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -28,7 +43,7 @@ export const userPoolOperations: INodeProperties[] = [
|
||||||
|
|
||||||
export const userPoolFields: INodeProperties[] = [
|
export const userPoolFields: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'User Pool ID',
|
displayName: 'User Pool',
|
||||||
name: 'userPoolId',
|
name: 'userPoolId',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'resourceLocator',
|
type: 'resourceLocator',
|
||||||
|
@ -69,4 +84,17 @@ export const userPoolFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Simplify',
|
||||||
|
name: 'simple',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['userPool'],
|
||||||
|
operation: ['get'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue