Website: Update Vanta integration (#19349)
Closes: https://github.com/fleetdm/confidential/issues/6069 Changes: - Added a new action to add support for the Vanta integration to be set up from a partners website. This action sets the required cookies provided via queryString and redirects users to the Vanta authorization page. - Updated the `create-vanta-authorization-request` action to redirect users who provide a `redirectToExternalPageAfterAuthorization` value the new endpoint instead of returning a vanta authorization URL. - Updated `view-vanta-authorization` to redirect users to the URL provided to the `create-vanta-authorization-request` endpoint (if one was provided)
This commit is contained in:
@@ -19,6 +19,10 @@ module.exports = {
|
||||
fleetApiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
redirectToExternalPageAfterAuthorization: {
|
||||
type: 'string',
|
||||
description: 'If provided, the user will be sent to this URL after they complete the setup of this integration'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -59,7 +63,6 @@ module.exports = {
|
||||
},
|
||||
|
||||
fn: async function (inputs) {
|
||||
|
||||
let url = require('url');
|
||||
|
||||
// Look for any existing VantaConnection records that use this fleet instance URL.
|
||||
@@ -139,17 +142,26 @@ module.exports = {
|
||||
fleetApiKey: inputs.fleetApiKey,
|
||||
});
|
||||
}
|
||||
|
||||
let callbackUrl = `/vanta-authorization`;
|
||||
if(inputs.redirectToExternalPageAfterAuthorization){
|
||||
callbackUrl += `?redirectAfterSetup=${inputs.redirectToExternalPageAfterAuthorization}`;
|
||||
}
|
||||
// Build the authorization URL for this request.
|
||||
let vantaAuthorizationRequestURL = `https://app.vanta.com/oauth/authorize?client_id=${encodeURIComponent(sails.config.custom.vantaAuthorizationClientId)}&scope=connectors.self:write-resource connectors.self:read-resource&state=${encodeURIComponent(generatedStateForThisRequest)}&source_id=${encodeURIComponent(sourceIDForThisRequest)}&redirect_uri=${encodeURIComponent(url.resolve(sails.config.custom.baseUrl, '/vanta-authorization'))}&response_type=code`;
|
||||
let vantaAuthorizationRequestURL = `https://app.vanta.com/oauth/authorize?client_id=${encodeURIComponent(sails.config.custom.vantaAuthorizationClientId)}&scope=connectors.self:write-resource connectors.self:read-resource&state=${encodeURIComponent(generatedStateForThisRequest)}&source_id=${encodeURIComponent(sourceIDForThisRequest)}&redirect_uri=${encodeURIComponent(url.resolve(sails.config.custom.baseUrl, callbackUrl))}&response_type=code`;
|
||||
|
||||
// Set a `state` cookie on the user's browser. This value will be checked against a query parameter when the user returns to fleetdm.com.
|
||||
this.res.cookie('state', generatedStateForThisRequest, {signed: true});
|
||||
if(inputs.redirectToExternalPageAfterAuthorization){
|
||||
let internalRedirectUrl = `${sails.config.custom.baseUrl}/redirect-vanta-authorization-request?vantaSourceId=${encodeURIComponent(sourceIDForThisRequest)}&state=${encodeURIComponent(generatedStateForThisRequest)}&vantaAuthorizationRequestURL=${encodeURIComponent(vantaAuthorizationRequestURL)}&redirectAfterSetup=${encodeURIComponent(inputs.redirectToExternalPageAfterAuthorization)}`;
|
||||
|
||||
// Set the sourceId to a cookie, we'll use this value to find the database record we created for this request when the user returns to fleetdm.com.
|
||||
this.res.cookie('vantaSourceId', sourceIDForThisRequest, {signed: true});
|
||||
|
||||
return vantaAuthorizationRequestURL;
|
||||
return internalRedirectUrl;
|
||||
// If the useInternalRedirect input was provided, we'll return the URL of an internal endpoiint that will set the required cookies for this request.
|
||||
} else {
|
||||
// Otherwise, if this request came from a user on the connect-vanta page, we'll set the cookies are redirect them directly to Vanta.
|
||||
// Set a `state` cookie on the user's browser. This value will be checked against a query parameter when the user returns to fleetdm.com.
|
||||
this.res.cookie('state', generatedStateForThisRequest, {signed: true});
|
||||
// Set the sourceId to a cookie, we'll use this value to find the database record we created for this request when the user returns to fleetdm.com.
|
||||
this.res.cookie('vantaSourceId', sourceIDForThisRequest, {signed: true});
|
||||
return vantaAuthorizationRequestURL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
module.exports = {
|
||||
|
||||
|
||||
friendlyName: 'Redirect vanta authorization request',
|
||||
|
||||
|
||||
description: 'Sets provided inputs in the user`s browser as cookies and redirects them to Vanta.',
|
||||
|
||||
|
||||
inputs: {
|
||||
vantaSourceId: {
|
||||
type: 'string',
|
||||
description: 'The generated vanta Source ID for this request.',
|
||||
required: true,
|
||||
},
|
||||
state: {
|
||||
type: 'string',
|
||||
description: 'The state provided to Vanta when an authorization request was created',
|
||||
required: true,
|
||||
},
|
||||
vantaAuthorizationRequestURL: {
|
||||
type: 'string',
|
||||
description: 'The Vanta authorization url that the user will be directed to after they are sent to this page.',
|
||||
required: true,
|
||||
},
|
||||
redirectAfterSetup: {
|
||||
type: 'string',
|
||||
description: 'The URL that the user will be redirected to after they complete setup.',
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
exits: {
|
||||
noMatchingVantaConnection: {
|
||||
description: 'No Vanta connection could be found using the provided vantaSourceId',
|
||||
responseType: 'badRequest'
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
fn: async function ({vantaSourceId, state, vantaAuthorizationRequestURL, redirectAfterSetup}) {
|
||||
|
||||
// Find the VantaConnection record that we created when the user created this request.
|
||||
let recordOfThisAuthorization = await VantaConnection.findOne({vantaSourceId: vantaSourceId});
|
||||
|
||||
// If no record of this authorization could be found, return a noMatchingVantaConnection response.
|
||||
if(!recordOfThisAuthorization){
|
||||
throw 'noMatchingVantaConnection';
|
||||
}
|
||||
|
||||
// Set a 'state' and 'vantaSourceId' cookie on the users browser.
|
||||
this.res.cookie('redirectAfterSetup', redirectAfterSetup, {signed: true});
|
||||
this.res.cookie('state', state, {signed: true});
|
||||
this.res.cookie('vantaSourceId', vantaSourceId, {signed: true});
|
||||
// now that the user has the required cookies to complete the vanta integration setup, redirect them to the provided VantaAuthorizationUrl.
|
||||
return this.res.redirect(vantaAuthorizationRequestURL);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
+3
-1
@@ -89,7 +89,9 @@ module.exports = {
|
||||
if(!updatedRecord){
|
||||
throw new Error(`When trying to update a VantaConnection record (id: ${recordOfThisAuthorization.id}) with an authorization token from Vanta, the database record associated with this request has gone missing.`);
|
||||
}
|
||||
|
||||
if(this.req.signedCookies.redirectAfterSetup){
|
||||
return this.res.redirect(this.req.signedCookies.redirectAfterSetup);
|
||||
}
|
||||
return {
|
||||
showSuccessMessage: true
|
||||
};
|
||||
|
||||
Vendored
+1
@@ -55,4 +55,5 @@ module.exports.policies = {
|
||||
'deliver-talk-to-us-form-submission': true,
|
||||
'get-human-interpretation-from-osquery-sql': true,
|
||||
'customers/view-new-license': true,
|
||||
'redirect-vanta-authorization-request': true,
|
||||
};
|
||||
|
||||
Vendored
+2
-1
@@ -589,7 +589,8 @@ module.exports.routes = {
|
||||
'POST /api/v1/create-or-update-one-newsletter-subscription': { action: 'create-or-update-one-newsletter-subscription' },
|
||||
'/api/v1/unsubscribe-from-all-newsletters': { action: 'unsubscribe-from-all-newsletters' },
|
||||
'POST /api/v1/admin/build-license-key': { action: 'admin/build-license-key' },
|
||||
'POST /api/v1/create-vanta-authorization-request': { action: 'create-vanta-authorization-request' },
|
||||
'POST /api/v1/create-vanta-authorization-request': { action: 'create-vanta-authorization-request', csrf: false },
|
||||
'GET /redirect-vanta-authorization-request': { action: 'redirect-vanta-authorization-request' },
|
||||
'POST /api/v1/deliver-mdm-beta-signup': { action: 'deliver-mdm-beta-signup' },
|
||||
'POST /api/v1/get-human-interpretation-from-osquery-sql': { action: 'get-human-interpretation-from-osquery-sql', csrf: false },
|
||||
'POST /api/v1/deliver-apple-csr ': { action: 'deliver-apple-csr', csrf: false},
|
||||
|
||||
Reference in New Issue
Block a user