From 0f5cc22d61ab7d0a52d0955ff752fa53af77046a Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 19 Jun 2025 16:09:26 -0500 Subject: [PATCH] Website: add `fleetPremiumTrialLicenseKey` user migration script. (#30125) Changes: - Added a script that sets a `fleetPremiumTrialLicenseKey` and `fleetPremiumTrialLicenseKeyExpiresAt` values on all User records. - Added a new email template to inform users that they have a new Fleet premium trial available. - Added the announcement banner to the /login, /register, and /try-fleet pages. --- .../admin/view-email-template-preview.js | 7 ++ website/assets/styles/layout.less | 24 +++++- website/assets/styles/pages/homepage.less | 20 ----- .../migrate-users-with-no-trial-key.js | 85 +++++++++++++++++++ .../emails/email-fleet-premium-trial.ejs | 30 +++++++ website/views/pages/entrance/login.ejs | 3 + website/views/pages/entrance/signup.ejs | 3 + website/views/pages/fleetctl-preview.ejs | 3 + 8 files changed, 154 insertions(+), 21 deletions(-) create mode 100644 website/scripts/migrate-users-with-no-trial-key.js create mode 100644 website/views/emails/email-fleet-premium-trial.ejs diff --git a/website/api/controllers/admin/view-email-template-preview.js b/website/api/controllers/admin/view-email-template-preview.js index 4e13a0cd32..0c490b6e2e 100644 --- a/website/api/controllers/admin/view-email-template-preview.js +++ b/website/api/controllers/admin/view-email-template-preview.js @@ -135,6 +135,13 @@ module.exports = { emailAddress: 'sage@example.com', }; break; + case 'email-fleet-premium-trial': + // layout = 'layout-nurture-email'; + fakeData = { + firstName: 'Sage', + emailAddress: 'sage@example.com', + }; + break; case 'email-deal-registration': layout = 'layout-email'; fakeData = { diff --git a/website/assets/styles/layout.less b/website/assets/styles/layout.less index 22d9638e04..abc9cfca74 100644 --- a/website/assets/styles/layout.less +++ b/website/assets/styles/layout.less @@ -59,7 +59,29 @@ html, body { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 500ms; } - +[purpose='announcement-banner'] { + br { + display: none; + @media (max-width: 375px) { + display: block; + } + } + display: flex; + width: 100%; + padding: 12px 8px; + justify-content: center; + align-items: center; + background: #0587FF; + color: var(--color-brand-white, #FFF); + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: normal; + [parasails-component='animated-arrow-button'] { + padding: 0; + } +} [purpose='continue-banner'] { z-index: 198; position: fixed; diff --git a/website/assets/styles/pages/homepage.less b/website/assets/styles/pages/homepage.less index 425481992e..a0538a94ee 100644 --- a/website/assets/styles/pages/homepage.less +++ b/website/assets/styles/pages/homepage.less @@ -34,26 +34,6 @@ line-height: 150%; } - [purpose='announcement-banner'] { - br { - display: none; - } - display: flex; - width: 100%; - padding: 12px 8px; - justify-content: center; - align-items: center; - background: #0587FF; - color: var(--color-brand-white, #FFF); - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 700; - line-height: normal; - [parasails-component='animated-arrow-button'] { - padding: 0; - } - } [purpose='hero-container'] { background: #FFFFFF; overflow: hidden; diff --git a/website/scripts/migrate-users-with-no-trial-key.js b/website/scripts/migrate-users-with-no-trial-key.js new file mode 100644 index 0000000000..eb98146dd4 --- /dev/null +++ b/website/scripts/migrate-users-with-no-trial-key.js @@ -0,0 +1,85 @@ +module.exports = { + + + friendlyName: 'Migrate users with no trial key', + + + description: 'Generate qualifying users a new Fleet premium license key and inform them via email.', + + inputs: { + dry: { type: 'boolean', description: 'Whether to make this a dry run. (No database changes will be made. Emails will not be sent.)' }, + }, + + fn: async function ({dry}) { + + sails.log('Running custom shell script... (`sails run migrate-users-with-no-trial-key`)'); + + let thirtyDaysFromNowAt = Date.now() + (1000 * 60 * 60 * 24 * 30); + // Get an array of all Users with + let idsOfUsersWithSubscriptions = await Subscription.find().select('user'); + let numberOfUsersWhoWouldHaveBeenUpdated = 0; + + await User.stream({ + lastSubmittedGetStartedQuestionnaireStep: { + 'in': [ // Only update users who have made it to the 'Is-it-any-good' step of the start questionnaire. + 'is-it-any-good', + 'what-did-you-think', + 'deploy-fleet-in-your-environment', + 'managed-cloud-for-growing-deployments', + 'self-hosted-deploy', + 'whats-left-to-get-you-set-up' + ] + }, + psychologicalStage: {'!=': '2 - Aware'},// Skip users who have told us that they decided not to use Fleet. + stageThreeNurtureEmailSentAt: {'!=': 1},// Do not update users who have unsubscribed from marketing emails. + }).eachRecord(async (thisUser)=>{ + // Stop running if this user has purchased a fleet premium license. + if(idsOfUsersWithSubscriptions.includes(thisUser.id)){ + sails.log.verbose(`Skipping ${thisUser.emailAddress} because they already have a premium subscription.`); + return; + } + + if(dry) { + sails.log.verbose(`Would have generated a new trial license key for ${thisUser.emailAddress} and informed them via email`); + numberOfUsersWhoWouldHaveBeenUpdated++; + } else { + // Generate a new trial license key for the user. + let trialLicenseKeyForThisUser = await sails.helpers.createLicenseKey.with({ + numberOfHosts: 10, + organization: thisUser.organization ? thisUser.organization : 'Fleet Premium trial', + expiresAt: thirtyDaysFromNowAt, + }); + + // Save the new license key to this user's db record + await User.updateOne({id: thisUser.id}).set({ + fleetPremiumTrialLicenseKey: trialLicenseKeyForThisUser, + fleetPremiumTrialLicenseKeyExpiresAt: thirtyDaysFromNowAt, + }); + + // Send an email informing the user that their new Fleet premium trial is available. + await sails.helpers.sendTemplateEmail.with({ + template: 'email-fleet-premium-trial', + layout: false, + templateData: { + emailAddress: thisUser.emailAddress + }, + to: thisUser.emailAddress, + subject: 'Whoops', + from: sails.config.custom.contactFormEmailAddress, + fromName: 'Mike McNeil', + ensureAck: true, + }); + } + }); + + if(dry){ + sails.log(`Dry run: would have generated trial licenses for and updated ${numberOfUsersWhoWouldHaveBeenUpdated} user records.`); + } + + + + } + + +}; + diff --git a/website/views/emails/email-fleet-premium-trial.ejs b/website/views/emails/email-fleet-premium-trial.ejs new file mode 100644 index 0000000000..e0eb63162f --- /dev/null +++ b/website/views/emails/email-fleet-premium-trial.ejs @@ -0,0 +1,30 @@ +
+
+
+
+ Logo +
+
+
+
+

Hi there,

+

In the process of migrating the license key database for the Fleet website, we hit a snag and figured "why not just let everybody have a new 30 day trial?"

+

+ You can visit https://fleetdm.com/try-fleet if you'd like to try it out (your license key will be available when you login).

+

Enjoy!
Mike, CEO

+
+
+
+ Join the osquery Slack community + View Fleet's GitHub repo + Conenct with Fleet on LinkedIn + Follow Fleet on Twitter + Watch Fleet's Youtube videos +
+
+

© <%= (new Date()).getFullYear() %> Fleet Inc.
All trademarks are the property of their respective owners.

+
+
+ Unsubscribe +
+
diff --git a/website/views/pages/entrance/login.ejs b/website/views/pages/entrance/login.ejs index 9ac0d8a367..8ed91786b4 100644 --- a/website/views/pages/entrance/login.ejs +++ b/website/views/pages/entrance/login.ejs @@ -1,4 +1,7 @@
+
+ 🎉 Fleet raises $27M for
open device management
+

Welcome to Fleet

diff --git a/website/views/pages/entrance/signup.ejs b/website/views/pages/entrance/signup.ejs index aee18e7544..ef7410ed73 100644 --- a/website/views/pages/entrance/signup.ejs +++ b/website/views/pages/entrance/signup.ejs @@ -1,4 +1,7 @@
+
+ 🎉 Fleet raises $27M for
open device management
+

Welcome to Fleet

diff --git a/website/views/pages/fleetctl-preview.ejs b/website/views/pages/fleetctl-preview.ejs index 6dcb2e3f0a..ff70cc9435 100644 --- a/website/views/pages/fleetctl-preview.ejs +++ b/website/views/pages/fleetctl-preview.ejs @@ -1,4 +1,7 @@
+
+ 🎉 Fleet raises $27M for
open device management
+

Try Fleet