mirror of https://github.com/wg-easy/wg-easy
11 changed files with 156 additions and 39 deletions
@ -0,0 +1,58 @@ |
|||||
|
<template> |
||||
|
<main v-if="data"> |
||||
|
<FormElement @submit.prevent="submit"> |
||||
|
<FormGroup> |
||||
|
<FormTextField id="PreUp" v-model="data.PreUp" label="PreUp" /> |
||||
|
<FormTextField id="PostUp" v-model="data.PostUp" label="PostUp" /> |
||||
|
<FormTextField id="PreDown" v-model="data.PreDown" label="PreDown" /> |
||||
|
<FormTextField id="PostDown" v-model="data.PostDown" label="PostDown" /> |
||||
|
</FormGroup> |
||||
|
<FormGroup> |
||||
|
<FormHeading>Actions</FormHeading> |
||||
|
<FormActionField type="submit" label="Save" /> |
||||
|
<FormActionField label="Revert" @click="revert" /> |
||||
|
</FormGroup> |
||||
|
</FormElement> |
||||
|
</main> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
const toast = useToast(); |
||||
|
|
||||
|
const { data: _data, refresh } = await useFetch(`/api/admin/hooks`, { |
||||
|
method: 'get', |
||||
|
}); |
||||
|
|
||||
|
const data = toRef(_data.value); |
||||
|
|
||||
|
async function submit() { |
||||
|
try { |
||||
|
const res = await $fetch(`/api/admin/hooks`, { |
||||
|
method: 'post', |
||||
|
body: data.value, |
||||
|
}); |
||||
|
toast.showToast({ |
||||
|
type: 'success', |
||||
|
title: 'Success', |
||||
|
message: 'Saved', |
||||
|
}); |
||||
|
if (!res.success) { |
||||
|
throw new Error('Failed to save'); |
||||
|
} |
||||
|
await refreshNuxtData(); |
||||
|
} catch (e) { |
||||
|
if (e instanceof Error) { |
||||
|
toast.showToast({ |
||||
|
type: 'error', |
||||
|
title: 'Error', |
||||
|
message: e.message, |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function revert() { |
||||
|
await refresh(); |
||||
|
data.value = toRef(_data.value).value; |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,4 @@ |
|||||
|
export default defineEventHandler(async () => { |
||||
|
const system = await Database.system.get(); |
||||
|
return system.hooks; |
||||
|
}); |
@ -0,0 +1,8 @@ |
|||||
|
export default defineEventHandler(async (event) => { |
||||
|
const data = await readValidatedBody( |
||||
|
event, |
||||
|
validateZod(hooksUpdateType, event) |
||||
|
); |
||||
|
await Database.system.updateHooks(data); |
||||
|
return { success: true }; |
||||
|
}); |
@ -0,0 +1,27 @@ |
|||||
|
import type { DeepReadonly } from 'vue'; |
||||
|
import type { System } from '~~/services/database/repositories/system'; |
||||
|
|
||||
|
/** |
||||
|
* Replace all {{key}} in the template with the values[key] |
||||
|
*/ |
||||
|
export function template(templ: string, values: Record<string, string>) { |
||||
|
return templ.replace(/\{\{(\w+)\}\}/g, (match, key) => { |
||||
|
return values[key] !== undefined ? values[key] : match; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Available keys: |
||||
|
* - address4: IPv4 address range |
||||
|
* - address6: IPv6 address range |
||||
|
* - device: Network device |
||||
|
* - port: Port number |
||||
|
*/ |
||||
|
export function iptablesTemplate(templ: string, system: DeepReadonly<System>) { |
||||
|
return template(templ, { |
||||
|
address4: system.userConfig.address4Range, |
||||
|
address6: system.userConfig.address6Range, |
||||
|
device: system.interface.device, |
||||
|
port: system.interface.port.toString(), |
||||
|
}); |
||||
|
} |
Loading…
Reference in new issue