fleet/website/api/controllers/webhooks/receive-from-customer-fleet-instance.js
Eric 17410ec59f
Website: Fix bug in customer migration webhook (#12277)
Changes:
- Updated the `receive-from-customer-fleet-instance` webhook to parse
the JSON response body from the request to the OAuth URL.
.
2023-06-09 19:06:25 -05:00

116 lines
5.6 KiB
JavaScript
Vendored

module.exports = {
friendlyName: 'Receive from customer Fleet instance',
description: 'Receive webhook requests from a customer\'s Fleet instance and sends a request to unenroll a specfied host from the customer\'s Workspace One instance.',
inputs: {
timestamp: {
type: 'string',
required: true,
description: 'An ISO 8601 timestamp representing when this request was sent.',
extendedDescription: 'This value is not used by the webhook.',
example: '0000-00-00T00:00:00Z'
},
host: {
type: {
id: 'number',
uuid: 'string',
hardware_serial: 'string'//eslint-disable-line camelcase
},
required: true,
description: 'An dictionary containing information about a host that will be unenrolled from the customers Workspace ONE instance.'
},
webhookSecret: {
type: 'string',
required: true,
description: 'A shared secret used to confirm that this request came from a customer\'s Fleet instance.',
extendedDescription: 'This webhook handler should always be requested over TLS. It is not safe to transmit shared secrets without transport-layer encryption.',
}
},
exits: {
unauthorized: {
responseType: 'unauthorized',
description: 'This webhook request could not be verified.',
}
},
fn: async function ({host, webhookSecret}) {
if(!sails.config.custom.customerWorkspaceOneBaseUrl) {
throw new Error('No sails.config.custom.customerWorkspaceOneBaseUrl configured! Please set this value to be the base url of the customers Workspace One instance.');
}
if(!sails.config.custom.customerWorkspaceOneOauthId) {
throw new Error('No sails.config.custom.customerWorkspaceOneOauthId configured! Please set this value to be the client id of the Oauth token for requests to the customer\'s Workspace One instance.');
}
if(!sails.config.custom.customerWorkspaceOneOauthSecret) {
throw new Error('No sails.config.custom.customerWorkspaceOneOauthSecret configured! Please set this value to be the client id of the Oauth token for requests to the customer\'s Workspace One instance.');
}
if(!sails.config.custom.customerMigrationWebhookSecret) {
throw new Error('No sails.config.custom.customerMigrationWebhookSecret configured! Please set this value to be the shared webhook secret for the host migration webhook.');
}
if(webhookSecret !== sails.config.custom.customerMigrationWebhookSecret) {
throw 'unauthorized';
}
// Send a request to Workspace ONE to get an authorization token to use for the request to the Workspace ONE instance.
// [?] https://docs.vmware.com/en/VMware-Workspace-ONE-Access/services/ws1_access_service_administration_cloud/GUID-2B419DC4-7332-448A-9285-E10FF90890F8.html
// Note: We're using the sendHttpRequest helper so we can set the enctype to be application/x-www-form-urlencoded
let oauthResponse = await sails.helpers.http.sendHttpRequest.with({
method: 'POST',
url: 'https://na.uemauth.vmwservices.com/connect/token',
enctype: 'application/x-www-form-urlencoded',
body: {
grant_type: 'client_credentials',//eslint-disable-line camelcase
client_id: sails.config.custom.customerWorkspaceOneOauthId,//eslint-disable-line camelcase
client_secret: sails.config.custom.customerWorkspaceOneOauthSecret,//eslint-disable-line camelcase
},
})
.intercept((err)=>{
return new Error(`When sending a request to get a Workspace ONE authorization token for the recieve-from-customer-fleet-instance webhook, an error occured. Full error: ${err.stack}`);
});
// The body in responses returned from the sendHttpRequest helper will always be a string, so we need to parse the raw JSON response body to get the access_token returned from the OAuth URL.
// [?]: https://github.com/sailshq/machinepack-http/blob/9770e75db5f005c21068f5411177bf7e072bfd78/lib/send-http-request.js#L91C27-L94
let oauthResponseBody = JSON.parse(oauthResponse.body);
// Send a request to unenroll this host in the customer's Workspace One instance.
await sails.helpers.http.post.with({
// Contrary to what you what think the EnterpriseWipe command only unenrolls the host from a Workspace One instance.
// [?] [Workspace One URL]/API/help/#!/CommandsV1/CommandsV1_ExecuteByAlternateIdAsync
url: `/api/mdm/devices/commands?searchby=Serialnumber&id=${encodeURIComponent(host.hardware_serial)}&command=EnterpriseWipe`,
headers: {
'Authorization': 'Bearer '+oauthResponseBody.access_token,
},
baseUrl: sails.config.custom.customerWorkspaceOneBaseUrl
})
.intercept('non200Response', (err)=>{
if(err.raw.statusCode === 404){
return new Error(`When sending a request to unenroll a host from a Workspace One instance (Host information: Serial number: ${host.hardware_serial}, id: ${host.id}, uuid: ${host.uuid}), the specified host was not found on the customer's Workspace One instance. Full error: ${err.stack}`);
} else if(err.raw.statusCode === 400) {
return new Error(`When sending a request to unenroll a host from a Workspace One instance (Host information: Serial number: ${host.hardware_serial}, id: ${host.id}, uuid: ${host.uuid}), the Workspace One instance could not unenroll the specified host. Full error: ${err.stack}`);
} else {
return new Error(`When sending a request to unenroll a host from a Workspace One instance (Host information: Serial number: ${host.hardware_serial}, id: ${host.id}, uuid: ${host.uuid}), an error occured. Full error: ${err.stack}`);
}
});
// All done.
return;
}
};