From f5c3cfc6c7d350c7e83a49cb0bb62f59692137c4 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Wed, 15 Jan 2025 16:24:10 -0600 Subject: [PATCH 1/6] Include notes on when automations won't run for a given host in software and script automation UIs (#25453) For #25452. - [x] Manual QA for all new/changed functionality --- .../InstallSoftwareModal/InstallSoftwareModal.tsx | 7 +++++-- .../components/InstallSoftwareModal/_styles.scss | 5 +++++ .../PolicyRunScriptModal/PolicyRunScriptModal.tsx | 8 +++++--- .../components/PolicyRunScriptModal/_styles.scss | 5 +++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx b/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx index 106dd3b64019..90c16e9e5454 100644 --- a/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx @@ -284,8 +284,11 @@ const InstallSoftwareModal = ({ )} - Selected software, if compatible with the host, will be installed - when hosts fail the chosen policy.{" "} + If compatible with the host, the selected software will be installed + when hosts fail the policy. App Store apps will not be installed if + hosts are not enrolled in MDM, or if no VPP licenses are available + for the app. If custom targets are enabled and a host with a failing + policy is not targeted, installation will be skipped.{" "} - Selected script, if{" "} + If{" "} compatible {" "} - with the host, will run when hosts fail the policy. Host counts will - reset when a new script is selected.{" "} + with the host, the selected script will run when hosts fail the + policy. The script will not run on hosts with scripts disabled, or + on hosts with too many pending scripts. Host counts will reset when + new scripts are selected.{" "} Date: Wed, 15 Jan 2025 16:31:37 -0600 Subject: [PATCH 2/6] Website: update query generator to use socket requests. (#25472) Closes: #25465 Changes: - Updated the query generator page to use socket requests to call the `get-llm-generated-sql` action to bypass Heroku's 30-second request timeout. --- .../query-generator/get-llm-generated-sql.js | 31 ++++++++++++++++--- .../js/pages/admin/query-generator.page.js | 25 +++++++++------ website/config/routes.js | 2 +- website/views/pages/admin/query-generator.ejs | 4 +-- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/website/api/controllers/query-generator/get-llm-generated-sql.js b/website/api/controllers/query-generator/get-llm-generated-sql.js index addb3f448eb1..4ec98c6801b8 100644 --- a/website/api/controllers/query-generator/get-llm-generated-sql.js +++ b/website/api/controllers/query-generator/get-llm-generated-sql.js @@ -25,7 +25,12 @@ module.exports = { fn: async function ({naturalLanguageQuestion}) { - + // Generate a random room name. + let roomId = await sails.helpers.strings.random(); + if(this.req.isSocket) { + // Add the requesting socket to the room. + sails.sockets.join(this.req, roomId); + } let completeTables = sails.config.builtStaticContent.schemaTables; let prunedTables = completeTables.map((table)=>{ let newTable = _.pick(table,['name','description','platforms', 'examples']); @@ -55,7 +60,12 @@ module.exports = { Please respond in JSON, with the same data shape as the provided context, but with the array filtered to include only relevant tables.`; let filteredTables = await sails.helpers.ai.prompt(schemaFiltrationPrompt, 'gpt-4o', true) .intercept((err)=>{ - return new Error(`When trying to get a subset of tables to use to generate a query for an Admin user, the Open AI API returned an error. Full error: ${require('util').inspect(err, {depth: 2})}`); + if(this.req.isSocket){ + // If this request was from a socket and an error occurs, broadcast an 'error' event and unsubscribe the socket from this room. + sails.sockets.broadcast(roomId, 'error', {error: err}); + sails.sockets.leave(this.req, roomId); + } + return new Error(`When trying to get a subset of tables to use to generate a query for an Admin user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`); }); @@ -95,9 +105,22 @@ module.exports = { }`; let sqlReport = await sails.helpers.ai.prompt(sqlPrompt, 'o1-preview', true) .intercept((err)=>{ - return new Error(`When trying to generate a query for an Admin user, the Open AI API returned an error. Full error: ${require('util').inspect(err, {depth: 2})}`); + if(this.req.isSocket){ + // If this request was from a socket and an error occurs, broadcast an 'error' event and unsubscribe the socket from this room. + sails.sockets.broadcast(roomId, 'error', {error: err}); + sails.sockets.leave(this.req, roomId); + } + return new Error(`When trying to generate a query for an Admin user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`); }); - return sqlReport; + + // If this request was from a socket, we'll broadcast a 'queryGenerated' event with the sqlReport and unsubscribe the socket + if(this.req.isSocket){ + sails.sockets.broadcast(roomId, 'queryGenerated', {result: sqlReport}); + sails.sockets.leave(this.req, roomId); + } else { + // Otherwise, return the JSON sqlReport. + return sqlReport; + } } diff --git a/website/assets/js/pages/admin/query-generator.page.js b/website/assets/js/pages/admin/query-generator.page.js index 319e923ab80e..95fc75384b96 100644 --- a/website/assets/js/pages/admin/query-generator.page.js +++ b/website/assets/js/pages/admin/query-generator.page.js @@ -36,17 +36,22 @@ parasails.registerPage('query-generator', { // ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ methods: { handleSubmittingForm: async function() { - let argins = this.formData.naturalLanguageQuestion; - this.queryResult = await Cloud.getLlmGeneratedSql(argins) - .tolerate((err)=>{ - this.cloudError = err; - this.syncing = false; - }); + this.syncing = true; + io.socket.get('/api/v1/query-generator/get-llm-generated-sql', {naturalLanguageQuestion: this.formData.naturalLanguageQuestion}, ()=>{}); + io.socket.on('queryGenerated', this._onQueryResultsReturned); + io.socket.on('error', this._onQueryGenerationError); }, - submittedQueryForm: function() { - if(!this.cloudError){ - this.showGeneratedQuery = true; - } + _onQueryResultsReturned: function(response) { + this.queryResult = response.result; + this.syncing = false; + this.showGeneratedQuery = true; + // Disable the socket event listener after we display the results. + io.socket.off('queryGenerated', this._onQueryResultsReturned); + }, + _onQueryGenerationError: function(response) { + this.cloudError = response.error; + this.syncing = false; + io.socket.off('error', this._onQueryGenerationError); }, clickResetQueryGenerator: function() { this.showGeneratedQuery = false; diff --git a/website/config/routes.js b/website/config/routes.js index 715711ad3d04..77ad2517db88 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -914,5 +914,5 @@ module.exports.routes = { 'POST /api/v1/deliver-deal-registration-submission': { action: 'deliver-deal-registration-submission' }, '/api/v1/unsubscribe-from-marketing-emails': { action: 'unsubscribe-from-marketing-emails' }, 'POST /api/v1/customers/get-stripe-checkout-session-url': { action: 'customers/get-stripe-checkout-session-url' }, - 'POST /api/v1/query-generator/get-llm-generated-sql': { action: 'query-generator/get-llm-generated-sql' }, + '/api/v1/query-generator/get-llm-generated-sql': { action: 'query-generator/get-llm-generated-sql' }, }; diff --git a/website/views/pages/admin/query-generator.ejs b/website/views/pages/admin/query-generator.ejs index 9cab588f4db2..d8e1b53bc4dd 100644 --- a/website/views/pages/admin/query-generator.ejs +++ b/website/views/pages/admin/query-generator.ejs @@ -2,10 +2,10 @@
- +

Query generator

- +
Ask your question.
From cefabf99545429650c2e3efabdfa6bd171fdee6c Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 15 Jan 2025 17:01:29 -0600 Subject: [PATCH 3/6] Website: update contact form @mentions (#25475) Closes: https://github.com/fleetdm/confidential/issues/9361 Changes: - Updated the Slack users who are @mentioned when users submit a contact form message. --- website/api/controllers/deliver-contact-form-message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/api/controllers/deliver-contact-form-message.js b/website/api/controllers/deliver-contact-form-message.js index 3a5116528fe4..bd5b602f1795 100644 --- a/website/api/controllers/deliver-contact-form-message.js +++ b/website/api/controllers/deliver-contact-form-message.js @@ -58,7 +58,7 @@ module.exports = { } await sails.helpers.http.post(sails.config.custom.slackWebhookUrlForContactForm, { - text: `New contact form message: (cc: <@U05CS07KASK>) (Remember: we have to email back; can't just reply to this thread.)`+ + text: `New contact form message: (cc: <@U0801Q57JDU>, <@U05CS07KASK>) (Remember: we have to email back; can't just reply to this thread.)`+ `Name: ${firstName + ' ' + lastName}, Email: ${emailAddress}, Message: ${message ? message : 'No message.'}` }); From 5d1839af197e100ed82f1d79e99e5236678c6c1a Mon Sep 17 00:00:00 2001 From: Rachael Shaw Date: Wed, 15 Jan 2025 17:11:31 -0600 Subject: [PATCH 4/6] Handbook: Update note about sentence case + step numbers (#25415) Discussed w/ @noahtalerman, concluded that capitalization makes sense in this case. --- handbook/company/why-this-way.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handbook/company/why-this-way.md b/handbook/company/why-this-way.md index e3ed816d86a1..806adc1aebb0 100644 --- a/handbook/company/why-this-way.md +++ b/handbook/company/why-this-way.md @@ -313,7 +313,7 @@ In sentence case, we write and capitalize words as if they were in sentences: > Ask questions about your servers, containers, and laptops running Linux, Windows, and macOS -As we use sentence case, only the first word is capitalized. But, if a word would normally be capitalized in the sentence (e.g., a proper noun, an acronym, or a stylization) it should remain capitalized. User roles (e.g., "observer" or "maintainer") and features (e.g. "automations") in the Fleet product aren't treated as proper nouns and shouldn't be capitalized. Words/phrases that follow steps numbers (e.g. "Step 1: create") in the documentation shouldn't be capitalized. +As we use sentence case, only the first word is capitalized. But, if a word would normally be capitalized in the sentence (e.g., a proper noun, an acronym, or a stylization) it should remain capitalized. User roles (e.g., "observer" or "maintainer") and features (e.g. "automations") in the Fleet product aren't treated as proper nouns and shouldn't be capitalized. However, words/phrases that follow step numbers in the documentation _should_ be capitalized (e.g. "Step 1: Create"), since the step number is merely acting as a label for the phrase that follows. The reason for sentence case at Fleet is that everyone capitalizes differently in English, and capitalization conventions have not been taught very consistently in schools. Sentence case simplifies capitalization rules so that contributors can deliver more natural, even-looking content with a voice that feels similar no matter where you're reading it. From 11ac949c7e0c0c41a9f06b09a2f67f975372ce2d Mon Sep 17 00:00:00 2001 From: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:27:14 -0600 Subject: [PATCH 5/6] Fix lock-screen-message.mobileconfig (#25443) Quick fix now that we have an iPhone fully enrolled in Dogfood. --- .../configuration-profiles/lock-screen-message.mobileconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it-and-security/lib/ios/configuration-profiles/lock-screen-message.mobileconfig b/it-and-security/lib/ios/configuration-profiles/lock-screen-message.mobileconfig index c67876021828..93203f9b3517 100644 --- a/it-and-security/lib/ios/configuration-profiles/lock-screen-message.mobileconfig +++ b/it-and-security/lib/ios/configuration-profiles/lock-screen-message.mobileconfig @@ -6,9 +6,9 @@ AssetTagInformation - This device is owned by Fleet + IfLostReturnToMessage - Fleet Device Management Inc. + This device is property of Fleet Device Management Inc. PayloadDescription Configures ownership information for a shared device PayloadDisplayName From c84d535347fc6cdbe90ebe3692d54a749c53ae63 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Wed, 15 Jan 2025 18:26:36 -0600 Subject: [PATCH 6/6] Capitalization: Update app-library.ejs (#25482) --- website/views/pages/app-library.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views/pages/app-library.ejs b/website/views/pages/app-library.ejs index 1c5501457883..e1ee79fa0708 100644 --- a/website/views/pages/app-library.ejs +++ b/website/views/pages/app-library.ejs @@ -57,7 +57,7 @@ Custom packages
-

Custom Packages

+

Custom packages

Upload any third-party software as a custom package to deploy all of the tools your end users need to work.