89 lines
2.6 KiB
JavaScript
89 lines
2.6 KiB
JavaScript
import { existsSync } from "node:fs";
|
|
import { resolveDataDir } from "../data-dir.mjs";
|
|
import { join } from "node:path";
|
|
|
|
const ENCRYPTED_PATTERN = "enc:v1:%";
|
|
const ENCRYPTED_COLUMNS = ["api_key", "access_token", "refresh_token", "id_token"];
|
|
|
|
/**
|
|
* Direct SQLite implementation for reset-encrypted-columns.
|
|
* Uses better-sqlite3 directly to avoid TypeScript source dependencies in production builds.
|
|
*/
|
|
export async function runResetEncryptedColumns(argv) {
|
|
const dataDir = resolveDataDir();
|
|
const dbPath = join(dataDir, "storage.sqlite");
|
|
|
|
if (!existsSync(dbPath)) {
|
|
console.log(`\x1b[33m⚠ No database found at ${dbPath}\x1b[0m`);
|
|
return 0;
|
|
}
|
|
|
|
const force = Array.isArray(argv) ? argv.includes("--force") : argv?.force === true;
|
|
|
|
if (!force) {
|
|
console.log(`
|
|
\x1b[1m\x1b[33m⚠ WARNING: This will erase all encrypted credentials\x1b[0m
|
|
|
|
This command will NULL out the following columns in provider_connections:
|
|
• api_key
|
|
• access_token
|
|
• refresh_token
|
|
• id_token
|
|
|
|
Provider metadata (name, provider_id, settings) will be preserved.
|
|
You will need to re-authenticate all providers after this operation.
|
|
|
|
Database: ${dbPath}
|
|
|
|
\x1b[1mTo confirm, run:\x1b[0m
|
|
omniroute reset-encrypted-columns --force
|
|
`);
|
|
return 0;
|
|
}
|
|
|
|
let db;
|
|
try {
|
|
// Use createRequire to load better-sqlite3 (works in both dev and production)
|
|
const { createRequire } = await import("node:module");
|
|
const require = createRequire(import.meta.url);
|
|
const Database = require("better-sqlite3");
|
|
|
|
db = new Database(dbPath);
|
|
|
|
// Build WHERE clause for encrypted values
|
|
const whereClause = ENCRYPTED_COLUMNS.map((col) => `${col} LIKE '${ENCRYPTED_PATTERN}'`).join(
|
|
" OR "
|
|
);
|
|
|
|
// Count affected rows
|
|
const countResult = db
|
|
.prepare(`SELECT COUNT(*) AS cnt FROM provider_connections WHERE ${whereClause}`)
|
|
.get();
|
|
const count = countResult?.cnt ?? 0;
|
|
|
|
if (count === 0) {
|
|
console.log("\x1b[32m✔ No encrypted credentials found — nothing to reset.\x1b[0m");
|
|
return 0;
|
|
}
|
|
|
|
// Reset columns
|
|
const nullCols = ENCRYPTED_COLUMNS.map((col) => `${col} = NULL`).join(", ");
|
|
db.prepare(`UPDATE provider_connections SET ${nullCols} WHERE ${whereClause}`).run();
|
|
|
|
console.log(
|
|
`\x1b[32m✔ Reset ${count} provider connection(s).\x1b[0m\n` +
|
|
` Re-authenticate your providers in the dashboard or re-add API keys.\n`
|
|
);
|
|
return 0;
|
|
} catch (err) {
|
|
console.error(
|
|
`\x1b[31m✖ Failed to reset encrypted columns:\x1b[0m ${err instanceof Error ? err.message : String(err)}`
|
|
);
|
|
return 1;
|
|
} finally {
|
|
if (db) {
|
|
db.close();
|
|
}
|
|
}
|
|
}
|