Spaces:
Runtime error
Runtime error
File size: 2,741 Bytes
cd8bd0a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import { NextResponse } from "next/server";
import {
getSettings,
getProviderConnections,
getProviderNodes,
getCombos,
getApiKeys,
} from "@/lib/localDb";
import { isAuthRequired, isAuthenticated } from "@/shared/utils/apiAuth";
import {
getAllUsageHistory,
getAllDomainCostHistory,
getAllDomainBudgets,
} from "@/lib/db/usageAnalytics";
/**
* GET /api/settings/export-json
* Exports a legacy OmniRoute-compatible JSON backup.
*/
export async function GET(request: Request) {
if (await isAuthRequired(request)) {
if (!(await isAuthenticated(request))) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
}
try {
const url = new URL(request.url);
// Telemetry/history tables grow indefinitely and inflate backups.
// Exclude them by default — opt-in with ?includeHistory=true (#2125).
const includeHistory = url.searchParams.get("includeHistory") === "true";
const rawSettings = await getSettings();
// REDACT sensitive security keys to maintain Zero-Trust posture
// even if the admin shares their backup file.
// Use destructuring (not delete) to avoid mutating a potentially cached object.
const { password: _pw, requireLogin: _rl, ...safeSettings } = rawSettings;
const providerConnections = await getProviderConnections();
const providerNodes = await getProviderNodes();
const combos = await getCombos();
const apiKeys = await getApiKeys();
const exportData: Record<string, unknown> = {
settings: safeSettings,
providerConnections,
providerNodes,
combos,
apiKeys,
// Metadata to identify export version
_meta: {
exportedAt: new Date().toISOString(),
version: "omniroute-v3-legacy-export",
includesHistory: includeHistory,
},
};
// Only include telemetry/history tables when explicitly requested.
// These tables (usage_history, domain_cost_history, domain_budgets) can contain
// thousands of rows and make the config backup grow to many MBs.
if (includeHistory) {
exportData.usageHistory = getAllUsageHistory();
exportData.domainCostHistory = getAllDomainCostHistory();
exportData.domainBudgets = getAllDomainBudgets();
}
return new NextResponse(JSON.stringify(exportData, null, 2), {
status: 200,
headers: {
"Content-Type": "application/json",
"Content-Disposition": `attachment; filename="omniroute-legacy-backup-${new Date().toISOString().replace(/[:.]/g, "-")}.json"`,
},
});
} catch (error) {
console.error("[API] Error exporting JSON backup:", error);
return NextResponse.json({ error: "Failed to export JSON" }, { status: 500 });
}
}
|