UNPKG

n8n-nodes-binalyze-air

Version:

Binalyze AIR nodes for automating DFIR with n8n workflows

1,251 lines 56.2 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrganizationsOperations = void 0;
exports.extractOrganizationId = extractOrganizationId;
exports.isValidOrganization = isValidOrganization;
exports.findOrganizationByName = findOrganizationByName;
exports.getOrganizations = getOrganizations;
exports.getOrganizationsOptions = getOrganizationsOptions;
exports.executeOrganizations = executeOrganizations;
const n8n_workflow_1 = require("n8n-workflow");
const helpers_1 = require("../utils/helpers");
const organizations_1 = require("../api/organizations/organizations");
const users_1 = require("../api/organizations/users/users");
exports.OrganizationsOperations = [
    {
        displayName: 'Operation',
        name: 'operation',
        type: 'options',
        noDataExpression: true,
        displayOptions: {
            show: {
                resource: ['organizations'],
            },
        },
        options: [
            {
                name: 'Add Tags',
                value: 'addTags',
                description: 'Add tags to an organization',
                action: 'Add tags to an organization',
            },
            {
                name: 'Assign User',
                value: 'assignUser',
                description: 'Assign a user to an organization',
                action: 'Assign a user to an organization',
            },
            {
                name: 'Check Name Exists',
                value: 'checkNameExists',
                description: 'Check if an organization name already exists',
                action: 'Check if organization name exists',
            },
            {
                name: 'Create',
                value: 'create',
                description: 'Create a new organization',
                action: 'Create an organization',
            },
            {
                name: 'Get',
                value: 'get',
                description: 'Retrieve a specific organization',
                action: 'Get an organization',
            },
            {
                name: 'Get Many',
                value: 'getAll',
                description: 'Retrieve many organizations',
                action: 'Get many organizations',
            },
            {
                name: 'Get Users',
                value: 'getUsers',
                description: 'Retrieve users assigned to an organization',
                action: 'Get users of an organization',
            },
            {
                name: 'Remove Tags',
                value: 'removeTags',
                description: 'Remove tags from an organization',
                action: 'Remove tags from an organization',
            },
            {
                name: 'Remove User',
                value: 'removeUser',
                description: 'Remove a user from an organization',
                action: 'Remove a user from an organization',
            },
            {
                name: 'Update',
                value: 'update',
                description: 'Update an organization',
                action: 'Update an organization',
            },
            {
                name: 'Update Shareable Deployment',
                value: 'updateShareableDeployment',
                description: 'Update organization shareable deployment status',
                action: 'Update shareable deployment status',
            },
        ],
        default: 'getAll',
    },
    {
        displayName: 'Organization',
        name: 'organizationId',
        type: 'resourceLocator',
        default: { mode: 'list', value: '' },
        placeholder: 'Select an organization...',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['get', 'getUsers', 'addTags', 'removeTags', 'assignUser', 'removeUser', 'update', 'updateShareableDeployment'],
            },
        },
        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 a positive number or 0 for default organization)',
                        },
                    },
                ],
                placeholder: 'Enter Organization ID (0 for default organization)',
            },
            {
                displayName: 'By Name',
                name: 'name',
                type: 'string',
                placeholder: 'Enter organization name',
            },
        ],
        required: true,
        description: 'The organization to retrieve',
    },
    {
        displayName: 'Tags',
        name: 'tags',
        type: 'string',
        default: '',
        placeholder: 'tag1, tag2, tag3',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['addTags', 'removeTags'],
            },
        },
        required: true,
        description: 'Comma-separated list of tags to add or remove',
    },
    {
        displayName: 'Organization Name',
        name: 'name',
        type: 'string',
        default: '',
        placeholder: 'Enter organization name',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['create'],
            },
        },
        required: true,
        description: 'Name of the organization (1-50 characters)',
        typeOptions: {
            validation: [
                {
                    type: 'regex',
                    properties: {
                        regex: '^(?!\\s*$).{1,50}$',
                        errorMessage: 'Organization name must be 1-50 characters and cannot be empty or only whitespace',
                    },
                },
            ],
        },
    },
    {
        displayName: 'Shareable Deployment Enabled',
        name: 'shareableDeploymentEnabled',
        type: 'boolean',
        default: false,
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['create'],
            },
        },
        required: true,
        description: 'Whether shareable deployment is enabled for this organization',
    },
    {
        displayName: 'Contact Name',
        name: 'contactName',
        type: 'string',
        default: '',
        placeholder: 'Enter contact name',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['create'],
            },
        },
        required: true,
        description: 'Name of the contact person for this organization',
        typeOptions: {
            validation: [
                {
                    type: 'regex',
                    properties: {
                        regex: '^(?!\\s*$).+$',
                        errorMessage: 'Contact name cannot be empty or only whitespace',
                    },
                },
            ],
        },
    },
    {
        displayName: 'Contact Email',
        name: 'contactEmail',
        type: 'string',
        default: '',
        placeholder: 'Enter contact email',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['create'],
            },
        },
        required: true,
        description: 'Email address of the contact person',
        typeOptions: {
            validation: [
                {
                    type: 'regex',
                    properties: {
                        regex: '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$',
                        errorMessage: 'Please enter a valid email address',
                    },
                },
            ],
        },
    },
    {
        displayName: 'Organization Name to Check',
        name: 'nameToCheck',
        type: 'string',
        default: '',
        placeholder: 'Enter organization name to check',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['checkNameExists'],
            },
        },
        required: true,
        description: 'Name of the organization to check for existence',
    },
    {
        displayName: 'User ID',
        name: 'userId',
        type: 'string',
        default: '',
        placeholder: 'Enter user ID',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['assignUser'],
            },
        },
        required: true,
        description: 'The ID of the user to assign to the organization',
        typeOptions: {
            validation: [
                {
                    type: 'regex',
                    properties: {
                        regex: '^[a-zA-Z0-9-_]+$',
                        errorMessage: 'Not a valid user ID (must contain only letters, numbers, hyphens, and underscores)',
                    },
                },
            ],
        },
    },
    {
        displayName: 'User ID',
        name: 'userId',
        type: 'string',
        default: '',
        placeholder: 'Enter user ID',
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['removeUser'],
            },
        },
        required: true,
        description: 'The ID of the user to remove from the organization',
        typeOptions: {
            validation: [
                {
                    type: 'regex',
                    properties: {
                        regex: '^[a-zA-Z0-9-_]+$',
                        errorMessage: 'Not a valid user ID (must contain only letters, numbers, hyphens, and underscores)',
                    },
                },
            ],
        },
    },
    {
        displayName: 'Shareable Deployment Status',
        name: 'shareableDeploymentStatus',
        type: 'boolean',
        default: false,
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['updateShareableDeployment'],
            },
        },
        required: true,
        description: 'Whether to enable or disable shareable deployment for the organization',
    },
    {
        displayName: 'Update Fields',
        name: 'updateFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['update'],
            },
        },
        options: [
            {
                displayName: 'Contact Email',
                name: 'contactEmail',
                type: 'string',
                default: '',
                placeholder: 'Enter contact email',
                description: 'Email address of the contact person',
                typeOptions: {
                    validation: [
                        {
                            type: 'regex',
                            properties: {
                                regex: '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$',
                                errorMessage: 'Please enter a valid email address',
                            },
                        },
                    ],
                },
            },
            {
                displayName: 'Contact Mobile',
                name: 'contactMobile',
                type: 'string',
                default: '',
                placeholder: 'Enter contact mobile',
                description: 'Mobile number of the contact person',
            },
            {
                displayName: 'Contact Name',
                name: 'contactName',
                type: 'string',
                default: '',
                placeholder: 'Enter contact name',
                description: 'Name of the contact person for this organization',
            },
            {
                displayName: 'Contact Phone',
                name: 'contactPhone',
                type: 'string',
                default: '',
                placeholder: 'Enter contact phone',
                description: 'Phone number of the contact person',
            },
            {
                displayName: 'Contact Title',
                name: 'contactTitle',
                type: 'string',
                default: '',
                placeholder: 'Enter contact title',
                description: 'Title of the contact person',
            },
            {
                displayName: 'Note',
                name: 'note',
                type: 'string',
                default: '',
                placeholder: 'Enter a note about this organization',
                description: 'Additional notes about the organization',
            },
        ],
    },
    {
        displayName: 'Additional Fields',
        name: 'additionalFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['organizations'],
                operation: ['getAll', 'getUsers', 'create'],
            },
        },
        options: [
            {
                displayName: 'Contact Mobile',
                name: 'contactMobile',
                type: 'string',
                default: '',
                placeholder: 'Enter contact mobile',
                description: 'Mobile number of the contact person',
                displayOptions: {
                    show: {
                        '/operation': ['create'],
                    },
                },
            },
            {
                displayName: 'Contact Phone',
                name: 'contactPhone',
                type: 'string',
                default: '',
                placeholder: 'Enter contact phone',
                description: 'Phone number of the contact person',
                displayOptions: {
                    show: {
                        '/operation': ['create'],
                    },
                },
            },
            {
                displayName: 'Contact Title',
                name: 'contactTitle',
                type: 'string',
                default: '',
                placeholder: 'Enter contact title',
                description: 'Title of the contact person',
                displayOptions: {
                    show: {
                        '/operation': ['create'],
                    },
                },
            },
            {
                displayName: 'Filter By Name',
                name: 'name',
                type: 'string',
                default: '',
                description: 'Filter organizations by exact name match',
                displayOptions: {
                    show: {
                        '/operation': ['getAll'],
                    },
                },
            },
            {
                displayName: 'Note',
                name: 'note',
                type: 'string',
                default: '',
                placeholder: 'Enter a note about this organization',
                description: 'Additional notes about the organization',
                displayOptions: {
                    show: {
                        '/operation': ['create'],
                    },
                },
            },
            {
                displayName: 'Page Number',
                name: 'pageNumber',
                type: 'number',
                default: 1,
                description: 'Which page of results to return',
                displayOptions: {
                    show: {
                        '/operation': ['getAll', 'getUsers'],
                    },
                },
                typeOptions: {
                    minValue: 1,
                },
            },
            {
                displayName: 'Page Size',
                name: 'pageSize',
                type: 'number',
                default: 100,
                description: 'How many results to return per page',
                displayOptions: {
                    show: {
                        '/operation': ['getAll', 'getUsers'],
                    },
                },
                typeOptions: {
                    minValue: 1,
                },
            },
            {
                displayName: 'Search Term',
                name: 'searchTerm',
                type: 'string',
                default: '',
                description: 'Search organizations by name (supports partial matches)',
                displayOptions: {
                    show: {
                        '/operation': ['getAll'],
                    },
                },
            },
        ],
    },
];
function extractOrganizationId(organization) {
    if (organization._id !== undefined && organization._id !== null && organization._id !== '') {
        return String(organization._id);
    }
    if (organization._id === 0) {
        return '0';
    }
    return (0, helpers_1.extractEntityId)(organization, 'organization');
}
function isValidOrganization(org) {
    if (!org)
        return false;
    try {
        extractOrganizationId(org);
        return true;
    }
    catch {
        return false;
    }
}
async function findOrganizationByName(context, credentials, organizationName) {
    const searchName = organizationName.trim();
    if (!searchName) {
        throw new Error('Organization name cannot be empty');
    }
    try {
        const organizations = await organizations_1.api.getAllOrganizations(context, credentials, searchName);
        const exactMatch = organizations.find((org) => org.name && org.name.toLowerCase() === searchName.toLowerCase());
        if (!exactMatch) {
            const allOrganizations = await organizations_1.api.getAllOrganizations(context, credentials);
            const exactMatchInAll = allOrganizations.find((org) => org.name && org.name.toLowerCase() === searchName.toLowerCase());
            if (exactMatchInAll) {
                return extractOrganizationId(exactMatchInAll);
            }
            const suggestions = allOrganizations
                .filter((org) => org.name && org.name.toLowerCase().includes(searchName.toLowerCase()))
                .map((org) => org.name)
                .slice(0, 5);
            let errorMessage = `Organization '${searchName}' not found.`;
            if (suggestions.length > 0) {
                errorMessage += ` Similar organizations: ${suggestions.join(', ')}`;
            }
            throw new Error(errorMessage);
        }
        return extractOrganizationId(exactMatch);
    }
    catch (error) {
        throw new Error(`Failed to find organization by name: ${error instanceof Error ? error.message : String(error)}`);
    }
}
async function getOrganizations(filter) {
    var _a;
    try {
        const credentials = await (0, helpers_1.getAirCredentials)(this);
        const options = filter ? { name: filter, pageSize: 50, pageNumber: 1 } : { pageSize: 50, pageNumber: 1 };
        const response = await organizations_1.api.getOrganizations(this, credentials, options);
        const organizations = ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
        return (0, helpers_1.createListSearchResults)(organizations, isValidOrganization, (organization) => {
            const orgId = extractOrganizationId(organization);
            const name = orgId === '0'
                ? `${organization.name || 'Organization'} (Default)`
                : (organization.name || `Organization ${orgId}`);
            const resourceValue = orgId === '0' ? '0' : orgId;
            return {
                name: name,
                value: resourceValue,
            };
        }, filter);
    }
    catch (error) {
        throw (0, helpers_1.catchAndFormatError)(error, 'load organizations');
    }
}
async function getOrganizationsOptions() {
    try {
        const credentials = await (0, helpers_1.getAirCredentials)(this);
        const allOrganizations = await organizations_1.api.getAllOrganizations(this, credentials);
        return (0, helpers_1.createLoadOptions)(allOrganizations, isValidOrganization, (organization) => {
            const orgId = extractOrganizationId(organization);
            const name = organization.name || `Organization ${orgId}`;
            return {
                name,
                value: orgId,
            };
        });
    }
    catch (error) {
        throw (0, helpers_1.catchAndFormatError)(error, 'load organizations');
    }
}
async function executeOrganizations() {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
    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 additionalFields = this.getNodeParameter('additionalFields', i);
                    const options = {};
                    if (additionalFields.pageNumber) {
                        options.pageNumber = additionalFields.pageNumber;
                    }
                    if (additionalFields.pageSize) {
                        options.pageSize = additionalFields.pageSize;
                    }
                    if (additionalFields.searchTerm) {
                        options.searchTerm = additionalFields.searchTerm;
                    }
                    if (additionalFields.name) {
                        options.nameFilter = additionalFields.name;
                    }
                    const response = await organizations_1.api.getOrganizations(this, credentials, Object.keys(options).length > 0 ? options : undefined);
                    (0, helpers_1.validateApiResponse)(response);
                    const entities = ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
                    const paginationInfo = (0, helpers_1.extractPaginationInfo)(response.result);
                    const processedEntities = processOrganizationEntities(entities, credentials.instanceUrl);
                    (0, helpers_1.processApiResponseEntities)(processedEntities, returnData, i, {
                        includePagination: true,
                        paginationData: paginationInfo,
                        excludeFields: ['sortables', 'filters'],
                    });
                    break;
                }
                case 'get': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const response = await organizations_1.api.getOrganizationById(this, credentials, parseInt(organizationId));
                    if (!response.success) {
                        const errorMessage = ((_b = response.errors) === null || _b === void 0 ? void 0 : _b.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    if (!response.result) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization not found', {
                            itemIndex: i,
                        });
                    }
                    const enrichedOrganization = enrichOrganizationEntity(response.result, credentials.instanceUrl);
                    returnData.push({
                        json: enrichedOrganization,
                        pairedItem: i,
                    });
                    break;
                }
                case 'getUsers': {
                    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 {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const options = {};
                    if (additionalFields.pageNumber) {
                        options.pageNumber = additionalFields.pageNumber;
                    }
                    if (additionalFields.pageSize) {
                        options.pageSize = additionalFields.pageSize;
                    }
                    const response = await users_1.api.getOrganizationUsers(this, credentials, parseInt(organizationId), Object.keys(options).length > 0 ? options : undefined);
                    (0, helpers_1.validateApiResponse)(response);
                    const entities = ((_c = response.result) === null || _c === void 0 ? void 0 : _c.entities) || [];
                    const paginationInfo = (0, helpers_1.extractPaginationInfo)(response.result);
                    (0, helpers_1.processApiResponseEntities)(entities, returnData, i, {
                        includePagination: true,
                        paginationData: paginationInfo,
                        excludeFields: ['sortables', 'filters'],
                    });
                    break;
                }
                case 'addTags': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    const tags = this.getNodeParameter('tags', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const tagList = tags.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0);
                    if (tagList.length === 0) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one tag must be provided', {
                            itemIndex: i,
                        });
                    }
                    const response = await organizations_1.api.addTagsToOrganization(this, credentials, parseInt(organizationId), tagList);
                    if (!response.success) {
                        const errorMessage = ((_d = response.errors) === null || _d === void 0 ? void 0 : _d.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to add tags to organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    const processedResult = response.result ? enrichOrganizationEntity(response.result, credentials.instanceUrl) : response.result;
                    returnData.push({
                        json: processedResult,
                        pairedItem: i,
                    });
                    break;
                }
                case 'removeTags': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    const tags = this.getNodeParameter('tags', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const tagList = tags.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0);
                    if (tagList.length === 0) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one tag must be provided', {
                            itemIndex: i,
                        });
                    }
                    const response = await organizations_1.api.deleteTagsFromOrganization(this, credentials, parseInt(organizationId), tagList);
                    if (!response.success) {
                        const errorMessage = ((_e = response.errors) === null || _e === void 0 ? void 0 : _e.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to remove tags from organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    const processedResult = response.result ? enrichOrganizationEntity(response.result, credentials.instanceUrl) : response.result;
                    returnData.push({
                        json: processedResult,
                        pairedItem: i,
                    });
                    break;
                }
                case 'create': {
                    const name = this.getNodeParameter('name', i);
                    const shareableDeploymentEnabled = this.getNodeParameter('shareableDeploymentEnabled', i);
                    const contactName = this.getNodeParameter('contactName', i);
                    const contactEmail = this.getNodeParameter('contactEmail', i);
                    const additionalFields = this.getNodeParameter('additionalFields', i);
                    const trimmedName = name.trim();
                    if (!trimmedName) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization name cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    const trimmedContactName = contactName.trim();
                    if (!trimmedContactName) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Contact name cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    const trimmedContactEmail = contactEmail.trim();
                    if (!trimmedContactEmail) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Contact email cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                    if (!emailRegex.test(trimmedContactEmail)) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Contact email must be a valid email address', {
                            itemIndex: i,
                        });
                    }
                    const createData = {
                        name: trimmedName,
                        shareableDeploymentEnabled,
                        contact: {
                            name: trimmedContactName,
                            title: ((_f = additionalFields.contactTitle) === null || _f === void 0 ? void 0 : _f.trim()) || '',
                            phone: ((_g = additionalFields.contactPhone) === null || _g === void 0 ? void 0 : _g.trim()) || '',
                            mobile: ((_h = additionalFields.contactMobile) === null || _h === void 0 ? void 0 : _h.trim()) || '',
                            email: trimmedContactEmail,
                        },
                        note: ((_j = additionalFields.note) === null || _j === void 0 ? void 0 : _j.trim()) || '',
                    };
                    const response = await organizations_1.api.createOrganization(this, credentials, createData);
                    if (!response.success) {
                        const errorMessage = ((_k = response.errors) === null || _k === void 0 ? void 0 : _k.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to create organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    const processedResult = response.result ? enrichOrganizationEntity(response.result, credentials.instanceUrl) : response.result;
                    returnData.push({
                        json: processedResult,
                        pairedItem: i,
                    });
                    break;
                }
                case 'checkNameExists': {
                    const nameToCheck = this.getNodeParameter('nameToCheck', i);
                    const trimmedName = nameToCheck.trim();
                    if (!trimmedName) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization name cannot be empty', {
                            itemIndex: i,
                        });
                    }
                    const response = await organizations_1.api.checkOrganizationNameExists(this, credentials, trimmedName);
                    if (!response.success) {
                        const errorMessage = ((_l = response.errors) === null || _l === void 0 ? void 0 : _l.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to check organization name: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    returnData.push({
                        json: {
                            name: trimmedName,
                            exists: response.result,
                            success: response.success,
                            statusCode: response.statusCode,
                        },
                        pairedItem: i,
                    });
                    break;
                }
                case 'update': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    const updateFields = this.getNodeParameter('updateFields', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const updateData = {};
                    if (updateFields.note) {
                        updateData.note = updateFields.note.trim();
                    }
                    if (updateFields.contactName || updateFields.contactEmail || updateFields.contactTitle || updateFields.contactPhone || updateFields.contactMobile) {
                        updateData.contact = {
                            name: ((_m = updateFields.contactName) === null || _m === void 0 ? void 0 : _m.trim()) || '',
                            email: ((_o = updateFields.contactEmail) === null || _o === void 0 ? void 0 : _o.trim()) || '',
                        };
                        if (updateFields.contactName) {
                            updateData.contact.name = updateFields.contactName.trim();
                        }
                        if (updateFields.contactEmail) {
                            updateData.contact.email = updateFields.contactEmail.trim();
                            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                            if (!emailRegex.test(updateData.contact.email)) {
                                throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Contact email must be a valid email address', {
                                    itemIndex: i,
                                });
                            }
                        }
                        if (updateFields.contactTitle) {
                            updateData.contact.title = updateFields.contactTitle.trim();
                        }
                        if (updateFields.contactPhone) {
                            updateData.contact.phone = updateFields.contactPhone.trim();
                        }
                        if (updateFields.contactMobile) {
                            updateData.contact.mobile = updateFields.contactMobile.trim();
                        }
                    }
                    if (Object.keys(updateData).length === 0) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one field must be provided for update', {
                            itemIndex: i,
                        });
                    }
                    const response = await organizations_1.api.updateOrganization(this, credentials, parseInt(organizationId), updateData);
                    if (!response.success) {
                        const errorMessage = ((_p = response.errors) === null || _p === void 0 ? void 0 : _p.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to update organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    const processedResult = response.result ? enrichOrganizationEntity(response.result, credentials.instanceUrl) : response.result;
                    returnData.push({
                        json: processedResult,
                        pairedItem: i,
                    });
                    break;
                }
                case 'updateShareableDeployment': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    const shareableDeploymentStatus = this.getNodeParameter('shareableDeploymentStatus', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const response = await organizations_1.api.updateOrganizationShareableDeployment(this, credentials, parseInt(organizationId), shareableDeploymentStatus);
                    if (!response.success) {
                        const errorMessage = ((_q = response.errors) === null || _q === void 0 ? void 0 : _q.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to update shareable deployment: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    returnData.push({
                        json: {
                            organizationId: parseInt(organizationId),
                            shareableDeploymentEnabled: shareableDeploymentStatus,
                            success: response.success,
                            statusCode: response.statusCode,
                        },
                        pairedItem: i,
                    });
                    break;
                }
                case 'assignUser': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    const userId = this.getNodeParameter('userId', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    let validatedUserId;
                    try {
                        validatedUserId = (0, helpers_1.normalizeAndValidateId)(userId, 'User ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const userIdList = [validatedUserId];
                    const response = await users_1.api.assignUsersToOrganization(this, credentials, parseInt(organizationId), userIdList);
                    if (!response.success) {
                        const errorMessage = ((_r = response.errors) === null || _r === void 0 ? void 0 : _r.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to assign user to organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    returnData.push({
                        json: {
                            organizationId: parseInt(organizationId),
                            assignedUserId: validatedUserId,
                            success: response.success,
                            statusCode: response.statusCode,
                        },
                        pairedItem: i,
                    });
                    break;
                }
                case 'removeUser': {
                    const organizationResource = this.getNodeParameter('organizationId', i);
                    const userId = this.getNodeParameter('userId', i);
                    let organizationId;
                    if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                        organizationId = organizationResource.value;
                    }
                    else if (organizationResource.mode === 'name') {
                        try {
                            organizationId = await 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,
                        });
                    }
                    try {
                        organizationId = (0, helpers_1.normalizeAndValidateId)(organizationId, 'Organization ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    let validatedUserId;
                    try {
                        validatedUserId = (0, helpers_1.normalizeAndValidateId)(userId, 'User ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const userIdList = [validatedUserId];
                    const response = await users_1.api.removeUserFromOrganization(this, credentials, parseInt(organizationId), userIdList);
                    if (!response.success) {
                        const errorMessage = ((_s = response.errors) === null || _s === void 0 ? void 0 : _s.join(', ')) || 'API request failed';
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to remove user from organization: ${errorMessage}`, {
                            itemIndex: i,
                        });
                    }
                    returnData.push({
                        json: {
                            organizationId: parseInt(organizationId),
                            removedUserId: validatedUserId,
                            success: response.success,
                            statusCode: response.statusCode,
                        },
                        pairedItem: i,
                    });
                    break;
                }
                default: {
                    throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, {
                        itemIndex: i,
                    });
                }
            }
        }
        catch (error) {
            (0, helpers_1.handleExecuteError)(this, error, i, returnData);
        }
    }
    return [returnData];
}
var Platform;
(function (Platform) {
    Platform["Windows"] = "windows";
    Platform["Linux"] = "linux";
    Platform["Darwin"] = "darwin";
})(Platform || (Platform = {}));
var PackageExtension;
(function (PackageExtension) {
    PackageExtension["msi"] = "msi";
    PackageExtension["deb"] = "deb";
    PackageExtension["rpm"] = "rpm";
    PackageExtension["pkg"] = "pkg";
})(PackageExtension || (PackageExtension = {}));
var Architecture;
(function (Architecture) {
    Architecture["i386"] = "386";
    Architecture["amd64"] = "amd64";
    Architecture["arm64"] = "arm64";
})(Architecture || (Architecture = {}));
function generateDeploymentPackages(organizationId, deploymentToken, instanceUrl) {
    const generateRandomKey = () => Math.random().toString(36).substring(2, 15);
    const baseUrl = `${instanceUrl}/api/endpoints/download/${organizationId}`;
    const deploymentPackages = {};
    const getArchLabel = (arch) => {
        switch (arch) {
            case Architecture.i386:
                return '32bit';
            case Architecture.amd64:
                return '64bit';
            case Architecture.arm64:
                return 'arm64';
            default:
                return arch;
        }
    };
    [Architecture.i386, Architecture.amd64].forEach(arch => {
        const archLabel = getArchLabel(arch);
        const key = `windows-${archLabel}-msi`;
        deploymentPackages[key] = `${baseUrl}/${Platform.Windows}/${PackageExtension.msi}/${arch}?deployment-token=${deploymentToken}&ckey=${generateRandomKey()}`;
    });
    [Architecture.i386, Architecture.amd64, Architecture.arm64].forEach(arch => {
        const archLabel = getArchLabel(arch);
        const debKey = `linux-${archLabel}-deb`;
        deploymentPackages[debKey] = `${baseUrl}/${Platform.Linux}/${PackageExtension.deb}/${arch}?deployment-token=${deploymentToken}&ckey=${generateRandomKey()}`;
        const rpmKey = `linux-${archLabel}-rpm`;
        deploymentPackages[rpmKey] = `${baseUrl}/${Platform.Linux}/${PackageExtension.rpm}/${arch}?deployment-token=${deploymentToken}&ckey=${generateRandomKey()}`;
    });
    [Architecture.amd64, Architecture.arm64].forEach(arch => {
        const archLabel = getArchLabel(arch);
        const key = `macos-${archLabel}-pkg`;
        deploymentPackages[key] = `${baseUrl}/${Platform.Darwin}/${PackageExtension.pkg}/${arch}?deployment-token=${deploymentToken}&ckey=${generateRandomKey()}`;
    });
    return deploymentPackages;
}
function enrichOrganizationEntity(organization, instanceUrl) {
    const processedOrg = { ...organization };
    if (organization.shareableDeploymentEnabled && organization.deploymentToken) {
        processedOrg.shareableDeploymentPage = `${instanceUrl}/#/shareable-deploy?token=${organization.deploymentToken}`;
    }
    else {
        processedOrg.shareableDeploymentPage = '';
    }
    if (organization.deploymentToken) {
        try {
            const organizationId = extractOrganizationId(organization);
            processedOrg.deploymentPackages = generateDeploymentPackages(organizationId, organization.deploymentToken, instanceUrl);
        }
        catch (error) {
            processedOrg.deploymentPackages = {};
        }
    }
    else {
        processedOrg.deploymentPackages = {};
    }
    return processedOrg;
}
function processOrganizationEntities(organizations, instanceUrl) {
    return organizations.map(org => enrichOrganizationEntity(org, instanceUrl));
}
//# sourceMappingURL=organizations.js.map