| import { getAdapter } from "../driver.js"; |
| import { parseJson, stringifyJson } from "../helpers/jsonCol.js"; |
|
|
| const DEFAULT_MITM_ROUTER_BASE = "http://localhost:20128"; |
|
|
| const DEFAULT_SETTINGS = { |
| cloudEnabled: false, |
| tunnelEnabled: false, |
| tunnelUrl: "", |
| tunnelProvider: "cloudflare", |
| tailscaleEnabled: false, |
| tailscaleUrl: "", |
| stickyRoundRobinLimit: 3, |
| providerStrategies: {}, |
| comboStrategy: "fallback", |
| comboStickyRoundRobinLimit: 1, |
| comboStrategies: {}, |
| requireLogin: true, |
| tunnelDashboardAccess: true, |
| authMode: "password", |
| oidcIssuerUrl: "", |
| oidcClientId: "", |
| oidcClientSecret: "", |
| oidcScopes: "openid profile email", |
| oidcLoginLabel: "Sign in with OIDC", |
| enableObservability: true, |
| observabilityMaxRecords: 1000, |
| observabilityBatchSize: 20, |
| observabilityFlushIntervalMs: 5000, |
| observabilityMaxJsonSize: 5, |
| outboundProxyEnabled: false, |
| outboundProxyUrl: "", |
| outboundNoProxy: "", |
| mitmRouterBaseUrl: DEFAULT_MITM_ROUTER_BASE, |
| dnsToolEnabled: {}, |
| rtkEnabled: true, |
| cavemanEnabled: false, |
| cavemanLevel: "full", |
| }; |
|
|
| async function readRaw() { |
| const db = await getAdapter(); |
| const row = db.get(`SELECT data FROM settings WHERE id = 1`); |
| return row ? parseJson(row.data, {}) : {}; |
| } |
|
|
| |
| function mergeWithDefaults(raw) { |
| const merged = { ...DEFAULT_SETTINGS, ...(raw || {}) }; |
| for (const [key, defVal] of Object.entries(DEFAULT_SETTINGS)) { |
| if (merged[key] === undefined) { |
| if ( |
| key === "outboundProxyEnabled" && |
| typeof merged.outboundProxyUrl === "string" && |
| merged.outboundProxyUrl.trim() |
| ) { |
| merged[key] = true; |
| } else { |
| merged[key] = defVal; |
| } |
| } |
| } |
| return merged; |
| } |
|
|
| export async function getSettings() { |
| const raw = await readRaw(); |
| return mergeWithDefaults(raw); |
| } |
|
|
| |
| export async function updateSettings(updates) { |
| const db = await getAdapter(); |
| let next; |
| db.transaction(() => { |
| const row = db.get(`SELECT data FROM settings WHERE id = 1`); |
| const current = row ? parseJson(row.data, {}) : {}; |
| next = { ...current, ...updates }; |
| db.run( |
| `INSERT INTO settings(id, data) VALUES(1, ?) ON CONFLICT(id) DO UPDATE SET data = excluded.data`, |
| [stringifyJson(next)] |
| ); |
| }); |
| return mergeWithDefaults(next); |
| } |
|
|
| export async function isCloudEnabled() { |
| const settings = await getSettings(); |
| return settings.cloudEnabled === true; |
| } |
|
|
| export async function getCloudUrl() { |
| const settings = await getSettings(); |
| return ( |
| settings.cloudUrl || |
| process.env.CLOUD_URL || |
| process.env.NEXT_PUBLIC_CLOUD_URL || |
| "" |
| ); |
| } |
|
|
| export async function exportSettings() { |
| return await readRaw(); |
| } |
|
|