n8n-nodes-binalyze-air
Version:
Binalyze AIR nodes for automating DFIR with n8n workflows
378 lines • 14.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.UsersOperations = void 0;
exports.extractUserId = extractUserId;
exports.isValidUser = isValidUser;
exports.fetchAllUsers = fetchAllUsers;
exports.findUserByUsername = findUserByUsername;
exports.getUsers = getUsers;
exports.getUsersOptions = getUsersOptions;
exports.executeUsers = executeUsers;
const n8n_workflow_1 = require("n8n-workflow");
const helpers_1 = require("../utils/helpers");
const users_1 = require("../api/users/users");
const organizations_1 = require("./organizations");
exports.UsersOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['users'],
},
},
options: [
{
name: 'Get Many',
value: 'getAll',
description: 'Retrieve many users',
action: 'Get many users',
},
{
name: 'Get',
value: 'get',
description: 'Retrieve a specific user',
action: 'Get a user',
},
],
default: 'getAll',
},
{
displayName: 'User',
name: 'userId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a user...',
displayOptions: {
show: {
resource: ['users'],
operation: ['get'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a user...',
typeOptions: {
searchListMethod: 'getUsers',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '^[a-zA-Z0-9-_]+$',
errorMessage: 'Not a valid user ID (must contain only letters, numbers, hyphens, and underscores)',
},
},
],
placeholder: 'Enter user ID (alphanumeric or GUID)',
},
{
displayName: 'By Username',
name: 'username',
type: 'string',
placeholder: 'Enter username or email',
},
],
required: true,
description: 'The user to retrieve',
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['users'],
operation: ['getAll'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select an organization...',
typeOptions: {
searchListMethod: 'getOrganizations',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '^[0-9]+$',
errorMessage: 'Not a valid organization ID (must be numeric)',
},
},
],
placeholder: 'Enter organization ID (use 0 for all organizations)',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
description: 'The organization to filter users by',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['users'],
operation: ['getAll'],
},
},
options: [
{
displayName: 'Page Number',
name: 'pageNumber',
type: 'number',
default: 1,
description: 'Which page of results to return',
typeOptions: {
minValue: 1,
},
},
{
displayName: 'Page Size',
name: 'pageSize',
type: 'number',
default: 100,
description: 'How many results to return per page',
typeOptions: {
minValue: 1,
},
},
{
displayName: 'Filter By Roles',
name: 'roles',
type: 'string',
default: '',
description: 'Filter users by roles (comma-separated)',
},
],
},
];
function extractUserId(user) {
return (0, helpers_1.extractEntityId)(user, 'user');
}
function isValidUser(user) {
return (0, helpers_1.isValidEntity)(user, ['username', 'email']);
}
async function fetchAllUsers(context, credentials, organizationIds = '0', searchFilter, pageSize = 100) {
var _a;
const allUsers = [];
let currentPage = 1;
let hasMorePages = true;
while (hasMorePages) {
const additionalParams = {
pageNumber: currentPage,
pageSize,
searchTerm: searchFilter,
};
const responseData = await users_1.api.getUsers(context, credentials, organizationIds, additionalParams);
const users = ((_a = responseData.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
allUsers.push(...users);
const result = responseData.result;
if (result && result.currentPage && result.totalPageCount && result.currentPage < result.totalPageCount) {
currentPage++;
}
else {
hasMorePages = false;
}
}
return allUsers;
}
async function findUserByUsername(context, credentials, username, organizationIds = '0') {
var _a, _b;
const searchUsername = username.trim();
if (!searchUsername) {
throw new Error('Username cannot be empty');
}
const responseData = await users_1.api.getUsers(context, credentials, organizationIds, {
searchTerm: searchUsername,
});
const users = ((_a = responseData.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
let exactMatch = users.find((user) => (user.username && user.username.toLowerCase() === searchUsername.toLowerCase()) ||
(user.email && user.email.toLowerCase() === searchUsername.toLowerCase()));
if (!exactMatch) {
const allUsersResponse = await users_1.api.getUsers(context, credentials, organizationIds);
const allUsers = ((_b = allUsersResponse.result) === null || _b === void 0 ? void 0 : _b.entities) || [];
exactMatch = allUsers.find((user) => (user.username && user.username.toLowerCase() === searchUsername.toLowerCase()) ||
(user.email && user.email.toLowerCase() === searchUsername.toLowerCase()));
}
if (!exactMatch) {
const suggestions = users
.map((user) => user.username || user.email)
.filter(Boolean)
.slice(0, 5);
let errorMessage = `User '${searchUsername}' not found.`;
if (suggestions.length > 0) {
errorMessage += ` Similar users: ${suggestions.join(', ')}`;
}
throw new Error(errorMessage);
}
return extractUserId(exactMatch);
}
async function getUsers(filter) {
try {
const credentials = await (0, helpers_1.getAirCredentials)(this);
const allUsers = await fetchAllUsers(this, credentials, '0', filter);
return (0, helpers_1.createListSearchResults)(allUsers, isValidUser, (user) => ({
name: user.username || user.email || `User ${extractUserId(user)}`,
value: extractUserId(user),
url: user.url || '',
}), filter);
}
catch (error) {
throw (0, helpers_1.catchAndFormatError)(error, 'load users');
}
}
async function getUsersOptions() {
try {
const credentials = await (0, helpers_1.getAirCredentials)(this);
const allUsers = await fetchAllUsers(this, credentials, '0');
return (0, helpers_1.createLoadOptions)(allUsers, isValidUser, (user) => {
const userId = extractUserId(user);
const name = user.username || user.email || `User ${userId || 'Unknown'}`;
return {
name,
value: userId,
};
});
}
catch (error) {
throw (0, helpers_1.catchAndFormatError)(error, 'load users');
}
}
async function executeUsers() {
var _a;
const items = this.getInputData();
const returnData = [];
const credentials = await (0, helpers_1.getAirCredentials)(this);
for (let i = 0; i < items.length; i++) {
try {
const operation = this.getNodeParameter('operation', i);
switch (operation) {
case 'getAll': {
const organizationResource = this.getNodeParameter('organizationId', i);
const additionalFields = this.getNodeParameter('additionalFields', i);
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
if (organizationResource.value.toLowerCase() === 'all organizations') {
organizationId = '0';
}
else {
organizationId = await (0, organizations_1.findOrganizationByName)(this, credentials, organizationResource.value);
}
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid organization selection mode', {
itemIndex: i,
});
}
if (!organizationId && organizationId !== '0') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization selection is required', {
itemIndex: i,
});
}
const additionalParams = {
pageNumber: additionalFields.pageNumber,
pageSize: additionalFields.pageSize,
roles: additionalFields.roles,
};
const responseData = await users_1.api.getUsers(this, credentials, organizationId, additionalParams);
const entities = ((_a = responseData.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
const paginationInfo = (0, helpers_1.extractPaginationInfo)(responseData.result);
(0, helpers_1.processApiResponseEntities)(entities, returnData, i, {
includePagination: true,
paginationData: paginationInfo,
excludeFields: ['sortables', 'filters'],
});
break;
}
case 'get': {
const userResource = this.getNodeParameter('userId', i);
let userId;
if (userResource.mode === 'list' || userResource.mode === 'id') {
userId = userResource.value;
}
else if (userResource.mode === 'username') {
try {
userId = await findUserByUsername(this, credentials, userResource.value);
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid user selection mode', {
itemIndex: i,
});
}
try {
userId = (0, helpers_1.normalizeAndValidateId)(userId, 'User ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
const responseData = await users_1.api.getUserById(this, credentials, userId);
const userData = responseData.result;
if (!userData) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'User not found', {
itemIndex: i,
});
}
returnData.push({
json: userData,
pairedItem: i,
});
break;
}
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The operation "${operation}" is not supported`, {
itemIndex: i,
});
}
}
catch (error) {
(0, helpers_1.handleExecuteError)(this, error, i, returnData);
}
}
return [returnData];
}
//# sourceMappingURL=users.js.map