mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-16 05:13:36 +00:00
1e7c9ea53c
* feat(sshid) - sshid.io equivalent for termix (#919) * feat(ssh-id): database schema, migrations and field encryption Adds ssh_identities, ssh_identity_keys and ssh_identity_ca tables (public keys stored plaintext for the unauthenticated resolver; CA private key registered for per-user field encryption), with UNIQUE(user_id), an index on ssh_identity_keys(identity_id), and idempotent CREATE TABLE migrations. * feat(ssh-id): backend API — resolver, key management, CA and certificates Mounts /sshid (nginx route added). Public text/plain authorized_keys resolver (+ exact /:algo filter, HTML viewer) and CA public-key endpoint; no-store + noindex headers on every resolver response including early 404s. Authenticated management: claim/rename/delete handle, add/import/generate/enable/delete keys, and a per-user CA (create/rotate/delete) with pure-Node OpenSSH certificate issuance. Audit logging on all mutations; UNIQUE races map to a precise 409. Unit tests for key parsing and certificate signing (ssh-keygen-validated). * feat(ssh-id): frontend panel, API client and i18n SSH ID panel wired into the app rail and AppShell: claim handle, resolver URL + curl one-liner, key list, generate, paste/import, CA enable/rotate/remove with server trust command, and per-key certificate issuance. API client re-exported through main-axios.ts; all strings i18n'd. * style(ssh-id): align panel and resolver page with Termix theme - Rebuild the SSH ID sidebar panel with the theme's square components (SectionCard / SettingRow / FakeSwitch) instead of rounded ad-hoc cards; use accent-brand and destructive tokens rather than raw red/green. - Fix panel scrolling: move overflow to a block scroll container so the cards keep their natural height instead of being clipped. - Restyle the public resolver HTML page (/sshid/u/:handle) to the Termix dark theme: square corners, #18181b/#303032 palette, #f59145 accent, uppercase section labels. - Tidy copy: 'Save To Credentials' label, drop the redundant generate intro, and correct the generate tooltip (the key is stored when saving to vault). * feat: rename to Termix ID, improve UI, backend inconsistencies, and general bug fixes --------- Co-authored-by: LukeGus <bugattiguy527@gmail.com> * ci(deps): bump actions/checkout from 6 to 7 in the github-actions group (#922) Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 6 to 7 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump the dev-patch-updates group with 11 updates (#923) Bumps the dev-patch-updates group with 11 updates: | Package | From | To | | --- | --- | --- | | [@codemirror/search](https://github.com/codemirror/search) | `6.7.0` | `6.7.1` | | [@codemirror/view](https://github.com/codemirror/view) | `6.43.0` | `6.43.1` | | [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.3.0` | `4.3.1` | | [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.1.8` | `4.1.9` | | [@vitest/ui](https://github.com/vitest-dev/vitest/tree/HEAD/packages/ui) | `4.1.8` | `4.1.9` | | [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) | `0.5.2` | `0.5.3` | | [lint-staged](https://github.com/lint-staged/lint-staged) | `17.0.7` | `17.0.8` | | [prettier](https://github.com/prettier/prettier) | `3.8.3` | `3.8.4` | | [sharp](https://github.com/lovell/sharp) | `0.35.1` | `0.35.2` | | [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.3.0` | `4.3.1` | | [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.8` | `4.1.9` | Updates `@codemirror/search` from 6.7.0 to 6.7.1 - [Changelog](https://github.com/codemirror/search/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/search/commits) Updates `@codemirror/view` from 6.43.0 to 6.43.1 - [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/view/commits) Updates `@tailwindcss/vite` from 4.3.0 to 4.3.1 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/@tailwindcss-vite) Updates `@vitest/coverage-v8` from 4.1.8 to 4.1.9 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/coverage-v8) Updates `@vitest/ui` from 4.1.8 to 4.1.9 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/ui) Updates `eslint-plugin-react-refresh` from 0.5.2 to 0.5.3 - [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases) - [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md) - [Commits](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/compare/v0.5.2...v0.5.3) Updates `lint-staged` from 17.0.7 to 17.0.8 - [Release notes](https://github.com/lint-staged/lint-staged/releases) - [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md) - [Commits](https://github.com/lint-staged/lint-staged/compare/v17.0.7...v17.0.8) Updates `prettier` from 3.8.3 to 3.8.4 - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.8.3...3.8.4) Updates `sharp` from 0.35.1 to 0.35.2 - [Release notes](https://github.com/lovell/sharp/releases) - [Commits](https://github.com/lovell/sharp/compare/v0.35.1...v0.35.2) Updates `tailwindcss` from 4.3.0 to 4.3.1 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/tailwindcss) Updates `vitest` from 4.1.8 to 4.1.9 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/vitest) --- updated-dependencies: - dependency-name: "@codemirror/search" dependency-version: 6.7.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@codemirror/view" dependency-version: 6.43.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@tailwindcss/vite" dependency-version: 4.3.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@vitest/coverage-v8" dependency-version: 4.1.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@vitest/ui" dependency-version: 4.1.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: eslint-plugin-react-refresh dependency-version: 0.5.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: lint-staged dependency-version: 17.0.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: prettier dependency-version: 3.8.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: sharp dependency-version: 0.35.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: tailwindcss dependency-version: 4.3.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: vitest dependency-version: 4.1.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump nanoid in the prod-patch-updates group (#925) Bumps the prod-patch-updates group with 1 update: [nanoid](https://github.com/ai/nanoid). Updates `nanoid` from 5.1.11 to 5.1.15 - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/5.1.11...5.1.15) --- updated-dependencies: - dependency-name: nanoid dependency-version: 5.1.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the major-updates group with 5 updates (#926) Bumps the major-updates group with 5 updates: | Package | From | To | | --- | --- | --- | | [js-yaml](https://github.com/nodeca/js-yaml) | `4.2.0` | `5.0.0` | | [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.39.4` | `10.0.1` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.2` | `26.0.0` | | [concurrently](https://github.com/open-cli-tools/concurrently) | `9.2.1` | `10.0.3` | | [eslint](https://github.com/eslint/eslint) | `9.39.4` | `10.5.0` | Updates `js-yaml` from 4.2.0 to 5.0.0 - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/4.2.0...5.0.0) Updates `@eslint/js` from 9.39.4 to 10.0.1 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/commits/v10.0.1/packages/js) Updates `@types/node` from 25.9.2 to 26.0.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `concurrently` from 9.2.1 to 10.0.3 - [Release notes](https://github.com/open-cli-tools/concurrently/releases) - [Commits](https://github.com/open-cli-tools/concurrently/compare/v9.2.1...v10.0.3) Updates `eslint` from 9.39.4 to 10.5.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v9.39.4...v10.5.0) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: major-updates - dependency-name: "@eslint/js" dependency-version: 10.0.1 dependency-type: direct:development update-type: version-update:semver-major dependency-group: major-updates - dependency-name: "@types/node" dependency-version: 26.0.0 dependency-type: direct:development update-type: version-update:semver-major dependency-group: major-updates - dependency-name: concurrently dependency-version: 10.0.3 dependency-type: direct:development update-type: version-update:semver-major dependency-group: major-updates - dependency-name: eslint dependency-version: 10.5.0 dependency-type: direct:development update-type: version-update:semver-major dependency-group: major-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(ssh): add HashiCorp Vault SSH signer authentication * fix: small fixes to vault feature to align with Termix codebase * chore: add view docs links for vault/termix id * fix: file upload fails with 400 and missing schema migrations on upgrade (#929) Two bugs introduced in v2.4.1: 1. uploadFileStream uses fileManagerApi.post() which triggers axios's transformRequest to JSON-serialize the FormData because the instance default Content-Type is application/json. Change to postForm() which sets Content-Type: multipart/form-data so the browser XHR sends the correct multipart body with boundary. 2. Two schema items added to schema.ts were not included in migrateSchema() in db/index.ts, causing 500 errors on existing installations upgrading from v2.4.0: - user_preferences.status_color_scheme (no such column) - dashboard_service_links table (no such table) Fixes #928 Co-authored-by: sash <sash@fominykh.io> * fix: support PuTTY PPK ssh keys (#930) * fix: chunk large file manager uploads (#932) * fix: route dashboard hosts by protocol (#934) * fix: resolve tunnel endpoints reliably (#935) * Fix Electron OIDC browser auth failures (#936) * Allow RDP connections without stored credentials (#937) * Sync role credential shares for OIDC users (#938) * Fix terminal link dialog layering (#940) * Confirm large files before opening editor (#942) * Confirm closing active host connections (#943) * Preserve file path case in file manager UI (#941) * fix: preserve unicode guacamole tokens (#933) * Persist VNC authentication settings (#944) * Fix Guacamole websocket base path (#946) * Promote file manager terminals to tabs (#939) * Guard Guacamole disconnect during startup (#945) * chore: increment ver * feat: bitwarden ssh agent integration * feat: serial connections support * fix: various small bug fixes * feat: open all sessions in a folder and terminal custom theme color support * feat: cross host file manager clipboard and several small bug fixes * feat: tailscale/wireguard support and added a new status state for when backend is checking status * feat: grafana like server stats history, new alert system, ntfy/webhook support * feat: new grid and widget based homepage function * feat: new donate button in dashboard * fix: alert ui incorrectly using termix css and fixed issue with alert system not loading * chore: start database layer refactor * docs: plan database layer refactor * docs: audit database layer refactor phase zero * chore: add database runtime adapter skeleton * chore: add settings repository skeleton * chore: add user session repository skeleton * chore: add host credential repository skeleton * chore: add field encryption boundary * chore: migrate settings route slice * chore: migrate user settings routes * chore: migrate host metrics settings routes * chore: migrate acme settings route * chore: migrate terminal settings route * chore: migrate tailscale settings read * chore: migrate guacamole settings reads * chore: migrate session timeout settings reads * chore: migrate auth route settings reads * chore: migrate host metrics settings reads * chore: migrate startup settings reads * chore: migrate user settings cleanup * chore: migrate password reset settings * chore: migrate oidc legacy settings read * chore: migrate user route settings slice * chore: migrate oidc state settings * chore: migrate user login settings reads * chore: migrate user crypto settings * chore: consolidate startup settings defaults * chore: consolidate database settings import export * chore: migrate core session auth paths * chore: migrate remaining session auth paths * chore: migrate admin user routes * chore: migrate user route admin checks * chore: migrate user lifecycle routes * chore: migrate auth user lookups * chore: migrate oidc user routes * chore: migrate api key repository paths * docs: add database gray rollout guide * chore: migrate trusted device paths * chore: migrate user session route user lookups * chore: add database repository rollout guard * chore: expose repository rollout status * chore: warn on repository rollout misconfiguration * chore: migrate remaining user lookup helpers * chore: migrate ssh user lookups * chore: migrate user settings admin lookups * chore: migrate acme ssl user lookups * chore: migrate audit log admin checks * chore: migrate oidc account user updates * chore: migrate password reset user updates * chore: migrate user deletion core records * chore: migrate snippet audit user lookups * chore: migrate ldap user sync paths * chore: migrate totp user updates * chore: migrate rbac user checks * chore: migrate rbac role paths * chore: migrate permission role lookups * chore: migrate rbac access list reads * chore: migrate shared rbac reads * chore: migrate rbac access writes * chore: migrate permission host access * chore: migrate role host access lookup * chore: migrate snippet access lookup * chore: migrate shared credential access lookups * chore: migrate host access cleanup writes * chore: migrate host list access checks * chore: migrate host access cleanup routes * chore: migrate shared credential role lookups * chore: migrate user role cleanup * chore: migrate admin role sync * chore: migrate ldap role sync * chore: migrate user role assignment * chore: migrate sso provider access * chore: migrate audit log access * chore: migrate user preference access * chore: migrate open tab access * chore: migrate dismissed alert access * chore: migrate homepage layout access * chore: migrate network topology access * chore: migrate dashboard service link access * chore: migrate command history access * chore: migrate recent activity cleanup * chore: migrate ssh credential usage access * chore: migrate transfer recent access * chore: migrate file manager bookmark access * chore: migrate c2s tunnel preset access * chore: migrate homepage item access * chore: migrate session recording access * chore: migrate tmux session tag access * chore: migrate opkssh token access * chore: migrate vault token access * chore: migrate vault profile access * chore: migrate host metrics preference access * chore: migrate host health access * chore: migrate host metrics history access * chore: migrate alert persistence access * chore: route alert host lookup through repository * chore: migrate user data export reads * chore: route host metrics stats sync through repository * chore: migrate host folder persistence * chore: migrate host resolution reads * chore: route jump host resolution reads * chore: route docker console jump host reads * chore: route docker ssh resolution reads * chore: route proxmox discovery resolution reads * chore: route file manager activity host reads * chore: route host metrics resolution reads * chore: route ssh auth credential reads * chore: route tunnel endpoint credential reads * chore: route credential deployment resolution reads * chore: route command history host flag reads * chore: route snippet execution resolution reads * chore: route terminal host resolution reads * chore: route vault oidc host resolution reads * chore: route wake on lan host reads * chore: route internal host list reads * chore: route host key verification persistence * chore: route credential read paths * chore: route credential host usage reads * chore: route credential folder rename * chore: route host owner access checks * chore: route shared credential source reads * chore: route user host credential cleanup * chore: route credential delete reads * chore: route credential update reads * chore: route host credential reads * chore: route host read paths * chore: route host projection reads * chore: route host list reads * chore: route snippet read paths * chore: route snippet folder writes * chore: route snippet crud paths * chore: route snippet bulk import * chore: route rbac ownership reads * chore: route user count reads * chore: route cleanup snippets folders * chore: route shared credential persistence * chore: route dashboard activity * chore: route guacamole host reads * chore: route host bulk lookups * chore: remove unlock-only simple db ops * chore: route host autostart persistence * chore: route ldap provisioning through users * chore: route credential encrypted writes * chore: route host encrypted writes * chore: route bulk host encrypted writes * chore: route termix id credentials * chore: route termix id ca persistence * chore: route termix identity persistence * chore: route credential system migration * chore: isolate user encryption migration storage * chore: remove legacy simple db ops * chore: isolate legacy sqlite migration copy * chore: route database settings import export * chore: route database host credential export * chore: route database host credential import * chore: route database file-manager import export * chore: route database alert usage import export * chore: route database user checks * chore: isolate auth lazy migration storage * chore: route explicit database saves * chore: initialize database save boundary * chore: route migration snapshot saves * chore: isolate sqlite import constraints * chore: route import sqlite boundary * chore: route user encryption migration store * chore: centralize current repository runtime * chore: route more current repositories * chore: route activity repository runtimes * chore: route token repository runtimes * chore: route health repository runtimes * chore: route identity repository runtimes * chore: route rbac repository runtime * chore: centralize current sqlite runtime access * chore: route user deletion key cleanup * chore: route user deletion vault cleanup * chore: route user deletion homepage cleanup * chore: route user deletion health cleanup * chore: route user deletion alert cleanup * chore: route user deletion identity cleanup * chore: add database layer preupgrade backup * Fix database repository type errors * fix: complete post-merge compile fixes for database refactor Restore missing DatabaseSaveTrigger/getDb imports, session log format fallback, OIDC provider resolution, guacamole recording insert, and passwordFallbackOnly typing after merging current dev. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: DivByZero <mr.oplus@yahoo.fr> Co-authored-by: LukeGus <bugattiguy527@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: devdanetra <46488477+devdanetra@users.noreply.github.com> Co-authored-by: Aleksandr Fominykh <neoformalex@users.noreply.github.com> Co-authored-by: sash <sash@fominykh.io>
448 lines
34 KiB
Markdown
448 lines
34 KiB
Markdown
# Database Layer Gray Rollout Guide
|
|
|
|
Status: Draft branch gray-rollout guide
|
|
Branch: `feature/database-layer-refactor`
|
|
Scope: repository-boundary migration for current SQLite snapshot runtime
|
|
|
|
This branch is not the full multi-database refactor. Gray rollout is only for
|
|
the already-migrated repository boundary paths while the production runtime still
|
|
uses the existing encrypted SQLite snapshot model.
|
|
|
|
## 1. Gray Scope
|
|
|
|
Allowed in gray rollout:
|
|
|
|
- Existing encrypted SQLite snapshot runtime.
|
|
- Existing database file format.
|
|
- Existing schema and migration flow.
|
|
- Settings, user, host, API key, session, trusted device, audit log, user
|
|
preference, open tab, dismissed alert, homepage layout/item, and network
|
|
topology, dashboard service link, session recording, command history, recent
|
|
activity, transfer recent, and file-manager bookmark current repository
|
|
plus C2S tunnel preset, tmux session tag, OPKSSH token, Vault token/profile,
|
|
SSH credential usage, role, SSO provider, host folder, alert, host health,
|
|
host metrics preference/history, credential, host resolution, snippet,
|
|
RBAC access, shared credential, Termix ID identity/CA, and user data export
|
|
current repository factories share `current-repository-runtime` for SQLite
|
|
context and write-save hooks.
|
|
- Settings reads and writes migrated behind `SettingsRepository`.
|
|
- Database import/export settings reads and admin upserts migrated behind
|
|
`SettingsRepository`.
|
|
- Session create/read/update/revoke/list paths migrated behind
|
|
`SessionRepository`.
|
|
- User create/read/update/delete/auth paths migrated behind `UserRepository`.
|
|
- User setup/count/db-health, password-login TOTP guard, and last-admin delete
|
|
guard reads migrated behind `UserRepository`.
|
|
- Database import/export user unlock/admin checks migrated behind
|
|
`UserRepository`.
|
|
- LDAP first-user provisioning and admin-group user creation migrated behind
|
|
`UserRepository`.
|
|
- API key create/list/delete and authentication last-used updates migrated behind
|
|
`ApiKeyRepository`.
|
|
- Trusted device check/add/remove and TOTP trusted-device cleanup migrated
|
|
behind `TrustedDeviceRepository`.
|
|
- Credential list, folder list, detail reads, update lookup/readback, host route
|
|
credential resolution reads, folder rename writes, apply usage writes, shared
|
|
credential source row reads, credential delete lookup/delete, and
|
|
credential-host list reads migrated behind `CredentialRepository` and
|
|
`HostResolutionRepository`.
|
|
- Database export host and credential read/decryption paths migrated behind
|
|
`HostRepository` and `CredentialRepository`.
|
|
- Database import host and credential duplicate checks plus encrypted creates
|
|
migrated behind `HostRepository` and `CredentialRepository`.
|
|
- Credential create/update encrypted writes migrated behind
|
|
`CredentialRepository`, including system-key copies for shared credentials.
|
|
- Credential delete host cleanup and apply-to-host writes migrated behind
|
|
`HostRepository`.
|
|
- Credential system-key copy backfill migration migrated behind
|
|
`CredentialRepository` and `SharedCredentialRepository`.
|
|
- Legacy user field-encryption migration SQL centralized behind
|
|
`RawSqliteUserEncryptionMigrationStore`.
|
|
- Auth login lazy user-field encryption migration now calls the `DataCrypto`
|
|
current-runtime migration boundary instead of opening SQLite in
|
|
`auth-manager.ts`.
|
|
- Current user-field encryption migration now resolves SQLite through
|
|
`createCurrentUserEncryptionMigrationStore` and the shared current runtime
|
|
helper, keeping `DataCrypto` on the migration-store interface.
|
|
- User, admin, TOTP, OIDC account, and credential migration explicit saves now
|
|
use `DatabaseSaveTrigger` instead of importing the SQLite snapshot save
|
|
function from routes.
|
|
- Current SQLite snapshot save trigger now initializes after database startup
|
|
regardless of file-encryption mode, and backend shutdown uses that save
|
|
boundary.
|
|
- Direct SQLite snapshot save-function imports are now isolated inside
|
|
`database/db/index.ts`; current user-field migration saves through
|
|
`DatabaseSaveTrigger`.
|
|
- Database import SQLite foreign-key toggling is isolated behind the
|
|
`withSqliteForeignKeysDisabled` runtime boundary and restores constraints in
|
|
a `finally` path; the current variant resolves SQLite through the shared
|
|
current runtime helper.
|
|
- Database import now uses the current SQLite foreign-key boundary without
|
|
importing `getDb()` in the route handler.
|
|
- Legacy unencrypted SQLite copy/verification path centralized behind
|
|
`LegacySqliteDatabaseCopyStore`.
|
|
- Termix ID credential lookup, generated credential persistence, and generated
|
|
credential cleanup migrated behind `CredentialRepository`.
|
|
- Host route update readback, single-host fetch, password-field fetch, and host
|
|
export reads migrated behind `HostResolutionRepository`.
|
|
- Host route create/update encrypted writes migrated behind `HostRepository`.
|
|
- Host route update-state and delete-audit host reads migrated behind
|
|
`HostResolutionRepository`.
|
|
- Host route delete final host-row writes and audit actor username lookups
|
|
migrated behind `HostRepository` and `UserRepository`.
|
|
- Host route own/shared list assembly reads migrated behind
|
|
`HostResolutionRepository` while preserving route-level own-host decryption.
|
|
- Host bulk-update state reads and non-sensitive bulk flag/config writes
|
|
migrated behind `HostRepository`.
|
|
- Host bulk import overwrite lookup and credential fallback reads migrated behind
|
|
current host resolution and credential repository boundaries.
|
|
- Host bulk JSON and SSH-config import encrypted create/update writes migrated
|
|
behind `HostRepository`.
|
|
- Host autostart enable, disable, status, and endpoint-host resolution paths
|
|
migrated behind `HostRepository`.
|
|
- Guacamole host token host and protocol credential reads migrated behind
|
|
`HostResolutionRepository`.
|
|
- Host user-cleanup delete paths migrated behind `HostRepository`.
|
|
- Snippet folder list/create/metadata/rename/delete, owned lookup, visible-list
|
|
owned reads, reorder, create/update/delete, export reads, and bulk import
|
|
plus user/password-reset cleanup migrated behind `SnippetRepository`.
|
|
- Host folder metadata user cleanup migrated behind `HostFolderRepository`.
|
|
- SSO provider listing, management, OIDC config loading, and LDAP provider
|
|
validation migrated behind `SsoProviderRepository`.
|
|
- Audit log writes, filtered reads, action lists, and user cleanup migrated
|
|
behind `AuditLogRepository`.
|
|
- User preferences read/write and user cleanup migrated behind
|
|
`UserPreferenceRepository`.
|
|
- Open tab restore/upsert/sync/update/delete and user cleanup migrated behind
|
|
`OpenTabRepository`.
|
|
- Dismissed alert read/dismiss/undismiss/export and user cleanup migrated behind
|
|
`DismissedAlertRepository`.
|
|
- Database import/export dismissed alert reads and writes migrated behind
|
|
`DismissedAlertRepository`.
|
|
- Homepage layout read/write paths migrated behind
|
|
`HomepageLayoutRepository`.
|
|
- Homepage item list/create/update/delete migrated behind
|
|
`HomepageItemRepository`.
|
|
- Network topology read/write and user cleanup migrated behind
|
|
`NetworkTopologyRepository`.
|
|
- Dashboard service link list/create/update/delete migrated behind
|
|
`DashboardServiceLinkRepository`.
|
|
- Session recording create/list/read/content/delete/prune and host/folder/user
|
|
cleanup migrated behind `SessionRecordingRepository`.
|
|
- Command history save/list/delete and host/user cleanup migrated behind
|
|
`CommandHistoryRepository`.
|
|
- Dashboard recent activity list/log/trim/reset and host/user cleanup migrated
|
|
behind `RecentActivityRepository`.
|
|
- SSH credential usage writes and host/user cleanup migrated behind
|
|
`SshCredentialUsageRepository`.
|
|
- Database export SSH credential usage reads migrated behind
|
|
`SshCredentialUsageRepository`.
|
|
- Transfer recent list/upsert/prune/export and host/folder/user cleanup migrated
|
|
behind `TransferRecentRepository`.
|
|
- File manager recent/pinned/shortcut list/create/delete/export and
|
|
host/folder/user/password-reset cleanup migrated behind
|
|
`FileManagerBookmarkRepository`.
|
|
- Database import/export file-manager recent/pinned/shortcut target reads and
|
|
writes migrated behind `FileManagerBookmarkRepository`.
|
|
- C2S tunnel preset list/create/update/delete migrated behind
|
|
`C2sTunnelPresetRepository`.
|
|
- Tmux session tag list/rename/delete/replace migrated behind
|
|
`TmuxSessionTagRepository`.
|
|
- OPKSSH token upsert/read/touch/delete and user cleanup migrated behind
|
|
`OpksshTokenRepository`.
|
|
- Vault token upsert/read/touch/delete migrated behind `VaultTokenRepository`.
|
|
- Vault profile list/create/update/delete and profile lookup migrated behind
|
|
`VaultProfileRepository`.
|
|
- Host metrics layout preference read/upsert and statsConfig widget sync migrated behind
|
|
`HostMetricsPreferenceRepository`.
|
|
- Host health check config and history read/write migrated behind
|
|
`HostHealthRepository`.
|
|
- Host metrics history record/prune/query migrated behind
|
|
`HostMetricsHistoryRepository`.
|
|
- Alert notification channels, rules, linked channels, firings, and alert
|
|
engine persistence reads/writes migrated behind `AlertRepository`.
|
|
- User data export host and credential read models migrated behind
|
|
`UserDataExportRepository`.
|
|
- SSH folder list, metadata upsert, rename, and folder host deletion writes
|
|
migrated behind `HostFolderRepository`.
|
|
- Host, jump-host, Docker SSH, Proxmox discovery, Docker console jump-host,
|
|
file-manager activity, host metrics, terminal SSH auth, and tunnel endpoint
|
|
credential plus credential deployment and command history host-flag resolution
|
|
plus snippet execution, terminal OPKSSH/activity, Vault OIDC profile, and
|
|
Wake-on-LAN host, internal host list, host-key verification metadata,
|
|
credential, permission-manager owner checks, and shared override read/write
|
|
models migrated behind `HostResolutionRepository`.
|
|
- Host metrics, host metrics viewer, tmux monitor, Docker, tunnel, and Proxmox
|
|
unlock gates now use `DataCrypto` directly instead of `SimpleDBOps`.
|
|
- Legacy `SimpleDBOps` compatibility helper removed after migrated route and
|
|
utility paths stopped importing it.
|
|
- RBAC role management and user-role assignment/listing paths migrated behind
|
|
`RoleRepository`.
|
|
- Permission manager role permission aggregation and admin-role checks migrated
|
|
behind `RoleRepository`.
|
|
- User deletion role-assignment cleanup migrated behind `RoleRepository`.
|
|
- User deletion API key, trusted device, dashboard link, homepage layout/item,
|
|
host health, host metrics preference, C2S preset, Vault token/profile, audit,
|
|
alert, Termix ID identity/CA, tmux session tag, encrypted-data, UI state, and
|
|
related per-user cleanup now uses current repository boundaries before the
|
|
final user row delete.
|
|
- User admin route role sync and admin-created default role assignment migrated
|
|
behind `RoleRepository`.
|
|
- LDAP login default role assignment and admin-role sync migrated behind
|
|
`RoleRepository`.
|
|
- Local, GitHub OIDC, and standard OIDC user default role assignment plus OIDC
|
|
admin-group role sync migrated behind `RoleRepository`.
|
|
- RBAC host/snippet access-list read models migrated behind
|
|
`RbacAccessRepository`.
|
|
- RBAC shared host/shared snippet read models migrated behind
|
|
`RbacAccessRepository`.
|
|
- RBAC route host/snippet owner checks and direct host-access credential
|
|
existence reads migrated behind current host, snippet, and credential
|
|
repository boundaries.
|
|
- RBAC host/snippet access grant, revoke, and direct host-access credential
|
|
override writes migrated behind `RbacAccessRepository`.
|
|
- Shared credential material create/update/delete, pending re-encryption, and
|
|
user cleanup persistence migrated behind `SharedCredentialRepository`.
|
|
- Permission manager host-access cleanup, shared-access lookup, and last-access
|
|
touch migrated behind `RbacAccessRepository`.
|
|
- Termix ID identity handle CRUD/resolution, public key publish/list/update/delete,
|
|
linked credential lookup, and certificate target key lookup migrated behind
|
|
`TermixIdentityRepository`.
|
|
- Termix ID CA public lookup, encrypted private-key create/rotate/delete, and
|
|
certificate signing reads migrated behind `TermixIdentityCaRepository`.
|
|
- Current field encryption behavior.
|
|
|
|
Not included in gray rollout:
|
|
|
|
- PostgreSQL or MySQL/MariaDB runtime.
|
|
- New external database configuration UI.
|
|
- New schema migration strategy.
|
|
- Host and credential route migration beyond existing repository skeletons.
|
|
- Remaining audit, preferences, file manager, and metrics repository migration.
|
|
- Multi-instance backend deployment.
|
|
|
|
## 2. Required Preflight
|
|
|
|
Before enabling this branch for any gray target:
|
|
|
|
1. Confirm the target is running from a full backup of the data directory.
|
|
2. Confirm the app can write to the data directory so the automatic
|
|
pre-upgrade backup can be created before first database startup.
|
|
3. Record the exact source commit and container/image tag currently serving
|
|
traffic.
|
|
4. Confirm the gray build commit is known.
|
|
5. Run the validation commands from this branch.
|
|
6. Use a target with a small, known user set first.
|
|
7. Keep an operator available for rollback during the first login/API-key smoke
|
|
tests.
|
|
|
|
Repository rollout is controlled by `DATABASE_LAYER_REPOSITORY_ROLLOUT`.
|
|
|
|
Recommended gray value:
|
|
|
|
```bash
|
|
DATABASE_LAYER_REPOSITORY_ROLLOUT=settings,users,sessions,api_keys,trusted_devices,credentials,termix_identity,termix_identity_ca,hosts,snippets,sso_providers,audit_logs,user_preferences,open_tabs,dismissed_alerts,homepage_layouts,homepage_items,network_topology,dashboard_service_links,session_recordings,command_history,recent_activity,ssh_credential_usage,transfer_recent,file_manager_bookmarks,c2s_tunnel_presets,tmux_session_tags,opkssh_tokens,vault_tokens,vault_profiles,host_metrics_preferences,host_health,host_metrics_history,alerts,user_data_exports,host_folders,host_resolution,roles,rbac_access,shared_credentials
|
|
```
|
|
|
|
Accepted values:
|
|
|
|
| Value | Behavior |
|
|
| ------------------------------------------- | --------------------------------------------- |
|
|
| unset | current migrated slice enabled; logs implicit |
|
|
| `all`, `true`, `1`, `on`, `enabled` | all current migrated repository domains |
|
|
| `off`, `false`, `0`, `none`, `disabled` | no migrated repository domains; fail closed |
|
|
| comma list, for example `settings,users` | only listed repository domains enabled |
|
|
| aliases such as `user`, `api-key`, `apikey` | normalized to the supported domain names |
|
|
|
|
Supported domains:
|
|
|
|
- `settings`
|
|
- `users`
|
|
- `sessions`
|
|
- `api_keys`
|
|
- `trusted_devices`
|
|
- `credentials`
|
|
- `termix_identity`
|
|
- `termix_identity_ca`
|
|
- `hosts`
|
|
- `snippets`
|
|
- `sso_providers`
|
|
- `audit_logs`
|
|
- `user_preferences`
|
|
- `open_tabs`
|
|
- `dismissed_alerts`
|
|
- `homepage_layouts`
|
|
- `homepage_items`
|
|
- `network_topology`
|
|
- `dashboard_service_links`
|
|
- `session_recordings`
|
|
- `command_history`
|
|
- `recent_activity`
|
|
- `ssh_credential_usage`
|
|
- `transfer_recent`
|
|
- `file_manager_bookmarks`
|
|
- `c2s_tunnel_presets`
|
|
- `tmux_session_tags`
|
|
- `opkssh_tokens`
|
|
- `vault_tokens`
|
|
- `vault_profiles`
|
|
- `host_metrics_preferences`
|
|
- `host_health`
|
|
- `host_metrics_history`
|
|
- `alerts`
|
|
- `user_data_exports`
|
|
- `host_folders`
|
|
- `host_resolution`
|
|
- `roles`
|
|
- `rbac_access`
|
|
- `shared_credentials`
|
|
|
|
The backend logs the parsed rollout mode at startup with operation
|
|
`repository_rollout_config`. Use an explicit value in any staging or production
|
|
gray target so logs show the intended rollout state.
|
|
|
|
Admin users can also verify the active rollout state through
|
|
`GET /database/migration/status`. The response includes `repositoryRollout`
|
|
with the parsed mode, enabled domains, supported domains, env key, and whether
|
|
the value was explicitly configured. Startup logs and this endpoint also expose
|
|
rollout warnings for implicit, disabled, or partial configurations.
|
|
|
|
Minimum backup artifacts:
|
|
|
|
- encrypted SQLite snapshot file
|
|
- environment configuration
|
|
- application version or image tag
|
|
- logs from the last healthy startup on the previous version
|
|
|
|
This branch also creates one automatic pre-upgrade backup before opening the
|
|
database for the first time. If `db.sqlite.encrypted`, `db.sqlite.encrypted.meta`,
|
|
or `db.sqlite` exists and `.database-layer-preupgrade-backup.json` is absent, the
|
|
backend copies the database file(s) plus `.env` into:
|
|
|
|
```text
|
|
<DATA_DIR>/backups/pre-database-layer-refactor-<timestamp>/
|
|
```
|
|
|
|
The backup directory and marker both include a `manifest.json` payload with the
|
|
app version, rollout config, source files, copied files, and backup reason. A
|
|
successful marker prevents repeat backups on every restart. If the backup cannot
|
|
be created, startup fails closed. Operators may bypass only when an external
|
|
backup has already been verified:
|
|
|
|
```bash
|
|
DATABASE_LAYER_SKIP_PREUPGRADE_BACKUP=1
|
|
```
|
|
|
|
The app keeps the latest three automatic pre-upgrade backups by default. Override
|
|
with `DATABASE_LAYER_PREUPGRADE_BACKUP_KEEP=<count>`.
|
|
|
|
## 3. Required Validation Commands
|
|
|
|
Run before deployment:
|
|
|
|
```bash
|
|
npm run type-check
|
|
npx eslint src/backend/database/repositories/repository-rollout.ts src/backend/database/repositories/repository-rollout.test.ts src/backend/database/repositories/current-settings-repository.ts src/backend/database/repositories/current-user-repository.ts src/backend/database/repositories/current-session-repository.ts src/backend/database/repositories/current-api-key-repository.ts src/backend/database/repositories/current-trusted-device-repository.ts src/backend/database/repositories/current-credential-repository.ts src/backend/database/repositories/credential-repository.ts src/backend/database/repositories/current-host-repository.ts src/backend/database/repositories/host-repository.ts src/backend/database/repositories/host-credential-repositories.test.ts src/backend/database/repositories/current-sso-provider-repository.ts src/backend/database/repositories/sso-provider-repository.ts src/backend/database/repositories/sso-provider-repository.test.ts src/backend/database/repositories/current-audit-log-repository.ts src/backend/database/repositories/audit-log-repository.ts src/backend/database/repositories/audit-log-repository.test.ts src/backend/database/repositories/current-user-preference-repository.ts src/backend/database/repositories/user-preference-repository.ts src/backend/database/repositories/user-preference-repository.test.ts src/backend/database/repositories/current-open-tab-repository.ts src/backend/database/repositories/open-tab-repository.ts src/backend/database/repositories/open-tab-repository.test.ts src/backend/database/repositories/current-dismissed-alert-repository.ts src/backend/database/repositories/dismissed-alert-repository.ts src/backend/database/repositories/dismissed-alert-repository.test.ts src/backend/database/repositories/current-homepage-layout-repository.ts src/backend/database/repositories/homepage-layout-repository.ts src/backend/database/repositories/homepage-layout-repository.test.ts src/backend/database/repositories/current-homepage-item-repository.ts src/backend/database/repositories/homepage-item-repository.ts src/backend/database/repositories/homepage-item-repository.test.ts src/backend/database/repositories/current-network-topology-repository.ts src/backend/database/repositories/network-topology-repository.ts src/backend/database/repositories/network-topology-repository.test.ts src/backend/database/repositories/current-dashboard-service-link-repository.ts src/backend/database/repositories/dashboard-service-link-repository.ts src/backend/database/repositories/dashboard-service-link-repository.test.ts src/backend/database/repositories/current-session-recording-repository.ts src/backend/database/repositories/session-recording-repository.ts src/backend/database/repositories/session-recording-repository.test.ts src/backend/database/repositories/current-command-history-repository.ts src/backend/database/repositories/command-history-repository.ts src/backend/database/repositories/command-history-repository.test.ts src/backend/database/repositories/current-recent-activity-repository.ts src/backend/database/repositories/recent-activity-repository.ts src/backend/database/repositories/recent-activity-repository.test.ts src/backend/database/repositories/current-ssh-credential-usage-repository.ts src/backend/database/repositories/ssh-credential-usage-repository.ts src/backend/database/repositories/ssh-credential-usage-repository.test.ts src/backend/database/repositories/current-transfer-recent-repository.ts src/backend/database/repositories/transfer-recent-repository.ts src/backend/database/repositories/transfer-recent-repository.test.ts src/backend/database/repositories/current-file-manager-bookmark-repository.ts src/backend/database/repositories/file-manager-bookmark-repository.ts src/backend/database/repositories/file-manager-bookmark-repository.test.ts src/backend/database/repositories/current-c2s-tunnel-preset-repository.ts src/backend/database/repositories/c2s-tunnel-preset-repository.ts src/backend/database/repositories/c2s-tunnel-preset-repository.test.ts src/backend/database/repositories/current-tmux-session-tag-repository.ts src/backend/database/repositories/tmux-session-tag-repository.ts src/backend/database/repositories/tmux-session-tag-repository.test.ts src/backend/database/repositories/current-opkssh-token-repository.ts src/backend/database/repositories/opkssh-token-repository.ts src/backend/database/repositories/opkssh-token-repository.test.ts src/backend/database/repositories/current-vault-token-repository.ts src/backend/database/repositories/vault-token-repository.ts src/backend/database/repositories/vault-token-repository.test.ts src/backend/database/repositories/current-vault-profile-repository.ts src/backend/database/repositories/vault-profile-repository.ts src/backend/database/repositories/vault-profile-repository.test.ts src/backend/database/repositories/current-host-metrics-preference-repository.ts src/backend/database/repositories/host-metrics-preference-repository.ts src/backend/database/repositories/host-metrics-preference-repository.test.ts src/backend/database/repositories/current-host-health-repository.ts src/backend/database/repositories/host-health-repository.ts src/backend/database/repositories/host-health-repository.test.ts src/backend/database/repositories/current-host-metrics-history-repository.ts src/backend/database/repositories/host-metrics-history-repository.ts src/backend/database/repositories/host-metrics-history-repository.test.ts src/backend/database/repositories/current-alert-repository.ts src/backend/database/repositories/alert-repository.ts src/backend/database/repositories/alert-repository.test.ts src/backend/database/repositories/current-user-data-export-repository.ts src/backend/database/repositories/user-data-export-repository.ts src/backend/database/repositories/user-data-export-repository.test.ts src/backend/database/repositories/current-host-folder-repository.ts src/backend/database/repositories/host-folder-repository.ts src/backend/database/repositories/host-folder-repository.test.ts src/backend/database/repositories/current-host-resolution-repository.ts src/backend/database/repositories/host-resolution-repository.ts src/backend/database/repositories/host-resolution-repository.test.ts src/backend/database/repositories/current-snippet-repository.ts src/backend/database/repositories/snippet-repository.ts src/backend/database/repositories/snippet-repository.test.ts src/backend/database/repositories/current-role-repository.ts src/backend/database/repositories/role-repository.ts src/backend/database/repositories/role-repository.test.ts src/backend/database/repositories/current-rbac-access-repository.ts src/backend/database/repositories/rbac-access-repository.ts src/backend/database/repositories/rbac-access-repository.test.ts src/backend/database/routes/rbac.ts src/backend/database/routes/snippets.ts src/backend/database/routes/host.ts src/backend/database/routes/credentials.ts src/backend/database/routes/delete-user-data.ts src/backend/database/routes/open-tabs.ts src/backend/database/routes/user-preferences.ts src/backend/database/routes/user-admin-routes.ts src/backend/database/routes/ldap-auth-routes.ts src/backend/database/routes/users.ts src/backend/database/routes/user-oidc-utils.ts src/backend/database/routes/sso-provider-routes.ts src/backend/database/routes/audit-log-routes.ts src/backend/database/routes/host-folder-routes.ts src/backend/database/routes/host-file-manager-bookmark-routes.ts src/backend/database/routes/c2s-tunnel-presets.ts src/backend/database/routes/alerts.ts src/backend/database/routes/alert-rules-routes.ts src/backend/database/routes/homepage-layout-routes.ts src/backend/database/routes/homepage-items-routes.ts src/backend/database/routes/network-topology.ts src/backend/database/routes/dashboard-service-links-routes.ts src/backend/database/routes/session-log-routes.ts src/backend/database/routes/host-command-history-routes.ts src/backend/database/routes/terminal.ts src/backend/database/routes/user-password-reset-routes.ts src/backend/ssh/terminal-session-manager.ts src/backend/ssh/tmux-monitor.ts src/backend/ssh/opkssh-auth.ts src/backend/ssh/vault-signer-auth.ts src/backend/ssh/vault-oidc-auth.ts src/backend/ssh/host-resolver.ts src/backend/ssh/host-metrics-preferences-routes.ts src/backend/ssh/managers/health.ts src/backend/ssh/host-metrics.ts src/backend/ssh/host-metrics-history-routes.ts src/backend/ssh/alert-engine.ts src/backend/utils/user-data-export.ts src/backend/utils/audit-logger.ts src/backend/utils/audit-logger.test.ts src/backend/utils/permission-manager.ts src/backend/utils/shared-credential-manager.ts src/backend/starter.ts
|
|
npm run test -- src/backend/database/runtime/config.test.ts src/backend/database/runtime/sqlite-adapter.test.ts src/backend/database/repositories/repository-rollout.test.ts src/backend/database/repositories/settings-repository.test.ts src/backend/database/repositories/user-session-repositories.test.ts src/backend/database/repositories/api-key-repository.test.ts src/backend/database/repositories/trusted-device-repository.test.ts src/backend/database/repositories/sso-provider-repository.test.ts src/backend/database/repositories/audit-log-repository.test.ts src/backend/database/repositories/user-preference-repository.test.ts src/backend/database/repositories/open-tab-repository.test.ts src/backend/database/repositories/dismissed-alert-repository.test.ts src/backend/database/repositories/homepage-layout-repository.test.ts src/backend/database/repositories/homepage-item-repository.test.ts src/backend/database/repositories/network-topology-repository.test.ts src/backend/database/repositories/dashboard-service-link-repository.test.ts src/backend/database/repositories/session-recording-repository.test.ts src/backend/database/repositories/command-history-repository.test.ts src/backend/database/repositories/recent-activity-repository.test.ts src/backend/database/repositories/ssh-credential-usage-repository.test.ts src/backend/database/repositories/transfer-recent-repository.test.ts src/backend/database/repositories/file-manager-bookmark-repository.test.ts src/backend/database/repositories/c2s-tunnel-preset-repository.test.ts src/backend/database/repositories/tmux-session-tag-repository.test.ts src/backend/database/repositories/opkssh-token-repository.test.ts src/backend/database/repositories/vault-token-repository.test.ts src/backend/database/repositories/vault-profile-repository.test.ts src/backend/database/repositories/host-metrics-preference-repository.test.ts src/backend/database/repositories/host-health-repository.test.ts src/backend/database/repositories/host-metrics-history-repository.test.ts src/backend/database/repositories/alert-repository.test.ts src/backend/database/repositories/user-data-export-repository.test.ts src/backend/database/repositories/host-folder-repository.test.ts src/backend/database/repositories/host-resolution-repository.test.ts src/backend/database/repositories/snippet-repository.test.ts src/backend/database/repositories/role-repository.test.ts src/backend/database/repositories/rbac-access-repository.test.ts src/backend/database/repositories/host-credential-repositories.test.ts src/backend/database/repositories/field-encryption-boundary.test.ts src/backend/utils/field-crypto.test.ts src/backend/utils/audit-logger.test.ts src/backend/guacamole/token-service.test.ts src/backend/database/routes/user-oidc-utils.test.ts src/backend/database/routes/termix-id.test.ts src/backend/database/routes/user-totp-routes.test.ts src/backend/utils/permission-manager.test.ts src/backend/ssh/credential-username.test.ts src/backend/ssh/tmux-monitor-helpers.test.ts
|
|
git diff --check
|
|
```
|
|
|
|
## 4. Smoke Test Matrix
|
|
|
|
Run these against the gray target:
|
|
|
|
| Area | Required check |
|
|
| ------------- | ------------------------------------------------------------------------------------------------------ |
|
|
| Startup | App starts from existing encrypted snapshot without schema errors |
|
|
| Login | Password login succeeds for an existing local user |
|
|
| Sessions | Refresh, logout, and session list/revoke still work |
|
|
| Users | `/users/me`, user list, admin create, make/remove admin still work |
|
|
| Registration | New local user registration works when registration is enabled |
|
|
| Password | Change password, logout, and login with the new password |
|
|
| OIDC | Existing OIDC login works; auto-provision check only if enabled |
|
|
| API keys | Admin create/list/delete API key; API key authentication updates usage |
|
|
| Settings | Read/write user settings and global auth settings |
|
|
| Preferences | Read/write user preferences and user cleanup still work |
|
|
| Open tabs | Tab restore, single upsert, bulk sync, update/delete, active session list, and user cleanup work |
|
|
| Alerts | Active alert filtering, dismiss/undismiss, dismissed list, export, and user cleanup work |
|
|
| Homepage | Homepage layout read/write still works |
|
|
| Topology | Network topology read/write and user cleanup still work |
|
|
| Dashboard | Dashboard service link list/create/update/delete still works |
|
|
| Command log | Terminal and host command history save/list/delete and cleanup still work |
|
|
| Activity | Recent activity cleanup for host, folder, password reset, and user deletion still works |
|
|
| Usage | SSH credential usage tracking and host/folder/user cleanup still work |
|
|
| SSO providers | Login provider list, admin provider list/create/update/delete, and OIDC/LDAP login config loading work |
|
|
| Audit logs | Audit write, audit list filters, action filter list, and user cleanup still work |
|
|
| Roles | Admin list/create/update/delete role and assign/remove a user role |
|
|
| RBAC access | Host/snippet share/revoke/list and shared host/snippet endpoints work |
|
|
| Security | Non-admin user is rejected from admin-only endpoints |
|
|
|
|
Do not continue gray rollout if any check fails.
|
|
|
|
Also verify these startup log cases before production gray:
|
|
|
|
| Environment value | Expected startup behavior |
|
|
| -------------------------------------------- | -------------------------------------------------- |
|
|
| `DATABASE_LAYER_REPOSITORY_ROLLOUT=all` | startup logs `mode: all` and all supported domains |
|
|
| `DATABASE_LAYER_REPOSITORY_ROLLOUT=off` | migrated repository use fails closed |
|
|
| `DATABASE_LAYER_REPOSITORY_ROLLOUT=settings` | only settings repository boundary is allowed |
|
|
|
|
Then check `/database/migration/status` as an admin and confirm
|
|
`repositoryRollout.mode`, `repositoryRollout.enabledDomains`, and
|
|
`repositoryRollout.explicit` match the intended gray target.
|
|
`repositoryRollout.warnings` should be empty for the recommended full gray
|
|
slice.
|
|
|
|
## 5. Rollout Stages
|
|
|
|
Recommended stages:
|
|
|
|
1. Local fixture run with copied production-like data.
|
|
2. Internal staging with one admin and one normal user.
|
|
3. Internal gray target with real integrations enabled.
|
|
4. Small production gray group.
|
|
|
|
Do not run multiple backend instances from this branch. The current runtime still
|
|
uses the encrypted SQLite snapshot model and is not safe for multi-writer
|
|
deployment.
|
|
|
|
## 6. Rollback
|
|
|
|
Rollback should be operationally simple because this gray scope does not change
|
|
the data format or require an external database.
|
|
|
|
Rollback steps:
|
|
|
|
1. Stop the gray build.
|
|
2. Restore the pre-gray encrypted database snapshot if any write-path smoke test
|
|
failed.
|
|
3. Deploy the previous known-good commit or image tag.
|
|
4. Start the previous version.
|
|
5. Verify startup, login, settings read, and one admin endpoint.
|
|
|
|
If the gray build only served read paths and no smoke test failed, restoring the
|
|
snapshot may not be necessary. If there is any doubt, restore the snapshot.
|
|
|
|
## 7. Stop Conditions
|
|
|
|
Stop gray rollout immediately if any of these happen:
|
|
|
|
- Login failure spike.
|
|
- API key authentication failure for known-good keys.
|
|
- Admin authorization mismatch.
|
|
- OIDC callback failure for existing users.
|
|
- Missing or stale settings after write.
|
|
- Data snapshot save errors.
|
|
- Any database error mentioning missing tables, unknown columns, or failed
|
|
serialization.
|
|
- Any user encryption or data unlock failure.
|
|
- Any unexpected `Repository domain ... is disabled` error for a domain that was
|
|
intended to be enabled.
|
|
|
|
## 8. Current Gray Readiness
|
|
|
|
Current branch can be considered gray-candidate only after all validation
|
|
commands and smoke checks above pass on staging.
|
|
|
|
The branch should remain draft until gray evidence is attached to the PR.
|