export const createManagedTunnelConfigRuntime = (deps) => { const { fsPromises, path, normalizeManagedRemoteTunnelHostname, normalizeManagedRemoteTunnelPresets, constants, } = deps; const { CLOUDFLARE_MANAGED_REMOTE_TUNNELS_FILE_PATH, CLOUDFLARE_LEGACY_NAMED_TUNNELS_FILE_PATH, CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, } = constants; let persistManagedRemoteTunnelConfigLock = Promise.resolve(); const sanitizeManagedRemoteTunnelConfigEntries = (value) => { if (!Array.isArray(value)) { return []; } const result = []; const seenIds = new Set(); const seenHostnames = new Set(); for (const entry of value) { if (!entry || typeof entry !== 'object') { continue; } const id = typeof entry.id === 'string' ? entry.id.trim() : ''; const name = typeof entry.name === 'string' ? entry.name.trim() : ''; const hostname = normalizeManagedRemoteTunnelHostname(entry.hostname); const token = typeof entry.token === 'string' ? entry.token.trim() : ''; const updatedAt = Number.isFinite(entry.updatedAt) ? entry.updatedAt : Date.now(); if (!id || !name || !hostname || !token) { continue; } if (seenIds.has(id) || seenHostnames.has(hostname)) { continue; } seenIds.add(id); seenHostnames.add(hostname); result.push({ id, name, hostname, token, updatedAt }); } return result; }; const writeManagedRemoteTunnelConfigToDisk = async (data) => { await fsPromises.mkdir(path.dirname(CLOUDFLARE_MANAGED_REMOTE_TUNNELS_FILE_PATH), { recursive: true }); await fsPromises.writeFile(CLOUDFLARE_MANAGED_REMOTE_TUNNELS_FILE_PATH, JSON.stringify(data, null, 2), { encoding: 'utf8', mode: 0o600 }); }; const migrateManagedRemoteTunnelConfigFromLegacyFile = async () => { try { const legacyRaw = await fsPromises.readFile(CLOUDFLARE_LEGACY_NAMED_TUNNELS_FILE_PATH, 'utf8'); const parsed = JSON.parse(legacyRaw); const tunnels = sanitizeManagedRemoteTunnelConfigEntries(parsed?.tunnels); const migrated = { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels, }; await writeManagedRemoteTunnelConfigToDisk(migrated); return migrated; } catch (error) { if (error && typeof error === 'object' && error.code === 'ENOENT') { return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: [] }; } console.warn('Failed to migrate legacy named tunnel config file:', error); return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: [] }; } }; const readManagedRemoteTunnelConfigFromDisk = async () => { try { const raw = await fsPromises.readFile(CLOUDFLARE_MANAGED_REMOTE_TUNNELS_FILE_PATH, 'utf8'); const parsed = JSON.parse(raw); if (!parsed || typeof parsed !== 'object') { return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: [] }; } return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: sanitizeManagedRemoteTunnelConfigEntries(parsed.tunnels), }; } catch (error) { if (error && typeof error === 'object' && error.code === 'ENOENT') { return migrateManagedRemoteTunnelConfigFromLegacyFile(); } console.warn('Failed to read managed remote tunnel config file:', error); return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: [] }; } }; const updateManagedRemoteTunnelConfig = async (mutate) => { persistManagedRemoteTunnelConfigLock = persistManagedRemoteTunnelConfigLock.then(async () => { const current = await readManagedRemoteTunnelConfigFromDisk(); const next = mutate({ version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: sanitizeManagedRemoteTunnelConfigEntries(current.tunnels), }); await writeManagedRemoteTunnelConfigToDisk({ version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: sanitizeManagedRemoteTunnelConfigEntries(next?.tunnels), }); }); return persistManagedRemoteTunnelConfigLock; }; const syncManagedRemoteTunnelConfigWithPresets = async (presets) => { const sanitizedPresets = normalizeManagedRemoteTunnelPresets(presets) || []; await updateManagedRemoteTunnelConfig((current) => { const byId = new Map(current.tunnels.map((entry) => [entry.id, entry])); const byHostname = new Map(current.tunnels.map((entry) => [entry.hostname, entry])); const nextTunnels = []; for (const preset of sanitizedPresets) { const existing = byId.get(preset.id) || byHostname.get(preset.hostname) || null; if (!existing) { continue; } nextTunnels.push({ ...existing, id: preset.id, name: preset.name, hostname: preset.hostname, }); } return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: nextTunnels, }; }); }; const upsertManagedRemoteTunnelToken = async ({ id, name, hostname, token }) => { if (typeof id !== 'string' || typeof name !== 'string' || typeof hostname !== 'string' || typeof token !== 'string') { return; } const normalizedId = id.trim(); const normalizedName = name.trim(); const normalizedHostname = normalizeManagedRemoteTunnelHostname(hostname); const normalizedToken = token.trim(); if (!normalizedId || !normalizedName || !normalizedHostname || !normalizedToken) { return; } await updateManagedRemoteTunnelConfig((current) => { const withoutConflicts = current.tunnels.filter((entry) => entry.id !== normalizedId && entry.hostname !== normalizedHostname); withoutConflicts.push({ id: normalizedId, name: normalizedName, hostname: normalizedHostname, token: normalizedToken, updatedAt: Date.now(), }); return { version: CLOUDFLARE_MANAGED_REMOTE_TUNNELS_VERSION, tunnels: withoutConflicts, }; }); }; const resolveManagedRemoteTunnelToken = async ({ presetId, hostname }) => { const normalizedPresetId = typeof presetId === 'string' ? presetId.trim() : ''; const normalizedHostname = normalizeManagedRemoteTunnelHostname(hostname); const config = await readManagedRemoteTunnelConfigFromDisk(); if (normalizedPresetId) { const byId = config.tunnels.find((entry) => entry.id === normalizedPresetId); if (byId?.token) { return byId.token; } } if (normalizedHostname) { const byHostname = config.tunnels.find((entry) => entry.hostname === normalizedHostname); if (byHostname?.token) { return byHostname.token; } } return ''; }; return { readManagedRemoteTunnelConfigFromDisk, syncManagedRemoteTunnelConfigWithPresets, upsertManagedRemoteTunnelToken, resolveManagedRemoteTunnelToken, }; };