godcrm/electron/ipc/apiUrl.ts
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

83 lines
2.6 KiB
TypeScript

import { ipcMain, app, net } from 'electron';
import path from 'node:path';
import fs from 'node:fs/promises';
import { bindUploadsAuth, unbindUploadsAuth } from './auth';
const DEFAULT_API_URL = 'https://crm.hltrn.cc/api/v3';
const SETTINGS_FILE = 'settings.json';
export async function getCurrentApiUrl(): Promise<string> {
const s = await readSettings();
return s.apiUrl ?? DEFAULT_API_URL;
}
interface Settings {
apiUrl?: string;
}
async function readSettings(): Promise<Settings> {
const file = path.join(app.getPath('userData'), SETTINGS_FILE);
try {
const raw = await fs.readFile(file, 'utf-8');
return JSON.parse(raw) as Settings;
} catch {
return {};
}
}
async function writeSettings(patch: Partial<Settings>): Promise<void> {
const file = path.join(app.getPath('userData'), SETTINGS_FILE);
const current = await readSettings();
const next = { ...current, ...patch };
await fs.writeFile(file, JSON.stringify(next, null, 2), 'utf-8');
}
export function registerApiUrlHandlers(): void {
ipcMain.handle('apiUrl:get', async () => {
const s = await readSettings();
return s.apiUrl ?? DEFAULT_API_URL;
});
ipcMain.handle('apiUrl:set', async (_e, url: string) => {
if (typeof url !== 'string' || !/^https?:\/\//i.test(url)) {
return false;
}
await writeSettings({ apiUrl: url });
unbindUploadsAuth();
bindUploadsAuth(url);
return true;
});
ipcMain.handle('apiUrl:test', async (_e, url: string) => {
if (typeof url !== 'string' || !/^https?:\/\//i.test(url)) {
return { success: false, error: 'Invalid URL' };
}
return new Promise<{ success: boolean; data?: unknown; error?: string }>((resolve) => {
try {
const origin = url.replace(/\/$/, '').replace(/\/api\/v3$/i, '');
const probeUrl = origin + '/api/health';
const request = net.request({ method: 'GET', url: probeUrl });
request.on('response', (response) => {
const ok = response.statusCode >= 200 && response.statusCode < 400;
let body = '';
response.on('data', (chunk) => {
body += chunk.toString();
});
response.on('end', () => {
resolve(
ok
? { success: true, data: body.slice(0, 512) }
: { success: false, error: `HTTP ${response.statusCode}` }
);
});
});
request.on('error', (err) => {
resolve({ success: false, error: err.message });
});
request.end();
} catch (err) {
resolve({ success: false, error: err instanceof Error ? err.message : String(err) });
}
});
});
}