refactor(crypto): make system-wrapped DEKs the authoritative key path

DataCrypto and AuthManager now read keys through UserKeyManager: DEKs are
always unwrappable server-side, so the in-memory unlock session, DEK-in-JWT
wrapping, session-expiry data locks and ALLOW_APIKEY_DATA_UNLOCK are gone.
utils/user-crypto.ts is deleted; boot migration now cleans legacy wraps.
A one-release shim adopts DEKs from legacy dataKeyWrap tokens so active
password users migrate without re-login. Password login migrates legacy
password-wrapped DEKs via migratePasswordUserAtLogin.
This commit is contained in:
LukeGus
2026-07-16 00:19:12 -05:00
parent 16506de9da
commit ee7768dd86
14 changed files with 234 additions and 1114 deletions
+3 -4
View File
@@ -11,7 +11,7 @@ import { createCurrentHostResolutionRepository } from "../database/repositories/
import { sshLogger, authLogger } from "../utils/logger.js";
import { logAudit } from "../utils/audit-logger.js";
import { AuthManager } from "../utils/auth-manager.js";
import { UserCrypto } from "../utils/user-crypto.js";
import { DataCrypto } from "../utils/data-crypto.js";
import {
createSocks5Connection,
type SOCKS5Config,
@@ -98,7 +98,6 @@ interface WebSocketMessage {
}
const authManager = AuthManager.getInstance();
const userCrypto = UserCrypto.getInstance();
const userConnections = new Map<string, Set<WebSocket>>();
@@ -158,7 +157,7 @@ wss.on("connection", async (ws: WebSocket, req) => {
return;
}
const dataKey = userCrypto.getUserDataKey(userId);
const dataKey = DataCrypto.getUserDataKey(userId);
if (!dataKey) {
ws.send(
JSON.stringify({
@@ -268,7 +267,7 @@ wss.on("connection", async (ws: WebSocket, req) => {
}
ws.on("message", async (msg: RawData) => {
const currentDataKey = userCrypto.getUserDataKey(userId);
const currentDataKey = DataCrypto.getUserDataKey(userId);
if (!currentDataKey) {
ws.send(
JSON.stringify({