Spaces:
Runtime error
Runtime error
| 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(); | |
| } | |
| } | |
| } | |