1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-22 07:10:09 +01:00
This commit is contained in:
Donald Zou 2024-10-29 14:57:29 +08:00
parent d7e5e2f381
commit 01c0175e8f
13 changed files with 299 additions and 225 deletions

View File

@ -441,12 +441,12 @@ class WireguardConfiguration:
return self.message return self.message
def __init__(self, name: str = None, data: dict = None, backup: dict = None): def __init__(self, name: str = None, data: dict = None, backup: dict = None):
print(f"[WGDashboard] Initialized Configuration: {name}")
self.__parser: configparser.ConfigParser = configparser.ConfigParser(strict=False) self.__parser: configparser.ConfigParser = configparser.ConfigParser(strict=False)
self.__parser.optionxform = str self.__parser.optionxform = str
self.__configFileModifiedTime = None self.__configFileModifiedTime = None
self.Status: bool = False self.Status: bool = False
self.Name: str = "" self.Name: str = ""
self.PrivateKey: str = "" self.PrivateKey: str = ""
@ -504,10 +504,13 @@ class WireguardConfiguration:
with open(self.__configPath, "w+") as configFile: with open(self.__configPath, "w+") as configFile:
self.__parser.write(configFile) self.__parser.write(configFile)
self.__initPeersList() self.__initPeersList()
print(f"[WGDashboard] Initialized Configuration: {name}")
if self.getAutostartStatus() and not self.getStatus():
self.toggleConfiguration()
print(f"[WGDashboard] Autostart Configuration: {name}")
def __initPeersList(self): def __initPeersList(self):
self.Peers: list[Peer] = [] self.Peers: list[Peer] = []
self.getPeersList() self.getPeersList()
@ -621,6 +624,10 @@ class WireguardConfiguration:
def getStatus(self) -> bool: def getStatus(self) -> bool:
self.Status = self.Name in psutil.net_if_addrs().keys() self.Status = self.Name in psutil.net_if_addrs().keys()
return self.Status return self.Status
def getAutostartStatus(self):
s, d = DashboardConfig.GetConfig("WireGuardConfiguration", "autostart")
return self.Name in d
def __getRestrictedPeers(self): def __getRestrictedPeers(self):
self.RestrictedPeers = [] self.RestrictedPeers = []
@ -1078,7 +1085,6 @@ class WireguardConfiguration:
self.__dropDatabase() self.__dropDatabase()
return True return True
class Peer: class Peer:
def __init__(self, tableData, configuration: WireguardConfiguration): def __init__(self, tableData, configuration: WireguardConfiguration):
self.configuration = configuration self.configuration = configuration
@ -1225,17 +1231,11 @@ PersistentKeepalive = {str(self.keepalive)}
except Exception as e: except Exception as e:
return False return False
return True return True
# Regex Match # Regex Match
def regex_match(regex, text): def regex_match(regex, text):
pattern = re.compile(regex) pattern = re.compile(regex)
return pattern.search(text) is not None return pattern.search(text) is not None
def iPv46RegexCheck(ip):
return re.match(
r'((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))',
ip)
class DashboardAPIKey: class DashboardAPIKey:
def __init__(self, Key: str, CreatedAt: str, ExpiredAt: str): def __init__(self, Key: str, CreatedAt: str, ExpiredAt: str):
self.Key = Key self.Key = Key
@ -1287,6 +1287,9 @@ class DashboardConfig:
}, },
"Database":{ "Database":{
"type": "sqlite" "type": "sqlite"
},
"WireGuardConfiguration": {
"autostart": ""
} }
} }
@ -1324,8 +1327,6 @@ class DashboardConfig:
sqlUpdate("UPDATE DashboardAPIKeys SET ExpiredAt = datetime('now', 'localtime') WHERE Key = ?", (key, )) sqlUpdate("UPDATE DashboardAPIKeys SET ExpiredAt = datetime('now', 'localtime') WHERE Key = ?", (key, ))
self.DashboardAPIKeys = self.__getAPIKeys() self.DashboardAPIKeys = self.__getAPIKeys()
def __configValidation(self, key, value: Any) -> [bool, str]: def __configValidation(self, key, value: Any) -> [bool, str]:
if type(value) is str and len(value) == 0: if type(value) is str and len(value) == 0:
return False, "Field cannot be empty!" return False, "Field cannot be empty!"
@ -1384,8 +1385,10 @@ class DashboardConfig:
self.__config[section][key] = "true" self.__config[section][key] = "true"
else: else:
self.__config[section][key] = "false" self.__config[section][key] = "false"
if type(value) in [int, float]: elif type(value) in [int, float]:
self.__config[section][key] = str(value) self.__config[section][key] = str(value)
elif type(value) is list:
self.__config[section][key] = "||".join(value)
else: else:
self.__config[section][key] = value self.__config[section][key] = value
return self.SaveConfig(), "" return self.SaveConfig(), ""
@ -1411,6 +1414,9 @@ class DashboardConfig:
if self.__config[section][key] in ["0", "no", "false", "off"]: if self.__config[section][key] in ["0", "no", "false", "off"]:
return True, False return True, False
if section == "WireGuardConfiguration" and key == "autostart":
return True, self.__config[section][key].split("||")
return True, self.__config[section][key] return True, self.__config[section][key]
@ -1421,12 +1427,7 @@ class DashboardConfig:
the_dict[section] = {} the_dict[section] = {}
for key, val in self.__config.items(section): for key, val in self.__config.items(section):
if key not in self.hiddenAttribute: if key not in self.hiddenAttribute:
if val in ["1", "yes", "true", "on"]: the_dict[section][key] = self.GetConfig(section, key)[1]
the_dict[section][key] = True
elif val in ["0", "no", "false", "off"]:
the_dict[section][key] = False
else:
the_dict[section][key] = val
return the_dict return the_dict

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -159,7 +159,7 @@ export default {
modalOpen: false modalOpen: false
}, },
deleteConfiguration: { deleteConfiguration: {
modalOpen: true modalOpen: false
} }
} }
}, },

