diff --git a/website/api/controllers/entrance/signup.js b/website/api/controllers/entrance/signup.js index 652b20e802..5c970562e6 100644 --- a/website/api/controllers/entrance/signup.js +++ b/website/api/controllers/entrance/signup.js @@ -63,18 +63,6 @@ the account verification message.)`, defaultsTo: 'Buy a license', }, - primaryBuyingSituation: { - type: 'string', - description: 'What the user will be using Fleet for.', - required: true, - isIn: [ - 'eo-security', - 'eo-it', - 'mdm', - 'vm' - ], - } - }, @@ -104,7 +92,7 @@ the account verification message.)`, }, - fn: async function ({emailAddress, password, firstName, lastName, organization, signupReason, primaryBuyingSituation}) { + fn: async function ({emailAddress, password, firstName, lastName, organization, signupReason}) { // Note: in Oct. 2023, the Fleet Sandbox related code was removed from this action. For more details, see https://github.com/fleetdm/fleet/pull/14638/files var newEmailAddress = emailAddress.toLowerCase(); @@ -153,7 +141,6 @@ the account verification message.)`, signupReason, password: await sails.helpers.passwords.hashPassword(password), stripeCustomerId, - primaryBuyingSituation, tosAcceptedByIp: this.req.ip }, sails.config.custom.verifyEmailAddresses? { emailProofToken: await sails.helpers.strings.random('url-friendly'), @@ -173,7 +160,6 @@ the account verification message.)`, lastName, organization, signupReason, - primaryBuyingSituation, webhookSecret: sails.config.custom.zapierSandboxWebhookSecret, } }) diff --git a/website/api/controllers/entrance/view-login.js b/website/api/controllers/entrance/view-login.js index 0bdc59dfac..cba099dbca 100644 --- a/website/api/controllers/entrance/view-login.js +++ b/website/api/controllers/entrance/view-login.js @@ -26,10 +26,8 @@ module.exports = { if (this.req.me) { if(this.req.me.isSuperAdmin){ throw {redirect: '/admin/generate-license'}; - } else if(this.req.me.hasBillingCard) { - throw {redirect: '/customers/new-license'}; } else { - throw {redirect: '/try-fleet/sandbox'}; + throw {redirect: '/start'}; } } diff --git a/website/api/controllers/save-questionnaire-progress.js b/website/api/controllers/save-questionnaire-progress.js new file mode 100644 index 0000000000..b2559c4ee3 --- /dev/null +++ b/website/api/controllers/save-questionnaire-progress.js @@ -0,0 +1,71 @@ +module.exports = { + + + friendlyName: 'Save questionnaire progress and continue', + + + description: 'Saves the user\'s current progress in the get started questionnaire', + + + inputs: { + currentStep: { + type: 'string', + description: 'The step of the get started questionnaire that is being saved.', + isIn: [ + 'start', + 'what-are-you-using-fleet-for', + 'have-you-ever-used-fleet', + 'how-many-hosts', + 'will-you-be-self-hosting', + 'what-are-you-working-on-eo-security', + 'is-it-any-good', + 'what-did-you-think', + 'deploy-fleet-in-your-environment', + 'managed-cloud-for-growing-deployments', + 'self-hosted-deploy', + ] + }, + formData: { + type: {}, + description: 'The formdata that will be saved for this step of the get started questionnaire' + } + }, + + + exits: { + + }, + + + fn: async function ({currentStep, formData}) { + // find this user's DB record. + let userRecord = await User.findOne({id: this.req.me.id}); + if(!userRecord){ + throw new Error(`Consistency violation: when trying to save a user's progress in the get started questionnaire, a User record with the ID ${this.req.me.id} could not be found.`); + } + let questionnaireProgress; + // If this user doesn't have a lastSubmittedGetStartedQuestionnaireStep or getStartedQuestionnaireAnswers, create an empty dictionary to store their answers. + if(!userRecord.lastSubmittedGetStartedQuestionnaireStep || _.isEmpty(userRecord.getStartedQuestionnaireAnswers)) { + questionnaireProgress = {}; + } else {// other wise clone it from the user record. + questionnaireProgress = _.clone(userRecord.getStartedQuestionnaireAnswers); + } + // When the 'what-are-you-using-fleet-for' is completed, update this user's DB record and session to include their answer. + if(currentStep === 'what-are-you-using-fleet-for') { + let primaryBuyingSituation = formData.primaryBuyingSituation; + await User.updateOne({id: this.req.me.id}).set({primaryBuyingSituation}); + // Set the primary buying situation in the user's session. + this.req.session.primaryBuyingSituation = primaryBuyingSituation; + } + // Set the user's answer to the current step. + questionnaireProgress[currentStep] = formData; + // Clone the questionnaireProgress to prevent any mutations from sending it through the updateOne Waterline method. + let getStartedProgress = _.clone(questionnaireProgress); + // Update the user's database model. + await User.updateOne({id: userRecord.id}).set({getStartedQuestionnaireAnswers: questionnaireProgress, lastSubmittedGetStartedQuestionnaireStep: currentStep}); + // Return the JSON dictionary of form data submitted by this user. + return getStartedProgress; + } + + +}; diff --git a/website/api/controllers/view-contact.js b/website/api/controllers/view-contact.js index 627c688a8a..8281db2fb2 100644 --- a/website/api/controllers/view-contact.js +++ b/website/api/controllers/view-contact.js @@ -12,6 +12,11 @@ module.exports = { description: 'A boolean that determines whether or not to display the talk to us form when the contact page loads.', defaultsTo: false, }, + + prefillFormDataFromUserRecord: { + type: 'boolean', + description: 'If true, the contact form will be prefilled in with information from this user\'s account.', + }, }, exits: { @@ -23,15 +28,19 @@ module.exports = { }, - fn: async function ({sendMessage}) { + fn: async function ({sendMessage, prefillFormDataFromUserRecord}) { let formToShow = 'talk-to-us'; if(sendMessage) { formToShow = 'contact'; } + // If the prefillFormDataFromUserRecord flag was set to true, but this user is not logged in, set it to false. + if(prefillFormDataFromUserRecord && !this.req.me){ + prefillFormDataFromUserRecord = false; + } // Respond with view. - return {formToShow}; + return {formToShow, prefillFormDataFromUserRecord}; } diff --git a/website/api/controllers/view-start.js b/website/api/controllers/view-start.js index 080e234a09..a18fdd8ed1 100644 --- a/website/api/controllers/view-start.js +++ b/website/api/controllers/view-start.js @@ -17,9 +17,15 @@ module.exports = { fn: async function () { - - // Respond with view. - return {}; + if(this.req.me.lastSubmittedGetStartedQuestionnaireStep && !_.isEmpty(this.req.me.getStartedQuestionnaireAnswers)){ + let currentStep = this.req.me.lastSubmittedGetStartedQuestionnaireStep; + let previouslyAnsweredQuestions = this.req.me.getStartedQuestionnaireAnswers; + // Respond with view. + return {currentStep, previouslyAnsweredQuestions}; + } else { + // Respond with view. + return; + } } diff --git a/website/api/models/User.js b/website/api/models/User.js index 513c4d083e..f664e0420d 100644 --- a/website/api/models/User.js +++ b/website/api/models/User.js @@ -212,6 +212,17 @@ without necessarily having a billing card.` 'mdm', 'vm', ] + }, + + lastSubmittedGetStartedQuestionnaireStep: { + type: 'string', + description: 'The last step the user reached in the get started form.' + }, + + getStartedQuestionnaireAnswers: { + type: 'json', + description: 'This answers the user provided when they filled out the get started form.', + defaultsTo: {}, } // ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗ diff --git a/website/assets/images/icon-deploy-fleet-64x64@2x.png b/website/assets/images/icon-deploy-fleet-64x64@2x.png new file mode 100644 index 0000000000..f70c0ac9fd Binary files /dev/null and b/website/assets/images/icon-deploy-fleet-64x64@2x.png differ diff --git a/website/assets/images/icon-form-success-12x12@2x.png b/website/assets/images/icon-form-success-12x12@2x.png new file mode 100644 index 0000000000..d09d7c9214 Binary files /dev/null and b/website/assets/images/icon-form-success-12x12@2x.png differ diff --git a/website/assets/js/cloud.setup.js b/website/assets/js/cloud.setup.js index 95044bcbb0..cf4a555bd5 100644 --- a/website/assets/js/cloud.setup.js +++ b/website/assets/js/cloud.setup.js @@ -13,7 +13,7 @@ Cloud.setup({ /* eslint-disable */ - methods: {"downloadSitemap":{"verb":"GET","url":"/sitemap.xml","args":[]},"downloadRssFeed":{"verb":"GET","url":"/rss/:categoryName","args":["categoryName"]},"receiveUsageAnalytics":{"verb":"POST","url":"/api/v1/webhooks/receive-usage-analytics","args":["anonymousIdentifier","fleetVersion","licenseTier","numHostsEnrolled","numUsers","numTeams","numPolicies","numLabels","softwareInventoryEnabled","vulnDetectionEnabled","systemUsersEnabled","hostsStatusWebHookEnabled","numWeeklyActiveUsers","numWeeklyPolicyViolationDaysActual","numWeeklyPolicyViolationDaysPossible","hostsEnrolledByOperatingSystem","hostsEnrolledByOrbitVersion","hostsEnrolledByOsqueryVersion","storedErrors","numHostsNotResponding","organization","mdmMacOsEnabled","mdmWindowsEnabled","liveQueryDisabled","hostExpiryEnabled"]},"receiveFromGithub":{"verb":"GET","url":"/api/v1/webhooks/github","args":["botSignature","action","sender","repository","changes","issue","comment","pull_request","label","release"]},"receiveFromStripe":{"verb":"POST","url":"/api/v1/webhooks/receive-from-stripe","args":["id","type","data","webhookSecret"]},"deliverContactFormMessage":{"verb":"POST","url":"/api/v1/deliver-contact-form-message","args":["emailAddress","firstName","lastName","message"]},"sendPasswordRecoveryEmail":{"verb":"POST","url":"/api/v1/entrance/send-password-recovery-email","args":["emailAddress"]},"signup":{"verb":"POST","url":"/api/v1/customers/signup","args":["emailAddress","password","organization","firstName","lastName","signupReason"]},"updateProfile":{"verb":"POST","url":"/api/v1/account/update-profile","args":["firstName","lastName","organization","emailAddress"]},"updatePassword":{"verb":"POST","url":"/api/v1/account/update-password","args":["oldPassword","newPassword"]},"updateBillingCard":{"verb":"POST","url":"/api/v1/account/update-billing-card","args":["stripeToken","billingCardLast4","billingCardBrand","billingCardExpMonth","billingCardExpYear"]},"login":{"verb":"POST","url":"/api/v1/customers/login","args":["emailAddress","password","rememberMe"]},"logout":{"verb":"GET","url":"/api/v1/account/logout","args":[]},"createQuote":{"verb":"POST","url":"/api/v1/customers/create-quote","args":["numberOfHosts"]},"saveBillingInfoAndSubscribe":{"verb":"POST","url":"/api/v1/customers/save-billing-info-and-subscribe","args":["quoteId","organization","firstName","lastName","paymentSource"]},"updatePasswordAndLogin":{"verb":"POST","url":"/api/v1/entrance/update-password-and-login","args":["password","token"]},"deliverDemoSignup":{"verb":"POST","url":"/api/v1/deliver-demo-signup","args":["emailAddress"]},"createOrUpdateOneNewsletterSubscription":{"verb":"POST","url":"/api/v1/create-or-update-one-newsletter-subscription","args":["emailAddress","subscribeTo"]},"unsubscribeFromAllNewsletters":{"verb":"GET","url":"/api/v1/unsubscribe-from-all-newsletters","args":["emailAddress"]},"buildLicenseKey":{"verb":"POST","url":"/api/v1/admin/build-license-key","args":["numberOfHosts","organization","expiresAt","partnerName"]},"createVantaAuthorizationRequest":{"verb":"POST","url":"/api/v1/create-vanta-authorization-request","args":["emailAddress","fleetInstanceUrl","fleetApiKey"]},"deliverMdmBetaSignup":{"verb":"POST","url":"/api/v1/deliver-mdm-beta-signup","args":["emailAddress","fullName","jobTitle","numberOfHosts"]},"deliverAppleCsr":{"verb":"POST","url":"/api/v1/deliver-apple-csr","args":["unsignedCsrData"]},"deliverPremiumUpgradeForm":{"verb":"POST","url":"/api/v1/deliver-premium-upgrade-form","args":["organization","monthsUsingFleetFree","emailAddress","numberOfHosts"]},"deliverLaunchPartySignup":{"verb":"POST","url":"/api/v1/deliver-launch-party-signup","args":["emailAddress","firstName","lastName","jobTitle","phoneNumber"]},"deliverMdmDemoEmail":{"verb":"POST","url":"/api/v1/deliver-mdm-demo-email","args":["emailAddress"]},"provisionSandboxInstanceAndDeliverEmail":{"verb":"POST","url":"/api/v1/admin/provision-sandbox-instance-and-deliver-email","args":["userId"]},"deliverTalkToUsFormSubmission":{"verb":"POST","url":"/api/v1/deliver-talk-to-us-form-submission","args":["emailAddress","firstName","lastName","organization","numberOfHosts","primaryBuyingSituation"]}} + methods: {"downloadSitemap":{"verb":"GET","url":"/sitemap.xml","args":[]},"downloadRssFeed":{"verb":"GET","url":"/rss/:categoryName","args":["categoryName"]},"receiveUsageAnalytics":{"verb":"POST","url":"/api/v1/webhooks/receive-usage-analytics","args":["anonymousIdentifier","fleetVersion","licenseTier","numHostsEnrolled","numUsers","numTeams","numPolicies","numLabels","softwareInventoryEnabled","vulnDetectionEnabled","systemUsersEnabled","hostsStatusWebHookEnabled","numWeeklyActiveUsers","numWeeklyPolicyViolationDaysActual","numWeeklyPolicyViolationDaysPossible","hostsEnrolledByOperatingSystem","hostsEnrolledByOrbitVersion","hostsEnrolledByOsqueryVersion","storedErrors","numHostsNotResponding","organization","mdmMacOsEnabled","mdmWindowsEnabled","liveQueryDisabled","hostExpiryEnabled"]},"receiveFromGithub":{"verb":"GET","url":"/api/v1/webhooks/github","args":["botSignature","action","sender","repository","changes","issue","comment","pull_request","label","release"]},"receiveFromStripe":{"verb":"POST","url":"/api/v1/webhooks/receive-from-stripe","args":["id","type","data","webhookSecret"]},"deliverContactFormMessage":{"verb":"POST","url":"/api/v1/deliver-contact-form-message","args":["emailAddress","firstName","lastName","message"]},"sendPasswordRecoveryEmail":{"verb":"POST","url":"/api/v1/entrance/send-password-recovery-email","args":["emailAddress"]},"signup":{"verb":"POST","url":"/api/v1/customers/signup","args":["emailAddress","password","organization","firstName","lastName","signupReason","primaryBuyingSituation"]},"updateProfile":{"verb":"POST","url":"/api/v1/account/update-profile","args":["firstName","lastName","organization","emailAddress"]},"updatePassword":{"verb":"POST","url":"/api/v1/account/update-password","args":["oldPassword","newPassword"]},"updateBillingCard":{"verb":"POST","url":"/api/v1/account/update-billing-card","args":["stripeToken","billingCardLast4","billingCardBrand","billingCardExpMonth","billingCardExpYear"]},"login":{"verb":"POST","url":"/api/v1/customers/login","args":["emailAddress","password","rememberMe"]},"logout":{"verb":"GET","url":"/api/v1/account/logout","args":[]},"createQuote":{"verb":"POST","url":"/api/v1/customers/create-quote","args":["numberOfHosts"]},"saveBillingInfoAndSubscribe":{"verb":"POST","url":"/api/v1/customers/save-billing-info-and-subscribe","args":["quoteId","organization","firstName","lastName","paymentSource"]},"updatePasswordAndLogin":{"verb":"POST","url":"/api/v1/entrance/update-password-and-login","args":["password","token"]},"deliverDemoSignup":{"verb":"POST","url":"/api/v1/deliver-demo-signup","args":["emailAddress"]},"createOrUpdateOneNewsletterSubscription":{"verb":"POST","url":"/api/v1/create-or-update-one-newsletter-subscription","args":["emailAddress","subscribeTo"]},"unsubscribeFromAllNewsletters":{"verb":"GET","url":"/api/v1/unsubscribe-from-all-newsletters","args":["emailAddress"]},"buildLicenseKey":{"verb":"POST","url":"/api/v1/admin/build-license-key","args":["numberOfHosts","organization","expiresAt","partnerName"]},"createVantaAuthorizationRequest":{"verb":"POST","url":"/api/v1/create-vanta-authorization-request","args":["emailAddress","fleetInstanceUrl","fleetApiKey"]},"deliverMdmBetaSignup":{"verb":"POST","url":"/api/v1/deliver-mdm-beta-signup","args":["emailAddress","fullName","jobTitle","numberOfHosts"]},"deliverAppleCsr":{"verb":"POST","url":"/api/v1/deliver-apple-csr","args":["unsignedCsrData"]},"deliverLaunchPartySignup":{"verb":"POST","url":"/api/v1/deliver-launch-party-signup","args":["emailAddress","firstName","lastName","jobTitle","phoneNumber"]},"deliverMdmDemoEmail":{"verb":"POST","url":"/api/v1/deliver-mdm-demo-email","args":["emailAddress"]},"provisionSandboxInstanceAndDeliverEmail":{"verb":"POST","url":"/api/v1/admin/provision-sandbox-instance-and-deliver-email","args":["userId"]},"deliverTalkToUsFormSubmission":{"verb":"POST","url":"/api/v1/deliver-talk-to-us-form-submission","args":["emailAddress","firstName","lastName","organization","numberOfHosts","primaryBuyingSituation"]},"saveQuestionnaireProgress":{"verb":"POST","url":"/api/v1/save-questionnaire-progress","args":["currentStep","formData"]}} /* eslint-enable */ }); diff --git a/website/assets/js/pages/contact.page.js b/website/assets/js/pages/contact.page.js index e5132f4fb8..2b629aa352 100644 --- a/website/assets/js/pages/contact.page.js +++ b/website/assets/js/pages/contact.page.js @@ -32,6 +32,8 @@ parasails.registerPage('contact', { message: {required: false}, }, + formDataToPrefillForLoggedInUsers: {}, + // Server error state for the form cloudError: '', @@ -46,6 +48,17 @@ parasails.registerPage('contact', { if(this.formToShow === 'contact'){ this.formToDisplay = this.formToShow; } + if(this.prefillFormDataFromUserRecord){ + this.formDataToPrefillForLoggedInUsers.emailAddress = this.me.emailAddress; + this.formDataToPrefillForLoggedInUsers.firstName = this.me.firstName; + this.formDataToPrefillForLoggedInUsers.lastName = this.me.lastName; + this.formDataToPrefillForLoggedInUsers.organization = this.me.organization; + // Only prefil this information if the user has this value set. + if(this.me.primaryBuyingSituation) { + this.formDataToPrefillForLoggedInUsers.primaryBuyingSituation = this.me.primaryBuyingSituation; + } + this.formData = _.clone(this.formDataToPrefillForLoggedInUsers); + } if(window.location.search){ window.history.replaceState({}, document.title, '/contact' ); } @@ -78,7 +91,11 @@ parasails.registerPage('contact', { }, clickSwitchForms: function(form) { - this.formData = {}; + if(this.prefillFormDataFromUserRecord){ + this.formData = _.clone(this.formDataToPrefillForLoggedInUsers); + } else { + this.formData = {}; + } this.formErrors = {}; this.cloudError = ''; this.formToDisplay = form; diff --git a/website/assets/js/pages/entrance/signup.page.js b/website/assets/js/pages/entrance/signup.page.js index 1528c7d780..dc9a3a7781 100644 --- a/website/assets/js/pages/entrance/signup.page.js +++ b/website/assets/js/pages/entrance/signup.page.js @@ -17,7 +17,6 @@ parasails.registerPage('signup', { organization: {required: true}, emailAddress: {required: true, isEmail: true}, password: {required: true, minLength: 8}, - primaryBuyingSituation: {required: true}, }, // Syncing / loading state syncing: false, diff --git a/website/assets/js/pages/start.page.js b/website/assets/js/pages/start.page.js index d1db7b5511..ab27d73540 100644 --- a/website/assets/js/pages/start.page.js +++ b/website/assets/js/pages/start.page.js @@ -3,7 +3,54 @@ parasails.registerPage('start', { // ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣ // ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝ data: { - //… + currentStep: 'start', + + syncing: false, + + // Form data + formData: { + 'start': {stepCompleted: true}, + 'what-are-you-using-fleet-for': {}, + 'have-you-ever-used-fleet': {}, + 'how-many-hosts': {}, + 'will-you-be-self-hosting': {}, + 'what-are-you-working-on-eo-security': {}, + 'is-it-any-good': {stepCompleted: true}, + 'what-did-you-think': {}, + }, + // For tracking client-side validation errors in our form. + // > Has property set to `true` for each invalid property in `formData`. + formErrors: { /* … */ }, + + formRules: {}, + primaryBuyingSituationFormRules: { + primaryBuyingSituation: {required: true} + }, + isUsingFleetFormRules: { + fleetUseStatus: {required: true} + }, + numberOfHostsFormRules: { + numberOfHosts: {required: true} + }, + hostingFleetFormRules: { + willSelfHost: {required: true} + }, + endpointOpsSecurityWorkingOnFormRules: { + endpointOpsSecurityUseCase: {required: true} + }, + endpointOpsSecurityIsItAnyGoodFormRules: { + isItAnyGood: {required: true} + }, + endpointOpsSecurityWhatDidYouThinkFormRules: { + whatDidYouThink: {required: true} + }, + previouslyAnsweredQuestions: {}, + + // Server error state for the forms + cloudError: '', + + // Success state when form has been submitted + cloudSuccess: false, }, // ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗ @@ -11,6 +58,9 @@ parasails.registerPage('start', { // ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝ beforeMount: function() { //… + if(this.currentStep !== 'start'){ + this.prefillPreviousAnswers(); + } }, mounted: async function() { //… @@ -20,6 +70,125 @@ parasails.registerPage('start', { // ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗ // ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ methods: { - //… + handleSubmittingForm: async function(argins) { + let formDataForThisStep = _.clone(argins); + let nextStep = this.getNextStep(); + let getStartedProgress = await Cloud.saveQuestionnaireProgress.with({ + currentStep: this.currentStep, + formData: formDataForThisStep, + }); + this.previouslyAnsweredQuestions[this.currentStep] = getStartedProgress[this.currentStep]; + this.syncing = false; + this.currentStep = nextStep; + }, + clickGoToPreviousStep: async function() { + switch(this.currentStep) { + case 'have-you-ever-used-fleet': + this.currentStep = 'what-are-you-using-fleet-for'; + break; + case 'how-many-hosts': + this.currentStep = 'have-you-ever-used-fleet'; + break; + case 'will-you-be-self-hosting': + this.currentStep = 'how-many-hosts'; + break; + case 'self-hosted-deploy': + this.currentStep = 'will-you-be-self-hosting'; + break; + case 'managed-cloud-for-growing-deployments': + this.currentStep = 'will-you-be-self-hosting'; + break; + case 'what-are-you-working-on-eo-security': + this.currentStep = 'have-you-ever-used-fleet'; + break; + case 'is-it-any-good': + this.currentStep = 'what-are-you-working-on-eo-security'; + break; + case 'lets-talk-to-your-team': + this.currentStep = 'how-many-hosts'; + break; + case 'welcome-to-fleet': + this.currentStep = 'have-you-ever-used-fleet'; + break; + case 'deploy-fleet-in-your-environment': + this.currentStep = 'what-did-you-think'; + break; + case 'what-did-you-think': + this.currentStep = 'is-it-any-good'; + break; + } + }, + getNextStep: function() { + let nextStepInForm; + switch(this.currentStep) { + case 'start': + nextStepInForm = 'what-are-you-using-fleet-for'; + break; + case 'what-are-you-using-fleet-for': + nextStepInForm = 'have-you-ever-used-fleet'; + break; + case 'have-you-ever-used-fleet': + let fleetUseStatus = this.formData['have-you-ever-used-fleet'].fleetUseStatus; + let primaryBuyingSituation = this.formData['what-are-you-using-fleet-for'].primaryBuyingSituation; + if(fleetUseStatus === 'yes-recently-deployed' || fleetUseStatus === 'yes-deployed') { + nextStepInForm = 'how-many-hosts'; + } else { + if(primaryBuyingSituation === 'eo-security'){ + nextStepInForm = 'what-are-you-working-on-eo-security'; + } else { + nextStepInForm = 'welcome-to-fleet'; + } + } + break; + case 'how-many-hosts': + if(this.formData['how-many-hosts'].numberOfHosts === '1-100' || + this.formData['how-many-hosts'].numberOfHosts === '100-700') { + nextStepInForm = 'will-you-be-self-hosting'; + } else { + nextStepInForm = 'lets-talk-to-your-team'; + } + break; + case 'will-you-be-self-hosting': + if(this.formData['will-you-be-self-hosting'].willSelfHost === 'true'){ + nextStepInForm = 'self-hosted-deploy'; + } else { + nextStepInForm = 'managed-cloud-for-growing-deployments'; + } + break; + case 'what-are-you-working-on-eo-security': + nextStepInForm = 'is-it-any-good'; + break; + case 'is-it-any-good': + nextStepInForm = 'what-did-you-think'; + break; + case 'what-did-you-think': + if(this.formData['what-did-you-think'].whatDidYouThink === 'let-me-think-about-it'){ + nextStepInForm = 'is-it-any-good'; + } else { + nextStepInForm = 'deploy-fleet-in-your-environment'; + } + break; + } + return nextStepInForm; + }, + clickGoToCalendly: function() { + window.location = `https://calendly.com/fleetdm/talk-to-us?email=${encodeURIComponent(this.me.emailAddress)}&name=${encodeURIComponent(this.me.firstName+' '+this.me.lastName)}`; + }, + clickGoToContactPage: function() { + window.location = `/contact?prefillFormDataFromUserRecord`; + }, + clickClearOneFormError: function(field) { + if(this.formErrors[field]){ + this.formErrors = _.omit(this.formErrors, field); + } + }, + prefillPreviousAnswers: function() { + if(!_.isEmpty(this.previouslyAnsweredQuestions)){ + for(let step in this.previouslyAnsweredQuestions){ + this.formData[step] = this.previouslyAnsweredQuestions[step]; + } + this.currentStep = this.getNextStep(); + } + }, } }); diff --git a/website/assets/styles/pages/start.less b/website/assets/styles/pages/start.less index 2ab70735ef..aa299005f0 100644 --- a/website/assets/styles/pages/start.less +++ b/website/assets/styles/pages/start.less @@ -8,18 +8,139 @@ font-weight: 800; line-height: 150%; } + h2 { + margin-bottom: 32px; + font-size: 24px; + font-weight: 800; + line-height: 120%; + } [purpose='logo-container'] { max-width: 524px; margin-left: auto; margin-right: auto; } + [purpose='form-container'] { + width: 528px; + margin-left: auto; + margin-right: auto; + } [purpose='page-container'] { - padding-top: 80px; + padding-top: 64px; padding-left: 64px; padding-right: 64px; + padding-bottom: 64px; max-width: unset; display: flex; flex-direction: column; + justify-content: center; + } + [purpose='progress-bar-container'] { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 32px; + img { + height: 18px; + display: inline; + margin-left: 10px; + } + } + [purpose='form-progress-bar'] { + height: 6px; + width: 200px; + background: #E2E4EA; + border-radius: 3px; + [purpose='current-progress'] { + background-color: #3DB67B; + height: 6px; + border-radius: 3px; + } + } + .form-group.is-invalid { + color: @core-vibrant-red; + .form-control { + color: @core-vibrant-red; + } + .invalid-feedback { + display: block; + } + } + [purpose='form-option'] { + user-select: none; + cursor: pointer; + width: fit-content; + padding: 8px 12px 8px 8px; + margin-bottom: 16px; + display: flex; + flex-direction: row; + align-items: center; + border-radius: 7px; + border: 1px solid #E2E4EA; + font-size: 16px; + line-height: 24px; + color: #515774; + white-space: nowrap; + height: fit-content; + input { + cursor: pointer; + margin-right: 8px; + display: none; + } + [purpose='custom-radio'] { + margin-right: 8px; + display: flex; + min-width: 18px; + min-height: 18px; + border-radius: 50%; + border: 1px solid #E2E4EA; + justify-content: center; + align-items: center; + [purpose='custom-radio-selected'] { + min-width: 10px; + min-height: 10px; + border-radius: 50%; + background-color: @core-vibrant-blue; + transform: scale(0); + transition: 180ms transform ease-in-out; + } + } + input[type='radio']:checked + [purpose='custom-radio'] { + [purpose='custom-radio-selected'] { + transform: scale(1); + } + } + .form-control { + height: 40px; + } + &:hover { + border: 1px solid @core-vibrant-blue; + } + &.selected { + border: 1px solid @core-vibrant-blue; + } + } + + [purpose='form-buttons'] { + margin-top: 32px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: start; + user-select: none; + } + [purpose='submit-button'] { + padding: 12px; + font-size: 14px; + font-weight: 700; + line-height: 150%; + margin-right: 24px; + } + [purpose='back-button'] { + cursor: pointer; + font-size: 14px; + font-weight: 700; + line-height: 150%; + margin-right: 24px; } [purpose='start-cards'] { display: flex; @@ -31,13 +152,14 @@ } [purpose='card'] { width: 252px; + height: 200px; display: flex; flex-direction: column; justify-content: center; align-items: center; text-decoration: none; - - padding: 43px 52px; + cursor: pointer; + padding: 24px; background: #FFF; color: @core-fleet-black-75; border-radius: 12px; @@ -57,7 +179,7 @@ font-size: 12px; font-weight: 400; line-height: 150%; - white-space: nowrap; + // white-space: nowrap; margin-bottom: 0px; } &:first-of-type { @@ -68,6 +190,51 @@ } } + [purpose='quote'] { + display: flex; + min-height: 300px; + padding: 32px; + flex-direction: column; + justify-content: center; + align-items: flex-start; + align-self: stretch; + border-radius: 16px; + background: #FFF; + box-shadow: none; + background-color: #FFF; + height: fit-content; + max-width: 100%; + text-align: left; + border: 1px solid @core-vibrant-blue-15; + [purpose='logo'] { + img { + max-height: 32px; + } + min-height: 0; + margin-bottom: 24px; + } + [purpose='quote-text'] { + margin-bottom: 24px; + font-size: 14px; + line-height: 150%; + } + [purpose='quote-author-info'] { + [purpose='job-title'] { + font-size: 12px; + line-height: 18px; + } + [purpose='name'] { + color: @core-fleet-black; + } + [purpose='profile-picture'] { + margin-right: 16px; + img { + height: 48px; + width: 48px; + } + } + } + } @media (max-width: 991px) { [purpose='page-container'] { padding-top: 60px; @@ -91,11 +258,23 @@ } [purpose='start-cards'] { flex-direction: column; + [purpose='card'] { + width: 100%; + } } [purpose='card']:first-of-type { margin-right: unset; margin-bottom: 20px; } + [purpose='form-container'] { + width: unset; + margin-left: 0; + margin-right: 0; + } + [purpose='form-option'] { + white-space: unset; + width: unset; + } } @media (max-width: 375px) { h1 { diff --git a/website/config/routes.js b/website/config/routes.js index 6a486f1db6..be70757038 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -280,8 +280,8 @@ module.exports.routes = { 'GET /start': { action: 'view-start', locals: { - hideHeaderLinks: true, hideFooterLinks: true, + hideGetStartedButton: true, pageTitleForMeta: 'Start | Fleet', pageDescriptionForMeta: 'Get Started with Fleet. Spin up a local demo or get your premium license key.', } @@ -577,4 +577,5 @@ module.exports.routes = { 'POST /api/v1/deliver-mdm-demo-email': { action: 'deliver-mdm-demo-email' }, 'POST /api/v1/admin/provision-sandbox-instance-and-deliver-email': { action: 'admin/provision-sandbox-instance-and-deliver-email' }, 'POST /api/v1/deliver-talk-to-us-form-submission': { action: 'deliver-talk-to-us-form-submission' }, + 'POST /api/v1/save-questionnaire-progress': { action: 'save-questionnaire-progress' }, }; diff --git a/website/generators/landing-page/index.js b/website/generators/landing-page/index.js index 5199522bb4..2ed7891caa 100644 --- a/website/generators/landing-page/index.js +++ b/website/generators/landing-page/index.js @@ -219,8 +219,8 @@ module.exports = {

${_.capitalize(scope.stem.replace(/\-/gim, ' '))}

Vitae architecto reiciendis in temporibus consequatur doloremque reprehenderit perferendis? Eaque quod voluptates earum corporis, quo labore reprehenderit libero sint.

- Talk to us - Try it out + Start now + Talk to us
@@ -274,8 +274,8 @@ module.exports = {
- Talk to us - Try it out + Start now + Talk to us
@@ -296,8 +296,8 @@ module.exports = {

Open-source device management

Lighter than air

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/layouts/layout.ejs b/website/views/layouts/layout.ejs index 0d069e0dac..dd6720d902 100644 --- a/website/views/layouts/layout.ejs +++ b/website/views/layouts/layout.ejs @@ -8,6 +8,7 @@ var hideHeaderLinks;// Hides the header navigation links. var hideFooterLinks;// Hides footer links, reduces the height of the footer to 60px; var showAdminLinks;// Shows links to admin pages to admin users. + var hideGetStartedButton;// Hides the 'Get started' button in the website's navigation header. // Applies personalization for who people come from ads, so that the website makes more sense for them: var primaryBuyingSituation; @@ -217,7 +218,9 @@ HTML Email preview tool <%}%> - Talk to us + <%if(!hideGetStartedButton){%> + Start now + <% }%> <%/* Desktop Navigation bar */%> @@ -264,7 +267,9 @@ - Talk to us + <%if(!hideGetStartedButton){%> + Start now + <% }%> <% if(_.has(me, 'id')) {%> Log out <% }%> diff --git a/website/views/pages/device-management.ejs b/website/views/pages/device-management.ejs index aa0a3eb1de..ce16776c7c 100644 --- a/website/views/pages/device-management.ejs +++ b/website/views/pages/device-management.ejs @@ -18,8 +18,8 @@ “Zero” trust, fewer tickets

You can use Fleet’s API to customize every aspect of conditional access – even the stuff your CISO hasn’t thought of yet.

- Talk to us - Try it out + Start now + Talk to us
@@ -206,8 +206,8 @@

Device management (MDM)

Manage everything in one place

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/endpoint-ops.ejs b/website/views/pages/endpoint-ops.ejs index f041ac90c4..90eadceb08 100644 --- a/website/views/pages/endpoint-ops.ejs +++ b/website/views/pages/endpoint-ops.ejs @@ -18,8 +18,8 @@ Osquery on easy mode

You don’t need to be an osquery expert to get the answers you need from your devices, Fleet does some of that for you.

- Talk to us - Try it out + Start now + Talk to us
@@ -194,8 +194,8 @@

Endpoint operations

A consistent interface

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/entrance/signup.ejs b/website/views/pages/entrance/signup.ejs index eb7ef5bec5..c5c7b6069b 100644 --- a/website/views/pages/entrance/signup.ejs +++ b/website/views/pages/entrance/signup.ejs @@ -43,19 +43,6 @@ -
- -
- -
-
Please select an option.
-

This email is already linked to a Fleet account.
Please sign in with your email and password.

diff --git a/website/views/pages/homepage.ejs b/website/views/pages/homepage.ejs index 5087db21ee..9a8c3655fc 100644 --- a/website/views/pages/homepage.ejs +++ b/website/views/pages/homepage.ejs @@ -10,8 +10,8 @@

<%- partial('../partials/primary-tagline.partial.ejs') %>

Replace the sprawl with open-source code that works the way you want.

- Talk to us - Try it out + Start now + Talk to us
@@ -277,8 +277,8 @@

For teams with lots of different endpoints

<%- partial('../partials/primary-tagline.partial.ejs') %>

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/imagine/higher-education.ejs b/website/views/pages/imagine/higher-education.ejs index 67272edc1e..5310abb0c6 100644 --- a/website/views/pages/imagine/higher-education.ejs +++ b/website/views/pages/imagine/higher-education.ejs @@ -8,8 +8,8 @@

Higher education meets simplified security

Automate security workflows in a single application by creating or installing policies to identify which devices comply with your security guidelines.

- Talk to us - Try it out + Start now + Talk to us
@@ -85,8 +85,8 @@

Open-source device management

Think for yourself

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/imagine/jamf-alternative.ejs b/website/views/pages/imagine/jamf-alternative.ejs index 599003ccb9..8f002393b7 100644 --- a/website/views/pages/imagine/jamf-alternative.ejs +++ b/website/views/pages/imagine/jamf-alternative.ejs @@ -8,8 +8,8 @@

Fleet brings GitOps to MDM

Bringh-your-own MDM. Enjoy enterprise-ready open-source MDM and leverage the best of DevOps and GitOps inside a full-featured Macbook MDM.

- Talk to us - Try it out + Start now + Talk to us
@@ -59,8 +59,8 @@

Open-source device management

Lighter than air

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/imagine/rapid-7-alternative.ejs b/website/views/pages/imagine/rapid-7-alternative.ejs index 0f4b5e19e5..3cd081e0db 100644 --- a/website/views/pages/imagine/rapid-7-alternative.ejs +++ b/website/views/pages/imagine/rapid-7-alternative.ejs @@ -8,8 +8,8 @@

Simplify vulnerability management

Fleet, an open-source security platform, empowers you to take control of vulnerability management for your organization. Designed with modern DevOps practices in mind, Fleet offers superior visibility, rapid response capabilities, and seamless integration with your existing workflows.

- Talk to us - Try it out + Start now + Talk to us
@@ -100,8 +100,8 @@

Open-source device management

Lighter than air

- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/imagine/unused-software.ejs b/website/views/pages/imagine/unused-software.ejs index c31434487e..5f62c7684b 100644 --- a/website/views/pages/imagine/unused-software.ejs +++ b/website/views/pages/imagine/unused-software.ejs @@ -8,8 +8,8 @@

Discover unused software licenses and optimize your IT budget

Fleet, the leading open-source, flexible device management solution, offers unprecedented visibility into your IT infrastructure, making it the ideal tool to discover and manage unused software licenses. This capability is essential to unlocking more IT budget, enhancing security, and ultimately improving the employee experience.

- Talk to us - Try it out + Start now + Talk to us
@@ -64,8 +64,8 @@
- Talk to us - Try it out + Start now + Talk to us
diff --git a/website/views/pages/pricing.ejs b/website/views/pages/pricing.ejs index 40dc82125c..e69f64189a 100644 --- a/website/views/pages/pricing.ejs +++ b/website/views/pages/pricing.ejs @@ -43,7 +43,7 @@
- Get started + Get started
diff --git a/website/views/pages/start.ejs b/website/views/pages/start.ejs index e48d94933c..ea6dad2f8d 100644 --- a/website/views/pages/start.ejs +++ b/website/views/pages/start.ejs @@ -1,23 +1,519 @@
-
-

Welcome to Fleet

-

Spin up a local demo or get your Fleet Premium license key.

+
+ <%// ┌─┐┌┬┐┌─┐┬─┐┌┬┐ + // └─┐ │ ├─┤├┬┘ │ + // └─┘ ┴ ┴ ┴┴└─ ┴ %> +
+
+

Let’s get started

+

To see whether Fleet’s right for your team, let's have a look at your hosts and what you're trying to do.

+

You can come back at any time and pick up where you left off.

+ +
+ Start +
+
+
-
- - Run a local demo of Fleet -

Try Fleet

-

Run a local demo of Fleet

-
- - Purchase a Fleet Premium license -

Start

-

Purchase a Fleet Premium license

-
+ <%// ┬ ┬┬ ┬┌─┐┌┬┐ ┌─┐┬─┐┌─┐ ┬ ┬┌─┐┬ ┬ ┬ ┬┌─┐┬┌┐┌┌─┐ ┌─┐┬ ┌─┐┌─┐┌┬┐ ┌─┐┌─┐┬─┐ + // │││├─┤├─┤ │ ├─┤├┬┘├┤ └┬┘│ ││ │ │ │└─┐│││││ ┬ ├┤ │ ├┤ ├┤ │ ├┤ │ │├┬┘ + // └┴┘┴ ┴┴ ┴ ┴ ┴ ┴┴└─└─┘ ┴ └─┘└─┘ └─┘└─┘┴┘└┘└─┘ └ ┴─┘└─┘└─┘ ┴ └ └─┘┴└─%> +
+
+
+ 🏆 +
+

What will you use Fleet for?

+ +
+ + + + +
Please select an option
+
+ +
+ Continue +
+
+
+ <%// ┬ ┬┌─┐┬ ┬┌─┐ ┬ ┬┌─┐┬ ┬ ┌─┐┬ ┬┌─┐┬─┐ ┬ ┬┌─┐┌─┐┌┬┐ ┌─┐┬ ┌─┐┌─┐┌┬┐ + // ├─┤├─┤└┐┌┘├┤ └┬┘│ ││ │ ├┤ └┐┌┘├┤ ├┬┘ │ │└─┐├┤ ││ ├┤ │ ├┤ ├┤ │ + // ┴ ┴┴ ┴ └┘ └─┘ ┴ └─┘└─┘ └─┘ └┘ └─┘┴└─ └─┘└─┘└─┘─┴┘ └ ┴─┘└─┘└─┘ ┴ %> +
+
+
+ 🏆 +
+

Have you ever used Fleet?

+ + +
+ + + + + +
Please select an option
+
+ +
+ Back + Continue +
+
+
+ <%// ┬ ┬┌─┐┬ ┬ ┌┬┐┌─┐┌┐┌┬ ┬ ┬ ┬┌─┐┌─┐┌┬┐┌─┐ + // ├─┤│ ││││ │││├─┤│││└┬┘ ├─┤│ │└─┐ │ └─┐ + // ┴ ┴└─┘└┴┘ ┴ ┴┴ ┴┘└┘ ┴ ┴ ┴└─┘└─┘ ┴ └─┘%> +
+
+
+ 🏆 +
+

How many hosts do you have:

+ +
+ +
+ + + + +
Please select an option
+
+
+ +
+ Back + Continue +
+
+
+ <%// ┬ ┬┬┬ ┬ ┬ ┬┌─┐┬ ┬ ┌┐ ┌─┐ ┌─┐┌─┐┬ ┌─┐ ┬ ┬┌─┐┌─┐┌┬┐┬┌┐┌┌─┐ + // │││││ │ └┬┘│ ││ │ ├┴┐├┤ └─┐├┤ │ ├┤ ├─┤│ │└─┐ │ │││││ ┬ + // └┴┘┴┴─┘┴─┘ ┴ └─┘└─┘ └─┘└─┘ └─┘└─┘┴─┘└ ┴ ┴└─┘└─┘ ┴ ┴┘└┘└─┘%> +
+
+
+ 🏆 +
+

Will you be hosting Fleet yourself?

+ + +
+ + +
Please select an option
+
+ +
+ Back + Continue +
+
+
+ <%// ┬ ┬┬ ┬┌─┐┌┬┐ ┌─┐┬─┐┌─┐ ┬ ┬┌─┐┬ ┬ ┬ ┬┌─┐┬─┐┬┌─┬┌┐┌┌─┐ ┌─┐┌┐┌ + // │││├─┤├─┤ │ ├─┤├┬┘├┤ └┬┘│ ││ │ ││││ │├┬┘├┴┐│││││ ┬ │ ││││ ─── + // └┴┘┴ ┴┴ ┴ ┴ ┴ ┴┴└─└─┘ ┴ └─┘└─┘ └┴┘└─┘┴└─┴ ┴┴┘└┘└─┘ └─┘┘└┘ + // ┌─┐┌─┐ ┌─┐┌─┐┌─┐┬ ┬┬─┐┬┌┬┐┬ ┬ + // ├┤ │ │───└─┐├┤ │ │ │├┬┘│ │ └┬┘ + // └─┘└─┘ └─┘└─┘└─┘└─┘┴└─┴ ┴ ┴%> +
+
+
+ 🏆 +
+

What are you working on, mainly?

+ +
+ +
+ + + + + + +
Please select an option
+
+
+ +
+ Back + Continue +
+
+
+ <%// ┬┌─┐ ┬┌┬┐ ┌─┐┌┐┌┬ ┬ ┌─┐┌─┐┌─┐┌┬┐ + // │└─┐ │ │ ├─┤│││└┬┘ │ ┬│ ││ │ ││ + // ┴└─┘ ┴ ┴ ┴ ┴┘└┘ ┴ └─┘└─┘└─┘─┴┘%> +
+ +
+
+ 🏆 +
+
+

Is it any good?

+

We don’t have a public sample environment, but you can try Fleet out locally on your computer.

+
+ +

You can come back here any time to continue with your deployment.

+
+ Back + Continue +
+
+
+ <%// ┬ ┬┬ ┬┌─┐┌┬┐ ┌┬┐┬┌┬┐ ┬ ┬┌─┐┬ ┬ ┌┬┐┬ ┬┬┌┐┌┬┌─ + // │││├─┤├─┤ │ │││ ││ └┬┘│ ││ │ │ ├─┤││││├┴┐ + // └┴┘┴ ┴┴ ┴ ┴ ─┴┘┴─┴┘ ┴ └─┘└─┘ ┴ ┴ ┴┴┘└┘┴ ┴%> +
+
+
+ 🏆 +
+

What did you think?

+

Now that you’ve seen what Fleet can do, what do you want to do next?

+ +
+
+ + + I’d like you to host Fleet for me +
+ + +
Please select an option
+
+ +
+
Deloitte logo
+

+ Something I really appreciate about working with you guys is that it doesn't feel like I'm talking to a vendor. It actually feels like I'm talking to my team, and I really appreciate it. +

+
+
+ Chandra Majumdar +
+
+

Chandra Majumdar

+

Partner - Cyber and Strategic Risk

+
+
+
+
+
Uber logo
+

+ Exciting. This is a team that listens to feedback. +

+
+
+ Erik Gomez +
+
+

Erik Gomez

+

Staff Client Platform Engineer

+
+
+
+
+

+ The visibility down into the assets covered by the agent is phenomenal. Fleet has become the central source for a lot of things. +

+
+
+ Andre Shields +
+
+

Andre Shields

+

Staff Cybersecurity Engineer, Vulnerability Management

+
+
+
+
+
Deputy logo
+

+ When we look at vendors, we look for ones that are very receptive to feedback, where you’re just part of the family, I guess. Fleet’s really good at that. +

+
+
+ Harrison Ravazzolo +
+
+

Harrison Ravazzolo

+

Lead platform and identity engineer

+
+
+
+
+
Atlassian logo
+

+ I love the steady and consistent delivery of features that help teams work how they want to work, not how your product dictates they work. +

+
+
+ Dan Grzelak +
+
+

Dan Grzelak

+

Security Chief of Staff

+
+
+
+
+ Back + Continue +
+
+
+ <%// ┬ ┌─┐┌┬┐┌─┐ ┌┬┐┌─┐┬ ┬┌─ ┌┬┐┌─┐ ┬ ┬┌─┐┬ ┬┬─┐ ┌┬┐┌─┐┌─┐┌┬┐ + // │ ├┤ │ └─┐ │ ├─┤│ ├┴┐ │ │ │ └┬┘│ ││ │├┬┘ │ ├┤ ├─┤│││ + // ┴─┘└─┘ ┴ └─┘ ┴ ┴ ┴┴─┘┴ ┴ ┴ └─┘ ┴ └─┘└─┘┴└─ ┴ └─┘┴ ┴┴ ┴%> +
+
+
+ 🏆 +
+
+

Let’s talk to your team

+

Great, let’s jump on a call to talk more about your fleet.

+
+ +
+ Back +
+
+ <%// ╔╦╗┌─┐┌─┐┬ ┌─┐┬ ┬ ┌─┐┬ ┌─┐┌─┐┌┬┐ ┬┌┐┌ ┬ ┬┌─┐┬ ┬┬─┐ ┌─┐┌┐┌┬ ┬┬┬─┐┌─┐┌┐┌┌┬┐┌─┐┌┐┌┌┬┐ + // ║║├┤ ├─┘│ │ │└┬┘ ├┤ │ ├┤ ├┤ │ ││││ └┬┘│ ││ │├┬┘ ├┤ │││└┐┌┘│├┬┘│ │││││││├┤ │││ │ + // ═╩╝└─┘┴ ┴─┘└─┘ ┴ └ ┴─┘└─┘└─┘ ┴ ┴┘└┘ ┴ └─┘└─┘┴└─ └─┘┘└┘ └┘ ┴┴└─└─┘┘└┘┴ ┴└─┘┘└┘ ┴%> +
+
+
+ 🏆 +
+
+

Deploy Fleet in your environment

+

Learn how to deploy and roll out Fleet in your environment.

+
+ +
+ +
+
+ Back +
+
+ <%// ┌─┐┌─┐┬ ┌─┐ ┬ ┬┌─┐┌─┐┌┬┐┌─┐┌┬┐ ┌┬┐┌─┐┌─┐┬ ┌─┐┬ ┬ + // └─┐├┤ │ ├┤───├─┤│ │└─┐ │ ├┤ ││ ││├┤ ├─┘│ │ │└┬┘ + // └─┘└─┘┴─┘└ ┴ ┴└─┘└─┘ ┴ └─┘─┴┘ ─┴┘└─┘┴ ┴─┘└─┘ ┴%> +
+
+
+ 🏆 +
+
+

Deploy Fleet in your environment

+

Learn how to deploy and rollout Fleet in your environment, get a Fleet Premium license, or both. You can come back in any time to upgrade.

+
+ +
+ Back +
+
+ <%// ┌┬┐┌─┐┌┐┌┌─┐┌─┐┌─┐┌┬┐ ┌─┐┬ ┌─┐┬ ┬┌┬┐ ┌─┐┌─┐┬─┐ ┌─┐┬─┐┌─┐┬ ┬┬┌┐┌┌─┐ + // │││├─┤│││├─┤│ ┬├┤ ││ │ │ │ ││ │ ││ ├┤ │ │├┬┘ │ ┬├┬┘│ │││││││││ ┬ + // ┴ ┴┴ ┴┘└┘┴ ┴└─┘└─┘─┴┘ └─┘┴─┘└─┘└─┘─┴┘ └ └─┘┴└─ └─┘┴└─└─┘└┴┘┴┘└┘└─┘ + // ┌┬┐┌─┐┌─┐┬ ┌─┐┬ ┬┌┬┐┌─┐┌┐┌┌┬┐┌─┐ + // ││├┤ ├─┘│ │ │└┬┘│││├┤ │││ │ └─┐ + // ─┴┘└─┘┴ ┴─┘└─┘ ┴ ┴ ┴└─┘┘└┘ ┴ └─┘%> +
+
+
+ 🏆 +
+
+

Managed cloud for growing deployments

+

Unfortunately, managed cloud hosting is not yet available for growing deployments of less than 700 hosts.

+
+ +
+ Back +
+
+ <%// ┬ ┬┌─┐┬ ┌─┐┌─┐┌┬┐┌─┐ ┌┬┐┌─┐ ┌─┐┬ ┌─┐┌─┐┌┬┐ + // │││├┤ │ │ │ ││││├┤ │ │ │ ├┤ │ ├┤ ├┤ │ + // └┴┘└─┘┴─┘└─┘└─┘┴ ┴└─┘ ┴ └─┘ └ ┴─┘└─┘└─┘ ┴%> +
+
+

Welcome to Fleet

+

Spin up a local demo or get your Fleet Premium license key.

+
+ +
+ +
+
+ Back +
-
-
diff --git a/website/views/pages/vulnerability-management.ejs b/website/views/pages/vulnerability-management.ejs index 6971d60fe4..886e50a9e5 100644 --- a/website/views/pages/vulnerability-management.ejs +++ b/website/views/pages/vulnerability-management.ejs @@ -18,8 +18,8 @@ Untangle your security stack

Use open data and APIs to connect your vulnerability solution with osquery, the agent you might already have deployed.

@@ -142,8 +142,8 @@

Open-source vulnerability management

Build the vulnerability program you actually want