UNPKG

@mui/x-telemetry

Version:
71 lines (66 loc) 2.51 kB
import fs from 'fs'; import isDocker from 'is-docker'; import os from 'os'; import { sha256 } from "./hash.mjs"; // Q: Why does MUI need a machine ID? // A: // MUI's telemetry uses a hashed machine ID to approximate unique developer counts. // Without a stable machine ID, every session in containers or CI creates a new // persona, inflating seat counts. // // Fallback chain: // 1. node-machine-id — most reliable, uses platform-specific APIs // (IOPlatformUUID on macOS, MachineGuid on Windows, /var/lib/dbus/machine-id on Linux) // 2. /etc/machine-id — present in most Linux distros and containers, // stable across container restarts (only changes on image rebuild) // 3. /var/lib/dbus/machine-id — alternative Linux path, some distros // use this instead of /etc/machine-id // 4. os.hostname() — used on macOS/Windows where hostnames are user-set and stable, // and in Docker where the hostname is the container ID (random but unique per container, // stable for the container's lifetime). Skipped on non-Docker Linux because hostnames // are often generic defaults (e.g., "localhost", "ubuntu") which would conflate // different machines into the same identity. export default async function getAnonymousMachineId() { // 1. Try node-machine-id (platform-specific, most reliable) try { const nodeMachineId = await import('node-machine-id'); const id = await nodeMachineId.machineId(true); if (id) { return sha256(id); } } catch { // Not available (e.g., sandboxed env, missing native deps) } // 2. Try /etc/machine-id (Linux, most containers) try { const id = fs.readFileSync('/etc/machine-id', 'utf-8').trim(); if (id) { return sha256(id); } } catch { // File doesn't exist (macOS, Windows, or minimal container image) } // 3. Try /var/lib/dbus/machine-id (alternative Linux path) try { const id = fs.readFileSync('/var/lib/dbus/machine-id', 'utf-8').trim(); if (id) { return sha256(id); } } catch { // File doesn't exist } // 4. Try hostname — only on macOS/Windows where it's user-set and stable. // On Linux, container runtimes assign random hostnames per run, // which would generate a different hash each session and inflate counts. if (process.platform !== 'linux' || isDocker()) { try { const hostname = os.hostname(); if (hostname) { return sha256(hostname); } } catch { // os.hostname() failed } } return null; }