View File

@ -58,7 +58,16 @@ export default {
exact-active-class="active"> exact-active-class="active">
<i class="bi bi-gear me-2"></i> <i class="bi bi-gear me-2"></i>
<LocaleText t="Settings"></LocaleText> <LocaleText t="Settings"></LocaleText>
</RouterLink></li> </RouterLink>
</li>
<li class="nav-item">
<a class="nav-link rounded-3"
target="_blank"
href="https://donaldzou.github.io/WGDashboard-Documentation/user-guides.html">
<i class="bi bi-question-circle me-2"></i>
<LocaleText t="Help"></LocaleText>
</a>
</li>
</ul> </ul>
<hr class="text-body"> <hr class="text-body">
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted text-center"> <h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted text-center">

View File

@ -78,16 +78,16 @@ export default {
</script> </script>
<template> <template>
<div class="d-flex flex-column"> <div class="d-flex flex-column gap-2">
<div class="row"> <div class="row g-2">
<div class="col-sm"> <div class="col-sm">
<div class="form-group mb-2"> <div class="form-group">
<label :for="'currentPassword_' + this.uuid" class="text-muted mb-1"> <label :for="'currentPassword_' + this.uuid" class="text-muted mb-1">
<strong><small> <strong><small>
<LocaleText t="Current Password"></LocaleText> <LocaleText t="Current Password"></LocaleText>
</small></strong> </small></strong>
</label> </label>
<input type="password" class="form-control mb-2" <input type="password" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}" :class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
v-model="this.value.currentPassword" v-model="this.value.currentPassword"
:id="'currentPassword_' + this.uuid"> :id="'currentPassword_' + this.uuid">
@ -95,13 +95,13 @@ export default {
</div> </div>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<div class="form-group mb-2"> <div class="form-group">
<label :for="'newPassword_' + this.uuid" class="text-muted mb-1"> <label :for="'newPassword_' + this.uuid" class="text-muted mb-1">
<strong><small> <strong><small>
<LocaleText t="New Password"></LocaleText> <LocaleText t="New Password"></LocaleText>
</small></strong> </small></strong>
</label> </label>
<input type="password" class="form-control mb-2" <input type="password" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}" :class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
v-model="this.value.newPassword" v-model="this.value.newPassword"
:id="'newPassword_' + this.uuid"> :id="'newPassword_' + this.uuid">
@ -109,13 +109,13 @@ export default {
</div> </div>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<div class="form-group mb-2"> <div class="form-group">
<label :for="'repeatNewPassword_' + this.uuid" class="text-muted mb-1"> <label :for="'repeatNewPassword_' + this.uuid" class="text-muted mb-1">
<strong><small> <strong><small>
<LocaleText t="Repeat New Password"></LocaleText> <LocaleText t="Repeat New Password"></LocaleText>
</small></strong> </small></strong>
</label> </label>
<input type="password" class="form-control mb-2" <input type="password" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}" :class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
v-model="this.value.repeatNewPassword" v-model="this.value.repeatNewPassword"
:id="'repeatNewPassword_' + this.uuid"> :id="'repeatNewPassword_' + this.uuid">

View File

@ -44,14 +44,19 @@ export default {
<template> <template>
<div> <div>
<h6>
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText>
</h6>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<strong>
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText> <div class="form-check form-switch">
</strong>
<div class="form-check form-switch ms-3">
<input class="form-check-input" type="checkbox" <input class="form-check-input" type="checkbox"
v-model="this.status" v-model="this.status"
role="switch" id="allowMFAKeysSwitch"> role="switch" id="allowMFAKeysSwitch">
<label for="allowMFAKeysSwitch">
<LocaleText t="Enabled" v-if="this.status"></LocaleText>
<LocaleText t="Disabled" v-else></LocaleText>
</label>
</div> </div>
<button class="btn bg-warning-subtle text-warning-emphasis border-1 border-warning-subtle ms-auto rounded-3 shadow-sm" <button class="btn bg-warning-subtle text-warning-emphasis border-1 border-warning-subtle ms-auto rounded-3 shadow-sm"
v-if="this.status" @click="this.resetMFA()"> v-if="this.status" @click="this.resetMFA()">

View File

@ -63,50 +63,52 @@ export default {
</script> </script>
<template> <template>
<div class="card mb-4 shadow rounded-3"> <div class="card rounded-3">
<div class="card-header d-flex"> <div class="card-body position-relative d-flex flex-column gap-2" >
<LocaleText t="API Keys"></LocaleText> <div class="d-flex align-items-center">
<div class="form-check form-switch ms-auto" v-if="!this.store.getActiveCrossServer()"> <h5 class="mb-0">
<input class="form-check-input" type="checkbox" <LocaleText t="API Keys"></LocaleText>
v-model="this.value" </h5>
@change="this.toggleDashboardAPIKeys()" <div class="form-check form-switch ms-auto" v-if="!this.store.getActiveCrossServer()" >
role="switch" id="allowAPIKeysSwitch"> <input class="form-check-input" type="checkbox"
<label class="form-check-label" for="allowAPIKeysSwitch"> v-model="this.value"
<LocaleText t="Enabled" v-if="this.value"></LocaleText> @change="this.toggleDashboardAPIKeys()"
<LocaleText t="Disabled" v-else></LocaleText> role="switch" id="allowAPIKeysSwitch">
<label class="form-check-label" for="allowAPIKeysSwitch">
<LocaleText t="Enabled" v-if="this.value"></LocaleText>
</label> <LocaleText t="Disabled" v-else></LocaleText>
</label>
</div>
</div> </div>
</div> <div v-if="this.value" class="d-flex flex-column gap-2">
<div class="card-body position-relative d-flex flex-column gap-2" v-if="this.value"> <button class="btn bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle rounded-3 shadow-sm"
<button class="ms-auto btn bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle rounded-3 shadow-sm" @click="this.newDashboardAPIKey = true"
@click="this.newDashboardAPIKey = true" v-if="!this.store.getActiveCrossServer()"
v-if="!this.store.getActiveCrossServer()" >
> <i class="bi bi-plus-circle-fill me-2"></i>
<i class="bi bi-plus-circle-fill me-2"></i> <LocaleText t="API Key"></LocaleText>
<LocaleText t="API Key"></LocaleText> </button>
</button> <div class="card" style="height: 300px" v-if="this.apiKeys.length === 0">
<div class="card" style="height: 300px" v-if="this.apiKeys.length === 0"> <div class="card-body d-flex text-muted">
<div class="card-body d-flex text-muted">
<span class="m-auto"> <span class="m-auto">
<LocaleText t="No WGDashboard API Key"></LocaleText> <LocaleText t="No WGDashboard API Key"></LocaleText>
</span> </span>
</div>
</div> </div>
<div class="d-flex flex-column gap-2 position-relative" v-else style="min-height: 300px">
<TransitionGroup name="apiKey">
<DashboardAPIKey v-for="key in this.apiKeys" :apiKey="key"
:key="key.Key"
@deleted="(nkeys) => this.apiKeys = nkeys"></DashboardAPIKey>
</TransitionGroup>
</div>
<Transition name="zoomReversed">
<NewDashboardAPIKey v-if="this.newDashboardAPIKey"
@created="(data) => this.apiKeys = data"
@close="this.newDashboardAPIKey = false"
></NewDashboardAPIKey>
</Transition>
</div> </div>
<div class="d-flex flex-column gap-2 position-relative" v-else style="min-height: 300px">
<TransitionGroup name="apiKey">
<DashboardAPIKey v-for="key in this.apiKeys" :apiKey="key"
:key="key.Key"
@deleted="(nkeys) => this.apiKeys = nkeys"></DashboardAPIKey>
</TransitionGroup>
</div>
<Transition name="zoomReversed">
<NewDashboardAPIKey v-if="this.newDashboardAPIKey"
@created="(data) => this.apiKeys = data"
@close="this.newDashboardAPIKey = false"
></NewDashboardAPIKey>
</Transition>
</div> </div>
</div> </div>

View File

@ -58,56 +58,54 @@ export default {
</script> </script>
<template> <template>
<div class="card mb-4 shadow rounded-3"> <div>
<p class="card-header"> <h5>
<LocaleText t="Dashboard IP Address & Listen Port"></LocaleText> <LocaleText t="Dashboard IP Address & Listen Port"></LocaleText>
</h5>
</p> <div class="row g-2">
<div class="card-body"> <div class="col-sm">
<div class="row gx-3"> <div class="form-group">
<div class="col-sm"> <label for="input_dashboard_ip" class="text-muted mb-1">
<div class="form-group mb-2"> <strong><small>
<label for="input_dashboard_ip" class="text-muted mb-1"> <LocaleText t="IP Address / Hostname"></LocaleText>
<strong><small> </small></strong>
<LocaleText t="IP Address / Hostname"></LocaleText> </label>
</small></strong> <input type="text" class="form-control"
</label> :class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
<input type="text" class="form-control" id="input_dashboard_ip"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}" v-model="this.ipAddress"
id="input_dashboard_ip" @keydown="this.changed = true"
v-model="this.ipAddress" @blur="useValidation($event, 'app_ip', this.ipAddress)"
@keydown="this.changed = true" :disabled="this.updating"
@blur="useValidation($event, 'app_ip', this.ipAddress)" >
:disabled="this.updating" <div class="invalid-feedback">{{this.invalidFeedback}}</div>
>
<div class="invalid-feedback">{{this.invalidFeedback}}</div>
</div>
</div>
<div class="col-sm">
<div class="form-group mb-2">
<label for="input_dashboard_ip" class="text-muted mb-1">
<strong><small>
<LocaleText t="Listen Port"></LocaleText>
</small></strong>
</label>
<input type="number" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
id="input_dashboard_ip"
v-model="this.port"
@keydown="this.changed = true"
@blur="useValidation($event, 'app_port', this.port)"
:disabled="this.updating"
>
<div class="invalid-feedback">{{this.invalidFeedback}}</div>
</div>
</div> </div>
</div> </div>
<div class="px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1 mb-2"> <div class="col-sm">
<small><i class="bi bi-exclamation-triangle-fill me-2"></i> <div class="form-group">
<LocaleText t="Manual restart of WGDashboard is needed to apply changes on IP Address and Listen Port"></LocaleText> <label for="input_dashboard_ip" class="text-muted mb-1">
</small> <strong><small>
<LocaleText t="Listen Port"></LocaleText>
</small></strong>
</label>
<input type="number" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
id="input_dashboard_ip"
v-model="this.port"
@keydown="this.changed = true"
@blur="useValidation($event, 'app_port', this.port)"
:disabled="this.updating"
>
<div class="invalid-feedback">{{this.invalidFeedback}}</div>
</div>
</div> </div>
</div> </div>
<div
class="px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mb-2 mt-2">
<small><i class="bi bi-exclamation-triangle-fill me-2"></i>
<LocaleText t="Manual restart of WGDashboard is needed to apply changes on IP Address and Listen Port"></LocaleText>
</small>
</div>
</div> </div>
</template> </template>

View File

@ -44,11 +44,11 @@ export default {
</script> </script>
<template> <template>
<div class="card mb-4 shadow rounded-3"> <div>
<p class="card-header"> <small class="text-muted d-block mb-1">
<LocaleText t="Dashboard Language"></LocaleText> <strong><LocaleText t="Language"></LocaleText></strong>
</p> </small>
<div class="card-body d-flex gap-2"> <div class="d-flex gap-2">
<div class="dropdown w-100"> <div class="dropdown w-100">
<button class="btn bg-primary-subtle text-primary-emphasis dropdown-toggle w-100 rounded-3" <button class="btn bg-primary-subtle text-primary-emphasis dropdown-toggle w-100 rounded-3"
:disabled="!this.languages" :disabled="!this.languages"

View File

@ -0,0 +1,30 @@
<script setup>
import LocaleText from "@/components/text/localeText.vue";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {computed, ref} from "vue";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
const store = DashboardConfigurationStore()
const wireguardConfigurationStore = WireguardConfigurationsStore()
const data = ref(store.Configuration.WireGuardConfiguration.autostart)
const configurations = computed(() => {
return wireguardConfigurationStore.Configurations.map(x => x.Name)
})
</script>
<template>
<div class="">
<h5>
<LocaleText t="Autostart"></LocaleText>
</h5>
<div class="d-flex gap-2">
<button class="btn btn-outline-primary" v-for="c in configurations">
<i class="bi-circle me-2"></i> {{c}}
</button>
</div>
</div>
</template>
<style scoped>
</style>

View File

@ -27,11 +27,13 @@ export default {
</script> </script>
<template> <template>
<div class="card mb-4 shadow rounded-3"> <div >
<p class="card-header"> <small class="text-muted mb-1 d-block">
<LocaleText t="Dashboard Theme"></LocaleText> <strong>
</p> <LocaleText t="Theme"></LocaleText>
<div class="card-body d-flex gap-2"> </strong>
</small>
<div class="d-flex gap-1">
<button class="btn bg-primary-subtle text-primary-emphasis flex-grow-1" <button class="btn bg-primary-subtle text-primary-emphasis flex-grow-1"
@click="this.switchTheme('light')" @click="this.switchTheme('light')"
:class="{active: this.dashboardConfigurationStore.Configuration.Server.dashboard_theme === 'light'}"> :class="{active: this.dashboardConfigurationStore.Configuration.Server.dashboard_theme === 'light'}">

View File

@ -14,11 +14,14 @@ import AccountSettingsMFA from "@/components/settingsComponent/accountSettingsMF
import LocaleText from "@/components/text/localeText.vue"; import LocaleText from "@/components/text/localeText.vue";
import DashboardLanguage from "@/components/settingsComponent/dashboardLanguage.vue"; import DashboardLanguage from "@/components/settingsComponent/dashboardLanguage.vue";
import DashboardIPPortInput from "@/components/settingsComponent/dashboardIPPortInput.vue"; import DashboardIPPortInput from "@/components/settingsComponent/dashboardIPPortInput.vue";
import DashboardSettingsWireguardConfigurationAutostart
from "@/components/settingsComponent/dashboardSettingsWireguardConfigurationAutostart.vue";
export default { export default {
name: "settings", name: "settings",
methods: {ipV46RegexCheck}, methods: {ipV46RegexCheck},
components: { components: {
DashboardSettingsWireguardConfigurationAutostart,
DashboardIPPortInput, DashboardIPPortInput,
DashboardLanguage, DashboardLanguage,
LocaleText, LocaleText,
@ -36,75 +39,99 @@ export default {
</script> </script>
<template> <template>
<div class="mt-md-5 mt-3"> <div class="mt-md-5 mt-3 text-body mb-3">
<div class="container-md"> <div class="container-md d-flex flex-column gap-4">
<h2 class="mb-4 text-body"> <div>
<LocaleText t="Settings"></LocaleText> <h2>
</h2> <LocaleText t="WireGuard Configuration Settings"></LocaleText>
</h2>
<div class="card mb-4 shadow rounded-3"> <hr>
<p class="card-header"> <div class="card rounded-3 mb-3">
<LocaleText t="Peers Default Settings"></LocaleText> <div class="card-body">
</p> <DashboardSettingsInputWireguardConfigurationPath
<div class="card-body"> targetData="wg_conf_path"
<PeersDefaultSettingsInput title="Configurations Directory"
targetData="peer_global_dns" title="DNS"></PeersDefaultSettingsInput> :warning="true"
<PeersDefaultSettingsInput warning-text="Remember to remove / at the end of your path. e.g /etc/wireguard"
targetData="peer_endpoint_allowed_ip" title="Endpoint Allowed IPs"></PeersDefaultSettingsInput> >
<PeersDefaultSettingsInput </DashboardSettingsInputWireguardConfigurationPath>
targetData="peer_mtu" title="MTU"></PeersDefaultSettingsInput> </div>
<PeersDefaultSettingsInput </div>
targetData="peer_keep_alive" title="Persistent Keepalive"></PeersDefaultSettingsInput> <div class="card rounded-3 mb-3">
<PeersDefaultSettingsInput <div class="card-body">
targetData="remote_endpoint" title="Peer Remote Endpoint" <DashboardSettingsWireguardConfigurationAutostart></DashboardSettingsWireguardConfigurationAutostart>
:warning="true" warningText="This will be changed globally, and will be apply to all peer's QR code and configuration file." </div>
></PeersDefaultSettingsInput> </div>
<div class="card rounded-3 mb-3">
<div class="card-body">
<h5>
<LocaleText t="Peer Default Settings"></LocaleText>
</h5>
<div>
<PeersDefaultSettingsInput
targetData="peer_global_dns" title="DNS"></PeersDefaultSettingsInput>
<PeersDefaultSettingsInput
targetData="peer_endpoint_allowed_ip" title="Endpoint Allowed IPs"></PeersDefaultSettingsInput>
<PeersDefaultSettingsInput
targetData="peer_mtu" title="MTU"></PeersDefaultSettingsInput>
<PeersDefaultSettingsInput
targetData="peer_keep_alive" title="Persistent Keepalive"></PeersDefaultSettingsInput>
<PeersDefaultSettingsInput
targetData="remote_endpoint" title="Peer Remote Endpoint"
:warning="true" warningText="This will be changed globally, and will be apply to all peer's QR code and configuration file."
></PeersDefaultSettingsInput>
</div>
</div>
</div> </div>
</div> </div>
<div class="card mb-4 shadow rounded-3"> <div>
<p class="card-header"> <h2>
<LocaleText t="WireGuard Configurations Settings"></LocaleText> <LocaleText t="WGDashboard Settings"></LocaleText>
</p> </h2>
<div class="card-body"> <hr>
<DashboardSettingsInputWireguardConfigurationPath <div class="d-flex flex-column gap-3">
targetData="wg_conf_path" <div class="card rounded-3">
title="Configurations Directory" <div class="card-body">
:warning="true" <div class="row g-2">
warning-text="Remember to remove / at the end of your path. e.g /etc/wireguard" <div class="col-sm">
> <DashboardTheme></DashboardTheme>
</DashboardSettingsInputWireguardConfigurationPath> </div>
</div> <div class="col-sm">
</div> <DashboardLanguage></DashboardLanguage>
<hr class="mb-4"> </div>
<div class="row gx-4"> </div>
<div class="col-sm"> </div>
<DashboardTheme></DashboardTheme> </div>
</div> <div class="card">
<div class="col-sm"> <div class="card-body">
<DashboardLanguage></DashboardLanguage> <DashboardIPPortInput></DashboardIPPortInput>
</div> </div>
</div>
<div class="card">
<div class="card-body d-flex flex-column gap-3">
<div>
<h5>
<LocaleText t="Account Settings"></LocaleText>
</h5>
<AccountSettingsInputUsername targetData="username"
title="Username"
></AccountSettingsInputUsername>
</div>
<div>
<h6>
<LocaleText t="Update Password"></LocaleText>
</h6>
<AccountSettingsInputPassword
targetData="password">
</AccountSettingsInputPassword>
</div>
</div> <AccountSettingsMFA v-if="!this.dashboardConfigurationStore.getActiveCrossServer()"></AccountSettingsMFA>
<DashboardIPPortInput></DashboardIPPortInput> </div>
</div>
<DashboardAPIKeys></DashboardAPIKeys>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">
<LocaleText t="WGDashboard Account Settings"></LocaleText>
</p>
<div class="card-body d-flex gap-4 flex-column">
<AccountSettingsInputUsername targetData="username"
title="Username"
></AccountSettingsInputUsername>
<hr class="m-0">
<AccountSettingsInputPassword
targetData="password">
</AccountSettingsInputPassword>
<hr class="m-0" v-if="!this.dashboardConfigurationStore.getActiveCrossServer()">
<AccountSettingsMFA v-if="!this.dashboardConfigurationStore.getActiveCrossServer()"></AccountSettingsMFA>
</div> </div>
</div> </div>
<DashboardAPIKeys></DashboardAPIKeys>
</div> </div>
</div> </div>
</template> </template>