Still working on translation...

This commit is contained in:
Donald Zou
2024-09-09 23:43:55 +08:00
parent d458a28337
commit a3a312e3db
32 changed files with 399 additions and 171 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
<script setup>
<script setup async>
import { RouterView } from 'vue-router'
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {computed, watch} from "vue";
@@ -21,7 +21,6 @@ const getActiveCrossServer = computed(() => {
}
return undefined
})
</script>
<template>

View File

@@ -2,10 +2,11 @@
import {wgdashboardStore} from "@/stores/wgdashboardStore.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import ConfigurationCard from "@/components/configurationListComponents/configurationCard.vue";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "configurationList",
components: {ConfigurationCard},
components: {LocaleText, ConfigurationCard},
async setup(){
const wireguardConfigurationsStore = WireguardConfigurationsStore();
return {wireguardConfigurationsStore}
@@ -36,16 +37,18 @@ export default {
<div class="d-flex mb-4 configurationListTitle">
<h3 class="text-body d-flex">
<i class="bi bi-body-text me-2"></i>
<span>WireGuard Configurations</span></h3>
<span>
<LocaleText t="WireGuard Configurations"></LocaleText>
</span></h3>
<RouterLink to="/new_configuration" class="btn btn-dark btn-brand rounded-3 px-3 py-2 shadow ms-auto rounded-3">
<i class="bi bi-plus-circle-fill me-2"></i>
Configuration
<LocaleText t="Configuration"></LocaleText>
</RouterLink>
</div>
<Transition name="fade" mode="out-in">
<div v-if="this.configurationLoaded">
<p class="text-muted" v-if="this.wireguardConfigurationsStore.Configurations.length === 0">
You don't have any WireGuard configurations yet. Please check the configuration folder or change it in "Settings". By default the folder is "/etc/wireguard".
<LocaleText t="You don't have any WireGuard configurations yet. Please check the configuration folder or change it in Settings. By default the folder is /etc/wireguard."></LocaleText>
</p>
<div class="d-flex gap-3 flex-column mb-3" v-else>
<ConfigurationCard v-for="c in this.wireguardConfigurationsStore.Configurations" :key="c.Name" :c="c"></ConfigurationCard>

View File

@@ -3,9 +3,11 @@ import {wgdashboardStore} from "@/stores/wgdashboardStore.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {fetchGet} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "navbar",
components: {LocaleText},
setup(){
const wireguardConfigurationsStore = WireguardConfigurationsStore();
const dashboardConfigurationStore = DashboardConfigurationStore();
@@ -47,17 +49,19 @@ export default {
<RouterLink class="nav-link rounded-3"
to="/" exact-active-class="active">
<i class="bi bi-house me-2"></i>
Home</RouterLink></li>
<LocaleText t="Home"></LocaleText>
</RouterLink></li>
<li class="nav-item">
<RouterLink class="nav-link rounded-3" to="/settings"
exact-active-class="active">
<i class="bi bi-gear me-2"></i>
Settings</RouterLink></li>
<LocaleText t="Settings"></LocaleText>
</RouterLink></li>
</ul>
<hr class="text-body">
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted text-center">
<i class="bi bi-body-text me-2"></i>
Configurations
<LocaleText t="WireGuard Configurations"></LocaleText>
</h6>
<ul class="nav flex-column px-2">
<li class="nav-item">
@@ -72,7 +76,7 @@ export default {
<hr class="text-body">
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted text-center">
<i class="bi bi-tools me-2"></i>
Tools
<LocaleText t="Tools"></LocaleText>
</h6>
<ul class="nav flex-column px-2">
<li class="nav-item">
@@ -87,16 +91,18 @@ export default {
@click="this.dashboardConfigurationStore.signOut()"
role="button" style="font-weight: bold">
<i class="bi bi-box-arrow-left me-2"></i>
Sign Out</a>
<LocaleText t="Sign Out"></LocaleText>
</a>
</li>
<li class="nav-item" style="font-size: 0.8rem">
<a :href="this.updateUrl" v-if="this.updateAvailable" class="text-decoration-none" target="_blank">
<small class="nav-link text-muted rounded-3" >
{{ this.updateMessage }}
<LocaleText :t="this.updateMessage"></LocaleText>
</small>
</a>
<small class="nav-link text-muted" v-else>
{{ this.updateMessage }}
<LocaleText :t="this.updateMessage"></LocaleText>
({{ dashboardConfigurationStore.Configuration.Server.version}})
</small>
</li>
</ul>

View File

@@ -2,9 +2,11 @@
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {v4} from "uuid";
import {fetchPost} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "accountSettingsInputPassword",
components: {LocaleText},
props:{
targetData: String,
warning: false,
@@ -81,7 +83,9 @@ export default {
<div class="col-sm">
<div class="form-group mb-2">
<label :for="'currentPassword_' + this.uuid" class="text-muted mb-1">
<strong><small>Current Password</small></strong>
<strong><small>
<LocaleText t="Current Password"></LocaleText>
</small></strong>
</label>
<input type="password" class="form-control mb-2"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
@@ -93,7 +97,9 @@ export default {
<div class="col-sm">
<div class="form-group mb-2">
<label :for="'newPassword_' + this.uuid" class="text-muted mb-1">
<strong><small>New Password</small></strong>
<strong><small>
<LocaleText t="New Password"></LocaleText>
</small></strong>
</label>
<input type="password" class="form-control mb-2"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
@@ -105,7 +111,9 @@ export default {
<div class="col-sm">
<div class="form-group mb-2">
<label :for="'repeatNewPassword_' + this.uuid" class="text-muted mb-1">
<strong><small>Repeat New Password</small></strong>
<strong><small>
<LocaleText t="Repeat New Password"></LocaleText>
</small></strong>
</label>
<input type="password" class="form-control mb-2"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
@@ -117,7 +125,8 @@ export default {
<button
:disabled="!this.passwordValid"
class="ms-auto btn bg-success-subtle text-success-emphasis border-1 border-success-subtle rounded-3 shadow-sm" @click="this.useValidation()">
<i class="bi bi-save2-fill me-2"></i>Update Password
<i class="bi bi-save2-fill me-2"></i>
<LocaleText t="Update Password"></LocaleText>
</button>
</div>
</template>

View File

@@ -2,14 +2,14 @@
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {v4} from "uuid";
import {fetchPost} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "accountSettingsInputUsername",
components: {LocaleText},
props:{
targetData: String,
title: String,
warning: false,
warningText: ""
},
setup(){
const store = DashboardConfigurationStore();
@@ -62,7 +62,9 @@ export default {
<template>
<div class="form-group mb-2">
<label :for="this.uuid" class="text-muted mb-1">
<strong><small>{{this.title}}</small></strong>
<strong><small>
<LocaleText :t="this.title"></LocaleText>
</small></strong>
</label>
<input type="text" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
@@ -73,11 +75,6 @@ export default {
:disabled="this.updating"
>
<div class="invalid-feedback">{{this.invalidFeedback}}</div>
<div class="px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1"
v-if="warning"
>
<small><i class="bi bi-exclamation-triangle-fill me-2"></i><span v-html="warningText"></span></small>
</div>
</div>
</template>

View File

@@ -2,9 +2,11 @@
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {v4} from "uuid";
import {fetchPost} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "accountSettingsMFA",
components: {LocaleText},
setup(){
const store = DashboardConfigurationStore();
const uuid = `input_${v4()}`;
@@ -43,7 +45,9 @@ export default {
<template>
<div>
<div class="d-flex align-items-center">
<strong>Multi-Factor Authentication</strong>
<strong>
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText>
</strong>
<div class="form-check form-switch ms-3">
<input class="form-check-input" type="checkbox"
v-model="this.status"
@@ -52,7 +56,9 @@ export default {
<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()">
<i class="bi bi-shield-lock-fill me-2"></i>
{{this.store.Configuration.Account["totp_verified"] ? "Reset" : "Setup" }} MFA
<LocaleText t="Reset" v-if='this.store.Configuration.Account["totp_verified"]'></LocaleText>
<LocaleText t="Setup" v-else></LocaleText>
MFA
</button>
</div>
</div>

View File

@@ -4,10 +4,11 @@ import {v4} from "uuid";
import {fetchGet, fetchPost} from "@/utilities/fetch.js";
import NewDashboardAPIKey from "@/components/settingsComponent/dashboardAPIKeysComponents/newDashboardAPIKey.vue";
import DashboardAPIKey from "@/components/settingsComponent/dashboardAPIKeysComponents/dashboardAPIKey.vue";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "dashboardAPIKeys",
components: {DashboardAPIKey, NewDashboardAPIKey},
components: {LocaleText, DashboardAPIKey, NewDashboardAPIKey},
setup(){
const store = DashboardConfigurationStore();
return {store};
@@ -64,14 +65,17 @@ export default {
<template>
<div class="card mb-4 shadow rounded-3">
<div class="card-header d-flex">
API Keys
<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">
{{this.value ? 'Enabled':'Disabled'}}
<LocaleText t="Enabled" v-if="this.value"></LocaleText>
<LocaleText t="Disabled" v-else></LocaleText>
</label>
</div>
</div>
@@ -80,12 +84,13 @@ export default {
@click="this.newDashboardAPIKey = true"
v-if="!this.store.getActiveCrossServer()"
>
<i class="bi bi-key me-2"></i> Create
<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">
No Dashboard API Key
<LocaleText t="No WGDashboard API Key"></LocaleText>
</span>
</div>
</div>

View File

@@ -1,9 +1,11 @@
<script>
import {fetchPost} from "@/utilities/fetch.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "dashboardAPIKey",
components: {LocaleText},
props: {
apiKey: Object
},
@@ -37,11 +39,15 @@ export default {
<div class="card rounded-3 shadow-sm">
<div class="card-body d-flex gap-3 align-items-center apiKey-card-body" v-if="!this.confirmDelete">
<div class="d-flex align-items-center gap-2">
<small class="text-muted">Key</small>
<small class="text-muted">
<LocaleText t="Key"></LocaleText>
</small>
<span style="word-break: break-all">{{this.apiKey.Key}}</span>
</div>
<div class="d-flex align-items-center gap-2 ms-auto">
<small class="text-muted">Expire At</small>
<small class="text-muted">
<LocaleText t="Expire At"></LocaleText>
</small>
{{this.apiKey.ExpiredAt ? this.apiKey.ExpiredAt : 'Never'}}
</div>
<a role="button" class="btn btn-sm bg-danger-subtle text-danger-emphasis rounded-3"
@@ -52,7 +58,7 @@ export default {
</div>
<div v-else class="card-body d-flex gap-3 align-items-center justify-content-end"
v-if="!this.store.getActiveCrossServer()">
Are you sure to delete this API key?
<LocaleText t="Are you sure to delete this API key?"></LocaleText>
<a role="button" class="btn btn-sm bg-success-subtle text-success-emphasis rounded-3"
@click="this.deleteAPIKey()"
>

View File

@@ -3,9 +3,11 @@ import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.
import {v4} from "uuid";
import {fetchPost} from "@/utilities/fetch.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "dashboardSettingsInputWireguardConfigurationPath",
components: {LocaleText},
props:{
targetData: String,
title: String,
@@ -66,7 +68,9 @@ export default {
<template>
<div class="form-group">
<label :for="this.uuid" class="text-muted mb-1">
<strong><small>{{this.title}}</small></strong>
<strong><small>
<LocaleText :t="this.title"></LocaleText>
</small></strong>
</label>
<div class="d-flex gap-2 align-items-start mb-2">
<div class="flex-grow-1">
@@ -90,7 +94,9 @@ export default {
<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"
v-if="warning"
>
<small><i class="bi bi-exclamation-triangle-fill me-2"></i><span v-html="warningText"></span></small>
<small><i class="bi bi-exclamation-triangle-fill me-2"></i>
<LocaleText :t="warningText"></LocaleText>
</small>
</div>
</div>

View File

@@ -1,9 +1,11 @@
<script>
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {fetchPost} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "dashboardTheme",
components: {LocaleText},
setup(){
const dashboardConfigurationStore = DashboardConfigurationStore();
return {dashboardConfigurationStore}
@@ -26,19 +28,21 @@ export default {
<template>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">Dashboard Theme</p>
<p class="card-header">
<LocaleText t="Dashboard Theme"></LocaleText>
</p>
<div class="card-body d-flex gap-2">
<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'}">
<i class="bi bi-sun-fill"></i>
Light
<i class="bi bi-sun-fill me-2"></i>
<LocaleText t="Light"></LocaleText>
</button>
<button class="btn bg-primary-subtle text-primary-emphasis flex-grow-1"
@click="this.switchTheme('dark')"
:class="{active: this.dashboardConfigurationStore.Configuration.Server.dashboard_theme === 'dark'}">
<i class="bi bi-moon-fill"></i>
Dark
<i class="bi bi-moon-fill me-2"></i>
<LocaleText t="Dark"></LocaleText>
</button>
</div>
</div>

View File

@@ -2,8 +2,10 @@
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {v4} from "uuid";
import {fetchPost} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
components: {LocaleText},
props:{
targetData: String,
title: String,
@@ -61,7 +63,9 @@ export default {
<template>
<div class="form-group mb-2">
<label :for="this.uuid" class="text-muted mb-1">
<strong><small>{{this.title}}</small></strong>
<strong><small>
<LocaleText :t="this.title"></LocaleText>
</small></strong>
</label>
<input type="text" class="form-control"
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
@@ -75,7 +79,9 @@ export default {
<div class="px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1"
v-if="warning"
>
<small><i class="bi bi-exclamation-triangle-fill me-2"></i><span v-html="warningText"></span></small>
<small><i class="bi bi-exclamation-triangle-fill me-2"></i>
<LocaleText :t="warningText"></LocaleText>
</small>
</div>
</div>
</template>

View File

@@ -0,0 +1,30 @@
<script>
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "signInInput",
methods: {GetLocale},
props: {
id: "",
data: "",
type: "",
placeholder: ""
},
computed: {
getLocaleText(){
return GetLocale(this.placeholder)
}
}
}
</script>
<template>
<input :type="type" v-model="this.data[this.id]" class="form-control"
:id="this.id" :name="this.id"
autocomplete="on"
:placeholder="this.getLocaleText" required>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,29 @@
<script>
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "signInTOTP",
methods: {GetLocale},
props: {
data: "",
},
computed: {
getLocaleText(){
return GetLocale(this.placeholder)
}
}
}
</script>
<template>
<input class="form-control totp"
required
id="totp" maxlength="6" type="text" inputmode="numeric" autocomplete="one-time-code"
:placeholder="this.getLocaleText('OTP from your authenticator')"
v-model="this.data.totp"
>
</template>
<style scoped>
</style>

View File

@@ -1,5 +1,6 @@
<script>
import dayjs from "dayjs";
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "RemoteServer",
@@ -73,7 +74,7 @@ export default {
return `${dayjs().subtract(this.startTime).millisecond()}ms`
}else{
if (this.refreshing){
return `Pinging...`
return GetLocale(`Pinging...`)
}
return this.errorMsg ? this.errorMsg : "N/A"
}

View File

@@ -1,6 +1,7 @@
<script>
import RemoteServer from "@/components/signInComponents/RemoteServer.vue";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "RemoteServerList",
@@ -8,18 +9,21 @@ export default {
const store = DashboardConfigurationStore();
return {store}
},
components: {RemoteServer}
components: {LocaleText, RemoteServer}
}
</script>
<template>
<div class="w-100 mt-3">
<div class="d-flex align-items-center mb-3">
<h5 class="mb-0">Server List</h5>
<h5 class="mb-0">
<LocaleText t="Server List"></LocaleText>
</h5>
<button
@click="this.store.addCrossServerConfiguration()"
class="btn bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle shadow-sm ms-auto">
<i class="bi bi-plus-circle-fill me-2"></i>Server
<i class="bi bi-plus-circle-fill me-2"></i>
<LocaleText t="Server"></LocaleText>
</button>
</div>
<div class="w-100 d-flex gap-3 flex-column p-3 border border-1 border-secondary-subtle rounded-3"
@@ -30,7 +34,10 @@ export default {
:key="key"
:server="server"></RemoteServer>
<h6 class="text-muted m-auto" v-if="Object.keys(this.store.CrossServerConfiguration.ServerList).length === 0">
Click<i class="bi bi-plus-circle-fill mx-1"></i>to add your server</h6>
<LocaleText t="Click"></LocaleText>
<i class="bi bi-plus-circle-fill mx-1"></i>
<LocaleText t="to add your server"></LocaleText>
</h6>
</div>
</div>
</template>

View File

@@ -0,0 +1,23 @@
<script>
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "localeText",
props: {
t: ""
},
computed: {
getLocaleText(){
return GetLocale(this.t)
}
}
}
</script>
<template>
{{ this.getLocaleText }}
</template>
<style scoped>
</style>

View File

@@ -10,17 +10,24 @@ import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {fetchGet} from "@/utilities/fetch.js";
let Locale;
await fetch("/api/locale").then(res => res.json()).then(res => Locale = JSON.parse(res.data))
const app = createApp(App)
app.use(router)
const pinia = createPinia();
app.use(router)
const pinia = createPinia();
pinia.use(({ store }) => {
store.$router = markRaw(router)
})
app.use(pinia)
app.mount('#app')
const store = DashboardConfigurationStore()
window.Locale = Locale;
app.mount('#app')

View File

@@ -1,6 +1,7 @@
import {defineStore} from "pinia";
import {fetchGet, fetchPost} from "@/utilities/fetch.js";
import {v4} from "uuid";
import {GetLocale} from "@/utilities/locale.js";
export const DashboardConfigurationStore = defineStore('DashboardConfigurationStore', {
state: () => ({
@@ -17,7 +18,8 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
},
ActiveServerConfiguration: undefined,
IsElectronApp: false,
ShowNavBar: false
ShowNavBar: false,
Locale: undefined
}),
actions: {
initCrossServerConfiguration(){
@@ -57,19 +59,11 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
this.ActiveServerConfiguration = undefined;
localStorage.removeItem('ActiveCrossServerConfiguration')
},
async getConfiguration(){
await fetchGet("/api/getDashboardConfiguration", {}, (res) => {
if (res.status) this.Configuration = res.data
});
},
// async updateConfiguration(){
// await fetchPost("/api/updateDashboardConfiguration", {
// DashboardConfiguration: this.Configuration
// }, (res) => {
// console.log(res)
// })
// },
async signOut(){
await fetchGet("/api/signout", {}, (res) => {
this.removeActiveCrossServer();
@@ -79,11 +73,25 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
newMessage(from, content, type){
this.Messages.push({
id: v4(),
from: from,
content: content,
from: GetLocale(from),
content: GetLocale(content),
type: type,
show: true
})
},
applyLocale(key){
if (this.Locale === null)
return key
const reg = Object.keys(this.Locale)
const match = reg.filter(x => {
return key.match(new RegExp('^' + x + '$', 'g')) !== null
})
console.log(match)
if (match.length === 0 || match.length > 1){
return key
}
return this.Locale[match[0]]
}
}
});

View File

@@ -0,0 +1,16 @@
export const GetLocale = (key) => {
console.log(key)
if (window.Locale === null)
return key
const reg = Object.keys(window.Locale)
const match = reg.filter(x => {
return key.match(new RegExp('^' + x + '$', 'g')) !== null
})
console.log(match)
if (match.length === 0 || match.length > 1){
return key
}
return window.Locale[match[0]]
}

View File

@@ -12,11 +12,13 @@ import DashboardSettingsInputIPAddressAndPort
from "@/components/settingsComponent/dashboardSettingsInputIPAddressAndPort.vue";
import DashboardAPIKeys from "@/components/settingsComponent/dashboardAPIKeys.vue";
import AccountSettingsMFA from "@/components/settingsComponent/accountSettingsMFA.vue";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "settings",
methods: {ipV46RegexCheck},
components: {
LocaleText,
AccountSettingsMFA,
DashboardAPIKeys,
DashboardSettingsInputIPAddressAndPort,
@@ -27,24 +29,20 @@ export default {
const dashboardConfigurationStore = DashboardConfigurationStore()
return {dashboardConfigurationStore}
},
watch: {
// 'dashboardConfigurationStore.Configuration': {
// deep: true,
// handler(){
// this.dashboardConfigurationStore.updateConfiguration();
// }
// }
}
}
</script>
<template>
<div class="mt-md-5 mt-3">
<div class="container-md">
<h3 class="mb-3 text-body">Settings</h3>
<h3 class="mb-3 text-body">
<LocaleText t="Settings"></LocaleText>
</h3>
<DashboardTheme></DashboardTheme>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">Peers Default Settings</p>
<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="Peer Endpoint Allowed IPs"></PeersDefaultSettingsInput>
@@ -56,19 +54,23 @@ export default {
</div>
</div>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">WireGuard Configurations Settings</p>
<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 <code>/</code> at the end of your path. e.g <code>/etc/wireguard</code>"
warning-text="Remember to remove / at the end of your path. e.g /etc/wireguard"
>
</DashboardSettingsInputWireguardConfigurationPath>
</div>
</div>
<div class="card mb-4 shadow rounded-3">
<p class="card-header">Account Settings</p>
<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"

View File

@@ -3,10 +3,14 @@ import {fetchGet, fetchPost} from "../utilities/fetch.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import Message from "@/components/messageCentreComponent/message.vue";
import RemoteServerList from "@/components/signInComponents/RemoteServerList.vue";
import {GetLocale} from "@/utilities/locale.js";
import LocaleText from "@/components/text/localeText.vue";
import SignInInput from "@/components/signIn/signInInput.vue";
import SignInTOTP from "@/components/signIn/signInTOTP.vue";
export default {
name: "signin",
components: {RemoteServerList, Message},
components: {SignInTOTP, SignInInput, LocaleText, RemoteServerList, Message},
async setup(){
const store = DashboardConfigurationStore()
let theme = "dark"
@@ -22,6 +26,7 @@ export default {
}),
fetchGet("/api/getDashboardVersion", {}, (res) => {
version = res.data
})
]);
}
@@ -30,9 +35,11 @@ export default {
},
data(){
return {
username: "",
password: "",
totp: "",
data: {
username: "",
password: "",
totp: "",
},
loginError: false,
loginErrorMessage: "",
loading: false
@@ -41,17 +48,17 @@ export default {
computed: {
getMessages(){
return this.store.Messages.filter(x => x.show)
},
applyLocale(key){
return GetLocale(key)
}
},
methods: {
GetLocale,
async auth(){
if (this.username && this.password && ((this.totpEnabled && this.totp) || !this.totpEnabled)){
if (this.data.username && this.data.password && ((this.totpEnabled && this.data.totp) || !this.totpEnabled)){
this.loading = true
await fetchPost("/api/authenticate", {
username: this.username,
password: this.password,
totp: this.totp
}, (response) => {
await fetchPost("/api/authenticate", this.data, (response) => {
if (response.status){
this.loginError = false;
this.$refs["signInBtn"].classList.add("signedIn")
@@ -97,45 +104,38 @@ export default {
:data-bs-theme="this.theme">
<div class="login-box m-auto" >
<div class="m-auto" style="width: 700px;">
<h4 class="mb-0 text-body">Welcome to</h4>
<h4 class="mb-0 text-body">
<LocaleText t="Welcome to"></LocaleText>
</h4>
<span class="dashboardLogo display-3"><strong>WGDashboard</strong></span>
<div class="alert alert-danger mt-2 mb-0" role="alert" v-if="loginError">
{{this.loginErrorMessage}}
<LocaleText :t="this.loginErrorMessage"></LocaleText>
</div>
<form @submit="(e) => {e.preventDefault(); this.auth();}"
v-if="!this.store.CrossServerConfiguration.Enable">
<div class="form-group text-body">
<label for="username" class="text-left" style="font-size: 1rem">
<i class="bi bi-person-circle"></i></label>
<input type="text" v-model="username" class="form-control" id="username" name="username"
autocomplete="on"
placeholder="Username" required>
<SignInInput id="username" :data="this.data"
type="text" placeholder="Username"></SignInInput>
</div>
<div class="form-group text-body">
<label for="password" class="text-left" style="font-size: 1rem"><i class="bi bi-key-fill"></i></label>
<input type="password"
v-model="password" class="form-control" id="password" name="password"
autocomplete="on"
placeholder="Password" required>
<SignInInput id="password" :data="this.data"
type="password" placeholder="Password"></SignInInput>
</div>
<div class="form-group text-body" v-if="totpEnabled">
<label for="totp" class="text-left" style="font-size: 1rem"><i class="bi bi-lock-fill"></i></label>
<input class="form-control totp"
required
id="totp" maxlength="6" type="text" inputmode="numeric" autocomplete="one-time-code"
placeholder="OTP from your authenticator"
v-model="this.totp"
>
<SignInTOTP :data="this.data"></SignInTOTP>
</div>
<button class="btn btn-lg btn-dark ms-auto mt-4 w-100 d-flex btn-brand signInBtn" ref="signInBtn">
<span v-if="!this.loading" class="d-flex w-100">
Sign In<i class="ms-auto bi bi-chevron-right"></i>
<LocaleText t="Sign In"></LocaleText>
<i class="ms-auto bi bi-chevron-right"></i>
</span>
<span v-else class="d-flex w-100 align-items-center">
Signing In...
<span class="spinner-border ms-auto spinner-border-sm" role="status">
<span class="visually-hidden">Loading...</span>
</span>
<LocaleText t="Signing In..."></LocaleText>
<span class="spinner-border ms-auto spinner-border-sm" role="status"></span>
</span>
</button>
</form>
@@ -146,7 +146,9 @@ export default {
<input
v-model="this.store.CrossServerConfiguration.Enable"
class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckChecked">
<label class="form-check-label" for="flexSwitchCheckChecked">Access Remote Server</label>
<label class="form-check-label" for="flexSwitchCheckChecked">
<LocaleText t="Access Remote Server"></LocaleText>
</label>
</div>
</div>
</div>

View File

@@ -21,6 +21,7 @@ export default defineConfig(({mode}) => {
}
},
build: {
target: "es2022",
outDir: '../../../../WGDashboard-Desktop',
rollupOptions: {
output: {
@@ -50,6 +51,7 @@ export default defineConfig(({mode}) => {
host: '0.0.0.0'
},
build: {
target: "es2022",
outDir: 'dist',
rollupOptions: {
output: {