mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-12-26 17:04:14 +08:00
Finished translating most of the UI. Left with notifications
This commit is contained in:
parent
17a9fe5024
commit
94bf1c2484
22 changed files with 290 additions and 90 deletions
|
@ -1983,7 +1983,10 @@ def API_ping_getAllPeersIpAddress():
|
|||
allowed_ip = p.allowed_ip.replace(" ", "").split(",")
|
||||
parsed = []
|
||||
for x in allowed_ip:
|
||||
ip = ipaddress.ip_network(x, strict=False)
|
||||
try:
|
||||
ip = ipaddress.ip_network(x, strict=False)
|
||||
except ValueError as e:
|
||||
print(f"{p.id} - {c.Name}")
|
||||
if len(list(ip.hosts())) == 1:
|
||||
parsed.append(str(ip.hosts()[0]))
|
||||
endpoint = p.endpoint.replace(" ", "").replace("(none)", "")
|
||||
|
@ -2073,7 +2076,7 @@ def API_getDashboardUpdate():
|
|||
htmlUrl = data.get('html_url')
|
||||
if tagName is not None and htmlUrl is not None:
|
||||
if tagName != DASHBOARD_VERSION:
|
||||
return ResponseObject(message=f"{tagName} is now avaible for update!", data=htmlUrl)
|
||||
return ResponseObject(message=f"{tagName} is now available for update!", data=htmlUrl)
|
||||
else:
|
||||
return ResponseObject(message="You're on the latest version")
|
||||
return ResponseObject(False)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "app",
|
||||
"version": "4.0.2",
|
||||
"version": "4.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import {GetLocale} from "@/utilities/locale.js";
|
||||
|
||||
export default {
|
||||
name: "allowedIPsInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean,
|
||||
|
@ -30,6 +33,9 @@ export default {
|
|||
this.availableIp.filter(x =>
|
||||
x.includes(this.availableIpSearchString) && !this.data.allowed_ips.includes(x)) :
|
||||
this.availableIp.filter(x => !this.data.allowed_ips.includes(x))
|
||||
},
|
||||
inputGetLocale(){
|
||||
return GetLocale("Enter IP Address/CIDR")
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -40,7 +46,7 @@ export default {
|
|||
return true;
|
||||
}
|
||||
this.allowedIpFormatError = true;
|
||||
this.dashboardStore.newMessage('WGDashboard', 'Allowed IP is invalid', 'danger')
|
||||
this.dashboardStore.newMessage('WGDashboard', 'Allowed IPs is invalid', 'danger')
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
@ -63,7 +69,11 @@ export default {
|
|||
<template>
|
||||
<div :class="{inactiveField: this.bulk}">
|
||||
<label for="peer_allowed_ip_textbox" class="form-label">
|
||||
<small class="text-muted">Allowed IPs <code>(Required)</code></small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Allowed IPs"></LocaleText>
|
||||
<code>
|
||||
<LocaleText t="(Required)"></LocaleText>
|
||||
</code></small>
|
||||
</label>
|
||||
<div class="d-flex gap-2 flex-wrap" :class="{'mb-2': this.data.allowed_ips.length > 0}">
|
||||
<TransitionGroup name="list">
|
||||
|
@ -77,7 +87,7 @@ export default {
|
|||
<div class="d-flex gap-2 align-items-center">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control form-control-sm rounded-start-3"
|
||||
placeholder="Enter IP Address/CIDR"
|
||||
:placeholder="this.inputGetLocale"
|
||||
:class="{'is-invalid': this.allowedIpFormatError}"
|
||||
v-model="customAvailableIp"
|
||||
:disabled="bulk">
|
||||
|
@ -88,23 +98,29 @@ export default {
|
|||
<i class="bi bi-plus-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
<small class="text-muted">or</small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="or"></LocaleText>
|
||||
</small>
|
||||
<div class="dropdown flex-grow-1">
|
||||
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-3 w-100"
|
||||
:disabled="!availableIp || bulk"
|
||||
data-bs-auto-close="outside"
|
||||
type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-filter-circle me-2"></i>
|
||||
Pick Available IP
|
||||
<LocaleText t="Pick Available IP"></LocaleText>
|
||||
</button>
|
||||
<ul class="dropdown-menu mt-2 shadow w-100 dropdown-menu-end rounded-3"
|
||||
v-if="this.availableIp"
|
||||
style="overflow-y: scroll; max-height: 270px; width: 300px !important;">
|
||||
<li>
|
||||
<div class="px-3 pb-2 pt-1">
|
||||
<input class="form-control form-control-sm rounded-3"
|
||||
v-model="this.availableIpSearchString"
|
||||
placeholder="Search...">
|
||||
<div class="px-3 pb-2 pt-1 d-flex gap-3 align-items-center">
|
||||
<label for="availableIpSearchString" class="text-muted">
|
||||
<i class="bi bi-search"></i>
|
||||
</label>
|
||||
<input
|
||||
id="availableIpSearchString"
|
||||
class="form-control form-control-sm rounded-3"
|
||||
v-model="this.availableIpSearchString">
|
||||
</div>
|
||||
</li>
|
||||
<li v-for="ip in this.searchAvailableIps" >
|
||||
|
@ -113,7 +129,9 @@ export default {
|
|||
</a>
|
||||
</li>
|
||||
<li v-if="this.searchAvailableIps.length === 0">
|
||||
<small class="px-3 text-muted">No available IP containing "{{this.availableIpSearchString}}"</small>
|
||||
<small class="px-3 text-muted">
|
||||
<LocaleText t="No available IP containing"></LocaleText>
|
||||
"{{this.availableIpSearchString}}"</small>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<script>
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import {GetLocale} from "@/utilities/locale.js";
|
||||
|
||||
export default {
|
||||
name: "bulkAdd",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
saving: Boolean,
|
||||
data: Object,
|
||||
availableIp: undefined
|
||||
},
|
||||
computed:{
|
||||
bulkAddGetLocale(){
|
||||
return GetLocale("How many peers you want to add?")
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -17,20 +26,22 @@ export default {
|
|||
:disabled="!this.availableIp"
|
||||
id="bulk_add" v-model="this.data.bulkAdd">
|
||||
<label class="form-check-label me-2" for="bulk_add">
|
||||
<small><strong>Bulk Add</strong></small>
|
||||
<small><strong>
|
||||
<LocaleText t="Bulk Add"></LocaleText>
|
||||
</strong></small>
|
||||
</label>
|
||||
</div>
|
||||
<p :class="{'mb-0': !this.data.bulkAdd}"><small class="text-muted d-block">
|
||||
By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP.
|
||||
<LocaleText t="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></LocaleText>
|
||||
</small></p>
|
||||
|
||||
<div class="form-group" v-if="this.data.bulkAdd">
|
||||
<input class="form-control form-control-sm rounded-3 mb-1" type="number" min="1"
|
||||
:max="this.availableIp.length"
|
||||
v-model="this.data.bulkAddAmount"
|
||||
placeholder="How many peers you want to add?">
|
||||
:placeholder="this.bulkAddGetLocale">
|
||||
<small class="text-muted">
|
||||
You can add up to <strong>{{this.availableIp.length}}</strong> peers
|
||||
<LocaleText :t="`You can add up to ` + this.availableIp.length + ' peers'"></LocaleText>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script>
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "dnsInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
|
||||
data: Object,
|
||||
|
@ -50,7 +52,9 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<label for="peer_DNS_textbox" class="form-label">
|
||||
<small class="text-muted">DNS</small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="DNS"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:class="{'is-invalid': this.error}"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script>
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "endpointAllowedIps",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean
|
||||
|
@ -47,7 +49,11 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<label for="peer_endpoint_allowed_ips" class="form-label">
|
||||
<small class="text-muted">Endpoint Allowed IPs <code>(Required)</code></small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Endpoint Allowed IPs"></LocaleText>
|
||||
<code>
|
||||
<LocaleText t="(Required)"></LocaleText>
|
||||
</code></small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:class="{'is-invalid': error}"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script>
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "mtuInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean
|
||||
|
@ -10,7 +13,9 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<label for="peer_mtu" class="form-label"><small class="text-muted">MTU</small></label>
|
||||
<label for="peer_mtu" class="form-label"><small class="text-muted">
|
||||
<LocaleText t="MTU"></LocaleText>
|
||||
</small></label>
|
||||
<input type="number" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.mtu"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script>
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "nameInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
bulk: Boolean,
|
||||
data: Object,
|
||||
|
@ -12,7 +15,9 @@ export default {
|
|||
<template>
|
||||
<div :class="{inactiveField: this.bulk}">
|
||||
<label for="peer_name_textbox" class="form-label">
|
||||
<small class="text-muted">Name</small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Name"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving || this.bulk"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script>
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "persistentKeepAliveInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean
|
||||
|
@ -11,7 +14,9 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<label for="peer_keep_alive" class="form-label">
|
||||
<small class="text-muted">Persistent Keepalive</small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Persistent Keepalive"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
<input type="number" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script>
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "presharedKeyInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean
|
||||
|
@ -26,7 +29,9 @@ export default {
|
|||
<div>
|
||||
<div class="d-flex align-items-start">
|
||||
<label for="peer_preshared_key_textbox" class="form-label">
|
||||
<small class="text-muted">Pre-Shared Key</small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Pre-Shared Key"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<script>
|
||||
import "@/utilities/wireguard.js"
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
export default {
|
||||
name: "privatePublicKeyInput",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean,
|
||||
|
@ -75,7 +77,11 @@ export default {
|
|||
<div class="d-flex gap-2 flex-column" :class="{inactiveField: this.bulk}">
|
||||
<div>
|
||||
<label for="peer_private_key_textbox" class="form-label">
|
||||
<small class="text-muted">Private Key <code>(Required for QR Code and Download)</code></small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Private Key"></LocaleText>
|
||||
<code>
|
||||
<LocaleText t="(Required for QR Code and Download)"></LocaleText>
|
||||
</code></small>
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control form-control-sm rounded-start-3"
|
||||
|
@ -94,14 +100,20 @@ export default {
|
|||
<div>
|
||||
<div class="d-flex">
|
||||
<label for="public_key" class="form-label">
|
||||
<small class="text-muted">Public Key <code>(Required)</code></small>
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Public Key"></LocaleText>
|
||||
<code>
|
||||
<LocaleText t="(Required)"></LocaleText>
|
||||
</code></small>
|
||||
</label>
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
:disabled="this.bulk"
|
||||
id="enablePublicKeyEdit" v-model="this.editKey">
|
||||
<label class="form-check-label" for="enablePublicKeyEdit">
|
||||
<small>Edit</small>
|
||||
<small>
|
||||
<LocaleText t="Use your own Private and Public Key"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,10 +12,12 @@ import PersistentKeepAliveInput
|
|||
from "@/components/configurationComponents/newPeersComponents/persistentKeepAliveInput.vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import BulkAdd from "@/components/configurationComponents/newPeersComponents/bulkAdd.vue";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "peerCreate",
|
||||
components: {
|
||||
LocaleText,
|
||||
BulkAdd,
|
||||
PersistentKeepAliveInput,
|
||||
MtuInput,
|
||||
|
@ -107,7 +109,9 @@ export default {
|
|||
<h3 class="mb-0 text-body">
|
||||
<i class="bi bi-chevron-left"></i>
|
||||
</h3>
|
||||
<h3 class="text-body mb-0">Add Peers</h3>
|
||||
<h3 class="text-body mb-0">
|
||||
<LocaleText t="Add Peers"></LocaleText>
|
||||
</h3>
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
|
@ -137,8 +141,11 @@ export default {
|
|||
v-model="this.data.preshared_key_bulkAdd"
|
||||
id="bullAdd_PresharedKey_Switch" checked>
|
||||
<label class="form-check-label" for="bullAdd_PresharedKey_Switch">
|
||||
Pre-Share Key
|
||||
{{this.data.preshared_key_bulkAdd ? "Enabled":"Disabled"}}
|
||||
<small class="fw-bold">
|
||||
<LocaleText t="Pre-Shared Key"></LocaleText>
|
||||
<LocaleText t="Enabled" v-if="this.data.preshared_key_bulkAdd"></LocaleText>
|
||||
<LocaleText t="Disabled" v-else></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -149,7 +156,8 @@ export default {
|
|||
@click="this.peerCreate()"
|
||||
>
|
||||
<i class="bi bi-plus-circle-fill me-2" v-if="!this.saving"></i>
|
||||
{{this.saving ? 'Saving...': 'Add'}}
|
||||
<LocaleText t="Adding..." v-if="this.saving"></LocaleText>
|
||||
<LocaleText t="Add" v-else></LocaleText>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -176,8 +176,7 @@ export default {
|
|||
}, (res) => {
|
||||
if (res.status){
|
||||
this.dashboardConfigurationStore.newMessage("Server",
|
||||
`${this.configurationInfo.Name} is
|
||||
${res.data ? 'is on':'is off'}`, "Success")
|
||||
`${this.configurationInfo.Name} ${res.data ? 'is on':'is off'}`, "success")
|
||||
}else{
|
||||
this.dashboardConfigurationStore.newMessage("Server",
|
||||
res.message, 'danger')
|
||||
|
@ -427,8 +426,13 @@ export default {
|
|||
</small></p>
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<label class="form-check-label" style="cursor: pointer" :for="'switch' + this.configurationInfo.id">
|
||||
<LocaleText t="On" v-if="this.configurationInfo.Status"></LocaleText>
|
||||
<LocaleText t="Off" v-else></LocaleText>
|
||||
|
||||
<LocaleText t="Turning Off..." v-if="!this.configurationInfo.Status && this.configurationToggling"></LocaleText>
|
||||
<LocaleText t="Turning On..." v-else-if="this.configurationInfo.Status && this.configurationToggling"></LocaleText>
|
||||
<LocaleText t="On" v-else-if="this.configurationInfo.Status && !this.configurationToggling"></LocaleText>
|
||||
<LocaleText t="Off" v-else-if="!this.configurationInfo.Status && !this.configurationToggling"></LocaleText>
|
||||
|
||||
|
||||
<span v-if="this.configurationToggling"
|
||||
class="spinner-border spinner-border-sm ms-2" aria-hidden="true"></span>
|
||||
</label>
|
||||
|
|
|
@ -122,7 +122,7 @@ export default {
|
|||
<a class="dropdown-item d-flex" role="button"
|
||||
@click="this.$emit('jobs')"
|
||||
>
|
||||
<i class="me-auto bi bi-app-indicator"></i> Schedule Jobs
|
||||
<i class="me-auto bi bi-app-indicator"></i> <LocaleText t="Schedule Jobs"></LocaleText>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
@ -133,7 +133,10 @@ export default {
|
|||
@click="this.restrictPeer()"
|
||||
:class="{disabled: this.restrictBtnDisabled}"
|
||||
role="button">
|
||||
<i class="me-auto bi bi-lock"></i> {{!this.restrictBtnDisabled ? "Restrict Access":"Restricting..."}}
|
||||
<i class="me-auto bi bi-lock"></i>
|
||||
<LocaleText t="Restrict Access" v-if="!this.restrictBtnDisabled"></LocaleText>
|
||||
<LocaleText t="Restricting..." v-else></LocaleText>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -141,7 +144,9 @@ export default {
|
|||
@click="this.deletePeer()"
|
||||
:class="{disabled: this.deleteBtnDisabled}"
|
||||
role="button">
|
||||
<i class="me-auto bi bi-trash"></i> {{!this.deleteBtnDisabled ? "Delete":"Deleting..."}}
|
||||
<i class="me-auto bi bi-trash"></i>
|
||||
<LocaleText t="Delete" v-if="!this.deleteBtnDisabled"></LocaleText>
|
||||
<LocaleText t="Deleting..." v-else></LocaleText>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
|
@ -149,10 +154,12 @@ export default {
|
|||
<li>
|
||||
<a class="dropdown-item d-flex text-warning"
|
||||
@click="this.allowAccessPeer()"
|
||||
:class="{disabled: this.restrictBtnDisabled}"
|
||||
:class="{disabled: this.allowAccessBtnDisabled}"
|
||||
role="button">
|
||||
<i class="me-auto bi bi-unlock"></i>
|
||||
{{!this.allowAccessBtnDisabled ? "Allow Access":"Allowing..."}}
|
||||
<i class="me-auto bi bi-unlock"></i>
|
||||
<LocaleText t="Allow Access" v-if="!this.allowAccessBtnDisabled"></LocaleText>
|
||||
<LocaleText t="Allowing Access..." v-else></LocaleText>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script>
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "configurationCard",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
c: {
|
||||
Name: String,
|
||||
|
@ -63,22 +65,30 @@ export default {
|
|||
<i class="bi bi-arrow-up me-2"></i>{{c.DataUsage.Sent > 0 ? c.DataUsage.Sent.toFixed(4) : 0}} GB
|
||||
</small>
|
||||
<small class="text-md-end col-6 col-md-3">
|
||||
<span class="dot me-2" :class="{active: c.ConnectedPeers > 0}"></span>{{c.ConnectedPeers}} Peers
|
||||
<span class="dot me-2" :class="{active: c.ConnectedPeers > 0}"></span>{{c.ConnectedPeers}}
|
||||
<LocaleText t="Peers"></LocaleText>
|
||||
</small>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<small class="text-muted">
|
||||
<strong style="word-break: keep-all">Public Key</strong>
|
||||
<strong style="word-break: keep-all">
|
||||
<LocaleText t="Public Key"></LocaleText>
|
||||
</strong>
|
||||
</small>
|
||||
<small class="mb-0 d-block d-lg-inline-block ">
|
||||
<samp style="line-break: anywhere">{{c.PublicKey}}</samp>
|
||||
</small>
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<label class="form-check-label" style="cursor: pointer" :for="'switch' + c.PrivateKey">
|
||||
{{this.configurationToggling ? 'Turning ':''}}
|
||||
{{c.Status ? "On":"Off"}}
|
||||
|
||||
<LocaleText t="Turning Off..." v-if="!c.Status && this.configurationToggling"></LocaleText>
|
||||
<LocaleText t="Turning On..." v-else-if="c.Status && this.configurationToggling"></LocaleText>
|
||||
<LocaleText t="On" v-else-if="c.Status && !this.configurationToggling"></LocaleText>
|
||||
<LocaleText t="Off" v-else-if="!c.Status && !this.configurationToggling"></LocaleText>
|
||||
|
||||
|
||||
<span v-if="this.configurationToggling"
|
||||
class="spinner-border spinner-border-sm" aria-hidden="true"></span>
|
||||
class="spinner-border spinner-border-sm ms-2" aria-hidden="true"></span>
|
||||
</label>
|
||||
<input class="form-check-input"
|
||||
style="cursor: pointer"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script>
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "message",
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
message: Object
|
||||
},
|
||||
|
@ -21,7 +24,9 @@ export default {
|
|||
:id="this.message.id"
|
||||
style="width: 400px">
|
||||
<div class="card-body">
|
||||
<small class="fw-bold d-block" style="text-transform: uppercase">FROM {{this.message.from}}</small>
|
||||
<small class="fw-bold d-block" style="text-transform: uppercase">
|
||||
<LocaleText t="FROM "></LocaleText>
|
||||
{{this.message.from}}</small>
|
||||
{{this.message.content}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@ import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStor
|
|||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import {GetLocale} from "@/utilities/locale.js";
|
||||
|
||||
export default {
|
||||
name: "navbar",
|
||||
|
@ -29,7 +30,7 @@ export default {
|
|||
}
|
||||
this.updateMessage = res.message
|
||||
}else{
|
||||
this.updateMessage = "Failed to check available update"
|
||||
this.updateMessage = GetLocale("Failed to check available update")
|
||||
console.log(`Failed to get update: ${res.message}`)
|
||||
}
|
||||
})
|
||||
|
@ -95,14 +96,15 @@ export default {
|
|||
</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">
|
||||
<a :href="this.updateUrl" v-if="this.updateAvailable" class="text-decoration-none rounded-3" target="_blank">
|
||||
<small class="nav-link text-muted rounded-3" >
|
||||
<LocaleText :t="this.updateMessage"></LocaleText>
|
||||
(<LocaleText t="Current Version:"></LocaleText> {{ dashboardConfigurationStore.Configuration.Server.version }})
|
||||
</small>
|
||||
</a>
|
||||
<small class="nav-link text-muted" v-else>
|
||||
<small class="nav-link text-muted rounded-3" v-else>
|
||||
<LocaleText :t="this.updateMessage"></LocaleText>
|
||||
({{ dashboardConfigurationStore.Configuration.Server.version}})
|
||||
({{ dashboardConfigurationStore.Configuration.Server.version }})
|
||||
</small>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
import {fetchGet, fetchPost} from "@/utilities/fetch.js";
|
||||
import QRCode from "qrcode";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "totp",
|
||||
components: {LocaleText},
|
||||
async setup(){
|
||||
const store = DashboardConfigurationStore();
|
||||
let l = ""
|
||||
|
@ -65,14 +67,25 @@ export default {
|
|||
<div class="m-auto text-body" style="width: 500px">
|
||||
<div class="d-flex flex-column">
|
||||
<div>
|
||||
<h1 class="dashboardLogo display-4">Multi-Factor Authentication</h1>
|
||||
<p class="mb-2"><small class="text-muted">1. Please scan the following QR Code to generate TOTP</small></p>
|
||||
<h1 class="dashboardLogo display-4">
|
||||
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText>
|
||||
</h1>
|
||||
<p class="mb-2"><small class="text-muted">
|
||||
<LocaleText t="1. Please scan the following QR Code to generate TOTP with your choice of authenticator"></LocaleText>
|
||||
</small></p>
|
||||
<canvas id="qrcode" class="rounded-3 mb-2"></canvas>
|
||||
<div class="p-3 bg-body-secondary rounded-3 border mb-3">
|
||||
<p class="text-muted mb-0"><small>Or you can click the link below:</small>
|
||||
<p class="text-muted mb-0">
|
||||
<small>
|
||||
<LocaleText t="Or you can click the link below:"></LocaleText>
|
||||
</small>
|
||||
</p><a :href="this.l"><code style="line-break: anywhere">{{this.l}}</code></a>
|
||||
</div>
|
||||
<label for="totp" class="mb-2"><small class="text-muted">2. Enter the TOTP generated by your authenticator to verify</small></label>
|
||||
<label for="totp" class="mb-2">
|
||||
<small class="text-muted">
|
||||
<LocaleText t="2. Enter the TOTP generated by your authenticator to verify"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
<div class="form-group mb-2">
|
||||
<input class="form-control text-center totp"
|
||||
id="totp" maxlength="6" type="text" inputmode="numeric" autocomplete="one-time-code"
|
||||
|
@ -80,16 +93,12 @@ export default {
|
|||
:disabled="this.verified"
|
||||
>
|
||||
<div class="invalid-feedback">
|
||||
{{this.totpInvalidMessage}}
|
||||
<LocaleText :t="this.totpInvalidMessage"></LocaleText>
|
||||
</div>
|
||||
<div class="valid-feedback">
|
||||
TOTP verified!
|
||||
<LocaleText t="TOTP verified!"></LocaleText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning rounded-3">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i> If you ever lost your TOTP and can't login, please follow instruction on
|
||||
<a href="https://github.com/donaldzou/WGDashboard" target="_blank">readme.md</a> to reset.
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="d-flex gap-3 mt-5 flex-column">
|
||||
|
@ -99,12 +108,14 @@ export default {
|
|||
class="btn bg-secondary-subtle text-secondary-emphasis
|
||||
rounded-3
|
||||
flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex">
|
||||
I don't need MFA <i class="bi bi-chevron-right ms-auto"></i>
|
||||
<LocaleText t="I don't need MFA"></LocaleText>
|
||||
<i class="bi bi-chevron-right ms-auto"></i>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/"
|
||||
v-else class="btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3">
|
||||
Complete <i class="bi bi-chevron-right ms-auto"></i>
|
||||
<LocaleText t="Complete"></LocaleText>
|
||||
<i class="bi bi-chevron-right ms-auto"></i>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
getLocaleText(){
|
||||
return GetLocale(this.placeholder)
|
||||
return GetLocale('OTP from your authenticator')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ export default {
|
|||
<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')"
|
||||
:placeholder="this.getLocaleText"
|
||||
v-model="this.data.totp"
|
||||
>
|
||||
</template>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script>
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {fetchPost} from "@/utilities/fetch.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
export default {
|
||||
name: "setup",
|
||||
components: {},
|
||||
components: {LocaleText},
|
||||
setup(){
|
||||
const store = DashboardConfigurationStore();
|
||||
return {store}
|
||||
|
@ -57,37 +58,57 @@ export default {
|
|||
<div class="container-fluid login-container-fluid d-flex main pt-5 overflow-scroll"
|
||||
:data-bs-theme="this.store.Configuration.Server.dashboard_theme">
|
||||
<div class="m-auto text-body" style="width: 500px">
|
||||
<span class="dashboardLogo display-4">Nice to meet you!</span>
|
||||
<p class="mb-5">Please fill in the following fields to finish setup 😊</p>
|
||||
<span class="dashboardLogo display-4">
|
||||
<LocaleText t="Nice to meet you!"></LocaleText>
|
||||
</span>
|
||||
<p class="mb-5">
|
||||
<LocaleText t="Please fill in the following fields to finish setup"></LocaleText>
|
||||
😊</p>
|
||||
<div>
|
||||
<h3>Create an account</h3>
|
||||
<h3>
|
||||
<LocaleText t="Create an account"></LocaleText>
|
||||
</h3>
|
||||
<div class="alert alert-danger" v-if="this.errorMessage">
|
||||
{{this.errorMessage}}
|
||||
</div>
|
||||
<div class="d-flex flex-column gap-3">
|
||||
<div id="createAccount" class="d-flex flex-column gap-2">
|
||||
<form id="createAccount" class="d-flex flex-column gap-2">
|
||||
<div class="form-group text-body">
|
||||
<label for="username" class="mb-1 text-muted">
|
||||
<small>Pick an username you like</small></label>
|
||||
<small>
|
||||
<LocaleText t="Enter an username you like"></LocaleText>
|
||||
</small></label>
|
||||
<input type="text"
|
||||
autocomplete="username"
|
||||
v-model="this.setup.username"
|
||||
class="form-control" id="username" name="username" placeholder="Maybe something like 'wiredragon'?" required>
|
||||
class="form-control" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="form-group text-body">
|
||||
<label for="password" class="mb-1 text-muted">
|
||||
<small>Create a password (at least 8 characters)</small></label>
|
||||
<small>
|
||||
<LocaleText t="Enter a password"></LocaleText>
|
||||
<code>
|
||||
<LocaleText t="(At least 8 characters and make sure is strong enough!)"></LocaleText>
|
||||
</code>
|
||||
</small>
|
||||
</label>
|
||||
<input type="password"
|
||||
autocomplete="new-password"
|
||||
v-model="this.setup.newPassword"
|
||||
class="form-control" id="password" name="password" placeholder="Make sure is strong enough" required>
|
||||
class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group text-body">
|
||||
<label for="confirmPassword" class="mb-1 text-muted">
|
||||
<small>Confirm password</small></label>
|
||||
<small>
|
||||
<LocaleText t="Confirm password"></LocaleText>
|
||||
</small>
|
||||
</label>
|
||||
<input type="password"
|
||||
autocomplete="confirm-new-password"
|
||||
v-model="this.setup.repeatNewPassword"
|
||||
class="form-control" id="confirmPassword" name="confirmPassword" placeholder="and you can remember it :)" required>
|
||||
class="form-control" id="confirmPassword" name="confirmPassword" required>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<!-- <div class="form-check form-switch">-->
|
||||
<!-- <input class="form-check-input" type="checkbox" role="switch" id="enable_totp" -->
|
||||
<!-- v-model="this.setup.enable_totp">-->
|
||||
|
@ -104,9 +125,12 @@ export default {
|
|||
ref="signInBtn"
|
||||
:disabled="!this.goodToSubmit || this.loading || this.done" @click="this.submit()">
|
||||
<span class="d-flex align-items-center w-100" v-if="!this.loading && !this.done">
|
||||
Next<i class="bi bi-chevron-right ms-auto"></i></span>
|
||||
<LocaleText t="Next"></LocaleText>
|
||||
|
||||
<i class="bi bi-chevron-right ms-auto"></i></span>
|
||||
<span class="d-flex align-items-center w-100" v-else>
|
||||
Saving...<span class="spinner-border ms-auto spinner-border-sm" role="status">
|
||||
<LocaleText t="Saving..."></LocaleText>
|
||||
<span class="spinner-border ms-auto spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</span></span>
|
||||
</button>
|
||||
|
|
|
@ -4,15 +4,17 @@ import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.
|
|||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import {ref} from "vue";
|
||||
import QRCode from "qrcode";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
|
||||
export default {
|
||||
name: "share",
|
||||
components: {LocaleText},
|
||||
async setup(){
|
||||
const route = useRoute();
|
||||
const loaded = ref(false)
|
||||
const store = DashboardConfigurationStore();
|
||||
const theme = ref("");
|
||||
const peerConfiguration = ref("");
|
||||
const peerConfiguration = ref(undefined);
|
||||
const blob = ref(new Blob())
|
||||
await fetchGet("/api/getDashboardTheme", {}, (res) => {
|
||||
theme.value = res.data
|
||||
|
@ -38,9 +40,11 @@ export default {
|
|||
return {store, theme, peerConfiguration, blob}
|
||||
},
|
||||
mounted() {
|
||||
QRCode.toCanvas(document.querySelector("#qrcode"), this.peerConfiguration.file , (error) => {
|
||||
if (error) console.error(error)
|
||||
})
|
||||
if(this.peerConfiguration){
|
||||
QRCode.toCanvas(document.querySelector("#qrcode"), this.peerConfiguration.file, (error) => {
|
||||
if (error) console.error(error)
|
||||
})
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
download(){
|
||||
|
@ -76,18 +80,23 @@ export default {
|
|||
<div class="position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp"
|
||||
style="animation-delay: 0.1s;"
|
||||
>
|
||||
<h3 class="m-auto">Oh no... This link is either expired or invalid.</h3>
|
||||
<h3 class="m-auto">
|
||||
<LocaleText t="Oh no... This link is either expired or invalid."></LocaleText>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="d-flex align-items-center flex-column gap-3">
|
||||
<div class="h1 dashboardLogo text-center animate__animated animate__fadeInUp">
|
||||
<h6>WGDashboard</h6>
|
||||
Scan QR Code from the WireGuard App
|
||||
<LocaleText t="Scan QR Code with the WireGuard App to add peer"></LocaleText>
|
||||
</div>
|
||||
<canvas id="qrcode" class="rounded-3 shadow animate__animated animate__fadeInUp mb-3" ref="qrcode"></canvas>
|
||||
<p class="text-muted animate__animated animate__fadeInUp mb-1"
|
||||
style="animation-delay: 0.2s;"
|
||||
>or click the button below to download the <samp>.conf</samp> file</p>
|
||||
style="animation-delay: 0.2s;">
|
||||
<LocaleText t="or click the button below to download the "></LocaleText>
|
||||
<samp>.conf</samp>
|
||||
<LocaleText t=" file"></LocaleText>
|
||||
</p>
|
||||
<a
|
||||
:download="this.peerConfiguration.fileName + '.conf'"
|
||||
:href="getBlob"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"Welcome to": "欢迎来到",
|
||||
"Username": "用户名",
|
||||
"Password": "密码",
|
||||
"OTP from your authenticator": "您双因素身份验证的一次性验证码",
|
||||
"OTP from your authenticator": "您多重身份验证器的一次性验证码",
|
||||
"Sign In": "登录",
|
||||
"Signing In\\.\\.\\.": "正在登录...",
|
||||
"Access Remote Server": "访问远程服务器",
|
||||
|
@ -35,7 +35,7 @@
|
|||
"New Password": "新密码",
|
||||
"Repeat New Password": "重复新密码",
|
||||
"Update Password": "更新密码",
|
||||
"Multi-Factor Authentication \\(MFA\\)": "多重身份验证(MFA)",
|
||||
"Multi-Factor Authentication \\(MFA\\)": "多重身份验证 (MFA)",
|
||||
"Reset": "重置",
|
||||
"Setup": "设置",
|
||||
"API Keys": "API 秘钥",
|
||||
|
@ -55,6 +55,8 @@
|
|||
"Status": "状态",
|
||||
"On": "已启用",
|
||||
"Off": "已停用",
|
||||
"Turning On\\.\\.\\.": "启用中...",
|
||||
"Turning Off\\.\\.\\.": "停用中...",
|
||||
"Address": "网络地址",
|
||||
"Listen Port": "监听端口",
|
||||
"Public Key": "公钥",
|
||||
|
@ -66,13 +68,14 @@
|
|||
"Real Time Received Data Usage": "实时接收数据量",
|
||||
"Real Time Sent Data Usage": "实时发送数据量",
|
||||
"Peer": "端点",
|
||||
"Peers": "端点",
|
||||
"Peer Settings": "端点设定",
|
||||
"Download All": "全部下载",
|
||||
"Search Peers\\.\\.\\.": "搜索端点...",
|
||||
"Display": "显示设置",
|
||||
"Sort By": "排列方式",
|
||||
"Refresh Interval": "刷新间隔",
|
||||
"Name": "名字",
|
||||
"Name": "名称",
|
||||
"Allowed IPs": "允许的 IP 地址",
|
||||
"Restricted": "已限制端点",
|
||||
"(.*) Seconds": "$1 秒",
|
||||
|
@ -112,6 +115,7 @@
|
|||
"Delete Peer": "删除端点",
|
||||
"Edit": "编辑",
|
||||
"Delete": "删除",
|
||||
"Deleting...": "删除中...",
|
||||
"Cancel": "取消",
|
||||
"Save": "保存",
|
||||
"No active job at the moment\\.": "没有未运行的任务",
|
||||
|
@ -130,5 +134,47 @@
|
|||
"Stop Sharing\\.\\.\\.": "停止分享中...",
|
||||
"Stop Sharing": "停止分享",
|
||||
"Access Restricted": "已限制访问",
|
||||
"Download \\& QR Code is not available due to no private key set for this peer": "下载以及二维码功能不可用,需要填写此端点的秘钥"
|
||||
"Restrict Access": "限制访问",
|
||||
"Restricting\\.\\.\\.": "限制访问中...",
|
||||
"Allow Access": "解除限制访问",
|
||||
"Allowing Access\\.\\.\\.": "解除限制访问中...",
|
||||
"Download \\& QR Code is not available due to no private key set for this peer": "下载以及二维码功能不可用,需要填写此端点的秘钥",
|
||||
"Add Peers": "创建端点",
|
||||
"Bulk Add": "批量添加",
|
||||
"By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP\\.": "如果选择批量添加端点,系统会自动生成每一个端点的名称,并且会自动安排可用的 IP 地址。",
|
||||
"How many peers you want to add\\?": "您想添加多少个端点?",
|
||||
"You can add up to (.*) peers": "您最多可以添加 $1 个端点",
|
||||
"Use your own Private and Public Key": "使用您自己的秘钥和公钥",
|
||||
"Enter IP Address/CIDR": "输入 IP 地址/前缀长度",
|
||||
"or": "或",
|
||||
"Pick Available IP": "选择可用的 IP 地址",
|
||||
"No available IP containing": "没有可用的 IP 地址含有 ",
|
||||
"Add": "创建",
|
||||
"Adding\\.\\.\\.": "创建中...",
|
||||
"Failed to check available update": "获取更新失败",
|
||||
"Nice to meet you!": "很高兴见到您!",
|
||||
"Please fill in the following fields to finish setup": "请填入以下信息来完成初始化设置",
|
||||
"Create an account": "创建账户",
|
||||
"Enter an username you like": "输入一个您喜欢的用户名",
|
||||
"Enter a password": "输入密码",
|
||||
"\\(At least 8 characters and make sure is strong enough!\\)": "(至少8个字符或以上并且确保它足够复杂哟!)",
|
||||
"Confirm password": "确认密码",
|
||||
"Next": "下一步",
|
||||
"Saving\\.\\.\\.": "保存中...",
|
||||
"1\\. Please scan the following QR Code to generate TOTP with your choice of authenticator": "1. 请使用您选择的验证器扫描以下二维码来生成一次性验证码",
|
||||
"Or you can click the link below:": "或者您可以点击以下链接:",
|
||||
"2\\. Enter the TOTP generated by your authenticator to verify": "2. 请输入验证器生成的一次性验证码进行验证",
|
||||
"TOTP verified!": "一次性验证码验证成功!",
|
||||
"I don't need MFA": "我不需要多重身份验证 (MFA)",
|
||||
"Complete": "完成",
|
||||
"(v[0-9.]{1,}) is now available for update!": "有新版本 $1 可更新!",
|
||||
"Current Version:": "当前版本: ",
|
||||
"Oh no\\.\\.\\. This link is either expired or invalid\\.": "噢不!此链接已过期或不正确。",
|
||||
"Scan QR Code with the WireGuard App to add peer": "使用 WireGuard APP 扫描以下二维码来添加端点",
|
||||
"or click the button below to download the ": "或点击下面的按钮下载 ",
|
||||
" file": " 文件",
|
||||
"FROM ": "来自 ",
|
||||
"(.*) is on": "$1 已启用",
|
||||
"(.*) is off": "$1 已停用",
|
||||
"Allowed IPs is invalid": "允许的 IP 地址错误"
|
||||
}
|
Loading…
Reference in a new issue