Commit Graph
3598 Commits
Author SHA1 Message Date
Eric 58642183c6 Website: update contact source for workshop requests (#50072)
Changes:
- Updated the contact source used for contacts created from workshop
requests

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Workshop requests are now correctly identified as “Website - Workshop
request” in CRM records, improving source tracking and reporting.
* Workshop request contacts are treated as form-based, ensuring the most
recent campaign member status is set to **Registered**.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-30 08:13:01 -05:00
Eric c69bb929d1 Website: update fleet-leave-behind-deck.pdf (#50206)
Changes:
- Updated fleet-leave-behind-deck.pdf to fix an issue where the file was
not loading on Chrome.
2026-07-30 00:13:03 -05:00
Allen HouchinsandMike Thomas 7f07651f97 Add Hawx case study (#50152)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** N/A

# Checklist for submitter

This PR adds one markdown file under `articles/` (a customer case study)
— no product code, so most of the template below doesn't apply.

## What changed

Adds `articles/hawx.md`, a case study on Hawx Pest Control.

**The story:** Hawx is a technology-first pest control company whose
field technicians can't be dispatched without a provisioned phone.
Hiring ramps up hard every summer, so onboarding and offboarding run
constantly. With Jamf, phones sat on the MDM screen until the technician
logged in, nobody remembered their credentials, and the helpdesk got
flooded from personal phones every season. Identifying which device
belonged to which technician took 5 to 10 minutes per call, 5 to 10
calls a day. Hawx now drives Fleet entirely through the API, paired with
Tines and Okta, so a device lands in the right fleet with the correct
profiles, policies, and apps the moment the technician verifies their
identity. Offboarding wipes or locks based on role. Migration took a
month.

**Source:** the 2026-07-20 customer interview with Loren Farr, IT
Manager at Hawx. Loren confirmed on the call that Fleet may use the
company name and his name and title, and was told nothing publishes
without his approval.

**Format:** drafted against the proposed `fleet-case-study-formatting`
skill in #49917 and the `content-style` skill:

- Three-act narrative (the challenge → why Fleet → the solution → the
results), headings in sentence case.
- Four `attribution-quote` divs spaced through the narrative rather than
clustered.
- A `checklist` div for the headline results.
- Full endmatter including the build-enforced `summaryChallenge` /
`summarySolution` / `summaryKeyResults` (semicolon-separated) plus the
company and hero-quote tags.
- "About Hawx" lives in `companyInfo` / `companyInfoLineTwo` rather than
the body, matching every published case study.

## Why

Hawx is a strong story in a segment Fleet's published case studies don't
yet cover: iOS-only, a small IT team (3 people, ~500 devices), a
seasonal workforce, and an API-only usage pattern where the customer
never touches the Fleet UI. It's also a clean Jamf migration narrative
with a quantified helpdesk result.

## ⚠️ Blockers before this can be published

This is a **draft PR on purpose**. Two items must be resolved first:

1. **The quotes are not verbatim yet.** The interview record is bullet
notes, not a transcript, so the four quotes are faithful reconstructions
of what Loren described, not transcribed speech. The case-study skill's
rule is that quotes are verbatim and never reconstructed. **Loren needs
to approve these as his words before merge.** Reviewers should not treat
them as citable until he has.
2. **Both image assets are missing.** There is no Hawx logo and no Loren
Farr headshot in `website/assets/images/`. `companyLogoFilename` and
`quoteAuthorImageFilename` are deliberately stubbed with `TODO-`
prefixes so the website build fails loudly rather than shipping broken
image references. Real files are needed following the
`{descriptor}-{css-width}x{css-height}@2x.{ext}` convention.

## Open questions for reviewers

- **The "more than 90%" figure was dropped.** An earlier draft said
credentials were forgotten in more than 90% of cases. That number isn't
in the interview notes (the notes say "nobody knew their username or
password"), so it's omitted. If Loren sourced it, it can go back in.
- **The warehoused-device problem is omitted.** The notes describe
devices offline more than 30 days needing a reset, currently a 30-minute
call, listed as a *current* problem. That would fit a "Looking ahead"
section if Fleet is the plan for it, but it doesn't belong in results as
an achieved outcome.
- **Hero quote choice.** `quoteContent` uses the "slam dunk ... control
over the phone itself" quote because it names the differentiator.
Loren's closer, "As long as you're not shy about getting into the code,
this is a fantastic platform," is arguably the more trustworthy line for
Fleet's audience. Easy swap if marketing prefers it.
- **Follow-up, not in this PR:** the pull quote could be added to
`handbook/company/testimonials.yml` for the `/customers` carousel. Left
alone since that file is curated by marketing.

- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`. — N/A, website content
only, not a product change

## Testing

- [ ] Added/updated automated tests — N/A, markdown content only
- [x] QA'd manually: cross-checked the structure, custom div syntax, and
required meta tags against the published case studies
(`articles/fastly.md`, `articles/primo.md`) and against the validation
logic in `website/scripts/build-static-content.js`; confirmed
`summaryKeyResults` is semicolon-separated; confirmed `articleTitle`
matches the H1 exactly; grepped `website/assets/images/` and confirmed
both referenced image files are absent (hence the `TODO-` stubs).

---------

Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
2026-07-30 11:03:23 +09:00
Mike Thomas bf95fda79e Website: update sales leave-behind deck (#50123)
**Related issue:** NA

# Checklist for submitter

- [x] QA'd all new/changed functionality manually

---

Updates the leave-behind deck with revisions from design review:

* Updated headings on slide 2 to address pain sooner
* Moved "The world has evolved rapidly" heading to slide 3
* Incorporated platform icons into illustration graphic
2026-07-30 07:53:09 +09:00
fb06efcaac Website: redesign /support page with unified card grid and testimonial (#50132)
**Related issue:** Related to fleetdm/confidential#16762 (not a full
close — see Notes)

# Checklist for submitter

## Testing

- [x] QA'd all new/changed functionality manually

## Summary
Redesigns fleetdm.com/support:
- Merges the previous "Ask the community" and "Support" sections into
one unified "How can we help?" section with a single 6-card grid
- Adds a new "Professional support" card linking to the SLA section of
the go-to-market-operations handbook page
- Adds a customer testimonial
- Consolidates responsive breakpoints (single-column switch and card
centering now both happen at 991px)
- Removes target="_blank" from the two cards linking to fleetdm.com
itself (Professional support, Ask us anything).

## Related
- fleetdm/confidential#16762

## Notes
This is a first iteration toward the broader vision in
https://github.com/fleetdm/confidential/issues/16762, discussed in
design review but intentionally deferred.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **New Features**
* Redesigned the Support page header into a single “How can we help?”
entry point.
* Added a Professional Support card linking to service-level agreement
details.
  * Introduced a customer quote section with author information.

* **Improvements**
* Refreshed support card design (cleaner layout, consistent spacing,
updated typography and link hover behavior).

* **Responsive**
* Improved the support card layout across breakpoints, including
3-column to 2-column to single-column grid behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
2026-07-29 17:18:19 -05:00
Eric bd419cd2de Website: update fallback talk to us meeting link (#50182)
Changes:
- Updated deliver-talk-to-us-form-submission to return a different
Salesforce user ID if territory information could not be found.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Updated the fallback “Talk to us” form submission contact-routing
behavior when territory information is unavailable or returns an
unexpected value, including changes to the default Calendly meeting link
and related warning messaging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-29 15:10:51 -05:00
Eric f25b1ec58d Website: update territory routing for talk to us submissions (#50101)
https://github.com/fleetdm/confidential/issues/16947

Changes:
- Updated the get-territory-user-id helper to accept `website` and
`numberOfEmployees` inputs
- Updated the deliver-talk-to-us-form-submission action to send website
and number of employees to the get-territory-user-id helper, and updated
the `bookingUrlByUserId` dictionary.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved territory routing for “Talk to us” submissions by using
employee count, city, and website details.
* Updated routing logic to direct submissions to the appropriate
Calendly booking link.
* Preserved existing validation and error handling for incomplete or
unexpected territory lookup results.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-29 13:48:08 -05:00
Noah Talerman 40bc83daa9 Add rachaelshaw (API design DRI) as auto reviewer for usage stasts (#50169)
- Context:
https://github.com/fleetdm/fleet/pull/49980#issuecomment-5121775909
2026-07-29 11:41:44 -07:00
LeAnn 460de7ca9c Update routes.js (#50010)
Add two new UI routes for Android host vitals tooltips

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #49791 


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added convenient links for learning more about device security posture
and software update status.
* These links redirect to the relevant Google Android Management API
reference documentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-29 11:06:51 -07:00
daed574428 Update MDM commands documentation with usage details (#49657)
Added note about MDM command limitations and usage of fleetctl.

---------

Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
2026-07-29 11:23:29 -06:00
kitzy f4d7064f9a Add Rtools as a Windows FMA (#50028)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #50020

# What this does

Adds **Rtools** as a Windows Fleet-maintained app. One of the 11 apps
split out of #48501 that failed the FMA validator; #50016 shipped the 6
that passed.

## Why it was failing

The install script hit the validator's 10-minute `executeScript` cap
exactly:

```
20:41:22  INFO  msg="Executing install script..." app=Rtools
20:51:22  ERROR msg="Error executing install script: exit status 1"   # exactly 10:00 later
20:51:22  WARN  msg="failed to remove rtools45-6768-6492.exe: ... Access is denied."
```

The locked installer in the temp dir shows a process was still alive.
`Start-Process -Wait` waits for the process *and all of its
descendants*, which is the same root cause as the other install-timeout
apps in this batch.

Rtools is also the one app in the batch where a **slow unpack** is a
plausible second cause — the installer is ~460 MB and expands a full
toolchain. So rather than assume, the script now waits on the installer
process alone with a 480s cap (under the caller's 10-minute budget) and
logs elapsed time plus Add/Remove Programs registration state on every
poll. If the cap is reached:

- **registered** → the install finished and only a lingering child
remains, so it stops that process and succeeds;
- **not registered** → the unpack genuinely didn't finish, and it fails
with that stated explicitly.

Either way the CI log now says which one happened instead of just timing
out.

## Notes

- **Identity verified against the installer**, not winget metadata. The
setup stub's PE version resource reads `CompanyName: The R Foundation`,
`ProductName: Rtools`. Inno derives `VersionInfoCompany` from
`AppPublisher`, so the ARP publisher is `The R Foundation` — which is
what the exists query uses.
- **Versioned ARP name.** The registry `DisplayName` is `Rtools 4.5
(6768-6492)`, so the input uses `fuzzy_match_name` and the exists query
is `name LIKE 'Rtools %'`.
- Installs to `C:\rtools45`, not Program Files, so the validator's "no
changes detected in `C:\Program Files`" line is an expected warning, not
a failure.
- Ships a new catalog icon and website asset.

# Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] FMA CI validator (install → detect → uninstall) **passes** on the
SYSTEM-context Windows runner — [run
30384196159](https://github.com/fleetdm/fleet/actions/runs/30384196159)
(`All checks passed`)
- [x] Generated output verified locally: manifest SHA matches the winget
manifest, exists/patched queries checked against the installer's PE
version resource, `apps.json` is valid JSON with a description filled
in.
- [x] QA'd all new/changed functionality manually




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added Rtools as a supported Windows application.
* Added installation and uninstallation support with silent setup and
silent removal.
* Added Rtools version metadata, installer verification, and Developer
tools categorization.
  * Added a dedicated Rtools icon for software listings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 23:01:31 -05:00
kitzy c61632305a Add Logitech Unifying Software as a Windows FMA (#50024)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #50020

# What this does

Adds **Logitech Unifying Software** as a Windows Fleet-maintained app.
One of the 11 apps split out of #48501 that failed the FMA validator;
#50016 shipped the 6 that passed.

## Why it was failing

Install and detection were already fine on the SYSTEM-context Windows
runner — osquery found `Logitech Unifying Software 2.52` at `C:\Program
Files\Common Files\LogiShrd\Unifying`. **Uninstall** was the failure:

```
20:40:55  INFO  msg="Executing uninstall script for app..."
20:40:57  INFO  msg="Found app: 'Logitech Unifying Software 2.52' ... Version: 2.52.33"
20:40:57  ERROR msg="App still present after uninstall (expected no match for version '2.52.33' in programs)"
```

Two seconds start to finish — the uninstaller hadn't actually done
anything yet. This is standard NSIS behavior: the uninstaller copies
itself to `%TEMP%` and relaunches, so the process the script starts
exits almost immediately while the real work happens in a detached
child.

The fix passes NSIS's `_?=<dir>` switch, which runs the uninstaller in
place instead of relaunching, making it synchronous. It has to be the
last argument and unquoted, so the script builds a single argument
string rather than an array (PowerShell would quote an element
containing spaces). A bounded poll on the ARP key follows as a backstop,
and the script fails explicitly if the entry is still there.

## Notes

- **Versioned ARP name.** The registry `DisplayName` is `Logitech
Unifying Software 2.52`, so the input uses `fuzzy_match_name` and the
exists query is `name LIKE 'Logitech Unifying Software %'`. The
uninstall script matches the same prefix rather than an exact string.
- Publisher `Logitech` confirmed against the winget locale manifest.
- Installs under `C:\Program Files\Common Files`, so the validator's "no
changes detected in `C:\Program Files`" line is an expected warning, not
a failure.
- Ships a new catalog icon and website asset.

# Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] FMA CI validator (install → detect → uninstall) **passes** on the
SYSTEM-context Windows runner — [run
30384010810](https://github.com/fleetdm/fleet/actions/runs/30384010810)
(`All checks passed`)
- [x] Generated output verified locally: manifest SHA matches the winget
manifest, exists/patched queries reviewed for name + publisher
correctness, `apps.json` is valid JSON with a description filled in.
- [x] QA'd all new/changed functionality manually




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Logitech Unifying Software to the Windows software catalog,
including the version 2.52.33 download, checksum, and install-detection
metadata.
* Implemented silent installation and a robust, registry-aware uninstall
flow (with process lock handling and timeout behavior).
* Added a dedicated Logitech Unifying Software icon to the software page
UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 22:59:09 -05:00
kitzy cfbb5a59fa Add GNU Privacy Guard as a Windows FMA (#50025)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #50020

# What this does

Adds **GNU Privacy Guard** as a Windows Fleet-maintained app. One of the
11 apps split out of #48501 that failed the FMA validator; #50016
shipped the 6 that passed.

## Why it was failing

The install itself worked — the validator logged `New application
detected at: C:\Program Files\GnuPG`. The *script* never returned:

```
20:18:36  INFO  msg="Executing install script..." app="GNU Privacy Guard"
20:28:36  ERROR msg="Error executing install script: exit status 1"   # exactly 10:00 later
20:28:36  INFO  msg="New application detected at: C:\Program Files\GnuPG"
```

Ten minutes on the nose is the validator's `executeScript` timeout. The
cause is a PowerShell detail rather than anything wrong with the
installer: **`Start-Process -Wait` waits for the process *and all of its
descendants***. GnuPG's installer starts `gpg-agent`, `dirmngr`,
`keyboxd` and `scdaemon` and leaves them resident, so `-Wait` never
returns. The same run left the installer `.exe` locked in the
validator's temp dir, which is the other tell that a child process was
still alive.

The install script now follows the pattern already established by
[`ollama_install.ps1`](ee/maintained-apps/inputs/winget/scripts/ollama_install.ps1):
start with `-PassThru` (no `-Wait`), wait on the installer process alone
with a 7-minute cap (below the caller's 10-minute script budget), poll
for the Add/Remove Programs entry so a fast-returning installer can't be
mistaken for a finished one, then stop the daemons.

Stopping the daemons also fixes the uninstall, which would otherwise
fail on files those processes hold open. The uninstall script stops them
up front, uses NSIS's `_?=<dir>` switch so the uninstaller runs in place
instead of relaunching itself detached from `%TEMP%`, and polls the ARP
key to confirm removal.

## Notes

- Clean ARP `DisplayName` (`GNU Privacy Guard`), so exact name matching
— no `fuzzy_match_name` needed. Publisher `The GnuPG Project`.
- Ships a new catalog icon and website asset.

# Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] FMA CI validator (install → detect → uninstall) **passes** on the
SYSTEM-context Windows runner — [run
30384069714](https://github.com/fleetdm/fleet/actions/runs/30384069714)
(`All checks passed`)
- [x] Generated output verified locally: manifest SHA matches the winget
manifest, exists/patched queries reviewed for name + publisher
correctness, `apps.json` is valid JSON with a description filled in.
- [x] QA'd all new/changed functionality manually





<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added GNU Privacy Guard as a supported Windows application in the
maintained apps catalog.
  * Added install/upgrade detection and uninstall support for Windows.
  * Added GNU Privacy Guard to the software catalog (Security category).
* Added a dedicated GNU Privacy Guard icon to the software interface for
proper name-based display.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 22:56:46 -05:00
kitzy 2fc41c7592 Add Azure Data Studio as a Windows FMA (#50027)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #50020

# What this does

Adds **Azure Data Studio** as a Windows Fleet-maintained app. One of the
11 apps split out of #48501 that failed the FMA validator; #50016
shipped the 6 that passed.

## Why it was failing

The install itself worked — the validator logged `New application
detected at: C:\Program Files\Azure Data Studio`. The *script* never
returned:

```
20:08:19  INFO  msg="Executing install script..." app="Azure Data Studio"
20:18:19  ERROR msg="Error executing install script: exit status 1"   # exactly 10:00 later
20:18:19  INFO  msg="New application detected at: C:\Program Files\Azure Data Studio"
```

Ten minutes on the nose is the validator's `executeScript` timeout.
Azure Data Studio is a Visual Studio Code fork and ships the same Inno
Setup script — including the **`runcode` task, which launches the app
when the install finishes**. Because `Start-Process -Wait` waits for the
process *and all of its descendants*, the launched app kept the script
blocked forever.

The fix is the switch VS Code's own FMA already uses:
`/MERGETASKS=!runcode` (see
[`vscode_install.ps1`](ee/maintained-apps/inputs/winget/scripts/vscode_install.ps1)
and
[`vscodium_install.ps1`](ee/maintained-apps/inputs/winget/scripts/vscodium_install.ps1),
both of which pass validation). The script also waits on the installer
process alone rather than its descendants, polls for the Add/Remove
Programs entry, and stops a stray `azuredatastudio` process as a
backstop in case a future build ignores the task suppression.

## Notes

- Machine-scope x64 installer, per the winget manifest — Azure Data
Studio publishes both user and machine scope, and Fleet installs run as
SYSTEM, so machine scope is required.
- Clean ARP `DisplayName` (`Azure Data Studio`), so exact name matching.
Publisher `Microsoft Corporation`.
- Uninstall is unchanged: the Inno uninstaller doesn't leave anything
resident, and `-Wait` waiting on descendants is the desired behavior
there (Inno relaunches itself from `%TEMP%`).
- Ships a new catalog icon and website asset.

# Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] FMA CI validator (install → detect → uninstall) **passes** on the
SYSTEM-context Windows runner — [run
30384162280](https://github.com/fleetdm/fleet/actions/runs/30384162280)
(`All checks passed`)
- [x] Generated output verified locally: manifest SHA matches the winget
manifest, exists/patched queries reviewed for name + publisher
correctness, `apps.json` is valid JSON with a description filled in.
- [x] QA'd all new/changed functionality manually




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added Azure Data Studio to the available Windows software catalog.
* Added support for installing and uninstalling Azure Data Studio
(version 1.52.0) via silent installer and uninstaller flows with
completion detection.
* Added an Azure Data Studio icon to the software interface for better
visual identification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 22:56:00 -05:00
Eric 8b8064e44d Website: update primary cta on homepage (#50071)
Changes:
- Updated the primary cta on the homepage to "Try it yourself"


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Updated homepage calls to action to encourage visitors to try the
product directly.
  * Added a “Try it yourself” option to the bottom CTA section.
  * Retained the “Get a demo” option as the final CTA button.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 12:22:54 -05:00
RachelElysia 0585ab68d1 Website: Handle unexpected responses from Microsoft's compliance and Graph APIs (#50015)
## Issue

#50013

## Description

The Microsoft compliance proxy controller
(`website/api/controllers/microsoft-proxy/receive-redirect-from-microsoft.js`)
called `JSON.parse` on response bodies from Microsoft's Partner
Compliance and Graph APIs without checking for empty bodies or
unexpected response shapes. When Microsoft returned an unexpected
response — for example, a 2xx status with an empty body, which can
happen on partial-setup tenant states or when API permissions on the
enterprise app haven't been fully consented — the controller threw a raw
`SyntaxError: Unexpected end of JSON input` that surfaced verbatim in
the Fleet UI as the `setup_error` string, giving admins a Node.js stack
trace instead of a useful message.

Changes:
- Added explicit empty-body checks before `JSON.parse` at both
API-response parse sites, with a friendly `setup_error` message pointing
at the likely causes (partial setup / missing API permissions).
- On parse failure, expanded the diagnostic log to include response
status code, body length, and a 200-char body snippet so we can diagnose
future occurrences from server logs instead of asking admins to
reproduce.
- Added defensive checks on `parsedPoliciesResponse.value` and
`parsedGroupResponse.value` before indexing — previously
`parsedPoliciesResponse.value[0].Id` would throw `TypeError` if
Microsoft returned a well-formed response missing the expected shape.

**Note for reviewers:** The new `sails.log.warn` calls interpolate the
runtime tenant ID (`informationAboutThisTenant.entraTenantId`) — same
pattern as the existing log at line 209 that logs `fleetInstanceUrl`.
Heroku logs will contain tenant IDs when these error paths fire, which
is intentional so infra can grep by tenant when triaging. If we'd rather
rely on request-correlation IDs and keep tenant IDs out of logs, happy
to make that a follow-up.

## Screenrecording


## Testing
- [ ] Sanity-checked locally by inducing an empty response body
- [ ] Verified no changes to the happy-path flow
- [ ] Verified existing setup_error strings that the Fleet UI checks for
(admin-did-not-consent, missing-conditional-access-group) are unchanged

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved Microsoft integration setup handling when API responses are
empty, invalid, or missing expected data.
* Added clearer setup error messages for missing policies or the “Fleet
conditional access” group.
* Enhanced diagnostics to help identify response-related setup failures.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 11:04:08 -05:00
kitzyandAllen Houchins 3ce3e238ed Add 6 Windows Fleet-maintained apps (#50016)
**Related issue:** N/A — Windows Fleet-maintained app (FMA) coverage for
apps found deployed in a customer's ManageEngine SDP environment but
missing from Fleet.

## What this does

Adds **6** Windows Fleet-maintained apps — the subset of a larger batch
that passes the FMA validator cleanly. Each has a winget-sourced input,
a generated output manifest, and a catalog icon. Detection identity was
verified against each app's real registry DisplayName; apps whose
DisplayName carries a version suffix use fuzzy name matching, the rest
match exactly.

**MSI (clean, auto upgrade-code uninstall):**
- **Git Extensions** — versioned ARP name (`Git Extensions 7.2.0.92`) →
fuzzy match
- **TightVNC**, **Yarn**, **SonicWall NetExtender** (WiX), **Zoom
Outlook Plugin** — clean ARP names → exact match

**EXE — NSIS (custom `/S` install + registry-lookup uninstall):**
- **Spyder** — versioned ARP name (`Spyder 6`) → fuzzy match

## Notes

- **Detection verification.** Every app's `unique_identifier` (registry
DisplayName / osquery `programs.name`) and publisher were verified per
the `new-fma` skill against winget `AppsAndFeaturesEntries`, MSI
Property tables (`msiinfo`), and vendor installer scripts — not assumed.
Git Extensions' MSI `ProductName` is `Git Extensions 7.2.0.92` and
Spyder's ARP entry is `Spyder 6`, so both need `fuzzy_match_name`; the
four exact-match apps were confirmed clean (e.g. TightVNC registers as
`TightVNC`, not a versioned string).
- **Validated on a real Windows host.** All six pass the FMA CI
validator (install → detect → uninstall) on the SYSTEM-context Windows
runner.
- **Icons.** Git Extensions, SonicWall NetExtender, TightVNC, Yarn, and
Zoom Outlook Plugin ship new catalog icons + website assets; Spyder
reuses the existing `Spyder` icon.

## Testing

- [x] FMA CI validator (install → detect → uninstall) on the
SYSTEM-context Windows runner.
- Generated outputs verified locally: all 6 produce valid manifests; MSI
apps carry the correct UpgradeCode-based uninstall; exists/patched
queries reviewed for name + publisher correctness; `go test
./ee/maintained-apps/...` passes.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added maintained Windows catalog entries for Git Extensions, SonicWall
NetExtender, Spyder, TightVNC, Yarn, and Zoom Outlook Plugin, including
silent install, version upgrade detection, and maintenance-ready
uninstall flows.
* Added new software icons for these apps and expanded icon matching so
they display correctly in the catalog.
* **Bug Fixes**
* Improved Spyder Windows uninstall targeting and command/argument
handling for more reliable removals.
* **Documentation**
  * Refreshed Spyder supported version details to 6.1.5.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Allen Houchins <allenhouchins@mac.com>
2026-07-28 10:14:53 -05:00
Allen Houchins aea7c4068f Remove Nocturnal as a macOS FMA (#50050)
**Related issue:** N/A — fixes the failing scheduled "Update
Fleet-maintained apps" workflow

The `nocturnal` cask was removed from homebrew-cask on 2026-07-28
([Homebrew/homebrew-cask@517db75](https://github.com/Homebrew/homebrew-cask/commit/517db75b78))
after being deprecated on 2024-07-27 and disabled on 2025-07-27, both
`because: :unmaintained` (upstream repo's last push was in 2018). The
brew API now returns 404 for it, so the maintained-apps ingester panics:

```
panic: ingesting homebrew app: app not found in brew API
```

This removes Nocturnal as a Fleet-maintained app, following the same
pattern as #46541 (Messenger) and #47420 (Dell Display Manager):

- `ee/maintained-apps/inputs/homebrew/nocturnal.json` — Homebrew input
- `ee/maintained-apps/outputs/nocturnal/darwin.json` — macOS output data
- `ee/maintained-apps/outputs/apps.json` — Nocturnal entry
- `frontend/pages/SoftwarePage/components/icons/Nocturnal.tsx` and its
import/mapping in `index.ts`
- `website/assets/images/app-icon-nocturnal-60x60@2x.png`

# Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing

- [x] QA'd all new/changed functionality manually (verified `apps.json`
still parses, no remaining `nocturnal` references, ESLint passes on the
icons index)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Removed Apps**
  - Removed Nocturnal from the maintained application catalog.
  - Removed its installation and uninstallation support.
  - Removed the Nocturnal icon from software listings.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 09:53:17 -05:00
Eric 53b92f9356 Website: Update "Talk to us" form and contact page (#50023)
Changes:
- Updated the quote shown on the contact page (and disabled the unused
personalization on the page)
- Removed the "What will you be using Fleet for" question on the "Talk
to us" form on the contact page

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Improvements**
* Simplified the “Talk to us” form by removing the “What will you be
using Fleet for?” question.
* Added an organization employee-count field with required numeric
validation.
* Streamlined form prefilling and submission details for returning
users.
* Updated the testimonial section to display a consistent customer story
and logo.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 19:11:21 -05:00
Eric 766408d93b Website: update package.json overrides, update package-lock (#49852)
Changes:
- Added an override for `body-parser@1.20.6` to the websites
package.json
- Updated thhe website's package-lock.json to include updated versions
of `body-parser` and `brace-expansion`
- Removed extraneous sails-hook-grunt dependencies from the website's
package-lock by running `npm update sails-hook-grunt`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated a package version override to improve dependency consistency
and reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 13:41:22 -05:00
melpike 0786a5c514 [Route] Add route for IDP account sync information (#49975)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45524 


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added a redirect from the IDP account sync information page to the
Apple account provisioning deployment guide.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 07:44:20 -06:00
melpikeandEric ea1c1e9646 Add route for Windows default fleet information (#49898)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41787

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a convenient link for learning how to set a default Fleet for
new Windows hosts.
* The link now redirects to the relevant Windows MDM setup guidance,
specifically for setting a default fleet for new hosts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Eric <eashaw@sailsjs.com>
2026-07-27 07:27:32 -06:00
Allen Houchins f96cb9d6c7 Add Windows FMAs (letter I): 17 apps (#49923)
**Related issue:** N/A — part of the ongoing Windows Fleet-maintained
apps (FMA) parity workstream (letter I).

## What this does

Adds **17** Windows Fleet-maintained apps for the letter-I batch.
apps.json descriptions follow the house `"<Name> is a …"` convention.

**IBM Semeru Runtime Open Edition (Java) — 8 apps** (MSI, machine, x64):
JDK 8/11/17/21 and JRE 8/11/17/21. Per-major detection follows the
Eclipse Temurin pattern — `name LIKE 'IBM Semeru Runtime Open Edition
(JDK|JRE)%' AND publisher = 'Semeru' AND version LIKE '<major>.%'` — so
majors and JDK/JRE never cross-match. All 8 share the IBM Semeru logo.

**Other apps (9):**
- **IronPython 3** — MSI; fuzzy `IronPython 3%` (excludes the EOL v2)
- **ImageGlass** — dual-scope MSI, custom `ALLUSERS=1` install
- **install4j** — install4j installer (bundled JRE), `-q`
- **IrfanView** — custom installer `/silent /allusers=1`; versioned+arch
name → fuzzy `IrfanView%`
- **iMazing HEIC Converter**, **IsoBuster**, **ImpExpPro** — Inno Setup
(`/VERYSILENT`)
- **Infix PDF Editor** — Inno, x86
- **Ibis Calculeren voor Bouw** — InstallShield wrapper; uninstall via
the MSI UpgradeCode (`uninstall_type: msi`)

## Dropped from this batch (recorded in the workstream tracker)
- **IBM Aspera Connect** — MSI installs per-user by default
(`ALLUSERS=2`/`MSIINSTALLPERUSER=1`, no machine switch in the manifest)
+ a rolling `/latest/` URL that 404s on the next release.
- **IcedTea-Web** (Azul and AdoptOpenJDK) — both declare a hard,
unbundled JRE dependency; it's a JNLP launcher that's dead-on-arrival
without Java the FMA won't install (AdoptOpenJDK variant is also
archived).
- **IronPython 2** — EOL (Python 2). **install4j 9** — legacy 2022
build. **IrfanView PlugIns** — add-on that drops DLLs with no
independent ARP entry (undetectable) and depends on the base app.
- **Intermedia Unite** and its **Teams Desktop Plugin** — both use
non-versioned "latest" URLs (winget-bot auto-updated; the pinned SHA
rots each release); the plugin also depends on Teams + Unite.

## Notes
- **Ibis Calculeren voor Bouw**, **ImpExpPro**, and **Infix PDF Editor**
ship without a catalog icon — no clean ≥256px first-party logo exists
for these niche apps (they fall back to the generic icon).
- **Ibis** carries some risk: its DisplayName couldn't be verified
offline (compressed InstallShield payload) and its installer URL is
non-versioned — flagging for the validator; will drop if
detection/version fails.
- **IsoBuster** uses a non-versioned URL that currently matches the
pinned 5.8, so no `ignore_hash`; winget re-ingestion tracks future
drift.
- Verification (installer type/scope/arch, ProductCode/UpgradeCode,
dependencies, silent switches, URL stability, en-US locale) was done per
the `new-fma` skill against the winget-pkgs manifests, with several
DisplayNames confirmed via `innoextract`/`msitools`.

## Testing
- [ ] FMA CI validator (install → detect → uninstall) on the
SYSTEM-context Windows runner — pending.
- Generated outputs verified locally: all 17 produce valid manifests;
per-major Semeru queries and MSI UpgradeCode uninstalls confirmed; all
apps.json descriptions present and convention-compliant.
2026-07-24 21:46:12 -05:00
Eric cb75dd04f7 Website: replace purple link icon (#49930)
Closes: https://github.com/fleetdm/fleet/issues/49885

Changes:
- Replaced the icon shown when hovering over headings on pages built
from Markdown.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Updated heading link hover icons across article and legal pages to use
the green link icon for improved visual consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 18:29:42 -05:00
Eric ce47cb924a Website: Update contact form for users who visit the page from "Get a demo" buttons (#49929)
Closes:  https://github.com/fleetdm/fleet/issues/47653

Changes:
- Updated the contact page to only display the "Talk to us" form if a
user visits it with a `?talkToUs` query string.
- Updated all "Get a demo" buttons to go to `/contact?talkToUs`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added a dedicated “Talk to us” contact experience.
* Updated “Get a demo,” “Talk to sales,” and “Talk to an engineer” links
across the site to open the appropriate contact form directly.
* **Bug Fixes**
* Improved contact form selection so the requested form displays
consistently across supported pages.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 18:27:11 -05:00
Eric eedfc5642c Website: (Android proxy) Add deviceNotFound exit to four android proxy endpoints (#49918)
Changes:
- Updated the delete-android-device, get-android-device,
issue-command-on-android-device, and modify-android-device actions to
return a `deviceNotFound` response to Fleet servers when the Android
management API returns a 404 response.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
  - Improved Android device management error handling.
- Device deletion, retrieval, command issuance, and modification now
clearly report when the requested device cannot be found.
  - Prevents missing devices from being reported as generic errors.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 15:20:02 -05:00
melpike 6ce0e7fc0a [Route] Add route for device and user scope information (#49915)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46242 


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added a convenient redirect from the device and user scope information
link to the relevant Custom OS Settings guide section.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 13:22:31 -06:00
Mike Thomas ade803d6eb Update Road to AI in IT PDF (#49870)
Updated PDF to fix rendering issues on iPhone.
2026-07-24 09:07:32 -05:00
Nico 13cf01f78a Bump websocket-driver to 0.7.5 in website/ (CVE-2026-54466) (#49575)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** N/A

Bumps `websocket-driver` to `0.7.5`


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated a package resolution override for improved dependency
compatibility.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 12:49:30 -05:00
Eric c681fcb9fb Website: Update license verification logging in register-one-fleet-instance-using-vpp action (#49783)
Changes:
- Updated the error logged in `register-one-fleet-instance-using-vpp`
action when a Fleet license key cannot be verified to include the
error's message.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved error reporting when Fleet license verification fails,
providing more specific details to support troubleshooting.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 16:22:29 -05:00
Allen Houchins 1a1b6e786a Add Box Tools Fleet-maintained app for Windows and macOS (#49779)
**Related issue:** Resolves #49738

Adds **Box Tools** as a Fleet-maintained app for **Windows** (winget
`Box.BoxTools`) and **macOS** (Homebrew cask `box-tools`).

## Windows details (verified against the real installer)

- Installer: `BoxToolsInstaller-AdminInstall.msi` (machine-wide admin
MSI, `ALLUSERS=1`), x64.
- MSI Property table verified with msitools: `ProductName` = `Box
Tools`, `Manufacturer` = `Box`, `ProductVersion` = `4.32.0.1324` — all
match the winget manifest, so `unique_identifier: "Box Tools"` and the
generated exists query (`name = 'Box Tools' AND publisher = 'Box'`)
match what osquery reports from the registry. No `program_publisher`
override needed.
- The winget manifest has no `Scope`, so `installer_scope: "machine"` is
set in the input (confirmed by `ALLUSERS=1`).
- ProductCode/UpgradeCode match the manifest; standard auto-generated
machine-MSI install + upgrade-code uninstall scripts.
- Downloaded SHA256 matches the manifest SHA (`9f5958...c5066`).
- No sibling-name collision with the existing Box Drive FMA (its
DisplayName is `Box`; matching is exact).

## macOS details

Box Tools on macOS is **per-user only**: the cask installs the app
bundles to `~/Library/Application Support/Box/Box Edit/`, Box's admin
`.pkg` forbids the local system domain (`enable_localSystem="false"`),
and [Box's large-scale deployment
docs](https://support.box.com/hc/en-us/articles/360043695834-Large-Scale-Deployments-Box-Tools)
instruct running the installer as the console user (multi-user Macs are
not a supported configuration).

Because the install location is outside osquery's `apps` directory scan
paths, detection relies on osquery's LaunchServices enumeration
(`_LSCopyAllApplicationURLs` in `genApps`), which surfaces the bundles
regardless of location — verified against a live install where all four
Box Tools bundles are LaunchServices-registered at the per-user path and
appear in the `apps` table.

- `unique_identifier: com.Box.Box-Edit` (verified `CFBundleIdentifier`
of `Box Edit.app` in the DMG).
- **Custom install script** (the cask's app artifacts are all
`target:`-style, which the script generator skips, so the auto-generated
script would be a no-op): resolves the console user (falling back to
`lastUserName` when run while logged out), quits the Box apps, copies
the four app bundles from the DMG's `Install Box
Tools.app/Contents/Resources/` into the user's `~/Library/Application
Support/Box/Box Edit/` (replicating the cask/pkg payload exactly),
chowns them, and registers them with LaunchServices in both root and
user contexts so inventory and box.com pick them up without a first
manual launch.
- **Custom uninstall script**: quits/kills the Box Tools processes and
removes `Box Edit` from every local user's home. The parent `Box`
directory is shared with Box Drive, so it is only removed if left empty.
- The cask uses `sha256 :no_check` (rolling `currentrelease` URL) — the
established FMA convention for such casks (same as Google Chrome/VS Code
darwin); the server pins the hash of what it downloads at add time.
- Cask version is `4.32` while `CFBundleShortVersionString` is `4.32.0`;
the validator's prefix matching and the patched query's
`version_compare` both treat these as consistent.

## Shared caveat

⚠️ Both installer URLs are rolling `currentrelease` links. On Windows
the pinned SHA will drift when Box ships a new build until the FMA
auto-update ingests the new manifest; macOS uses `no_check` per the
cask.

## Icon

Generated from the official 512×512 Box Tools icon shipped inside the
vendor DMG via `tools/software/icons/generate-icons.sh` (frontend
`BoxTools.tsx` + map entry, website `app-icon-box-tools-60x60@2x.png`).
Both platforms share the icon via the common `name`/slug.

# Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing

- [x] Verified installer identity fields (MSI Property table, Info.plist
bundle identifiers/versions) with msitools/PlistBuddy against the live
installers; Windows output SHA matches the winget manifest.
- [x] Verified on a live macOS install that the per-user Box Tools
bundles are LaunchServices-registered and visible to osquery's `apps`
table.
- [ ] FMA validation CI (Windows + macOS runners) to confirm
install/uninstall/detection.
- [ ] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added Box Tools support for both Windows and macOS.
* Added Box Tools install, upgrade, and uninstall handling for the
maintained app catalog.
* Published Box Tools metadata to the software catalog (including
platform-specific entries and version targeting).
* Added a Box Tools icon to the software interface for improved name
matching.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 15:41:21 -05:00
Allen Houchins a3f6a45fa9 Add Windows FMAs (letter H): 5 apps (#49478)
**Related issue:** N/A — part of the ongoing Windows Fleet-maintained
apps (FMA) parity workstream (letter H).

## What this does

Adds **5** Windows Fleet-maintained apps for the letter-H batch, each
with a winget-sourced input, generated output manifest, and a
first-party catalog icon.

- **HashTools** — Inno Setup, machine, x64. File-checksum utility
(Binary Fortress). Has an evergreen WebView2 dependency (present on
virtually all fleets; core hashing works without it).
- **HeidiSQL** — Inno Setup, machine, x64. Custom install passes
`/ALLUSERS` for machine scope (the ingester doesn't forward manifest
`Custom` switches).
- **HWMonitor** — Inno Setup, machine, x86. ARP DisplayName is `CPUID
HWMonitor`; installs a kernel driver removed by its uninstaller.
- **HP Prime Virtual Calculator** — WiX burn bundle, machine, x64. Uses
a name-only exists query (the ARP publisher is MORAVIA Consulting, not
the manifest's "HP").
- **Huddle** — InstallShield exe (`/exenoui /quiet`), machine, x86.
Uninstall via the MSI UpgradeCode (`uninstall_type: msi`); `ignore_hash`
for the non-versioned installer URL.

## Dropped from this batch (recorded in the workstream tracker)
- **HandBrake** — the GUI declares an unbundled
`Microsoft.DotNet.DesktopRuntime.10` dependency (won't run without it);
the CLI is a portable zip with no Add/Remove Programs entry to detect.
- **HiPIN** (`KPN.HIPIN`) — unbundled VCRedist + WebView2 dependencies,
a non-versioned "latest" URL, and no ARP DisplayName/ProductCode. The
`binbat.whipinto` candidate is an unrelated WebRTC tool (mismatch).

## Notes
- **Huddle** uses a non-versioned `HuddleSetup.exe` URL — if the vendor
ships past 4.8.0.0, osquery version detection may drift (same pattern
that failed GoodSync in letter G). Flagging for the validator; will drop
if it can't match.
- Verification (winget manifest identity, installer type/scope/arch,
ProductCode/UpgradeCode, silent switches, dependencies, URL stability)
was done per the `new-fma` skill against the winget-pkgs manifests.

## Testing
- [ ] FMA CI validator (install → detect → uninstall) on the
SYSTEM-context Windows runner — pending.
- Generated outputs verified locally: all 5 produce valid manifests;
exists/patched queries reviewed; Huddle's MSI UpgradeCode uninstall
auto-generated correctly.
2026-07-22 14:34:36 -05:00
Eric 8b49181a14 Website: Update logging in register-one-fleet-instance-using-vpp action (#49764)
Changes:
- Updated register-one-fleet-instance-using-vpp action to log the name
of the error when a Fleet license key cannot be verified.
2026-07-22 13:30:17 -05:00
Allen Houchins 70f8ce56a1 Add article: Build your own Linux self-service with script-only packages (#49605)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** NA

## What changed

Adds a new blog article,
`articles/build-your-own-linux-self-service-with-script-only-packages.md`,
published under the `articles` category.

The article is a how-to piece showing how Fleet 4.89.0's new support for
**uninstall script, pre-install query, and post-install script on
script-only packages** turns `apt-get install` / `dnf install` into a
GitOps-managed, self-service Linux software catalog, with no
`.deb`/`.rpm` to host. It ends with a small generator that emits the
install script, uninstall script, and YAML block from just a package
name.

## Why

Script-only packages became a full install/uninstall/verify lifecycle in
4.89.0. This article documents a practical pattern built on top of that
capability for teams managing Linux with Fleet.

## Notes for reviewers

- Content-only change: one new markdown file, no code.
- Technical claims were verified against the 4.89.0 `CHANGELOG.md` and
`docs/Configuration/yaml-files.md` / the deploy-software-packages guide.
In particular, script-only packages support `uninstall_script`,
`post_install_script`, and `pre_install_query` (they still do **not**
support `install_script` or automatic install via policy).
- All links point to real destinations (`fleetdm.com` routes and GitHub
paths) that were checked against `website/config/routes.js` and the
docs.
- Followed the `fleet-article-formatting` house style (dek, key
takeaways, post-takeaways CTA button, "See it live" endmatter) and
`content-style` rules.

# Checklist for submitter

- [x] QA'd all new/changed functionality manually (proofread; verified
links and technical claims against repo docs/changelog).

<sub>This change is a documentation/content-only addition; the code,
testing, database, configuration, and fleetd sections of the standard
template do not apply.</sub>
2026-07-22 12:16:57 -05:00
melpike 8923dda11b [Route] Add route for MDM enrollment guide (#48658)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41787 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added a new redirect for the “Learn more about MDM enrollment” page,
sending visitors to the Windows MDM setup guide’s manual enrollment
section.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 10:04:50 -06:00
Mike Thomas 1e75ff0431 Update leave behind deck PDF (#49722)
Update leave behind deck PDF
2026-07-22 13:35:31 +09:00
Eric c66b724704 Website: add Reddit script tag (#49723)
Changes:
- Added a Reddit ads script tag to the website layout
2026-07-21 22:31:48 -05:00
Mike Thomas 05bae755a6 PDF text rendering fix (#49720)
Fixed text rendering issues in PDF.
2026-07-22 12:15:18 +09:00
Eric 52974b55a2 Website: Update new license form links (#49709)
Changes:
- Updated the form on the /new-license page to link users who create a
quote for >700 hosts to the /contact page

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Updated the high-volume license quote flow with a direct “Talk to us”
link to the contact page.
* **Style**
* Improved submit button alignment and hover visibility for clearer
interaction feedback.
  * Removed outdated link styling from the new license page.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-21 15:41:05 -05:00
Eric 647ab1863c Website: update logos (#49695)
Closes: https://github.com/fleetdm/confidential/issues/16891


Changes:
- Updated logos shown on the logo carousel component and solutions
pages.
2026-07-21 14:18:04 -05:00
Eric 460e575bb4 Website: update /ai page's meta title (#49661)
Changes:
- Updated the meta title of the /ai page (AI in IT » AI-powered IT)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Updated the AI page’s metadata title to “AI-powered IT” for improved
page labeling.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-21 09:45:04 -05:00
EricandMike Thomas c4c3c57c2e Website: Add AI-powered IT page (#49650)
Closes: https://github.com/fleetdm/confidential/issues/16847

Changes:
- Added a new page, AI-powered IT (/ai)
- Added links to the new page to the homepage, /linux-management,
/infrastructure-as-code, /device-management, and
/visibility-and-reporting pages


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an “AI-powered IT” page at `/ai`, including structured marketing
content, responsive hero imagery, and clear calls to action.
* Added an “AI-powered IT” entry to the Solutions navigation and updated
key page CTAs to link to `/ai`.
* **Style**
* Introduced and refined responsive `section-buttons`/button-group
layouts across multiple pages.
* Added dedicated styling for the new AI in IT page and adjusted related
feature-with-image spacing for better mobile presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
2026-07-21 09:19:03 -05:00
Mike Thomas d477c44098 Add AI in IT report PDF (#49634)
Adds state of AI in IT report PDF.
2026-07-21 19:42:59 +09:00
EricandMike Thomas 8e97e62a22 Website: Add case study, update card links on customers page (#49448)
Changes:
- Added a case study from Primo
- Added a link to the new case study to the /customers page

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a new Primo case study card to the Customers page, including its
logo, description, and navigation link.
- **Bug Fixes**
- Corrected the Customers page template block comment syntax to improve
rendering consistency.
- Updated case-study quote author images to display with a circular
shape.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
2026-07-20 19:07:47 -05:00
Eric 632b4d924b Website: use shared Google API auth client in android proxy endpoints. (#47810)
Closes: https://github.com/fleetdm/fleet/issues/46496

Changes:
- Updated the website's custom hook to create a Google API auth client
and make it available at `sails.googleAuthClient`
- Updated Android proxy endpoints to use the shared Google API auth
client.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Optimized Google API authentication handling for Android management
features to improve system performance and reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 18:38:55 -05:00
Lucas Manuel RodriguezandEric df36ce891a Website: don't require an API key on Microsoft compliance proxy requests (#49434)
**Related issue:** Resolves #47699

## Testing

- [x] QA'd all new/changed functionality manually

## What & why

Entra conditional access is becoming available to self-hosted Fleet
Premium instances, which don't have the shared `MS-API-KEY` that
cloud-managed customers use. This makes the `microsoft-proxy/*`
endpoints reachable without that key by dropping the `is-cloud-customer`
policy gate (and the now-unused shared-secret config comments / policy
file).

A replacement auth mechanism for the proxy is tracked separately in
#47702.

> Split out of #49414 so the website change can ship independently.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Security / Access Control**
* Updated Microsoft proxy access handling to bypass the prior
cloud-customer check for matching requests.
* **Configuration**
* Removed unused cloud-customer compliance proxy shared-secret settings.
* **Bug Fixes**
* Improved compliance partner tenant creation by detecting existing
tenants using the provided Entra tenant ID and corrected the success
message text.
* **Data Model**
* Removed uniqueness enforcement for stored fleet instance URLs to
prevent avoidable conflicts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eric <eashaw@sailsjs.com>
2026-07-20 15:38:28 -05:00
Luke Heath d91d8d7cc7 Remove outdated scrum ritual docs (#49578) 2026-07-20 11:06:15 -06:00
Noah TalermanandEric bd74a7d5d1 Fix query editor syntax-highlighting colors and visual bugs (#49391)
For the following quick win:
- https://github.com/fleetdm/fleet/issues/49373


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Style**
- Refined syntax highlighting across documentation code examples for
more consistent visual theming.
- Column-name matches are now highlighted with dedicated styling
(separate from generic string highlighting), improving readability.
- Updated Highlight.js token colors (keywords, operators, numbers, and
strings) across docs pages to align with the shared theme palette,
including new/overridden column-token styling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eric <eashaw@sailsjs.com>
2026-07-17 17:57:54 -05:00
Eric bbd4f74333 Website: Update create-android-signup-url error handling (#49488)
Changes:
- Updated the website's Android proxy's create-android-signup-url
endpoint to log a more detailed message if Google returns a 429 (rate
limit exceeded) response in the get-is-enterprise-managed-by-fleet
helper
2026-07-17 17:25:36 -05:00
Allen Houchins 0e587dc80c Add Firefox Nightly and Firefox Developer Edition Fleet-maintained apps (#49501)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #49149

Adds **Firefox Nightly** and **Firefox Developer Edition** as
Fleet-maintained apps for macOS and Windows (4 new FMAs). Mozilla VPN
(also requested in #49149) is not included, so this doesn't close the
issue.

## What's included

| App | macOS | Windows |
|-----|-------|---------|
| Firefox Nightly | Homebrew cask `firefox@nightly`, bundle ID
`org.mozilla.nightly` | MSIX `Mozilla.Firefox.Nightly.MSIX` (no exe
package exists in winget) |
| Firefox Developer Edition | Homebrew cask `firefox@developer-edition`,
bundle ID `org.mozilla.firefoxdeveloperedition` | NSIS exe
`Mozilla.Firefox.DeveloperEdition`, machine scope, `/S` |

All identity fields were verified against the real installers, not
catalog metadata: bundle IDs read from the DMGs' `Info.plist`, MSIX
identity ("Firefox Nightly" / publisher "Mozilla Corporation") read from
the package's `AppxManifest.xml`, and DevEd's registry identity
(`Firefox Developer Edition (x64 en-US)`, publisher `Mozilla`,
versionless DisplayName) confirmed in Mozilla's NSIS installer source at
the shipped release tags.

The MSIX install/uninstall scripts follow the established Slack/Claude
pattern (provision machine-wide + register for the logged-on user via
scheduled task).

## Pre-release version handling (macOS)

Mozilla's pre-release bundles report only the base version in
`CFBundleShortVersionString` (`153.0` for cask version `153.0b13`),
which would make the generated patch policy flag every up-to-date
install as outdated. Instead, the patch policies for these two channels
compare **`bundle_version`** (`CFBundleVersion` encodes the build date,
e.g. `15326.7.15`), so individual pre-release builds are
distinguishable:

- **Nightly**: derived directly from the build timestamp embedded in the
cask version (`154.0a1,2026-07-17-09-27-13` → `15426.7.17`). No external
calls.
- **Developer Edition**: build date resolved from Mozilla's
[buildhub](https://buildhub.moz.tools) (indexed as product `firefox`,
channel `aurora`). On buildhub failure the ingester logs a warning and
falls back to a base-version comparison (cycle granularity) rather than
failing the run; it self-corrects on the next scheduled ingestion.

The macOS validator gets a matching exception accepting `base + "b"`
versions for the DevEd bundle ID. Both computed values were verified
against the actual DMGs' `Info.plist`.

**Known limitation (Windows):** patch detection for Developer Edition on
Windows is only accurate to the release cycle (153 vs 154), not between
betas (b13 vs b14) — the registry `DisplayVersion` and winget's
`PackageVersion` are both the base version (`151.0`) with no beta
number, and osquery's `programs` table has nothing finer to compare.
Nightly on Windows is day-granular since its MSIX package version
encodes the build date. Documented in #49149.

## Other changes

- Tightened `firefox_uninstall.ps1` (release channel FMA): its
`*Firefox*` match would have uninstalled Developer Edition (or ESR)
first depending on registry enumeration order. Now matches `Mozilla
Firefox*` and excludes ESR; `firefox/windows` output regenerated.
- Channel-specific icons generated from the real app bundles (frontend
components + website PNGs), with map keys covering both catalog and
inventory names.

## Why Firefox Beta is not included

Beta (requested in #49149) was deliberately dropped:
- On Windows, the Beta exe registers the same identity as release
Firefox (`Mozilla Firefox (x64 en-US)`), making it indistinguishable in
inventory. The only distinct package is `Mozilla.Firefox.Beta.MSIX`,
which has no `en-US` winget locale manifest (only `en`), which the
ingester requires.
- On macOS, Beta shares both the bundle ID (`org.mozilla.firefox`) and
the install path (`/Applications/Firefox.app`) with release Firefox, so
installing it silently replaces a release install.

## Notes for reviewers

- Nightly URLs are date-stamped and refresh with the daily FMA
ingestion; within-cycle Nightly darwin builds share a `CFBundleVersion`
date so same-day rebuilds are indistinguishable.
- DevEd's winget package lags Mozilla's releases (winget latest is 151.0
vs current 153.0b13); the FMA tracks winget as usual.
- The `CFBundleVersion` format (`<major><yy>.<M>.<D>`, unpadded) is an
inferred contract of Mozilla's build system, verified against both
shipped DMGs; if it ever changes, patch status fails visibly (reports
unpatched), not silently.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] Added/updated automated tests
- [ ] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added deployment support for Mozilla Firefox Developer Edition and
Firefox Nightly on macOS and Windows (including Homebrew/Winget inputs
and platform-specific install/uninstall workflows).
* Added new catalog entries and dedicated UI icons for both Firefox
variants.
* **Bug Fixes**
* Improved macOS “patched” detection and version matching for Developer
Edition and Nightly builds.
* Enhanced Homebrew ingestion by resolving build information (with
fallback when unavailable).
* Refined Windows uninstallation matching to target the correct Firefox
release channels and avoid ESR.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-17 16:05:27 -05:00