mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
fix: harden Wake-on-LAN MAC handling
Normalize stored MAC addresses, avoid shell execution for ether-wake, handle missing WOL history gracefully, and improve the WOL menu display for named MAC entries.
This commit is contained in:
@@ -56,33 +56,37 @@ export const Wol = () => {
|
||||
|
||||
const isEdit = false;
|
||||
const macList = rsp.data.macs
|
||||
.filter((item: string) => item.trim() !== '')
|
||||
.map((item: string) => item.trim())
|
||||
.filter((item: string) => item !== '')
|
||||
.map((item: string) => {
|
||||
const parts = item.split(' ');
|
||||
const isName = parts.length > 1;
|
||||
const name = isName ? parts[1] : '';
|
||||
const mac = parts[0];
|
||||
const separator = item.search(/\s/);
|
||||
const mac = separator === -1 ? item : item.slice(0, separator);
|
||||
const name = separator === -1 ? '' : item.slice(separator).trim();
|
||||
const isName = name !== '';
|
||||
const isShow = !isName;
|
||||
return { name, mac, isShow, isName, isEdit };
|
||||
});
|
||||
|
||||
setMacList([]);
|
||||
setMacList(macList);
|
||||
});
|
||||
}
|
||||
|
||||
function toggleShow(mac: string) {
|
||||
setMacList(
|
||||
macList.map((item) => (item.mac === mac ? { ...item, isShow: !item.isShow } : item))
|
||||
setMacList((list) =>
|
||||
list.map((item) => (item.mac === mac ? { ...item, isShow: !item.isShow } : item))
|
||||
);
|
||||
}
|
||||
|
||||
function editMac(mac: string, isEdit: boolean) {
|
||||
setMacList(macList.map((item) => (item.mac === mac ? { ...item, isEdit: !isEdit } : item)));
|
||||
setMacList((list) =>
|
||||
list.map((item) => (item.mac === mac ? { ...item, isEdit: !isEdit } : item))
|
||||
);
|
||||
}
|
||||
|
||||
async function setMacName(e: React.KeyboardEvent<HTMLInputElement>, mac: string) {
|
||||
const value: string = e.currentTarget.value;
|
||||
const value = e.currentTarget.value.trim();
|
||||
if (!value) return;
|
||||
|
||||
const rsp = await setWolMacName(mac, value);
|
||||
if (rsp.code !== 0) {
|
||||
console.log(rsp.msg);
|
||||
@@ -102,7 +106,7 @@ export const Wol = () => {
|
||||
function wake(mac?: string) {
|
||||
if (status === 'loading') return;
|
||||
|
||||
const value = mac ? mac : input;
|
||||
const value = (mac ? mac : input).trim();
|
||||
if (!value) return;
|
||||
|
||||
setStatus('loading');
|
||||
@@ -123,6 +127,7 @@ export const Wol = () => {
|
||||
})
|
||||
.catch(() => {
|
||||
setStatus('failed');
|
||||
setLog(t('auth.error'));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -134,15 +139,20 @@ export const Wol = () => {
|
||||
|
||||
<Divider style={{ margin: '10px 0 10px 0' }} />
|
||||
|
||||
<div className="pb-1 text-neutral-500">{t('wol.input')}</div>
|
||||
<div className="flex items-center space-x-1">
|
||||
<Input ref={inputRef} value={input} onChange={handleChange} onPressEnter={() => wake()} />
|
||||
<Button type="primary" onClick={() => wake()}>
|
||||
{t('wol.ok')}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="w-full space-y-1 py-3">
|
||||
<div className="flex items-center space-x-1">
|
||||
<Input
|
||||
ref={inputRef}
|
||||
value={input}
|
||||
placeholder={t('wol.input')}
|
||||
onChange={handleChange}
|
||||
onPressEnter={() => wake()}
|
||||
/>
|
||||
<Button type="primary" onClick={() => wake()}>
|
||||
{t('wol.ok')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={clsx('py-2')}>
|
||||
{status && (
|
||||
<div
|
||||
className={clsx(
|
||||
@@ -155,58 +165,60 @@ export const Wol = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<List
|
||||
itemLayout="horizontal"
|
||||
locale={{ emptyText: ' ' }}
|
||||
dataSource={macList}
|
||||
renderItem={(item) => (
|
||||
<List.Item className="flex w-full items-center justify-between">
|
||||
<div className="h-[24px] max-w-[200px]">
|
||||
{item.isEdit ? (
|
||||
<Input
|
||||
onFocus={() => setIsKeyboardEnable(false)}
|
||||
onBlur={() => setIsKeyboardEnable(true)}
|
||||
defaultValue={item.name}
|
||||
onPressEnter={(e) => setMacName(e, item.mac)}
|
||||
/>
|
||||
) : item.isShow ? (
|
||||
item.mac
|
||||
) : (
|
||||
item.name
|
||||
)}
|
||||
</div>
|
||||
{macList.length > 0 && (
|
||||
<List
|
||||
itemLayout="horizontal"
|
||||
dataSource={macList}
|
||||
renderItem={(item) => (
|
||||
<List.Item className="flex w-full items-center justify-between">
|
||||
<div className="h-[24px] max-w-[200px]">
|
||||
{item.isEdit ? (
|
||||
<Input
|
||||
placeholder={item.mac}
|
||||
onFocus={() => setIsKeyboardEnable(false)}
|
||||
onBlur={() => setIsKeyboardEnable(true)}
|
||||
defaultValue={item.name}
|
||||
onPressEnter={(e) => setMacName(e, item.mac)}
|
||||
/>
|
||||
) : item.isShow ? (
|
||||
item.mac
|
||||
) : (
|
||||
item.name
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-1">
|
||||
{item.isName && (
|
||||
<div className="flex items-center space-x-1">
|
||||
{item.isName && (
|
||||
<div
|
||||
className="text-500 flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded hover:bg-neutral-700/80"
|
||||
onClick={() => toggleShow(item.mac)}
|
||||
>
|
||||
{item.isShow ? <EyeClosed size={16} /> : <Eye size={16} />}
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="text-500 flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded hover:bg-neutral-700/80"
|
||||
onClick={() => toggleShow(item.mac)}
|
||||
className="text-500 flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded hover:bg-neutral-700"
|
||||
onClick={() => editMac(item.mac, item.isEdit)}
|
||||
>
|
||||
{item.isShow ? <EyeClosed size={16} /> : <Eye size={16} />}
|
||||
<Pencil size={16} />
|
||||
</div>
|
||||
<div
|
||||
className="flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded text-green-500 hover:bg-neutral-700/80"
|
||||
onClick={() => wake(item.mac)}
|
||||
>
|
||||
<SendIcon size={16} />
|
||||
</div>
|
||||
<div
|
||||
className="flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded text-red-500 hover:bg-neutral-700"
|
||||
onClick={() => deleteMac(item.mac)}
|
||||
>
|
||||
<Trash2Icon size={16} />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="text-500 flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded hover:bg-neutral-700"
|
||||
onClick={() => editMac(item.mac, item.isEdit)}
|
||||
>
|
||||
<Pencil size={16} />
|
||||
</div>
|
||||
<div
|
||||
className="flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded text-green-500 hover:bg-neutral-700/80"
|
||||
onClick={() => wake(item.mac)}
|
||||
>
|
||||
<SendIcon size={16} />
|
||||
</div>
|
||||
<div
|
||||
className="flex h-[24px] w-[24px] cursor-pointer items-center justify-center rounded text-red-500 hover:bg-neutral-700"
|
||||
onClick={() => deleteMac(item.mac)}
|
||||
>
|
||||
<Trash2Icon size={16} />
|
||||
</div>
|
||||
</div>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user