diff --git a/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts b/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts new file mode 100644 index 0000000000..88c369c665 --- /dev/null +++ b/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts @@ -0,0 +1,27 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +const scopes = [ + 'https://www.googleapis.com/auth/admin.directory.user', + 'https://www.googleapis.com/auth/admin.directory.domain.readonly', + 'https://www.googleapis.com/auth/admin.directory.userschema.readonly', +]; + +export class GSuiteAdminOAuth2Api implements ICredentialType { + name = 'gSuiteAdminOAuth2Api'; + extends = [ + 'googleOAuth2Api', + ]; + displayName = 'G Suite Admin OAuth2 API'; + documentationUrl = 'google'; + properties = [ + { + displayName: 'Scope', + name: 'scope', + type: 'hidden' as NodePropertyTypes, + default: scopes.join(' '), + }, + ]; +} diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts b/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts new file mode 100644 index 0000000000..6d89f6e8a6 --- /dev/null +++ b/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts @@ -0,0 +1,361 @@ +import { + IExecuteFunctions, +} from 'n8n-core'; + +import { + IDataObject, + INodeExecutionData, + INodeTypeDescription, + INodeType, + ILoadOptionsFunctions, + INodePropertyOptions, +} from 'n8n-workflow'; + +import { + googleApiRequest, + googleApiRequestAllItems, +} from './GenericFunctions'; + +import { + userOperations, + userFields, +} from './UserDescription'; + +export class GSuiteAdmin implements INodeType { + description: INodeTypeDescription = { + displayName: 'G Suite Admin', + name: 'gSuiteAdmin', + icon: 'file:gSuiteAdmin.png', + group: ['input'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume G Suite Admin API', + defaults: { + name: 'G Suite Admin', + color: '#ecbb26', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'gSuiteAdminOAuth2Api', + required: true, + }, + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'User', + value: 'user', + }, + ], + default: 'user', + description: 'The resource to operate on.' + }, + ...userOperations, + ...userFields, + ], + }; + + methods = { + loadOptions: { + // Get all the domains to display them to user so that he can + // select them easily + async getDomains( + this: ILoadOptionsFunctions + ): Promise { + const returnData: INodePropertyOptions[] = []; + const domains = await googleApiRequestAllItems.call( + this, + 'domains', + 'GET', + '/directory/v1/customer/my_customer/domains' + ); + for (const domain of domains) { + const domainName = domain.domainName; + const domainId = domain.domainName; + returnData.push({ + name: domainName, + value: domainId + }); + } + return returnData; + }, + // Get all the schemas to display them to user so that he can + // select them easily + async getSchemas( + this: ILoadOptionsFunctions + ): Promise { + const returnData: INodePropertyOptions[] = []; + const schemas = await googleApiRequestAllItems.call( + this, + 'schemas', + 'GET', + '/directory/v1/customer/my_customer/schemas' + ); + for (const schema of schemas) { + const schemaName = schema.displayName; + const schemaId = schema.schemaName; + returnData.push({ + name: schemaName, + value: schemaId + }); + } + return returnData; + }, + }, + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: IDataObject[] = []; + const length = (items.length as unknown) as number; + const qs: IDataObject = {}; + let responseData; + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + for (let i = 0; i < length; i++) { + + if (resource === 'user') { + + //https://developers.google.com/admin-sdk/directory/v1/reference/users/insert + if (operation === 'create') { + + const domain = this.getNodeParameter('domain', i) as string; + + const firstName = this.getNodeParameter('firstName', i) as string; + + const lastName = this.getNodeParameter('lastName', i) as string; + + const password = this.getNodeParameter('password', i) as string; + + const username = this.getNodeParameter('username', i) as string; + + const makeAdmin = this.getNodeParameter('makeAdmin', i) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + name: { + familyName: lastName, + givenName: firstName, + }, + password, + primaryEmail: `${username}@${domain}`, + }; + + Object.assign(body, additionalFields); + + if (additionalFields.phoneUi) { + + const phones = (additionalFields.phoneUi as IDataObject).phoneValues as IDataObject[]; + + body.phones = phones; + + delete body.phoneUi; + } + + if (additionalFields.emailUi) { + + const emails = (additionalFields.emailUi as IDataObject).emailValues as IDataObject[]; + + body.emails = emails; + + delete body.emailUi; + } + + responseData = await googleApiRequest.call( + this, + 'POST', + `/directory/v1/users`, + body, + qs + ); + + if (makeAdmin) { + + await googleApiRequest.call( + this, + 'POST', + `/directory/v1/users/${responseData.id}/makeAdmin`, + { status: true }, + ); + + responseData.isAdmin = true; + } + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/users/delete + if (operation === 'delete') { + + const userId = this.getNodeParameter('userId', i) as string; + + responseData = await googleApiRequest.call( + this, + 'DELETE', + `/directory/v1/users/${userId}`, + {} + ); + + responseData = { success: true }; + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/users/get + if (operation === 'get') { + + const userId = this.getNodeParameter('userId', i) as string; + + const projection = this.getNodeParameter('projection', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.projection = projection; + + Object.assign(qs, options); + + if (qs.customFieldMask) { + qs.customFieldMask = (qs.customFieldMask as string[]).join(' '); + } + + if (qs.projection === 'custom' && qs.customFieldMask === undefined) { + throw new Error('When projection is set to custom, the custom schemas field must be defined'); + } + + responseData = await googleApiRequest.call( + this, + 'GET', + `/directory/v1/users/${userId}`, + {}, + qs + ); + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/users/list + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const projection = this.getNodeParameter('projection', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.projection = projection; + + Object.assign(qs, options); + + if (qs.customer === undefined) { + qs.customer = 'my_customer'; + } + + if (qs.customFieldMask) { + qs.customFieldMask = (qs.customFieldMask as string[]).join(' '); + } + + if (qs.projection === 'custom' && qs.customFieldMask === undefined) { + throw new Error('When projection is set to custom, the custom schemas field must be defined'); + } + + if (returnAll) { + + responseData = await googleApiRequestAllItems.call( + this, + 'users', + 'GET', + `/directory/v1/users`, + {}, + qs + ); + + } else { + + qs.maxResults = this.getNodeParameter('limit', i) as number; + + responseData = await googleApiRequest.call( + this, + 'GET', + `/directory/v1/users`, + {}, + qs + ); + + responseData = responseData.users; + } + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/users/update + if (operation === 'update') { + + const userId = this.getNodeParameter('userId', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body: { name: { givenName?: string, familyName?: string }, emails?: IDataObject[], phones?: IDataObject[] } = { name: {} }; + + Object.assign(body, updateFields); + + if (updateFields.firstName) { + body.name.givenName = updateFields.firstName as string; + //@ts-ignore + delete body.firstName; + } + + if (updateFields.lastName) { + body.name.familyName = updateFields.lastName as string; + //@ts-ignore + delete body.lastName; + } + + if (Object.keys(body.name).length === 0) { + delete body.name; + } + + if (updateFields.phoneUi) { + + const phones = (updateFields.phoneUi as IDataObject).phoneValues as IDataObject[]; + + body.phones = phones; + + //@ts-ignore + delete body.phoneUi; + } + + if (updateFields.emailUi) { + + const emails = (updateFields.emailUi as IDataObject).emailValues as IDataObject[]; + + body.emails = emails; + + //@ts-ignore + delete body.emailUi; + } + + //@ts-ignore + body['customSchemas'] = { testing: { hasdog: true } }; + + responseData = await googleApiRequest.call( + this, + 'PUT', + `/directory/v1/users/${userId}`, + body, + qs + ); + } + } + } + + if (Array.isArray(responseData)) { + + returnData.push.apply(returnData, responseData as IDataObject[]); + + } else if (responseData !== undefined) { + + returnData.push(responseData as IDataObject); + } + + return [this.helpers.returnJsonArray(returnData)]; + } +} diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/GenericFunctions.ts b/packages/nodes-base/nodes/Google/GSuiteAdmin/GenericFunctions.ts new file mode 100644 index 0000000000..e41fc33061 --- /dev/null +++ b/packages/nodes-base/nodes/Google/GSuiteAdmin/GenericFunctions.ts @@ -0,0 +1,67 @@ +import { + OptionsWithUri, + } from 'request'; + +import { + IExecuteFunctions, + IExecuteSingleFunctions, + ILoadOptionsFunctions, +} from 'n8n-core'; + +import { + IDataObject, +} from 'n8n-workflow'; + +export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, headers: IDataObject = {}): Promise { // tslint:disable-line:no-any + const options: OptionsWithUri = { + headers: { + 'Content-Type': 'application/json', + }, + method, + body, + qs, + uri: uri || `https://www.googleapis.com/admin${resource}`, + json: true + }; + try { + if (Object.keys(headers).length !== 0) { + options.headers = Object.assign({}, options.headers, headers); + } + if (Object.keys(body).length === 0) { + delete options.body; + } + //@ts-ignore + return await this.helpers.requestOAuth2.call(this, 'gSuiteAdminOAuth2Api', options); + } catch (error) { + if (error.response && error.response.body && error.response.body.error) { + + let errors = error.response.body.error.errors; + + errors = errors.map((e: IDataObject) => e.message); + // Try to return the error prettier + throw new Error( + `G Suite Admin error response [${error.statusCode}]: ${errors.join('|')}` + ); + } + throw error; + } +} + +export async function googleApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string ,method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any + + const returnData: IDataObject[] = []; + + let responseData; + query.maxResults = 100; + + do { + responseData = await googleApiRequest.call(this, method, endpoint, body, query); + query.pageToken = responseData['nextPageToken']; + returnData.push.apply(returnData, responseData[propertyName]); + } while ( + responseData['nextPageToken'] !== undefined && + responseData['nextPageToken'] !== '' + ); + + return returnData; +} diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/UserDescription.ts b/packages/nodes-base/nodes/Google/GSuiteAdmin/UserDescription.ts new file mode 100644 index 0000000000..436cab6801 --- /dev/null +++ b/packages/nodes-base/nodes/Google/GSuiteAdmin/UserDescription.ts @@ -0,0 +1,964 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const userOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'user', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a user', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a user', + }, + { + name: 'Get', + value: 'get', + description: 'Get a user', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all users', + }, + { + name: 'Update', + value: 'update', + description: 'Update a user', + }, + ], + default: 'create', + description: 'The operation to perform.' + } +] as INodeProperties[]; + +export const userFields = [ + /* -------------------------------------------------------------------------- */ + /* user:create */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'create' + ], + resource: [ + 'user' + ], + }, + }, + default: '' + }, + { + displayName: 'Password', + name: 'password', + type: 'string', + typeOptions: { + password: true, + }, + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + description: 'Stores the password for the user account. A minimum of 8 characters is required. The maximum length is 100 characters.' + }, + { + displayName: 'Domain', + name: 'domain', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getDomains', + }, + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + }, + { + displayName: 'Username', + name: 'username', + type: 'string', + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + description: `The username that will be set to the user. Example: If you domain is example.com and you set the username to jhon then the user's final email address will be jhon@example.com.` + }, + { + displayName: 'Make Admin', + name: 'makeAdmin', + type: 'boolean', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'user', + ], + }, + }, + default: false, + description: 'Makes a user a super administrator', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'user', + ], + }, + }, + options: [ + { + displayName: 'Change Password At Next Login', + name: 'changePasswordAtNextLogin', + type: 'boolean', + default: false, + description: 'Indicates if the user is forced to change their password at next login.', + }, + { + displayName: 'Phones', + name: 'phoneUi', + placeholder: 'Add Phone', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + options: [ + { + name: 'phoneValues', + displayName: 'Phone', + values: [ + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Assistant', + value: 'assistant', + }, + { + name: 'Callback', + value: 'callback', + }, + { + name: 'Car', + value: 'car', + }, + { + name: 'Company Main', + value: 'company_main', + }, + { + name: 'Custom', + value: 'custom', + }, + { + name: 'Grand Central', + value: 'grand_central', + }, + { + name: 'Home', + value: 'home', + }, + { + name: 'Home Fax', + value: 'home_fax', + }, + { + name: 'isdn', + value: 'isdn', + }, + { + name: 'Main', + value: 'main', + }, + { + name: 'Mobile', + value: 'mobile', + }, + { + name: 'Other', + value: 'other', + }, + { + name: 'Other Fax', + value: 'other_fax', + }, + { + name: 'Pager', + value: 'pager', + }, + { + name: 'Radio', + value: 'radio', + }, + { + name: 'Telex', + value: 'telex', + }, + { + name: 'tty tdd', + value: 'tty_tdd', + }, + { + name: 'Work', + value: 'work', + }, + { + name: 'Work Fax', + value: 'work_fax', + }, + { + name: 'Work Mobile', + value: 'work_mobile', + }, + { + name: 'Work Pager', + value: 'work_pager', + }, + ], + default: 'work', + description: 'The type of phone number', + }, + { + displayName: 'Phone Number', + name: 'value', + type: 'string', + default: '', + }, + { + displayName: 'Primary', + name: 'primary', + type: 'boolean', + default: false, + description: `Indicates if this is the user's primary phone number. A user may only have one primary phone number.`, + }, + ], + }, + ], + }, + { + displayName: 'Secondary Emails', + name: 'emailUi', + placeholder: 'Add Email', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + options: [ + { + name: 'emailValues', + displayName: 'Email', + values: [ + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Home', + value: 'home', + }, + { + name: 'Work', + value: 'work', + }, + { + name: 'Other', + value: 'other', + }, + ], + default: 'work', + description: 'The type of the email account', + }, + { + displayName: 'Email', + name: 'address', + type: 'string', + default: '', + }, + ], + }, + ], + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* user:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'User ID', + name: 'userId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + description: `The value can be the user's primary email address, alias email address, or unique user ID.`, + }, + /* -------------------------------------------------------------------------- */ + /* user:get */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'User ID', + name: 'userId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + description: `The value can be the user's primary email address, alias email address, or unique user ID.`, + }, + { + displayName: 'Projection', + name: 'projection', + type: 'options', + required: true, + options: [ + { + name: 'Basic', + value: 'basic', + description: 'Do not include any custom fields for the user', + }, + { + name: 'Custom', + value: 'custom', + description: 'Include custom fields from schemas requested in customField', + }, + { + name: 'Full', + value: 'full', + description: 'Include all fields associated with this user', + }, + ], + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'user', + ], + }, + }, + default: 'basic', + description: 'What subset of fields to fetch for this user', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Options', + default: {}, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'user', + ], + }, + }, + options: [ + { + displayName: 'Custom Schemas', + name: 'customFieldMask', + type: 'multiOptions', + displayOptions: { + show: { + '/projection': [ + 'custom', + ], + }, + }, + typeOptions: { + loadOptionsMethod: 'getSchemas', + }, + default: [], + description: `A comma-separated list of schema names. All fields from these schemas are fetched. This should only be set when projection=custom.`, + }, + { + displayName: 'View Type', + name: 'viewType', + type: 'options', + options: [ + { + name: 'Admin View', + value: 'admin_view', + description: 'Results include both administrator-only and domain-public fields for the user', + }, + { + name: 'Descending', + value: 'DESCENDING', + description: 'Results only include fields for the user that are publicly visible to other users in the domain', + }, + ], + default: 'admin_view', + description: 'Whether to fetch the administrator-only or domain-wide public view of the user. For more information, see Retrieve a user as a non-administrator.', + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* user:getAll */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'user', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'user', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 500, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Projection', + name: 'projection', + type: 'options', + required: true, + options: [ + { + name: 'Basic', + value: 'basic', + description: 'Do not include any custom fields for the user', + }, + { + name: 'Custom', + value: 'custom', + description: 'Include custom fields from schemas requested in customField', + }, + { + name: 'Full', + value: 'full', + description: 'Include all fields associated with this user', + }, + ], + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'user', + ], + }, + }, + default: 'basic', + description: 'What subset of fields to fetch for this user', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'user', + ], + }, + }, + options: [ + { + displayName: 'Custom Schemas', + name: 'customFieldMask', + type: 'multiOptions', + displayOptions: { + show: { + '/projection': [ + 'custom', + ], + }, + }, + typeOptions: { + loadOptionsMethod: 'getSchemas', + }, + default: [], + description: `A comma-separated list of schema names. All fields from these schemas are fetched. This should only be set when projection=custom.`, + }, + { + displayName: 'Customer', + name: 'customer', + type: 'string', + default: '', + description: `The unique ID for the customer's G Suite account. In case of a multi-domain account, to fetch all groups for a customer, fill this field instead of domain`, + }, + { + displayName: 'Domain', + name: 'domain', + type: 'string', + default: '', + description: 'The domain name. Use this field to get fields from only one domain.', + }, + { + displayName: 'Order By', + name: 'orderBy', + type: 'options', + options: [ + { + name: 'Email', + value: 'email', + }, + { + name: 'Family Name', + value: 'familyName', + }, + { + name: 'Given Name', + value: 'givenName', + }, + ], + default: '', + description: 'Property to use for sorting results.', + }, + { + displayName: 'Projection', + name: 'projection', + type: 'options', + options: [ + { + name: 'Basic', + value: 'basic', + description: 'Do not include any custom fields for the user', + }, + { + name: 'Custom', + value: 'custom', + description: 'Include custom fields from schemas requested in customField', + }, + { + name: 'Full', + value: 'full', + description: 'Include all fields associated with this user', + }, + ], + default: 'basic', + description: 'Property to use for sorting results.', + }, + { + displayName: 'Query', + name: 'query', + type: 'string', + default: '', + description: `Free text search terms to find users that match these terms in any field, except for extended properties.
+ For more information on constructing user queries, see Search for Users`, + }, + { + displayName: 'Show Deleted', + name: 'showDeleted', + type: 'boolean', + default: false, + description: 'Whether to include deleted users (with status equals "cancelled") in the result.', + }, + { + displayName: 'Sort Order', + name: 'sortOrder', + type: 'options', + options: [ + { + name: 'Ascending', + value: 'ASCENDING', + }, + { + name: 'Descending', + value: 'DESCENDING', + }, + ], + default: '', + description: 'Whether to return results in ascending or descending order', + }, + { + displayName: 'View Type', + name: 'viewType', + type: 'options', + options: [ + { + name: 'Admin View', + value: 'admin_view', + description: 'Results include both administrator-only and domain-public fields for the user', + }, + { + name: 'Descending', + value: 'DESCENDING', + description: 'Results only include fields for the user that are publicly visible to other users in the domain', + }, + ], + default: 'admin_view', + description: 'Whether to fetch the administrator-only or domain-wide public view of the user. For more information, see Retrieve a user as a non-administrator.', + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* user:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'User ID', + name: 'userId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'user', + ], + }, + }, + default: '', + description: `The value can be the user's primary email address, alias email address, or unique user ID.`, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'user', + ], + }, + }, + options: [ + { + displayName: 'Archived', + name: 'archived', + type: 'boolean', + default: false, + description: 'Indicates if user is archived.', + }, + { + displayName: 'Change Password At Next Login', + name: 'changePasswordAtNextLogin', + type: 'boolean', + default: false, + description: 'Indicates if the user is forced to change their password at next login.', + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '' + }, + { + displayName: 'Password', + name: 'password', + type: 'string', + default: '', + description: 'Stores the password for the user account. A minimum of 8 characters is required. The maximum length is 100 characters.' + }, + { + displayName: 'Phones', + name: 'phoneUi', + placeholder: 'Add Phone', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + options: [ + { + name: 'phoneValues', + displayName: 'Phone', + values: [ + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Assistant', + value: 'assistant', + }, + { + name: 'Callback', + value: 'callback', + }, + { + name: 'Car', + value: 'car', + }, + { + name: 'Company Main', + value: 'company_main', + }, + { + name: 'Custom', + value: 'custom', + }, + { + name: 'Grand Central', + value: 'grand_central', + }, + { + name: 'Home', + value: 'home', + }, + { + name: 'Home Fax', + value: 'home_fax', + }, + { + name: 'isdn', + value: 'isdn', + }, + { + name: 'Main', + value: 'main', + }, + { + name: 'Mobile', + value: 'mobile', + }, + { + name: 'Other', + value: 'other', + }, + { + name: 'Other Fax', + value: 'other_fax', + }, + { + name: 'Pager', + value: 'pager', + }, + { + name: 'Radio', + value: 'radio', + }, + { + name: 'Telex', + value: 'telex', + }, + { + name: 'tty tdd', + value: 'tty_tdd', + }, + { + name: 'Work', + value: 'work', + }, + { + name: 'Work Fax', + value: 'work_fax', + }, + { + name: 'Work Mobile', + value: 'work_mobile', + }, + { + name: 'Work Pager', + value: 'work_pager', + }, + ], + default: 'work', + description: 'The type of phone number', + }, + { + displayName: 'Phone Number', + name: 'value', + type: 'string', + default: '', + }, + { + displayName: 'Primary', + name: 'primary', + type: 'boolean', + default: false, + description: `Indicates if this is the user's primary phone number. A user may only have one primary phone number.`, + }, + ], + }, + ], + }, + { + displayName: 'Primary Email', + name: 'primaryEmail', + type: 'string', + default: '', + description: `The user's primary email address. This property is required in a request to create a user account. The primaryEmail must be unique and cannot be an alias of another user.`, + }, + { + displayName: 'Secondary Emails', + name: 'emailUi', + placeholder: 'Add Email', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + options: [ + { + name: 'emailValues', + displayName: 'Email', + values: [ + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Home', + value: 'home', + }, + { + name: 'Work', + value: 'work', + }, + { + name: 'Other', + value: 'other', + }, + ], + default: 'work', + description: 'The type of the email account', + }, + { + displayName: 'Email', + name: 'address', + type: 'string', + default: '', + }, + ], + }, + ], + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/gSuiteAdmin.png b/packages/nodes-base/nodes/Google/GSuiteAdmin/gSuiteAdmin.png new file mode 100644 index 0000000000..70e45de814 Binary files /dev/null and b/packages/nodes-base/nodes/Google/GSuiteAdmin/gSuiteAdmin.png differ diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 362ebdd3b6..56bd0cb5f6 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -79,6 +79,7 @@ "dist/credentials/GoogleDriveOAuth2Api.credentials.js", "dist/credentials/GoogleOAuth2Api.credentials.js", "dist/credentials/GoogleSheetsOAuth2Api.credentials.js", + "dist/credentials/GSuiteAdminOAuth2Api.credentials.js", "dist/credentials/GoogleTasksOAuth2Api.credentials.js", "dist/credentials/YouTubeOAuth2Api.credentials.js", "dist/credentials/GumroadApi.credentials.js", @@ -260,6 +261,7 @@ "dist/nodes/Google/Contacts/GoogleContacts.node.js", "dist/nodes/Google/Drive/GoogleDrive.node.js", "dist/nodes/Google/Gmail/Gmail.node.js", + "dist/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.js", "dist/nodes/Google/Sheet/GoogleSheets.node.js", "dist/nodes/Google/Task/GoogleTasks.node.js", "dist/nodes/Google/YouTube/YouTube.node.js",