- backend/api/magic/register: explicit import of MAGIC_DEVICE_LIMIT and createAdGuardClient (Nitro auto-import was missing them → ReferenceError → HTTP 500 on /api/magic/register) - mac-app: default backendBaseUrl falls back to staging.rebreak.org (app.rebreak.org serves wrong TLS cert) - native MagicSheet: fallback download/dmg URLs point to staging - native settings: Magic sheet capped at detents=[0.85] so AppHeader stays visible - bundles all in-flight Magic feature work (pair create/redeem, device endpoints, schema, adguard utils, mac-app, locales)
119 lines
3.3 KiB
TypeScript
119 lines
3.3 KiB
TypeScript
/**
|
|
* AdGuard Home API Client für RebreakMagic DNS-over-HTTPS Client-Provisioning.
|
|
* Docs: https://github.com/AdguardTeam/AdGuardHome/tree/master/openapi
|
|
*/
|
|
|
|
export interface AdGuardClientOptions {
|
|
use_global_settings?: boolean;
|
|
filtering_enabled?: boolean;
|
|
parental_enabled?: boolean;
|
|
safebrowsing_enabled?: boolean;
|
|
safesearch_enabled?: boolean;
|
|
blocked_services?: string[];
|
|
upstreams?: string[];
|
|
tags?: string[];
|
|
}
|
|
|
|
interface AdGuardClientPayload {
|
|
name: string;
|
|
ids: string[];
|
|
use_global_settings?: boolean;
|
|
filtering_enabled?: boolean;
|
|
parental_enabled?: boolean;
|
|
safebrowsing_enabled?: boolean;
|
|
safesearch_enabled?: boolean;
|
|
blocked_services?: string[];
|
|
upstreams?: string[];
|
|
tags?: string[];
|
|
}
|
|
|
|
/**
|
|
* Erstellt einen AdGuard Persistent Client mit gegebener Client-ID (DNS-Token).
|
|
* AdGuard nutzt die Client-ID im DoH-URL-Path: /dns-query/{clientId}
|
|
*
|
|
* @param name - Interner Client-Name (z.B. "magic_<deviceId>")
|
|
* @param clientId - DNS-Token (wird in DoH URL embedded)
|
|
* @param options - Filtering/Blocking-Optionen
|
|
*/
|
|
export async function createAdGuardClient(
|
|
name: string,
|
|
clientId: string,
|
|
options: AdGuardClientOptions = {},
|
|
): Promise<void> {
|
|
const config = useRuntimeConfig();
|
|
const baseUrl = config.adguardBaseUrl || "https://dns.rebreak.org";
|
|
const user = config.adguardUser;
|
|
const password = config.adguardPassword;
|
|
|
|
if (!user || !password) {
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: "ADGUARD_USER and ADGUARD_PASSWORD required for Magic features",
|
|
});
|
|
}
|
|
|
|
const payload: AdGuardClientPayload = {
|
|
name,
|
|
ids: [clientId],
|
|
...options,
|
|
};
|
|
|
|
const authHeader = `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`;
|
|
|
|
try {
|
|
const response = await $fetch(`${baseUrl}/control/clients/add`, {
|
|
method: "POST",
|
|
headers: {
|
|
Authorization: authHeader,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: payload,
|
|
});
|
|
return response as void;
|
|
} catch (err: any) {
|
|
console.error("[AdGuard] Client creation failed:", err);
|
|
throw createError({
|
|
statusCode: 502,
|
|
message: `AdGuard API error: ${err.message || "unknown"}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Löscht einen AdGuard Persistent Client.
|
|
* @param name - Interner Client-Name (z.B. "magic_<deviceId>")
|
|
*/
|
|
export async function deleteAdGuardClient(name: string): Promise<void> {
|
|
const config = useRuntimeConfig();
|
|
const baseUrl = config.adguardBaseUrl || "https://dns.rebreak.org";
|
|
const user = config.adguardUser;
|
|
const password = config.adguardPassword;
|
|
|
|
if (!user || !password) {
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: "ADGUARD_USER and ADGUARD_PASSWORD required for Magic features",
|
|
});
|
|
}
|
|
|
|
const authHeader = `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`;
|
|
|
|
try {
|
|
const response = await $fetch(`${baseUrl}/control/clients/delete`, {
|
|
method: "POST",
|
|
headers: {
|
|
Authorization: authHeader,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: { name },
|
|
});
|
|
return response as void;
|
|
} catch (err: any) {
|
|
console.error("[AdGuard] Client deletion failed:", err);
|
|
throw createError({
|
|
statusCode: 502,
|
|
message: `AdGuard API error: ${err.message || "unknown"}`,
|
|
});
|
|
}
|
|
}
|