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

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
},
deleteConfiguration: {
modalOpen: true
modalOpen: false
}
}
},

View File

@@ -58,7 +58,16 @@ export default {
exact-active-class="active">
<i class="bi bi-gear me-2"></i>
<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>
<hr class="text-body">
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted text-center">

View File

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

View File

@@ -44,14 +44,19 @@ export default {
<template>
<div>
<h6>
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText>
</h6>
<div class="d-flex align-items-center">
<strong>
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText>
</strong>
<div class="form-check form-switch ms-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
v-model="this.status"
role="switch" id="allowMFAKeysSwitch">
<label for="allowMFAKeysSwitch">
<LocaleText t="Enabled" v-if="this.status"></LocaleText>
<LocaleText t="Disabled" v-else></LocaleText>
</label>
</div>
<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()">

View File

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

View File

@@ -58,56 +58,54 @@ export default {
</script>
<template>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">
<div>
<h5>
<LocaleText t="Dashboard IP Address & Listen Port"></LocaleText>
</p>
<div class="card-body">
<div class="row gx-3">
<div class="col-sm">
<div class="form-group mb-2">
<label for="input_dashboard_ip" class="text-muted mb-1">
<strong><small>
<LocaleText t="IP Address / Hostname"></LocaleText>
</small></strong>
</label>
<input type="text" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
id="input_dashboard_ip"
v-model="this.ipAddress"
@keydown="this.changed = true"
@blur="useValidation($event, 'app_ip', this.ipAddress)"
:disabled="this.updating"
>
<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>
</h5>
<div class="row g-2">
<div class="col-sm">
<div class="form-group">
<label for="input_dashboard_ip" class="text-muted mb-1">
<strong><small>
<LocaleText t="IP Address / Hostname"></LocaleText>
</small></strong>
</label>
<input type="text" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
id="input_dashboard_ip"
v-model="this.ipAddress"
@keydown="this.changed = true"
@blur="useValidation($event, 'app_ip', this.ipAddress)"
:disabled="this.updating"
>
<div class="invalid-feedback">{{this.invalidFeedback}}</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">
<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 class="col-sm">
<div class="form-group">
<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
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>
</template>

View File

@@ -44,11 +44,11 @@ export default {
</script>
<template>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">
<LocaleText t="Dashboard Language"></LocaleText>
</p>
<div class="card-body d-flex gap-2">
<div>
<small class="text-muted d-block mb-1">
<strong><LocaleText t="Language"></LocaleText></strong>
</small>
<div class="d-flex gap-2">
<div class="dropdown w-100">
<button class="btn bg-primary-subtle text-primary-emphasis dropdown-toggle w-100 rounded-3"
: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>
<template>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">
<LocaleText t="Dashboard Theme"></LocaleText>
</p>
<div class="card-body d-flex gap-2">
<div >
<small class="text-muted mb-1 d-block">
<strong>
<LocaleText t="Theme"></LocaleText>
</strong>
</small>
<div class="d-flex gap-1">
<button class="btn bg-primary-subtle text-primary-emphasis flex-grow-1"
@click="this.switchTheme('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 DashboardLanguage from "@/components/settingsComponent/dashboardLanguage.vue";
import DashboardIPPortInput from "@/components/settingsComponent/dashboardIPPortInput.vue";
import DashboardSettingsWireguardConfigurationAutostart
from "@/components/settingsComponent/dashboardSettingsWireguardConfigurationAutostart.vue";
export default {
name: "settings",
methods: {ipV46RegexCheck},
components: {
DashboardSettingsWireguardConfigurationAutostart,
DashboardIPPortInput,
DashboardLanguage,
LocaleText,
@@ -36,75 +39,99 @@ export default {
</script>
<template>
<div class="mt-md-5 mt-3">
<div class="container-md">
<h2 class="mb-4 text-body">
<LocaleText t="Settings"></LocaleText>
</h2>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">
<LocaleText t="Peers Default Settings"></LocaleText>
</p>
<div class="card-body">
<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 class="mt-md-5 mt-3 text-body mb-3">
<div class="container-md d-flex flex-column gap-4">
<div>
<h2>
<LocaleText t="WireGuard Configuration Settings"></LocaleText>
</h2>
<hr>
<div class="card rounded-3 mb-3">
<div class="card-body">
<DashboardSettingsInputWireguardConfigurationPath
targetData="wg_conf_path"
title="Configurations Directory"
:warning="true"
warning-text="Remember to remove / at the end of your path. e.g /etc/wireguard"
>
</DashboardSettingsInputWireguardConfigurationPath>
</div>
</div>
<div class="card rounded-3 mb-3">
<div class="card-body">
<DashboardSettingsWireguardConfigurationAutostart></DashboardSettingsWireguardConfigurationAutostart>
</div>
</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 class="card mb-4 shadow rounded-3">
<p class="card-header">
<LocaleText t="WireGuard Configurations Settings"></LocaleText>
</p>
<div class="card-body">
<DashboardSettingsInputWireguardConfigurationPath
targetData="wg_conf_path"
title="Configurations Directory"
:warning="true"
warning-text="Remember to remove / at the end of your path. e.g /etc/wireguard"
>
</DashboardSettingsInputWireguardConfigurationPath>
</div>
</div>
<hr class="mb-4">
<div class="row gx-4">
<div class="col-sm">
<DashboardTheme></DashboardTheme>
</div>
<div class="col-sm">
<DashboardLanguage></DashboardLanguage>
</div>
<div>
<h2>
<LocaleText t="WGDashboard Settings"></LocaleText>
</h2>
<hr>
<div class="d-flex flex-column gap-3">
<div class="card rounded-3">
<div class="card-body">
<div class="row g-2">
<div class="col-sm">
<DashboardTheme></DashboardTheme>
</div>
<div class="col-sm">
<DashboardLanguage></DashboardLanguage>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<DashboardIPPortInput></DashboardIPPortInput>
</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>
<DashboardIPPortInput></DashboardIPPortInput>
<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>
<AccountSettingsMFA v-if="!this.dashboardConfigurationStore.getActiveCrossServer()"></AccountSettingsMFA>
</div>
</div>
<DashboardAPIKeys></DashboardAPIKeys>
</div>
</div>
<DashboardAPIKeys></DashboardAPIKeys>
</div>
</div>
</template>