feat: sending wake packets, closes #10
This commit is contained in:
parent
f1143551d6
commit
96d2696e17
@ -34,7 +34,7 @@
|
||||
}}
|
||||
>
|
||||
{#if data.Icon}
|
||||
<data.Icon class="sm:-ml-2 {data.spin ? 'animate-spin' : ''}" />
|
||||
<data.Icon class="-ml-2 {data.spin ? 'animate-spin' : ''} w-5 sm:w-auto" />
|
||||
{/if}
|
||||
<p role="alert">{data.content}</p>
|
||||
{#if data.dismissable}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import { Button } from 'bits-ui';
|
||||
import IconEdit from '~icons/tabler/edit';
|
||||
import IconPlay from '~icons/tabler/player-play';
|
||||
|
||||
let { title, subtitle, editHref = null, wakePost = null } = $props();
|
||||
let { title, subtitle, editHref = null, wakeId = null } = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -25,13 +26,16 @@
|
||||
</Button.Root>
|
||||
{/if}
|
||||
|
||||
{#if wakePost}
|
||||
{#if wakeId}
|
||||
<form use:enhance method="POST" action="?/wake">
|
||||
<input type="hidden" name="id" value={wakeId} />
|
||||
<Button.Root
|
||||
class="bg-emerald-600 hover:bg-emerald-800 transition-all duration-300 ease-in-out
|
||||
border border-emerald-500 rounded-full p-4 text-neutral-100 cursor-pointer"
|
||||
>
|
||||
<IconPlay />
|
||||
</Button.Root>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { FORBIDDEN, SUCCESS } from '$lib/server/commonResponses';
|
||||
import { users } from '$lib/server/db';
|
||||
import type { ServerLoad } from '@sveltejs/kit';
|
||||
import { fail, type Actions, type ServerLoad } from '@sveltejs/kit';
|
||||
import { wake } from 'wake_on_lan';
|
||||
|
||||
export const load: ServerLoad = async ({ locals: { guard } }) => {
|
||||
const user = guard.requiresAuth().orRedirects().getUser();
|
||||
@ -7,3 +9,44 @@ export const load: ServerLoad = async ({ locals: { guard } }) => {
|
||||
devices: await users.fetchDevices(user.id),
|
||||
};
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
wake: async ({ locals: { guard }, request }) => {
|
||||
guard = guard.requiresAuth();
|
||||
if (guard.isFailed()) return FORBIDDEN;
|
||||
|
||||
const deviceId = (await request.formData()).get('id');
|
||||
const device = (await users.fetchDevices(guard.getUser().id)).find((d) => d.id === deviceId);
|
||||
|
||||
if (!device) {
|
||||
return fail(404, { error: 'Could not find device.' });
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Sending WOL packets to ${device.name} (${device.mac}) on ${guard.getUser().name}'s request.`,
|
||||
);
|
||||
|
||||
const err = await new Promise<any>((resolve) => {
|
||||
wake(
|
||||
device.mac,
|
||||
{
|
||||
address: device.broadcast,
|
||||
port: device.port,
|
||||
num_packets: device.packets,
|
||||
},
|
||||
(err: any) => {
|
||||
resolve(err);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return fail(500, {
|
||||
error: 'An error occured while trying to wake the device. Please see logs.',
|
||||
});
|
||||
}
|
||||
|
||||
return { ...SUCCESS, deviceName: device.name };
|
||||
},
|
||||
} satisfies Actions;
|
||||
|
||||
@ -1,11 +1,31 @@
|
||||
<script>
|
||||
import { store } from '$lib/v2/globalStore.svelte.js';
|
||||
import ListPage from '$lib/v2/snippets/ListPage.svelte';
|
||||
import { Toast } from '$lib/v2/toast/notification.js';
|
||||
import ResCard from '$lib/v2/ui/ResCard.svelte';
|
||||
import { untrack } from 'svelte';
|
||||
import IconCheck from '~icons/tabler/check';
|
||||
import IconX from '~icons/tabler/x';
|
||||
|
||||
let { data } = $props();
|
||||
let { data, form } = $props();
|
||||
|
||||
store.pageTitle = 'Listing all devices';
|
||||
|
||||
$effect(() => {
|
||||
if (form?.error && !form.success) {
|
||||
untrack(() => {
|
||||
Toast.add({ Icon: IconX, content: form.error, theme: 'error' });
|
||||
});
|
||||
} else if (form?.success) {
|
||||
untrack(() => {
|
||||
Toast.add({
|
||||
Icon: IconCheck,
|
||||
content: `Sent magic packets to ${form.deviceName}.`,
|
||||
theme: 'success',
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<ListPage createHref={data.user.admin ? '/dash/devices/new' : null} msgAdd="Add Device">
|
||||
@ -15,7 +35,7 @@
|
||||
title={device.name}
|
||||
subtitle={device.mac}
|
||||
editHref={data.user.admin ? `/dash/devices/${device.id}` : null}
|
||||
wakePost={`/dash/devices/${device.id}/wake`}
|
||||
wakeId={device.id}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { FORBIDDEN, PARSE_ERROR, SUCCESS } from '$lib/server/commonResponses';
|
||||
import { devices, users } from '$lib/server/db/index.js';
|
||||
import { fail, redirect, type Actions, type ServerLoad } from '@sveltejs/kit';
|
||||
import { devices } from '$lib/server/db/index.js';
|
||||
import { redirect, type Actions, type ServerLoad } from '@sveltejs/kit';
|
||||
import { decode } from 'decode-formdata';
|
||||
import validator from 'validator';
|
||||
import { wake } from 'wake_on_lan';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const load: ServerLoad = async ({ locals: { guard }, params }) => {
|
||||
@ -65,25 +64,4 @@ export const actions = {
|
||||
const err = await devices.delete(params.id ?? '');
|
||||
return err ? err.toFail() : SUCCESS;
|
||||
},
|
||||
|
||||
wake: async ({ params, locals: { guard } }) => {
|
||||
guard = guard.requiresAuth();
|
||||
if (guard.isFailed()) return FORBIDDEN;
|
||||
|
||||
const device = (await users.fetchDevices(guard.getUser().id)).find((d) => d.id === params.id);
|
||||
|
||||
if (!device) {
|
||||
return fail(404);
|
||||
}
|
||||
|
||||
console.log('Trying to wake ' + device.name);
|
||||
|
||||
wake(device.mac, {
|
||||
address: device.broadcast,
|
||||
port: device.port,
|
||||
num_packets: device.packets,
|
||||
});
|
||||
|
||||
return SUCCESS;
|
||||
},
|
||||
} satisfies Actions;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user