fix(backup): exclude autopass dir from backup, remove after restore
CI / Build & Test (push) Has been cancelled

- Backup: do not include autopass/ (may be in use); always include
  autopass-identity.json so sync identity is never lost
- Restore: remove autopass/ after extract so autopass can recreate from
  restored identity
- Docs: BACKUP.md, SYNC.md, ARCHITECTURE.md updated
This commit is contained in:
Raven Scott
2026-03-15 03:25:07 -04:00
parent e00028ca8e
commit cce71920e9
4 changed files with 28 additions and 12 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ Holesail Browser is composed of three parts: a browser extension, a native host
| File | Purpose |
|------|---------|
| `certificate-authority.js` | Generates a 2048-bit RSA root CA (10-year validity) using `node-forge`. Signs per-TLD wildcard domain certs on demand (1-year). Installs the CA into the OS trust store. Fingerprint-verifies to detect stale entries. |
| `backup-manager.js` | Creates/restores `tar.gz` backups of storage (state, sync data when linked) and all certificates. Quiesces sync (via `sync-manager.closeSyncForBackup`) before copy/restore so Corestore is not written to; supports create, list, restore, delete, and auto-prune by retention count. |
| `backup-manager.js` | Creates/restores `tar.gz` backups of storage (state, `autopass-identity.json` when linked; **excludes** `autopass/` directory) and all certificates. Quiesces sync before copy/restore; after restore removes `autopass/` so autopass can recreate it from the identity. Supports create, list, restore, delete, and auto-prune by retention count. |
| `sync-manager.js` | Syncs state (excluding certs) across linked devices via autopass. Handles `getSyncStatus`, `createSyncInvite`, `pairWithInvite`; pushes state on save, pulls on autopass `update` and applies via the same flow as backup restore. Exposes `closeSyncForBackup()` for backup-manager. |
| `ssh-manager.js` | Per SSH session: starts a Holesail client tunnel, spawns `ssh` with a real PTY via `tt-native` (`forkpty`), starts a `bare-ws` WebSocket server, and bridges PTY ↔ WebSocket. SSH is spawned only after the browser WebSocket client connects and sends a ready-signal. Password delivery uses `SSH_ASKPASS` + a named FIFO — public key auth is tried first; a password prompt appears in xterm.js only if key auth fails and no password is saved. |
| `rdp-manager.js` | Per RDP/VNC session: starts a Holesail client tunnel, starts a WebSocket server. VNC: transparent byte pipe. RDP: `node-rdpjs-2` client, converts bitmap updates to JSON. |
+4 -5
View File
@@ -9,16 +9,15 @@ Each backup archive contains:
| Path in archive | Source |
|-----------------|--------|
| `storage/state.json` | All virtual hosts, server tunnels (with labels), service tunnels, SSH connections (with `passwordB64`), RDP connections (with `passwordB64`), and settings |
| `storage/autopass/` | Sync data (Corestore/autopass) — included when device is linked; needed to restore sync on another machine |
| `storage/autopass-identity.json` | Sync identity (key material for the sync group) — included when linked |
| `storage/autopass-identity.json` | Sync identity (key material for the sync group) — **always included when present** so sync identity is never lost |
| `certs/ca.key.pem` | Root CA private key |
| `certs/ca.cert.pem` | Root CA certificate |
| `certs/wildcard.hole.sail/` | Wildcard cert for the default `.hole.sail` TLD |
| `certs/wildcard.<parent>/` | One directory per custom TLD parent (e.g. `wildcard.my.internal/`, `wildcard.haha.wooo/`) |
The entire `holesail-browser-certs/` directory is archived — all wildcard cert directories are included, not just the default one. The entire `holesail-browser-storage/` directory is archived except the `backups/` subdirectory (so `state.json`, `autopass/`, and `autopass-identity.json` are included when present). Backups do **not** include the binary itself, the log file, or other backup archives.
The entire `holesail-browser-certs/` directory is archived — all wildcard cert directories are included, not just the default one. The entire `holesail-browser-storage/` directory is archived except the `backups/` subdirectory and the **`autopass/`** directory. So `state.json` and `autopass-identity.json` are included when present; the `autopass/` directory (Corestore data) is **not** backed up because it may be read or written during the backup and cannot be safely copied. Autopass will recreate the corestore from the restored identity when sync is next used. Backups do **not** include the binary itself, the log file, or other backup archives.
**Sync and backup:** Creating or restoring a backup temporarily **pauses sync** (closes the Corestore so nothing is writing to `autopass/`). This ensures a consistent copy of sync data. Backup will fail if sync cannot be paused. After the backup or restore finishes, the next time you open the Sync page (or any sync operation runs), sync reconnects automatically. To sync state across devices without copying certificates, see [Device sync](SYNC.md).
**Sync and backup:** Creating or restoring a backup temporarily **pauses sync** so state and identity are not written during the copy. After restore, the `autopass/` directory is removed so autopass can recreate it from the restored identity when you next open the Sync page or use sync. To sync state across devices without copying certificates, see [Device sync](SYNC.md).
The default backup retention is **5 backups** (configurable in Settings via `backupRetention`).
@@ -49,7 +48,7 @@ holesail-backup-2026-02-28_12-00-00.tar.gz
1. Open the dashboard → **Backups**
2. Find the backup you want to restore
3. Click **Restore**
4. The native host pauses sync, extracts the archive (overwriting current state, certs, and sync data when present), then reloads state from disk. Sync reconnects the next time you open the Sync page.
4. The native host pauses sync, extracts the archive (overwriting current state, certs, and `autopass-identity.json` when present), removes any `autopass/` directory so autopass can recreate it from the identity, then reloads state from disk. Sync reconnects the next time you open the Sync page.
> After restoring a backup that contains different certificates, you may need to reinstall the root CA (dashboard → Proxy & CA → Install Root CA) and restart Chrome.
+1 -1
View File
@@ -56,7 +56,7 @@ To stop syncing, remove or rename the `autopass` directory and `autopass-identit
## Backups and sync
Backups (Dashboard → Backups) **include** sync data when linked: `autopass/` and `autopass-identity.json` are in the archive so you can restore a full snapshot (state, certs, and sync identity) on the same or another machine. Creating or restoring a backup temporarily pauses sync so the Corestore is not written to during the copy; sync reconnects automatically afterward. Use backups for full local or cross-machine snapshots; use sync for live replication across devices (state only, no certs). See [Backups](BACKUP.md).
Backups (Dashboard → Backups) **include** `autopass-identity.json` when linked (so sync identity is never lost) but **do not** include the `autopass/` directory — corestore data may be in use during backup and is recreated from the identity when sync is used after a restore. Restoring a backup removes any existing `autopass/` directory so autopass can recreate it from the restored identity. Use backups for full local or cross-machine snapshots; use sync for live replication across devices (state only, no certs). See [Backups](BACKUP.md).
## Troubleshooting