device-id

Source: device-id.js:13

The machine's identity for the per-seat device cap: a random UUID, created once and reused forever. Main-process only, like everything auth-adjacent.

On macOS it lives in the Keychain (via /usr/bin/security), which survives app deletion and app-data wipes — a reinstall keeps its slot. Anywhere the Keychain isn't available (other platforms, locked keychain) it falls back to a plain JSON file in userData; the ID is random and grants nothing by itself, so the file needs no encryption — the only cost of the fallback is that wiping app data makes the machine look new (one self-service deactivation fixes that).


Instance Methods

keychainRead(): string

Read the device ID from the macOS Keychain.

Returns

  • string — The stored ID, or null when absent or the Keychain is unavailable.

keychainWrite(id: string): boolean

Write the device ID to the macOS Keychain.

Parameters

  • id (string) — Device UUID to store.

Returns

  • boolean — True on success, false when the Keychain refused.

getDeviceId(userDataDir: string): string

Get-or-create the device ID, stable across calls. Prefers the Keychain on macOS and falls back to userData/device-id.json when the Keychain refuses, on other platforms, or when EZL_PASSWORD_STORE=basic. That env var is the existing test hook (e2e + headless CI): it opts safeStorage out of the OS keychain, and device identity follows — the throwaway test profile gets a file-backed ID, so every e2e launch is a fresh machine and tests never write to the developer's real Keychain. An unreadable or first-run file mints a fresh UUID and writes it.

Parameters

  • userDataDir (string) — Electron userData directory (app.getPath('userData')).

Returns

  • string — The device UUID.

Other

SERVICE

Keychain service name the device ID is stored under. @type {string}