Files
rayhunter/daemon/web/src/lib/utils.svelte.ts

184 lines
4.8 KiB
TypeScript

import { add_error } from './action_errors.svelte';
import { Manifest } from './manifest.svelte';
import type { SystemStats } from './systemStats';
export interface AnalyzerConfig {
imsi_requested: boolean;
connection_redirect_2g_downgrade: boolean;
lte_sib6_and_7_downgrade: boolean;
null_cipher: boolean;
nas_null_cipher: boolean;
incomplete_sib: boolean;
test_analyzer: boolean;
diagnostic_analyzer: boolean;
}
export enum enabled_notifications {
Warning = 'Warning',
LowBattery = 'LowBattery',
}
export interface WebdavConfig {
url: string;
username: string | null;
password: string | null;
upload_timeout_secs: number;
poll_interval_secs: number;
min_age_secs: number;
delete_on_upload: boolean;
}
export enum GpsMode {
Disabled = 0,
Fixed = 1,
Api = 2,
}
export interface Config {
device: string;
ui_level: number;
colorblind_mode: boolean;
key_input_mode: number;
ntfy_url: string;
enabled_notifications: enabled_notifications[];
analyzers: AnalyzerConfig;
min_space_to_start_recording_mb: number;
min_space_to_continue_recording_mb: number;
wifi_ssid: string | null;
wifi_password: string | null;
wifi_security: 'wpa_psk' | 'sae' | null;
wifi_enabled: boolean;
dns_servers: string[] | null;
firewall_restrict_outbound: boolean;
firewall_allowed_ports: number[] | null;
webdav: WebdavConfig;
gps_mode: GpsMode;
gps_fixed_latitude: number | null;
gps_fixed_longitude: number | null;
}
export interface WifiStatus {
state: string;
ssid?: string;
ip?: string;
error?: string;
}
export interface WifiNetwork {
ssid: string;
signal_dbm: number;
security: string;
}
export async function get_wifi_status(): Promise<WifiStatus> {
return JSON.parse(await req('GET', '/api/wifi-status'));
}
export async function scan_wifi_networks(): Promise<WifiNetwork[]> {
return JSON.parse(await req('POST', '/api/wifi-scan'));
}
export async function req(method: string, url: string, json_body?: unknown): Promise<string> {
const options: RequestInit = { method };
if (json_body !== undefined) {
options.body = JSON.stringify(json_body);
options.headers = { 'Content-Type': 'application/json' };
}
const response = await fetch(url, options);
const responseBody = await response.text();
if (response.status >= 200 && response.status < 300) {
return responseBody;
} else {
throw new Error(responseBody);
}
}
// A wrapper around req that reports errors to the UI
export async function user_action_req(
method: string,
url: string,
error_msg: string,
json_body?: unknown
): Promise<string | undefined> {
try {
return await req(method, url, json_body);
} catch (error) {
if (error instanceof Error) {
add_error(error, error_msg);
}
return undefined;
}
}
export async function get_manifest(): Promise<Manifest> {
const manifest_json = JSON.parse(await req('GET', '/api/qmdl-manifest'));
return new Manifest(manifest_json);
}
export async function get_system_stats(): Promise<SystemStats> {
return JSON.parse(await req('GET', '/api/system-stats'));
}
export async function get_logs(): Promise<string> {
return await req('GET', '/api/log');
}
export async function get_config(): Promise<Config> {
return JSON.parse(await req('GET', '/api/config'));
}
export async function set_config(config: Config): Promise<void> {
const response = await fetch('/api/config', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(config),
});
if (!response.ok) {
const error = await response.text();
throw new Error(error);
}
}
export async function test_notification(): Promise<void> {
const response = await fetch('/api/test-notification', {
method: 'POST',
});
if (!response.ok) {
const error = await response.text();
throw new Error(error);
}
}
export interface TimeResponse {
system_time: string;
adjusted_time: string;
offset_seconds: number;
}
export async function get_daemon_time(): Promise<TimeResponse> {
return JSON.parse(await req('GET', '/api/time'));
}
export interface GpsData {
latitude: number;
longitude: number;
/** Unix timestamp in seconds (0 = fixed/no real time). */
timestamp: number;
}
export async function get_gps(): Promise<GpsData | null> {
const response = await fetch('/api/gps', { cache: 'no-store' });
if (response.status === 404) {
return null;
}
if (response.status >= 200 && response.status < 300) {
return response.json();
}
throw new Error(await response.text());
}