mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-31 23:55:23 +00:00
chore: lock the plugin boundary and remove 2.9.0 leftovers
This commit is contained in:
1 parent
6489b62ece
commit
2961297989
399 files changed
+3964
-5627
No files matched your search
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Reseals 2.8 Termix ID certificate authority keys for the termix-identity
|
||||
* plugin.
|
||||
*
|
||||
* Core encrypted termix_identity_ca.private_key with the owner's data key.
|
||||
* The plugin adopts that table as p_termix_identity_ca and reads the key with
|
||||
* ctx.secrets.unseal, which only opens installation-key encryption. Each row
|
||||
* still under a data key is decrypted and written back with
|
||||
* encryptSystemSecret, what ctx.secrets.seal writes.
|
||||
*
|
||||
* Does nothing until the plugin's table exists. A row whose owner's data key
|
||||
* cannot be opened is skipped and tried again next time. Idempotent.
|
||||
*/
|
||||
|
||||
import { sql } from "drizzle-orm";
|
||||
import { databaseLogger } from "../utils/logger.js";
|
||||
import { DataCrypto } from "../utils/data-crypto.js";
|
||||
import { LazyFieldEncryption } from "../utils/lazy-field-encryption.js";
|
||||
import {
|
||||
encryptSystemSecret,
|
||||
isSystemEncrypted,
|
||||
} from "../utils/system-secret-crypto.js";
|
||||
import {
|
||||
runStatement,
|
||||
selectRows,
|
||||
} from "../utils/crypto-migration/raw-rows.js";
|
||||
|
||||
const CA_TABLE = "p_termix_identity_ca";
|
||||
|
||||
interface CaRow {
|
||||
id: number;
|
||||
user_id: string;
|
||||
private_key: string | null;
|
||||
}
|
||||
|
||||
export async function runTermixIdentityCaMigration(): Promise<number> {
|
||||
let rows: CaRow[];
|
||||
try {
|
||||
rows = await selectRows<CaRow>(
|
||||
sql`SELECT id, user_id, private_key FROM ${sql.identifier(CA_TABLE)}`,
|
||||
);
|
||||
} catch {
|
||||
// The plugin has not adopted the table yet.
|
||||
return 0;
|
||||
}
|
||||
|
||||
let resealed = 0;
|
||||
for (const row of rows) {
|
||||
if (!row.private_key || isSystemEncrypted(row.private_key)) continue;
|
||||
try {
|
||||
const dek = DataCrypto.getUserDataKey(row.user_id);
|
||||
if (!dek) continue;
|
||||
const plain = LazyFieldEncryption.safeGetFieldValue(
|
||||
row.private_key,
|
||||
dek,
|
||||
String(row.id),
|
||||
"privateKey",
|
||||
);
|
||||
if (!plain) continue;
|
||||
await runStatement(
|
||||
sql`UPDATE ${sql.identifier(CA_TABLE)} SET private_key = ${await encryptSystemSecret(plain)} WHERE id = ${row.id}`,
|
||||
);
|
||||
resealed++;
|
||||
} catch (error) {
|
||||
databaseLogger.warn("Termix ID CA reseal failed for a row", {
|
||||
operation: "termix_identity_ca_migration",
|
||||
caId: row.id,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (resealed > 0) {
|
||||
databaseLogger.info("Resealed Termix ID CA keys for the plugin", {
|
||||
operation: "termix_identity_ca_migration",
|
||||
resealed,
|
||||
});
|
||||
}
|
||||
return resealed;
|
||||
}
|
||||
Reference in new issue
Block a user