import { getDb, DatabaseSaveTrigger } from "../database/db/index.js"; import { DataCrypto } from "./data-crypto.js"; import type { SQLiteTable } from "drizzle-orm/sqlite-core"; type TableName = "users" | "ssh_data" | "ssh_credentials"; class SimpleDBOps { static async insert>( // eslint-disable-next-line @typescript-eslint/no-explicit-any table: SQLiteTable, tableName: TableName, data: T, userId: string, ): Promise { const userDataKey = DataCrypto.validateUserAccess(userId); const tempId = data.id || `temp-${userId}-${Date.now()}`; const dataWithTempId = { ...data, id: tempId }; const encryptedData = DataCrypto.encryptRecord( tableName, dataWithTempId, userId, userDataKey, ); if (!data.id) { delete encryptedData.id; } const result = await getDb() .insert(table) .values(encryptedData) .returning(); DatabaseSaveTrigger.triggerSave(`insert_${tableName}`); const decryptedResult = DataCrypto.decryptRecord( tableName, result[0], userId, userDataKey, ); return decryptedResult as T; } static async select>( query: unknown, tableName: TableName, userId: string, ): Promise { const userDataKey = DataCrypto.getUserDataKey(userId); if (!userDataKey) { return []; } const results = await query; const decryptedResults = DataCrypto.decryptRecords( tableName, results as unknown[], userId, userDataKey, ); return decryptedResults as T[]; } static async selectOne>( query: unknown, tableName: TableName, userId: string, ): Promise { const userDataKey = DataCrypto.getUserDataKey(userId); if (!userDataKey) { return undefined; } const result = await query; if (!result) return undefined; const decryptedResult = DataCrypto.decryptRecord( tableName, result as Record, userId, userDataKey, ); return decryptedResult; } static async update>( // eslint-disable-next-line @typescript-eslint/no-explicit-any table: SQLiteTable, tableName: TableName, where: unknown, data: Partial, userId: string, ): Promise { const userDataKey = DataCrypto.validateUserAccess(userId); const encryptedData = DataCrypto.encryptRecord( tableName, data, userId, userDataKey, ); const result = await getDb() .update(table) .set(encryptedData) // eslint-disable-next-line @typescript-eslint/no-explicit-any .where(where as any) .returning(); DatabaseSaveTrigger.triggerSave(`update_${tableName}`); const decryptedResults = DataCrypto.decryptRecords( tableName, result, userId, userDataKey, ); return decryptedResults as T[]; } static async delete( // eslint-disable-next-line @typescript-eslint/no-explicit-any table: SQLiteTable, tableName: TableName, where: unknown, _userId: string, ): Promise { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = await getDb() .delete(table) .where(where as any) .returning(); DatabaseSaveTrigger.triggerSave(`delete_${tableName}`); return result; } static async healthCheck(userId: string): Promise { return DataCrypto.canUserAccessData(userId); } static isUserDataUnlocked(userId: string): boolean { return DataCrypto.getUserDataKey(userId) !== null; } static async selectEncrypted( query: unknown, _tableName: TableName, ): Promise { const results = await query; return results as unknown[]; } } export { SimpleDBOps, type TableName };