Files
fleet/website
ecdf1ff003 Add TeamViewer Host as a Windows Fleet-maintained app (#50553)
**Related issue:** Resolves #50332

Adds **TeamViewer Host** as a Windows Fleet-maintained app.

## The issue's premise was wrong — this needed no new capability

#50332 was blocked on "not in winget." It is in winget:
`TeamViewer.TeamViewer.Host`, published continuously since **June 2023**
(v15.42.8), currently **15.80.4** (merged upstream as
microsoft/winget-pkgs#409335, 2026-07-29). I downloaded the live x64
installer and its SHA256 matches that manifest byte-for-byte.

It reads as absent because it's nested a level deeper than you'd expect
— `manifests/t/TeamViewer/TeamViewer/Host/`, a sibling of the full
client's *version* directories rather than of the publisher's package
directories.

Consequence: this comes off the dependency on #50364, and that FR loses
one of its three examples. The other two (#50328, #50329, OLE DB Driver
18/19) still hold — there is no OLE DB package under any winget
publisher.

## Identity verified against the installer, not winget metadata

Per the `new-fma` golden rule, from the x64 MSI's `Property` and
`Registry` tables:

| Field | Value | Evidence |
|---|---|---|
| `unique_identifier` | `TeamViewer Host` | MSI `ProductName`; no
`ARPDISPLAYNAME`, empty `Registry` table, so this is the ARP DisplayName
|
| publisher | `TeamViewer` | MSI `Manufacturer`, equal to the winget
locale `Publisher` → no `program_publisher` override |
| `installer_scope` | `machine` | `ALLUSERS=1` |
| bootstrapper? | No | no `ARPSYSTEMCOMPONENT` |

Corroborated independently by [silentinstallhq's PSADT
script](https://silentinstallhq.com/teamviewer-host-install-and-uninstall-powershell/),
which detects the app with `Get-InstalledApplication -Name 'TeamViewer
Host'` and uses `/S` for both install and uninstall.

Generated exists query:

```sql
SELECT 1 FROM programs WHERE name = 'TeamViewer Host' AND publisher = 'TeamViewer';
```

No collision with the existing `teamviewer/windows` FMA, which generates
an exact `name = 'TeamViewer'`.

## Why exe + `ignore_hash`, matching the full client

winget offers Host as an NSIS exe and as a nested `wix` MSI inside a
zip. The ingester can't select the zip (`installer.InstallerType` is
`zip`, which never normalizes to `msi`), so the exe is the only
reachable installer.

TeamViewer publishes no version-pinned Host exe —
`TeamViewer_Host_Setup_x64_15.80.4.exe` and the x86 equivalent both 404
— so the manifest's URL is the unpinned `TeamViewer_Host_Setup_x64.exe`
and `ignore_hash: true` is required. This is vendor asymmetry, not a
fixable winget defect: the *full* client does publish pinned exe URLs.
Same reason `teamviewer/windows` already sets `ignore_hash`.

## Correcting the coexistence note in #50332

The issue assumed Host and the full client can co-exist. They can't. The
Host MSI's `LaunchCondition` table blocks the install outright:

> Error 25001: An incompatible TeamViewer package was detected that
conflicts with the current MSI package: TeamViewer_Full 64-bit. Please
manually uninstall this package.

…plus equivalents for Full 32-bit/ARM64, Host ARM64, and the NSIS
installs. **Relevant to validation: the validator host must not already
have `teamviewer/windows` installed.**

## Icons

No `index.ts` change needed — `matchLoosePrefixToKey` treats keys as
whole words at the start, so `"teamviewer host"` matches the existing
`teamviewer` key and inherits the TeamViewer brand icon. Verified
against the real 1,163-key map.

The website resolves its icon from the slug
(`app-icon-${slug}-60x60@2x.png`) with no such fallback, so
`app-icon-teamviewer-host-60x60@2x.png` is added — a copy of the
existing TeamViewer brand asset, since Host ships the same logo.

## Two things for review

1. **The PowerShell is unverified.** Authored on macOS with no
PowerShell available, so install/uninstall have not been executed. The
uninstall script searches ARP by DisplayName instead of a hardcoded key,
and uses the three-shape `UninstallString` parser (TeamViewer's is
unquoted and contains a space in `C:\Program Files\...`, which the older
`.Split('"')` approach in `teamviewer_uninstall.ps1` mishandles).
Validator run is the real check.
2. **Category mismatch with the macOS side.** This uses `Communication`,
matching the merged `teamviewer/windows`. #47121 adds
`teamviewer-host/darwin` with `Productivity`. Worth reconciling — and
that PR will want this same website PNG, so expect a trivial conflict.

`name` is `TeamViewer Host`, matching #47121 so both platforms group
together in the FMA library.

## Testing

- [x] `go test ./cmd/maintained-apps/... ./ee/maintained-apps/...`
passes
- [x] Generator is idempotent — re-running produces no diff and
preserves the `apps.json` description
- [x] `apps.json` is valid JSON with no empty descriptions
- [x] Live installer SHA256 confirmed against the winget manifest
- [ ] FMA validator: install → detect → uninstall on a Windows host
**(pending — needs a host without the full TeamViewer client)**

No shared code changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Allen Houchins <allenhouchins@mac.com>
2026-08-05 14:04:49 -05:00
..
2026-08-04 07:11:56 -06:00

fleetdm.com

This is where the code for the public https://fleetdm.com website lives.

Bugs

To report a bug or make a suggestion for the website, create an issue in the fleet GitHub repository.

Testing locally

See https://fleetdm.com/handbook/engineering#test-fleetdm-com-locally

Deploying the website

To deploy changes to the website to production, merge changes to the main branch. If the changes affect the website's code, or touch any files that the website relies on to build content, such as the query library, osquery schema, docs, handbook, articles, etc., then the website will be redeployed.

Wondering how this works? This is implemented in a GitHub action in this repo. Check out the code there to see how it works! For help understanding what sails run and npm run commands in there do, check the scripts in website/package.json and in website/scripts/.

Changing the database schema

To deploy new code to production that relies on changes to the database schema or other external systems (e.g. Stripe), first put the website in "maintenance mode" in Heroku. Then, make your changes in the database schema. Next, if you have a script to fix/migrate existing data, go ahead and run it now. (e.g. sails run fix-or-migrate-existing-data). Then, merge your changes and wait for the deploy to finish. Finally, switch off "maintenance mode" in Heroku.

Note that entering maintenance mode prevents visitors from using the website, so it should be used sparingly, and ideally at low-traffic times of day.

Warning: Doing an especially sensitive schema migration? There is a potential timing issue to consider, thanks to an infrastructure change that eliminated downtime during deploys by using Heroku's built-in support for hot-swapping. Read more in https://github.com/fleetdm/fleet/issues/6568#issuecomment-1211503881

Wiping the production database

I hope you know what you're doing. The "easiest" kind of database schema migration:

sails_datastores__default__url='REAL_DB_URI_HERE' sails run wipe

Then when you see the sailboat, hit CTRL+C to exit. All done!