UNPKG

n8n-nodes-base

Version:

Base nodes of n8n

291 lines 13.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.microsoftApiRequest = microsoftApiRequest; exports.microsoftApiPaginateRequest = microsoftApiPaginateRequest; exports.handleErrorPostReceive = handleErrorPostReceive; exports.getGroupProperties = getGroupProperties; exports.getUserProperties = getUserProperties; exports.getGroups = getGroups; exports.getUsers = getUsers; const n8n_workflow_1 = require("n8n-workflow"); const xml2js_1 = require("xml2js"); async function microsoftApiRequest(method, endpoint, body = {}, qs, headers, url) { const credentials = await this.getCredentials('microsoftEntraOAuth2Api'); const baseUrl = (typeof credentials.graphApiBaseUrl === 'string' && credentials.graphApiBaseUrl !== '' ? credentials.graphApiBaseUrl : 'https://graph.microsoft.com').replace(/\/+$/, ''); const options = { method, url: url ?? `${baseUrl}/v1.0${endpoint}`, json: true, headers, body, qs, }; return await this.helpers.requestWithAuthentication.call(this, 'microsoftEntraOAuth2Api', options); } async function microsoftApiPaginateRequest(method, endpoint, body = {}, qs, headers, url, itemIndex = 0) { const credentials = await this.getCredentials('microsoftEntraOAuth2Api'); const baseUrl = (typeof credentials.graphApiBaseUrl === 'string' && credentials.graphApiBaseUrl !== '' ? credentials.graphApiBaseUrl : 'https://graph.microsoft.com').replace(/\/+$/, ''); // Todo: IHttpRequestOptions doesn't have uri property which is required for requestWithAuthenticationPaginated const options = { method, uri: url ?? `${baseUrl}/v1.0${endpoint}`, json: true, headers, body, qs, }; const pages = await this.helpers.requestWithAuthenticationPaginated.call(this, options, itemIndex, { continue: '={{ !!$response.body?.["@odata.nextLink"] }}', request: { url: '={{ $response.body?.["@odata.nextLink"] ?? $request.url }}', }, requestInterval: 0, }, 'microsoftEntraOAuth2Api'); let results = []; for (const page of pages) { const items = page.body.value; if (items) { results = results.concat(items); } } return results; } async function handleErrorPostReceive(data, response) { if (String(response.statusCode).startsWith('4') || String(response.statusCode).startsWith('5')) { const resource = this.getNodeParameter('resource'); const operation = this.getNodeParameter('operation'); const { code: errorCode, message: errorMessage, details: errorDetails, } = response.body?.error; // Operation specific errors if (resource === 'group') { if (operation === 'create') { } else if (operation === 'delete') { if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required group doesn't match any existing one", description: "Double-check the value in the parameter 'Group to Delete' and try again", }); } } else if (operation === 'get') { if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required group doesn't match any existing one", description: "Double-check the value in the parameter 'Group to Get' and try again", }); } } else if (operation === 'getAll') { } else if (operation === 'update') { if (errorCode === 'BadRequest' && errorMessage === 'Empty Payload. JSON content expected.') { // Ignore empty payload error. Currently n8n deletes the empty body object from the request. return data; } if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required group doesn't match any existing one", description: "Double-check the value in the parameter 'Group to Update' and try again", }); } } } else if (resource === 'user') { if (operation === 'addGroup') { if (errorCode === 'Request_BadRequest' && errorMessage === "One or more added object references already exist for the following modified properties: 'members'.") { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: 'The user is already in the group', description: 'The specified user cannot be added to the group because they are already a member', }); } else if (errorCode === 'Request_ResourceNotFound') { const group = this.getNodeParameter('group.value'); if (errorMessage.includes(group)) { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required group doesn't match any existing one", description: "Double-check the value in the parameter 'Group' and try again", }); } else { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required user doesn't match any existing one", description: "Double-check the value in the parameter 'User to Add' and try again", }); } } } else if (operation === 'create') { } else if (operation === 'delete') { if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required user doesn't match any existing one", description: "Double-check the value in the parameter 'User to Delete' and try again", }); } } else if (operation === 'get') { if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required user doesn't match any existing one", description: "Double-check the value in the parameter 'User to Get' and try again", }); } } else if (operation === 'getAll') { } else if (operation === 'removeGroup') { if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: 'The user is not in the group', description: 'The specified user cannot be removed from the group because they are not a member of the group', }); } else if (errorCode === 'Request_UnsupportedQuery' && errorMessage === "Unsupported referenced-object resource identifier for link property 'members'.") { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: 'The user ID is invalid', description: 'The ID should be in the format e.g. 02bd9fd6-8f93-4758-87c3-1fb73740a315', }); } } else if (operation === 'update') { if (errorCode === 'BadRequest' && errorMessage === 'Empty Payload. JSON content expected.') { // Ignore empty payload error. Currently n8n deletes the empty body object from the request. return data; } if (errorCode === 'Request_ResourceNotFound') { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: "The required user doesn't match any existing one", description: "Double-check the value in the parameter 'User to Update' and try again", }); } } } // Generic errors if (errorCode === 'Request_BadRequest' && errorMessage.startsWith('Invalid object identifier')) { const group = this.getNodeParameter('group.value', ''); const parameterResource = resource === 'group' || errorMessage.includes(group) ? 'group' : 'user'; throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: `The ${parameterResource} ID is invalid`, description: 'The ID should be in the format e.g. 02bd9fd6-8f93-4758-87c3-1fb73740a315', }); } if (errorDetails?.some((x) => x.code === 'ObjectConflict' || x.code === 'ConflictingObjects')) { throw new n8n_workflow_1.NodeApiError(this.getNode(), response, { message: `The ${resource} already exists`, description: errorMessage, }); } throw new n8n_workflow_1.NodeApiError(this.getNode(), response); } return data; } async function getGroupProperties() { const returnData = []; const response = await microsoftApiRequest.call(this, 'GET', '/$metadata#groups'); const metadata = await (0, xml2js_1.parseStringPromise)(response, { explicitArray: false, }); /* eslint-disable */ const entities = metadata['edmx:Edmx']['edmx:DataServices']['Schema'] .find((x) => x['$']['Namespace'] === 'microsoft.graph')['EntityType'].filter((x) => ['entity', 'directoryObject', 'group'].includes(x['$']['Name'])); let properties = entities .flatMap((x) => x['Property']) .map((x) => x['$']['Name']); /* eslint-enable */ properties = properties.filter((x) => !['id', 'isArchived', 'hasMembersWithLicenseErrors'].includes(x)); properties = properties.sort(); for (const property of properties) { returnData.push({ name: property, value: property, }); } return returnData; } async function getUserProperties() { const returnData = []; const response = await microsoftApiRequest.call(this, 'GET', '/$metadata#users'); const metadata = await (0, xml2js_1.parseStringPromise)(response, { explicitArray: false, }); /* eslint-disable */ const entities = metadata['edmx:Edmx']['edmx:DataServices']['Schema'] .find((x) => x['$']['Namespace'] === 'microsoft.graph')['EntityType'].filter((x) => ['entity', 'directoryObject', 'user'].includes(x['$']['Name'])); let properties = entities .flatMap((x) => x['Property']) .map((x) => x['$']['Name']); /* eslint-enable */ // signInActivity requires AuditLog.Read.All // mailboxSettings MailboxSettings.Read properties = properties.filter((x) => !['id', 'deviceEnrollmentLimit', 'mailboxSettings', 'print', 'signInActivity'].includes(x)); properties = properties.sort(); for (const property of properties) { returnData.push({ name: property, value: property, }); } return returnData; } async function getGroups(filter, paginationToken) { let response; if (paginationToken) { response = await microsoftApiRequest.call(this, 'GET', '/groups', {}, undefined, undefined, paginationToken); } else { const qs = { $select: 'id,displayName', }; const headers = {}; if (filter) { headers.ConsistencyLevel = 'eventual'; qs.$search = `"displayName:${filter}"`; } response = await microsoftApiRequest.call(this, 'GET', '/groups', {}, qs, headers); } const groups = response.value; const results = groups .map((g) => ({ name: g.displayName, value: g.id, })) .sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' })); return { results, paginationToken: response['@odata.nextLink'] }; } async function getUsers(filter, paginationToken) { let response; if (paginationToken) { response = await microsoftApiRequest.call(this, 'GET', '/users', {}, undefined, undefined, paginationToken); } else { const qs = { $select: 'id,displayName', }; const headers = {}; if (filter) { qs.$filter = `startsWith(displayName, '${filter}') OR startsWith(userPrincipalName, '${filter}')`; } response = await microsoftApiRequest.call(this, 'GET', '/users', {}, qs, headers); } const users = response.value; const results = users .map((u) => ({ name: u.displayName, value: u.id, })) .sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' })); return { results, paginationToken: response['@odata.nextLink'] }; } //# sourceMappingURL=GenericFunctions.js.map