diff --git a/src/server/api/root.ts b/src/server/api/root.ts index 28d8cc9e0..31284ccf3 100644 --- a/src/server/api/root.ts +++ b/src/server/api/root.ts @@ -5,6 +5,7 @@ import { configRouter } from './routers/config'; import { dockerRouter } from './routers/docker/router'; import { iconRouter } from './routers/icon'; import { dashDotRouter } from './routers/dash-dot'; +import { dnsHoleRouter } from './routers/dns-hole'; /** * This is the primary router for your server. @@ -18,6 +19,7 @@ export const rootRouter = createTRPCRouter({ docker: dockerRouter, icon: iconRouter, dashDot: dashDotRouter, + dnsHole: dnsHoleRouter, }); // export type definition of API diff --git a/src/server/api/routers/dns-hole.ts b/src/server/api/routers/dns-hole.ts new file mode 100644 index 000000000..410aef26b --- /dev/null +++ b/src/server/api/routers/dns-hole.ts @@ -0,0 +1,61 @@ +import { z } from 'zod'; +import { createTRPCRouter, publicProcedure } from '../trpc'; +import { getConfig } from '~/tools/config/getConfig'; +import { AdGuard } from '~/tools/server/sdk/adGuard/adGuard'; +import { ConfigAppType } from '~/types/app'; +import { findAppProperty } from '~/tools/client/app-properties'; +import { PiHoleClient } from '~/tools/server/sdk/pihole/piHole'; + +export const dnsHoleRouter = createTRPCRouter({ + control: publicProcedure + .input( + z.object({ + status: z.enum(['enabled', 'disabled']), + configName: z.string(), + }) + ) + .mutation(async ({ input }) => { + const config = getConfig(input.configName); + + const applicableApps = config.apps.filter( + (x) => x.integration?.type && ['pihole', 'adGuardHome'].includes(x.integration?.type) + ); + + await Promise.all( + applicableApps.map(async (app) => { + if (app.integration?.type === 'pihole') { + await processPiHole(app, input.status === 'disabled'); + return; + } + + await processAdGuard(app, input.status === 'disabled'); + }) + ); + }), +}); + +const processAdGuard = async (app: ConfigAppType, enable: boolean) => { + const adGuard = new AdGuard( + app.url, + findAppProperty(app, 'username'), + findAppProperty(app, 'password') + ); + + if (enable) { + await adGuard.disable(); + return; + } + + await adGuard.enable(); +}; + +const processPiHole = async (app: ConfigAppType, enable: boolean) => { + const pihole = new PiHoleClient(app.url, findAppProperty(app, 'password')); + + if (enable) { + await pihole.enable(); + return; + } + + await pihole.disable(); +}; diff --git a/src/widgets/dnshole/DnsHoleControls.tsx b/src/widgets/dnshole/DnsHoleControls.tsx index 0da8a3178..f7f0c8469 100644 --- a/src/widgets/dnshole/DnsHoleControls.tsx +++ b/src/widgets/dnshole/DnsHoleControls.tsx @@ -5,9 +5,10 @@ import { useConfigContext } from '../../config/provider'; import { defineWidget } from '../helper'; import { WidgetLoading } from '../loading'; import { IWidget } from '../widgets'; -import { useDnsHoleControlMutation, useDnsHoleSummeryQuery } from './query'; +import { useDnsHoleSummeryQuery } from './query'; import { PiholeApiSummaryType } from './type'; import { queryClient } from '../../tools/server/configurations/tanstack/queryClient.tool'; +import { api } from '~/utils/api'; const definition = defineWidget({ id: 'dns-hole-controls', @@ -33,9 +34,9 @@ function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) { const { mutateAsync } = useDnsHoleControlMutation(); const { t } = useTranslation('common'); - const { config } = useConfigContext(); + const { name: configName, config } = useConfigContext(); - if (isInitialLoading || !data) { + if (isInitialLoading || !data || !configName) { return ; } @@ -44,7 +45,10 @@ function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) {