mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Merge branch 'main' into feat-software-installers
This commit is contained in:
commit
75e86ff321
34 changed files with 217 additions and 110 deletions
|
|
@ -37,13 +37,19 @@ jobs:
|
|||
run: |
|
||||
npm install && npm run test
|
||||
|
||||
- name: Set the version
|
||||
working-directory: ./ee/fleetd-chrome
|
||||
run: |
|
||||
echo "FLEETD_CHROME_VERSION=$(npm pkg get version --workspaces=false | tr -d \")" >> $GITHUB_ENV
|
||||
|
||||
- name: Build & sign extension
|
||||
working-directory: ./ee/fleetd-chrome
|
||||
env:
|
||||
CHROME_SIGNING_KEY: ${{ secrets.FLEETD_CHROME_SIGNING_KEY_BETA }}
|
||||
run: |
|
||||
echo -e 'FLEET_URL=""\nFLEET_ENROLL_SECRET=""' > .env
|
||||
npm install && npm run build
|
||||
npm run build
|
||||
sed -i "s/FLEETD_CHROME_VERSION/${{ env.FLEETD_CHROME_VERSION }}/g" updates-beta.xml
|
||||
echo "$CHROME_SIGNING_KEY" > chrome.pem
|
||||
/usr/bin/google-chrome --pack-extension=./dist --pack-extension-key=chrome.pem
|
||||
|
||||
|
|
|
|||
8
.github/workflows/release-fleetd-chrome.yml
vendored
8
.github/workflows/release-fleetd-chrome.yml
vendored
|
|
@ -38,13 +38,19 @@ jobs:
|
|||
run: |
|
||||
npm install && npm run test
|
||||
|
||||
- name: Set the version
|
||||
working-directory: ./ee/fleetd-chrome
|
||||
run: |
|
||||
echo "FLEETD_CHROME_VERSION=$(npm pkg get version --workspaces=false | tr -d \")" >> $GITHUB_ENV
|
||||
|
||||
- name: Build & sign extension
|
||||
working-directory: ./ee/fleetd-chrome
|
||||
env:
|
||||
CHROME_SIGNING_KEY: ${{ secrets.FLEETD_CHROME_SIGNING_KEY }}
|
||||
run: |
|
||||
echo -e 'FLEET_URL=""\nFLEET_ENROLL_SECRET=""' > .env
|
||||
npm install && npm run build
|
||||
npm run build
|
||||
sed -i "s/FLEETD_CHROME_VERSION/${{ env.FLEETD_CHROME_VERSION }}/g" updates.xml
|
||||
echo "$CHROME_SIGNING_KEY" > chrome.pem
|
||||
/usr/bin/google-chrome --pack-extension=./dist --pack-extension-key=chrome.pem
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
## fleetd-chrome 1.3.1 (May 20, 2024)
|
||||
|
||||
* Fixed bug where fleetd-chrome sent multiple read requests to Fleet server at the same time.
|
||||
|
||||
* Improved console log output messages when Fleet server is down.
|
||||
|
||||
## fleetd-chrome 1.3.0 (Apr 29, 2024)
|
||||
|
||||
* Created a fix to recover after a rare RuntimeError coming from sqlite web assembly code by reinitializing the DB.
|
||||
|
|
|
|||
|
|
@ -67,18 +67,17 @@ npm run test
|
|||
|
||||
## Release
|
||||
|
||||
1. Update CHANGELOG.md by running `version="X.X.X" make changelog-chrome`
|
||||
1. At the top of the repo, update CHANGELOG.md by running `version="X.X.X" make changelog-chrome`
|
||||
2. Review CHANGELOG.md
|
||||
3. Run `npm version X.X.X` to update the version in `package.json` and `package-lock.json`
|
||||
4. Update [updates.xml](./updates.xml) and [updates-beta.xml](./updates-beta.xml) versions.
|
||||
5. Commit the changes and tag the commit with `fleetd-chrome-vX.X.X-beta`. This will trigger the beta release workflow.
|
||||
6. Once the beta release is tested and PR merged, tag the commit with `fleetd-chrome-vX.X.X`. This will trigger the release workflow.
|
||||
7. Announce the release in the #help-engineering channel in Slack.
|
||||
3. At `ee/fleetd-chrome`, run `npm version X.X.X` to update the version in `package.json` and `package-lock.json`
|
||||
4. Commit the changes and tag the commit with `fleetd-chrome-vX.X.X-beta`. This will trigger the beta release workflow.
|
||||
5. Once the beta release is tested and PR merged, tag the commit with `fleetd-chrome-vX.X.X`. This will trigger the release workflow.
|
||||
6. Announce the release in the #help-engineering channel in Slack.
|
||||
|
||||
Release a new version via GitHub automation. Update the [package.json](./package.json) and [updates.xml](./updates.xml) versions, then tag a commit with `fleetd-chrome-vX.X.X` to kick off the build and deploy. The build is automatically uploaded to R2 and properly configured clients should be able to update immediately when the job completes. Note that automatic updates seem to only happen about once a day in Chrome -- Hit the "Update" button in `chrome://extensions` to trigger the update manually.
|
||||
Using GitHub Actions, the build is automatically uploaded to R2 and properly configured clients should be able to update immediately when the job completes. Note that automatic updates seem to only happen about once a day in Chrome -- Hit the "Update" button in `chrome://extensions` to trigger the update manually.
|
||||
|
||||
### Beta releases
|
||||
|
||||
Beta releases are pushed to `https://chrome-beta.fleetdm.com/updates.xml` with the extension ID `bfleegjcoffelppfmadimianphbcdjkb`.
|
||||
|
||||
Kick off a beta release by updating the [package.json](./package.json) and [updates-beta.xml](./updates-beta.xml) versions, then tag a commit with `fleetd-chrome-vX.X.X-beta` to kick off the build and deploy.
|
||||
Kick off a beta release by updating the [package.json](./package.json), then tag a commit with `fleetd-chrome-vX.X.X-beta` to kick off the build and deploy.
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Fixed bug where fleetd-chrome sent multiple read requests to Fleet server at the same time.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Improved console log output messages when Fleet server is down.
|
||||
4
ee/fleetd-chrome/package-lock.json
generated
4
ee/fleetd-chrome/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "fleetd-for-chrome",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "fleetd-for-chrome",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"dependencies": {
|
||||
"async-mutex": "^0.5.0",
|
||||
"dotenv": "^16.0.3",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "fleetd-for-chrome",
|
||||
"description": "Extension for Fleetd on ChromeOS",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"dependencies": {
|
||||
"async-mutex": "^0.5.0",
|
||||
"dotenv": "^16.0.3",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='bfleegjcoffelppfmadimianphbcdjkb'>
|
||||
<updatecheck codebase='https://chrome-beta.fleetdm.com/fleetd.crx' version='1.3.0' />
|
||||
<updatecheck codebase='https://chrome-beta.fleetdm.com/fleetd.crx' version='FLEETD_CHROME_VERSION' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='fleeedmmihkfkeemmipgmhhjemlljidg'>
|
||||
<updatecheck codebase='https://chrome.fleetdm.com/fleetd.crx' version='1.3.0' />
|
||||
<updatecheck codebase='https://chrome.fleetdm.com/fleetd.crx' version='FLEETD_CHROME_VERSION' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
|
@ -71,31 +71,18 @@ module.exports = {
|
|||
`Name: ${firstName + ' ' + lastName}, Email: ${emailAddress}, Message: ${message ? message : 'No message.'}`
|
||||
});
|
||||
|
||||
await sails.helpers.salesforce.updateOrCreateContactAndAccount.with({
|
||||
emailAddress: emailAddress,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
});
|
||||
|
||||
|
||||
// Send a POST request to Zapier
|
||||
await sails.helpers.http.post(
|
||||
'https://hooks.zapier.com/hooks/catch/3627242/3cxcriz/',
|
||||
{
|
||||
'emailAddress': emailAddress,
|
||||
'firstName': firstName,
|
||||
'lastName': lastName,
|
||||
'message': message,
|
||||
'webhookSecret': sails.config.custom.zapierSandboxWebhookSecret
|
||||
}
|
||||
)
|
||||
.timeout(5000)
|
||||
.tolerate(['non200Response', 'requestFailed'], (err)=>{
|
||||
// Note that Zapier responds with a 2xx status code even if something goes wrong, so just because this message is not logged doesn't mean everything is hunky dory. More info: https://github.com/fleetdm/fleet/pull/6380#issuecomment-1204395762
|
||||
sails.log.warn(`When a user submitted a contact form message, a lead/contact could not be updated in the CRM for this email address: ${emailAddress}. Raw error: ${err}`);
|
||||
return;
|
||||
});
|
||||
|
||||
// Use timers.setImmediate() to update/create CRM records in the background.
|
||||
require('timers').setImmediate(async ()=>{
|
||||
await sails.helpers.salesforce.updateOrCreateContactAndAccountAndCreateLead.with({
|
||||
emailAddress: emailAddress,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
leadSource: 'Website - Contact forms',
|
||||
leadDescription: `Sent a contact form message: ${message}`,
|
||||
}).tolerate((err)=>{
|
||||
sails.log.warn(`Background task failed: When a user submitted a contact form message, a lead/contact could not be updated in the CRM for this email address: ${emailAddress}. Error:`, err.raw);
|
||||
});
|
||||
});//_∏_ (Meanwhile...)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,37 +74,23 @@ module.exports = {
|
|||
throw 'invalidEmailDomain';
|
||||
}
|
||||
|
||||
await sails.helpers.salesforce.updateOrCreateContactAndAccount.with({
|
||||
emailAddress,
|
||||
firstName,
|
||||
lastName,
|
||||
organization: organization,
|
||||
primaryBuyingSituation: primaryBuyingSituation === 'eo-security' ? 'Endpoint operations - Security' : primaryBuyingSituation === 'eo-it' ? 'Endpoint operations - IT' : primaryBuyingSituation === 'mdm' ? 'Device management (MDM)' : 'Vulnerability management',
|
||||
});
|
||||
|
||||
await sails.helpers.http.post.with({
|
||||
url: 'https://hooks.zapier.com/hooks/catch/3627242/3cxwxdo/',
|
||||
data: {
|
||||
emailAddress,
|
||||
firstName,
|
||||
lastName,
|
||||
organization,
|
||||
numberOfHosts,
|
||||
primaryBuyingSituation,
|
||||
webhookSecret: sails.config.custom.zapierSandboxWebhookSecret,
|
||||
}
|
||||
})
|
||||
.timeout(5000)
|
||||
.tolerate(['non200Response', 'requestFailed'], (err)=>{
|
||||
// Note that Zapier responds with a 2xx status code even if something goes wrong, so just because this message is not logged doesn't mean everything is hunky dory. More info: https://github.com/fleetdm/fleet/pull/6380#issuecomment-1204395762
|
||||
sails.log.warn(`When a user submitted a contact form message, a lead/contact could not be updated in the CRM for this email address: ${emailAddress}. Raw error: ${err}`);
|
||||
return;
|
||||
});
|
||||
|
||||
|
||||
// Use timers.setImmediate() to update/create CRM records in the background.
|
||||
require('timers').setImmediate(async ()=>{
|
||||
await sails.helpers.salesforce.updateOrCreateContactAndAccountAndCreateLead.with({
|
||||
emailAddress: emailAddress,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
organization: organization,
|
||||
numberOfHosts: numberOfHosts,
|
||||
primaryBuyingSituation: primaryBuyingSituation === 'eo-security' ? 'Endpoint operations - Security' : primaryBuyingSituation === 'eo-it' ? 'Endpoint operations - IT' : primaryBuyingSituation === 'mdm' ? 'Device management (MDM)' : primaryBuyingSituation === 'vm' ? 'Vulnerability management' : undefined,
|
||||
leadSource: 'Website - Contact forms',
|
||||
leadDescription: `Submitted the "Talk to us" form.`,
|
||||
}).tolerate((err)=>{
|
||||
sails.log.warn(`Background task failed: When a user submitted the "Talk to us" form, a lead/contact could not be updated in the CRM for this email address: ${emailAddress}. Error:`, err.raw);
|
||||
});
|
||||
});//_∏_ (Meanwhile...)
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
18
website/api/controllers/entrance/signup.js
vendored
18
website/api/controllers/entrance/signup.js
vendored
|
|
@ -138,24 +138,18 @@ the account verification message.)`,
|
|||
.intercept({name: 'UsageError'}, 'invalid')
|
||||
.fetch();
|
||||
|
||||
if(sails.config.environment === 'production') {
|
||||
let recordIds = await sails.helpers.salesforce.updateOrCreateContactAndAccount.with({
|
||||
// Use timers.setImmediate() to update/create CRM records in the background.
|
||||
require('timers').setImmediate(async ()=>{
|
||||
await sails.helpers.salesforce.updateOrCreateContactAndAccountAndCreateLead.with({
|
||||
emailAddress: newEmailAddress,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
organization: organization,
|
||||
});
|
||||
|
||||
await sails.helpers.salesforce.createLead.with({
|
||||
salesforceContactId: recordIds.salesforceContactId,
|
||||
salesforceAccountId: recordIds.salesforceAccountId,
|
||||
leadSource: 'Website - Sign up',
|
||||
})
|
||||
.tolerate((err)=>{
|
||||
sails.log.warn(`When a user signed up, a lead could not be created in the CRM for this email address: ${newEmailAddress}. Error from create-lead helper: ${err}`);
|
||||
return;
|
||||
}).tolerate((err)=>{
|
||||
sails.log.warn(`Background task failed: When a user (email: ${newEmailAddress} sign up for a fleetdm.com account, a Contact, Account, and Lead record could not be created/updated in the CRM. Error:`, err.raw);
|
||||
});
|
||||
}
|
||||
});//_∏_ (Meanwhile...)
|
||||
|
||||
// Store the user's new id in their session.
|
||||
this.req.session.userId = newUserRecord.id;
|
||||
|
|
|
|||
90
website/api/helpers/salesforce/update-or-create-contact-and-account-and-create-lead.js
vendored
Normal file
90
website/api/helpers/salesforce/update-or-create-contact-and-account-and-create-lead.js
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
module.exports = {
|
||||
|
||||
|
||||
friendlyName: 'Update or create contact and account and create lead',
|
||||
|
||||
|
||||
description: 'Updates or creates a contact and account in Salesforce, then uses the IDs of the created records to create a Lead record.',
|
||||
|
||||
extendedDescription: 'This is a wrapper for the update-or-create-contact-and-account and create-lead helpers used to run both of them in the background with timers.setImmediate().',
|
||||
|
||||
inputs: {
|
||||
|
||||
// Find by…
|
||||
emailAddress: { type: 'string' },
|
||||
linkedinUrl: { type: 'string' },
|
||||
|
||||
// Set…
|
||||
firstName: { type: 'string', required: true },
|
||||
lastName: { type: 'string', required: true },
|
||||
organization: { type: 'string' },
|
||||
primaryBuyingSituation: { type: 'string' },
|
||||
psychologicalStage: {
|
||||
type: 'string',
|
||||
isIn: [
|
||||
'1 - Unaware',
|
||||
'2 - Aware',
|
||||
'3 - Intrigued',
|
||||
'4 - Has use case',
|
||||
'5 - Personally confident',
|
||||
'6 - Has team buy-in'
|
||||
]
|
||||
},
|
||||
// For new leads.
|
||||
leadDescription: {
|
||||
type: 'string',
|
||||
description: 'A description of what this lead is about; e.g. a contact form message, or the size of t-shirt being requested.'
|
||||
},
|
||||
leadSource: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
isIn: [
|
||||
'Website - Contact forms',
|
||||
'Website - Sign up',
|
||||
'Website - Waitlist',
|
||||
'Website - swag request',
|
||||
],
|
||||
},
|
||||
numberOfHosts: { type: 'number' },
|
||||
},
|
||||
|
||||
exits: {
|
||||
|
||||
success: {
|
||||
extendedDescription: 'Note that this deliberately has no return value.',
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
fn: async function ({emailAddress, linkedinUrl, firstName, lastName, organization, primaryBuyingSituation, psychologicalStage, leadSource, leadDescription, numberOfHosts}) {
|
||||
if(sails.config.environment !== 'production') {
|
||||
sails.log('Skipping Salesforce integration...');
|
||||
return;
|
||||
}
|
||||
|
||||
let recordIds = await sails.helpers.salesforce.updateOrCreateContactAndAccount.with({
|
||||
emailAddress,
|
||||
firstName,
|
||||
lastName,
|
||||
organization,
|
||||
linkedinUrl,
|
||||
primaryBuyingSituation,
|
||||
psychologicalStage,
|
||||
});
|
||||
|
||||
await sails.helpers.salesforce.createLead.with({
|
||||
salesforceContactId: recordIds.salesforceContactId,
|
||||
salesforceAccountId: recordIds.salesforceAccountId,
|
||||
leadDescription,
|
||||
leadSource,
|
||||
numberOfHosts,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ parasails.registerPage('edit-password', {
|
|||
// > (Note that we re-enable the syncing state here. This is on purpose--
|
||||
// > to make sure the spinner stays there until the page navigation finishes.)
|
||||
this.syncing = true;
|
||||
window.location = '/account';
|
||||
this.goto('/account');
|
||||
},
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ parasails.registerPage('edit-profile', {
|
|||
// > (Note that we re-enable the syncing state here. This is on purpose--
|
||||
// > to make sure the spinner stays there until the page navigation finishes.)
|
||||
this.syncing = true;
|
||||
window.location = '/account';
|
||||
this.goto('/account');
|
||||
},
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ parasails.registerPage('connect-vanta', {
|
|||
|
||||
submittedAuthorizationForm: async function() {
|
||||
this.syncing = true;
|
||||
window.location = this.vantaAuthorizationRequestURL;
|
||||
this.goto(this.vantaAuthorizationRequestURL);
|
||||
},
|
||||
|
||||
clickClearErrors: async function() {
|
||||
|
|
|
|||
4
website/assets/js/pages/contact.page.js
vendored
4
website/assets/js/pages/contact.page.js
vendored
|
|
@ -88,9 +88,9 @@ parasails.registerPage('contact', {
|
|||
submittedTalkToUsForm: async function() {
|
||||
this.syncing = true;
|
||||
if(this.formData.numberOfHosts > 700){
|
||||
window.location = `https://calendly.com/fleetdm/talk-to-us?email=${encodeURIComponent(this.formData.emailAddress)}&name=${encodeURIComponent(this.formData.firstName+' '+this.formData.lastName)}`;
|
||||
this.goto(`https://calendly.com/fleetdm/talk-to-us?email=${encodeURIComponent(this.formData.emailAddress)}&name=${encodeURIComponent(this.formData.firstName+' '+this.formData.lastName)}`);
|
||||
} else {
|
||||
window.location = `https://calendly.com/fleetdm/chat?email=${encodeURIComponent(this.formData.emailAddress)}&name=${encodeURIComponent(this.formData.firstName+' '+this.formData.lastName)}`;
|
||||
this.goto(`https://calendly.com/fleetdm/chat?email=${encodeURIComponent(this.formData.emailAddress)}&name=${encodeURIComponent(this.formData.firstName+' '+this.formData.lastName)}`);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ parasails.registerPage('new-license', {
|
|||
|
||||
clickGoToDashboard: async function() {
|
||||
this.syncing = true;
|
||||
window.location = '/customers/dashboard?order-complete';
|
||||
this.goto('/customers/dashboard?order-complete');
|
||||
},
|
||||
|
||||
submittedQuoteForm: async function(quote) {
|
||||
|
|
@ -90,7 +90,7 @@ parasails.registerPage('new-license', {
|
|||
clickScheduleDemo: async function() {
|
||||
this.syncing = true;
|
||||
// Note: we keep loading spinner present indefinitely so that it is apparent that a new page is loading
|
||||
window.location = `https://calendly.com/fleetdm/talk-to-us?email=${encodeURIComponent(this.me.emailAddress)}&name=${encodeURIComponent(this.me.firstName+' '+this.me.lastName)}`;
|
||||
this.goto(`https://calendly.com/fleetdm/talk-to-us?email=${encodeURIComponent(this.me.emailAddress)}&name=${encodeURIComponent(this.me.firstName+' '+this.me.lastName)}`);
|
||||
},
|
||||
|
||||
clickResetForm: async function() {
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ parasails.registerPage('basic-documentation', {
|
|||
methods: {
|
||||
|
||||
clickCTA: function (slug) {
|
||||
window.location = slug;
|
||||
this.goto(slug);
|
||||
},
|
||||
|
||||
isCurrentSection: function (section) {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ parasails.registerPage('login', {
|
|||
// > (Note that we re-enable the syncing state here. This is on purpose--
|
||||
// > to make sure the spinner stays there until the page navigation finishes.)
|
||||
this.syncing = true;
|
||||
window.location = this.pageToRedirectToAfterLogin;
|
||||
this.goto(this.pageToRedirectToAfterLogin);
|
||||
},
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ parasails.registerPage('new-password', {
|
|||
// > (Note that we re-enable the syncing state here. This is on purpose--
|
||||
// > to make sure the spinner stays there until the page navigation finishes.)
|
||||
this.syncing = true;
|
||||
window.location = '/customers/login';
|
||||
this.goto('/customers/login');
|
||||
},
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ parasails.registerPage('signup', {
|
|||
// > (Note that we re-enable the syncing state here. This is on purpose--
|
||||
// > to make sure the spinner stays there until the page navigation finishes.)
|
||||
this.syncing = true;
|
||||
window.location = this.pageToRedirectToAfterRegistration;// « / start if the user came here from the start now button, or customers/new-license if the user came here from the "Get your license" link.
|
||||
this.goto(this.pageToRedirectToAfterRegistration);// « / start if the user came here from the start now button, or customers/new-license if the user came here from the "Get your license" link.
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
2
website/assets/js/pages/query-detail.page.js
vendored
2
website/assets/js/pages/query-detail.page.js
vendored
|
|
@ -23,7 +23,7 @@ parasails.registerPage('query-detail', {
|
|||
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
|
||||
methods: {
|
||||
clickAvatar: function (contributor) {
|
||||
window.location = contributor.htmlUrl;
|
||||
this.goto(contributor.htmlUrl);
|
||||
},
|
||||
getDisplayName: function (contributor) {
|
||||
return !contributor.name ? contributor.handle : contributor.name;
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ parasails.registerPage('query-library', {
|
|||
},
|
||||
|
||||
clickCard: function (querySlug) {
|
||||
window.location = '/queries/' + querySlug; // we can trust the query slug is url-safe
|
||||
this.goto('/queries/' + querySlug); // we can trust the query slug is url-safe
|
||||
},
|
||||
|
||||
clickAvatar: function (contributor) {
|
||||
window.location = contributor.htmlUrl;
|
||||
this.goto(contributor.htmlUrl);
|
||||
},
|
||||
|
||||
getAvatarUrl: function (contributorData) {
|
||||
|
|
|
|||
6
website/assets/js/pages/start.page.js
vendored
6
website/assets/js/pages/start.page.js
vendored
|
|
@ -104,7 +104,7 @@ parasails.registerPage('start', {
|
|||
});
|
||||
this.previouslyAnsweredQuestions[this.currentStep] = getStartedProgress[this.currentStep];
|
||||
if(_.startsWith(nextStep, '/')){
|
||||
window.location = nextStep;
|
||||
this.goto(nextStep);
|
||||
} else {
|
||||
this.syncing = false;
|
||||
this.currentStep = nextStep;
|
||||
|
|
@ -282,10 +282,10 @@ parasails.registerPage('start', {
|
|||
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)}`;
|
||||
this.goto(`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`;
|
||||
this.goto(`/contact`);
|
||||
},
|
||||
clickClearOneFormError: function(field) {
|
||||
if(this.formErrors[field]){
|
||||
|
|
|
|||
|
|
@ -55,17 +55,17 @@ parasails.registerPage('query-report', {
|
|||
watch: {
|
||||
selectedTable: function(val){
|
||||
if(val !== this.tableToDisplay){
|
||||
window.location = `/try-fleet/explore-data/${this.selectedHost}/${this.selectedTable}`;
|
||||
this.goto(`/try-fleet/explore-data/${this.selectedHost}/${this.selectedTable}`);
|
||||
}
|
||||
},
|
||||
hostToDisplayResultsFor: function(val){
|
||||
if(val !== this.selectedHost){
|
||||
if(val === 'Linux'){
|
||||
window.location = `/try-fleet/explore-data/linux/apparmor_events`;
|
||||
this.goto(`/try-fleet/explore-data/linux/apparmor_events`);
|
||||
} else if(val === 'Windows'){
|
||||
window.location = `/try-fleet/explore-data/windows/appcompat_shims`;
|
||||
this.goto(`/try-fleet/explore-data/windows/appcompat_shims`);
|
||||
} else {
|
||||
window.location = `/try-fleet/explore-data/macos/account_policy_data`;
|
||||
this.goto(`/try-fleet/explore-data/macos/account_policy_data`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +85,6 @@ parasails.registerPage('query-report', {
|
|||
|
||||
tableContainer.addEventListener('scroll', (event)=>{
|
||||
let container = event.target;
|
||||
console.log(container);
|
||||
let isScrolledFullyToLeft = container.scrollLeft === 0;
|
||||
let isScrolledFullyToRight = (container.scrollWidth - container.scrollLeft <= container.clientWidth + 1);
|
||||
// Update the class on the table container based on how much the table is scrolled.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ parasails.registerPage('sandbox-teleporter', {
|
|||
// Binding an event handler to 'onpageshow', if a user navigates to a locally cached version of this page (e.g., A Safari user clicking the back button from their Fleet Sandbox), they will be taken to the fleetdm.com homepage.
|
||||
window.onpageshow = function(event) {
|
||||
if(event.persisted) {
|
||||
window.location = '/';
|
||||
this.goto('/');
|
||||
}
|
||||
};
|
||||
// Confused? Understandable, this approach is a bit unusual. See this page's view action for more info on what this code is doing and why, as well as a link where you can read more information.
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@
|
|||
font-size: 16px;
|
||||
line-height: @text-lineheight;
|
||||
color: @core-fleet-black-75;
|
||||
a[href] {
|
||||
text-decoration: underline;
|
||||
color: @core-fleet-black-75;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
}
|
||||
strong {
|
||||
color: @core-fleet-black;
|
||||
|
|
@ -185,6 +190,13 @@
|
|||
}
|
||||
[purpose='testimonial-quote'] {
|
||||
width: 640px;
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: unset;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
[purpose='quote'] {
|
||||
p {
|
||||
color: @core-fleet-black-75;
|
||||
|
|
|
|||
|
|
@ -174,6 +174,13 @@
|
|||
}
|
||||
}
|
||||
[purpose='testimonial-quote'] {
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: unset;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
max-width: 591px;
|
||||
[purpose='quote'] {
|
||||
p {
|
||||
|
|
|
|||
|
|
@ -172,6 +172,13 @@
|
|||
}
|
||||
[purpose='testimonial-quote'] {
|
||||
width: 380px;
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: unset;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
[purpose='quote'] {
|
||||
p {
|
||||
color: @core-fleet-black-75;
|
||||
|
|
|
|||
4
website/views/pages/device-management.ejs
vendored
4
website/views/pages/device-management.ejs
vendored
|
|
@ -25,7 +25,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div purpose="testimonials" class="d-flex flex-md-row flex-column align-items-center justify-content-between">
|
||||
<div purpose="testimonial-quote" @click="goto('<%= ['eo-security','vm'].includes(primaryBuyingSituation) ? 'https://www.linkedin.com/posts/nwaisman_movingtofleet-activity-7156319785981509632-bk_W' : ['eo-it'].includes(primaryBuyingSituation) ? 'https://www.linkedin.com/in/mrerictan/' : 'https://www.linkedin.com/in/kennybotelho/'%>')">
|
||||
<div purpose="testimonial-quote">
|
||||
<a href="<%= ['eo-security','vm'].includes(primaryBuyingSituation) ? 'https://www.linkedin.com/posts/nwaisman_movingtofleet-activity-7156319785981509632-bk_W' : ['eo-it'].includes(primaryBuyingSituation) ? 'https://www.linkedin.com/in/mrerictan/' : 'https://www.linkedin.com/in/kennybotelho/'%>" target="_blank">
|
||||
<div purpose="quote">
|
||||
<img alt="an opening quotation mark" style="width:20px; margin-bottom: 16px;" src="/images/icon-quote-21x17@2x.png">
|
||||
<p>
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
<p purpose="title"><%= ['eo-security','vm'].includes(primaryBuyingSituation) ? 'CISO of Lyft' : ['eo-it'].includes(primaryBuyingSituation) ? 'CIO & Chief Security Officer at Flock Safety' : 'Client Platform Engineer at gaming company'%></p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<logo-carousel></logo-carousel>
|
||||
|
|
|
|||
12
website/views/pages/endpoint-ops.ejs
vendored
12
website/views/pages/endpoint-ops.ejs
vendored
|
|
@ -42,7 +42,8 @@
|
|||
</div>
|
||||
<div purpose="testimonials" class="d-flex flex-md-row flex-column align-items-center justify-content-between">
|
||||
<% if (['eo-security'].includes(primaryBuyingSituation)) { %>
|
||||
<div purpose="testimonial-quote" @click="goto('https://www.linkedin.com/in/charleszaffery/')">
|
||||
<div purpose="testimonial-quote">
|
||||
<a href="https://www.linkedin.com/in/charleszaffery/" target="_blank">
|
||||
<div purpose="quote">
|
||||
<img alt="an opening quotation mark" style="width:20px; margin-bottom: 16px;" src="/images/icon-quote-21x17@2x.png">
|
||||
<p>"Fleet has such a huge amount of use cases. My goal was to get telemetry on endpoints, but then our IR team, our TBM team, and multiple other folks in security started heavily utilizing the system in ways I didn’t expect. It spread so naturally, even our corporate and infrastructure teams want to run it."</p>
|
||||
|
|
@ -54,9 +55,11 @@
|
|||
<p purpose="title">Principal computer janitor</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<% } else if (['vm'].includes(primaryBuyingSituation)) { %>
|
||||
<div purpose="testimonial-quote" @click="goto('https://www.linkedin.com/in/austin-anderson-73172185/')">
|
||||
<div purpose="testimonial-quote">
|
||||
<a href="https://www.linkedin.com/in/austin-anderson-73172185/" target="_blank">
|
||||
<div purpose="quote">
|
||||
<img alt="an opening quotation mark" style="width:20px; margin-bottom: 16px;" src="/images/icon-quote-21x17@2x.png">
|
||||
<p>"Fleet lets us be more actionable with fewer people. It helps us to filter out the noise better than we could with the other big name products we replaced."</p>
|
||||
|
|
@ -68,9 +71,11 @@
|
|||
<p purpose="title">Cybersecurity team senior manager</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<div purpose="testimonial-quote" @click="goto('https://www.linkedin.com/in/nickfohs/')">
|
||||
<div purpose="testimonial-quote">
|
||||
<a target="_blank" href="https://www.linkedin.com/in/nickfohs/">
|
||||
<div purpose="quote">
|
||||
<img alt="an opening quotation mark" style="width:20px; margin-bottom: 16px;" src="/images/icon-quote-21x17@2x.png">
|
||||
<p>“Fleet provides a way to surface device data and telemetry to our other teams and partners.”</p>
|
||||
|
|
@ -82,6 +87,7 @@
|
|||
<p purpose="title">Systems and infrastructure manager</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<% } %>
|
||||
<div purpose="testimonial-videos" class="d-flex">
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
</div>
|
||||
<div purpose="testimonials" class="d-flex flex-md-row flex-column align-items-center justify-content-between">
|
||||
<div purpose="testimonial-quote">
|
||||
<a href="https://www.linkedin.com/in/andre-shields/" target="_blank">
|
||||
<div purpose="quote">
|
||||
<img alt="an opening quotation mark" style="width:20px; margin-bottom: 16px;" src="/images/icon-quote-21x17@2x.png">
|
||||
<p>Fleet lets us be more actionable with fewer people. It helps us to filter out the noise better than we could with the other big name products we replaced.</p>
|
||||
|
|
@ -37,6 +38,7 @@
|
|||
<p purpose="title">Cybersecurity Security Engineer, Vulnerability Management</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div purpose="testimonial-videos" class="d-flex">
|
||||
<div purpose="testimonial-video" @click="clickOpenVideoModal('austin-anderson')">
|
||||
|
|
|
|||
Loading…
Reference in a new issue