mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-07-15 17:07:26 +02:00
154 lines
4.0 KiB
TypeScript
154 lines
4.0 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import type { LaunchOptions } from "donutbrowser-camoufox-js/dist/utils.js";
|
|
import tmp from "tmp";
|
|
|
|
export interface CamoufoxConfig {
|
|
id: string;
|
|
options: LaunchOptions;
|
|
profilePath?: string;
|
|
url?: string;
|
|
processId?: number;
|
|
customConfig?: string; // JSON string of the fingerprint config
|
|
}
|
|
|
|
const STORAGE_DIR = path.join(tmp.tmpdir, "donutbrowser", "camoufox");
|
|
|
|
if (!fs.existsSync(STORAGE_DIR)) {
|
|
fs.mkdirSync(STORAGE_DIR, { recursive: true });
|
|
}
|
|
|
|
/**
|
|
* Save a Camoufox configuration to disk
|
|
* @param config The Camoufox configuration to save
|
|
*/
|
|
export function saveCamoufoxConfig(config: CamoufoxConfig): void {
|
|
const filePath = path.join(STORAGE_DIR, `${config.id}.json`);
|
|
fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
|
|
}
|
|
|
|
/**
|
|
* Get a Camoufox configuration by ID
|
|
* @param id The Camoufox ID
|
|
* @returns The Camoufox configuration or null if not found
|
|
*/
|
|
export function getCamoufoxConfig(id: string): CamoufoxConfig | null {
|
|
const filePath = path.join(STORAGE_DIR, `${id}.json`);
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
return JSON.parse(content) as CamoufoxConfig;
|
|
} catch (error) {
|
|
console.error({
|
|
message: `Error reading Camoufox config ${id}`,
|
|
error: (error as Error).message,
|
|
});
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a Camoufox configuration
|
|
* @param id The Camoufox ID to delete
|
|
* @returns True if deleted, false if not found
|
|
*/
|
|
export function deleteCamoufoxConfig(id: string): boolean {
|
|
const filePath = path.join(STORAGE_DIR, `${id}.json`);
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
fs.unlinkSync(filePath);
|
|
return true;
|
|
} catch (error) {
|
|
console.error({
|
|
message: `Error deleting Camoufox config ${id}`,
|
|
error: (error as Error).message,
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* List all saved Camoufox configurations
|
|
* @returns Array of Camoufox configurations
|
|
*/
|
|
export function listCamoufoxConfigs(): CamoufoxConfig[] {
|
|
if (!fs.existsSync(STORAGE_DIR)) {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
return fs
|
|
.readdirSync(STORAGE_DIR)
|
|
.filter((file) => file.endsWith(".json"))
|
|
.map((file) => {
|
|
try {
|
|
const content = fs.readFileSync(
|
|
path.join(STORAGE_DIR, file),
|
|
"utf-8",
|
|
);
|
|
return JSON.parse(content) as CamoufoxConfig;
|
|
} catch (error) {
|
|
console.error({
|
|
message: `Error reading Camoufox config ${file}`,
|
|
error,
|
|
});
|
|
return null;
|
|
}
|
|
})
|
|
.filter((config): config is CamoufoxConfig => config !== null)
|
|
.map((config) => {
|
|
config.options = "Removed for logging" as any;
|
|
config.customConfig = "Removed for logging" as any;
|
|
return config;
|
|
});
|
|
} catch (error) {
|
|
console.error({ message: "Error listing Camoufox configs:", error });
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update a Camoufox configuration
|
|
* @param config The Camoufox configuration to update
|
|
* @returns True if updated, false if not found
|
|
*/
|
|
export function updateCamoufoxConfig(config: CamoufoxConfig): boolean {
|
|
const filePath = path.join(STORAGE_DIR, `${config.id}.json`);
|
|
|
|
try {
|
|
fs.readFileSync(filePath, "utf-8");
|
|
fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
|
|
return true;
|
|
} catch (error) {
|
|
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
console.error({
|
|
message: `Config ${config.id} was deleted while the app was running`,
|
|
});
|
|
return false;
|
|
}
|
|
|
|
console.error({
|
|
message: `Error updating Camoufox config ${config.id}`,
|
|
error,
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate a unique ID for a Camoufox instance
|
|
* @returns A unique ID string
|
|
*/
|
|
export function generateCamoufoxId(): string {
|
|
// Include process ID to ensure uniqueness across multiple processes
|
|
return `camoufox_${Date.now()}_${process.pid}_${Math.floor(Math.random() * 10000)}`;
|
|
}
|