mirror of
https://github.com/h44z/wg-portal.git
synced 2025-09-15 15:21:14 +00:00
Brought into working condition for LDAP authentication.
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
<script setup>
|
||||
import Modal from "./Modal.vue";
|
||||
import {peerStore} from "@/stores/peers";
|
||||
import {interfaceStore} from "@/stores/interfaces";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import { peerStore } from "@/stores/peers";
|
||||
import { interfaceStore } from "@/stores/interfaces";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { notify } from "@kyvg/vue3-notification";
|
||||
import Vue3TagsInput from "vue3-tags-input";
|
||||
import { validateCIDR, validateIP, validateDomain } from '@/helpers/validators';
|
||||
import isCidr from "is-cidr";
|
||||
import {isIP} from 'is-ip';
|
||||
import { isIP } from 'is-ip';
|
||||
import { freshPeer, freshInterface } from '@/helpers/models';
|
||||
import { profileStore } from "@/stores/profile";
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const peers = peerStore()
|
||||
const interfaces = interfaceStore()
|
||||
const profile = profileStore()
|
||||
|
||||
const props = defineProps({
|
||||
peerId: String,
|
||||
@@ -24,7 +26,16 @@ const props = defineProps({
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
const selectedPeer = computed(() => {
|
||||
return peers.Find(props.peerId)
|
||||
let p = peers.Find(props.peerId)
|
||||
|
||||
if (!p) {
|
||||
if (!!props.peerId || props.peerId.length) {
|
||||
p = profile.peers.find((p) => p.Identifier === props.peerId)
|
||||
} else {
|
||||
p = freshPeer() // dummy peer to avoid 'undefined' exceptions
|
||||
}
|
||||
}
|
||||
return p
|
||||
})
|
||||
|
||||
const selectedInterface = computed(() => {
|
||||
@@ -59,121 +70,119 @@ const formData = ref(freshPeer())
|
||||
// functions
|
||||
|
||||
watch(() => props.visible, async (newValue, oldValue) => {
|
||||
if (oldValue === false && newValue === true) { // if modal is shown
|
||||
console.log(selectedInterface.value)
|
||||
console.log(selectedPeer.value)
|
||||
if (!selectedPeer.value) {
|
||||
await peers.PreparePeer(selectedInterface.value.Identifier)
|
||||
if (oldValue === false && newValue === true) { // if modal is shown
|
||||
if (!selectedPeer.value) {
|
||||
await peers.PreparePeer(selectedInterface.value.Identifier)
|
||||
|
||||
formData.value.Identifier = peers.Prepared.Identifier
|
||||
formData.value.DisplayName = peers.Prepared.DisplayName
|
||||
formData.value.UserIdentifier = peers.Prepared.UserIdentifier
|
||||
formData.value.InterfaceIdentifier = peers.Prepared.InterfaceIdentifier
|
||||
formData.value.Disabled = peers.Prepared.Disabled
|
||||
formData.value.ExpiresAt = peers.Prepared.ExpiresAt
|
||||
formData.value.Notes = peers.Prepared.Notes
|
||||
formData.value.Identifier = peers.Prepared.Identifier
|
||||
formData.value.DisplayName = peers.Prepared.DisplayName
|
||||
formData.value.UserIdentifier = peers.Prepared.UserIdentifier
|
||||
formData.value.InterfaceIdentifier = peers.Prepared.InterfaceIdentifier
|
||||
formData.value.Disabled = peers.Prepared.Disabled
|
||||
formData.value.ExpiresAt = peers.Prepared.ExpiresAt
|
||||
formData.value.Notes = peers.Prepared.Notes
|
||||
|
||||
formData.value.Endpoint = peers.Prepared.Endpoint
|
||||
formData.value.EndpointPublicKey = peers.Prepared.EndpointPublicKey
|
||||
formData.value.AllowedIPs = peers.Prepared.AllowedIPs
|
||||
formData.value.ExtraAllowedIPs = peers.Prepared.ExtraAllowedIPs
|
||||
formData.value.PresharedKey = peers.Prepared.PresharedKey
|
||||
formData.value.PersistentKeepalive = peers.Prepared.PersistentKeepalive
|
||||
formData.value.Endpoint = peers.Prepared.Endpoint
|
||||
formData.value.EndpointPublicKey = peers.Prepared.EndpointPublicKey
|
||||
formData.value.AllowedIPs = peers.Prepared.AllowedIPs
|
||||
formData.value.ExtraAllowedIPs = peers.Prepared.ExtraAllowedIPs
|
||||
formData.value.PresharedKey = peers.Prepared.PresharedKey
|
||||
formData.value.PersistentKeepalive = peers.Prepared.PersistentKeepalive
|
||||
|
||||
formData.value.PrivateKey = peers.Prepared.PrivateKey
|
||||
formData.value.PublicKey = peers.Prepared.PublicKey
|
||||
formData.value.PrivateKey = peers.Prepared.PrivateKey
|
||||
formData.value.PublicKey = peers.Prepared.PublicKey
|
||||
|
||||
formData.value.Mode = peers.Prepared.Mode
|
||||
formData.value.Mode = peers.Prepared.Mode
|
||||
|
||||
formData.value.Addresses = peers.Prepared.Addresses
|
||||
formData.value.CheckAliveAddress = peers.Prepared.CheckAliveAddress
|
||||
formData.value.Dns = peers.Prepared.Dns
|
||||
formData.value.DnsSearch = peers.Prepared.DnsSearch
|
||||
formData.value.Mtu = peers.Prepared.Mtu
|
||||
formData.value.FirewallMark = peers.Prepared.FirewallMark
|
||||
formData.value.RoutingTable = peers.Prepared.RoutingTable
|
||||
formData.value.Addresses = peers.Prepared.Addresses
|
||||
formData.value.CheckAliveAddress = peers.Prepared.CheckAliveAddress
|
||||
formData.value.Dns = peers.Prepared.Dns
|
||||
formData.value.DnsSearch = peers.Prepared.DnsSearch
|
||||
formData.value.Mtu = peers.Prepared.Mtu
|
||||
formData.value.FirewallMark = peers.Prepared.FirewallMark
|
||||
formData.value.RoutingTable = peers.Prepared.RoutingTable
|
||||
|
||||
formData.value.PreUp = peers.Prepared.PreUp
|
||||
formData.value.PostUp = peers.Prepared.PostUp
|
||||
formData.value.PreDown = peers.Prepared.PreDown
|
||||
formData.value.PostDown = peers.Prepared.PostDown
|
||||
formData.value.PreUp = peers.Prepared.PreUp
|
||||
formData.value.PostUp = peers.Prepared.PostUp
|
||||
formData.value.PreDown = peers.Prepared.PreDown
|
||||
formData.value.PostDown = peers.Prepared.PostDown
|
||||
|
||||
} else { // fill existing data
|
||||
formData.value.Identifier = selectedPeer.value.Identifier
|
||||
formData.value.DisplayName = selectedPeer.value.DisplayName
|
||||
formData.value.UserIdentifier = selectedPeer.value.UserIdentifier
|
||||
formData.value.InterfaceIdentifier = selectedPeer.value.InterfaceIdentifier
|
||||
formData.value.Disabled = selectedPeer.value.Disabled
|
||||
formData.value.ExpiresAt = selectedPeer.value.ExpiresAt
|
||||
formData.value.Notes = selectedPeer.value.Notes
|
||||
} else { // fill existing data
|
||||
formData.value.Identifier = selectedPeer.value.Identifier
|
||||
formData.value.DisplayName = selectedPeer.value.DisplayName
|
||||
formData.value.UserIdentifier = selectedPeer.value.UserIdentifier
|
||||
formData.value.InterfaceIdentifier = selectedPeer.value.InterfaceIdentifier
|
||||
formData.value.Disabled = selectedPeer.value.Disabled
|
||||
formData.value.ExpiresAt = selectedPeer.value.ExpiresAt
|
||||
formData.value.Notes = selectedPeer.value.Notes
|
||||
|
||||
formData.value.Endpoint = selectedPeer.value.Endpoint
|
||||
formData.value.EndpointPublicKey = selectedPeer.value.EndpointPublicKey
|
||||
formData.value.AllowedIPs = selectedPeer.value.AllowedIPs
|
||||
formData.value.ExtraAllowedIPs = selectedPeer.value.ExtraAllowedIPs
|
||||
formData.value.PresharedKey = selectedPeer.value.PresharedKey
|
||||
formData.value.PersistentKeepalive = selectedPeer.value.PersistentKeepalive
|
||||
formData.value.Endpoint = selectedPeer.value.Endpoint
|
||||
formData.value.EndpointPublicKey = selectedPeer.value.EndpointPublicKey
|
||||
formData.value.AllowedIPs = selectedPeer.value.AllowedIPs
|
||||
formData.value.ExtraAllowedIPs = selectedPeer.value.ExtraAllowedIPs
|
||||
formData.value.PresharedKey = selectedPeer.value.PresharedKey
|
||||
formData.value.PersistentKeepalive = selectedPeer.value.PersistentKeepalive
|
||||
|
||||
formData.value.PrivateKey = selectedPeer.value.PrivateKey
|
||||
formData.value.PublicKey = selectedPeer.value.PublicKey
|
||||
formData.value.PrivateKey = selectedPeer.value.PrivateKey
|
||||
formData.value.PublicKey = selectedPeer.value.PublicKey
|
||||
|
||||
formData.value.Mode = selectedPeer.value.Mode
|
||||
formData.value.Mode = selectedPeer.value.Mode
|
||||
|
||||
formData.value.Addresses = selectedPeer.value.Addresses
|
||||
formData.value.CheckAliveAddress = selectedPeer.value.CheckAliveAddress
|
||||
formData.value.Dns = selectedPeer.value.Dns
|
||||
formData.value.DnsSearch = selectedPeer.value.DnsSearch
|
||||
formData.value.Mtu = selectedPeer.value.Mtu
|
||||
formData.value.FirewallMark = selectedPeer.value.FirewallMark
|
||||
formData.value.RoutingTable = selectedPeer.value.RoutingTable
|
||||
formData.value.Addresses = selectedPeer.value.Addresses
|
||||
formData.value.CheckAliveAddress = selectedPeer.value.CheckAliveAddress
|
||||
formData.value.Dns = selectedPeer.value.Dns
|
||||
formData.value.DnsSearch = selectedPeer.value.DnsSearch
|
||||
formData.value.Mtu = selectedPeer.value.Mtu
|
||||
formData.value.FirewallMark = selectedPeer.value.FirewallMark
|
||||
formData.value.RoutingTable = selectedPeer.value.RoutingTable
|
||||
|
||||
formData.value.PreUp = selectedPeer.value.PreUp
|
||||
formData.value.PostUp = selectedPeer.value.PostUp
|
||||
formData.value.PreDown = selectedPeer.value.PreDown
|
||||
formData.value.PostDown = selectedPeer.value.PostDown
|
||||
formData.value.PreUp = selectedPeer.value.PreUp
|
||||
formData.value.PostUp = selectedPeer.value.PostUp
|
||||
formData.value.PreDown = selectedPeer.value.PreDown
|
||||
formData.value.PostDown = selectedPeer.value.PostDown
|
||||
|
||||
if (!formData.value.Endpoint.Overridable ||
|
||||
!formData.value.EndpointPublicKey.Overridable ||
|
||||
!formData.value.AllowedIPs.Overridable ||
|
||||
!formData.value.PersistentKeepalive.Overridable ||
|
||||
!formData.value.Dns.Overridable ||
|
||||
!formData.value.DnsSearch.Overridable ||
|
||||
!formData.value.Mtu.Overridable ||
|
||||
!formData.value.FirewallMark.Overridable ||
|
||||
!formData.value.RoutingTable.Overridable ||
|
||||
!formData.value.PreUp.Overridable ||
|
||||
!formData.value.PostUp.Overridable ||
|
||||
!formData.value.PreDown.Overridable ||
|
||||
!formData.value.PostDown.Overridable) {
|
||||
formData.value.IgnoreGlobalSettings = true
|
||||
}
|
||||
}
|
||||
if (!formData.value.Endpoint.Overridable ||
|
||||
!formData.value.EndpointPublicKey.Overridable ||
|
||||
!formData.value.AllowedIPs.Overridable ||
|
||||
!formData.value.PersistentKeepalive.Overridable ||
|
||||
!formData.value.Dns.Overridable ||
|
||||
!formData.value.DnsSearch.Overridable ||
|
||||
!formData.value.Mtu.Overridable ||
|
||||
!formData.value.FirewallMark.Overridable ||
|
||||
!formData.value.RoutingTable.Overridable ||
|
||||
!formData.value.PreUp.Overridable ||
|
||||
!formData.value.PostUp.Overridable ||
|
||||
!formData.value.PreDown.Overridable ||
|
||||
!formData.value.PostDown.Overridable) {
|
||||
formData.value.IgnoreGlobalSettings = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(() => formData.value.IgnoreGlobalSettings, async (newValue, oldValue) => {
|
||||
formData.value.Endpoint.Overridable = !newValue
|
||||
formData.value.EndpointPublicKey.Overridable = !newValue
|
||||
formData.value.AllowedIPs.Overridable = !newValue
|
||||
formData.value.PersistentKeepalive.Overridable = !newValue
|
||||
formData.value.Dns.Overridable = !newValue
|
||||
formData.value.DnsSearch.Overridable = !newValue
|
||||
formData.value.Mtu.Overridable = !newValue
|
||||
formData.value.FirewallMark.Overridable = !newValue
|
||||
formData.value.RoutingTable.Overridable = !newValue
|
||||
formData.value.PreUp.Overridable = !newValue
|
||||
formData.value.PostUp.Overridable = !newValue
|
||||
formData.value.PreDown.Overridable = !newValue
|
||||
formData.value.PostDown.Overridable = !newValue
|
||||
}
|
||||
formData.value.Endpoint.Overridable = !newValue
|
||||
formData.value.EndpointPublicKey.Overridable = !newValue
|
||||
formData.value.AllowedIPs.Overridable = !newValue
|
||||
formData.value.PersistentKeepalive.Overridable = !newValue
|
||||
formData.value.Dns.Overridable = !newValue
|
||||
formData.value.DnsSearch.Overridable = !newValue
|
||||
formData.value.Mtu.Overridable = !newValue
|
||||
formData.value.FirewallMark.Overridable = !newValue
|
||||
formData.value.RoutingTable.Overridable = !newValue
|
||||
formData.value.PreUp.Overridable = !newValue
|
||||
formData.value.PostUp.Overridable = !newValue
|
||||
formData.value.PreDown.Overridable = !newValue
|
||||
formData.value.PostDown.Overridable = !newValue
|
||||
}
|
||||
)
|
||||
|
||||
watch(() => formData.value.Disabled, async (newValue, oldValue) => {
|
||||
if (oldValue && !newValue && formData.value.ExpiresAt) {
|
||||
formData.value.ExpiresAt = "" // reset expiry date
|
||||
}
|
||||
}
|
||||
if (oldValue && !newValue && formData.value.ExpiresAt) {
|
||||
formData.value.ExpiresAt = "" // reset expiry date
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
function close() {
|
||||
@@ -184,7 +193,7 @@ function close() {
|
||||
function handleChangeAddresses(tags) {
|
||||
let validInput = true
|
||||
tags.forEach(tag => {
|
||||
if(isCidr(tag) === 0) {
|
||||
if (isCidr(tag) === 0) {
|
||||
validInput = false
|
||||
notify({
|
||||
title: "Invalid CIDR",
|
||||
@@ -193,7 +202,7 @@ function handleChangeAddresses(tags) {
|
||||
})
|
||||
}
|
||||
})
|
||||
if(validInput) {
|
||||
if (validInput) {
|
||||
formData.value.Addresses = tags
|
||||
}
|
||||
}
|
||||
@@ -201,7 +210,7 @@ function handleChangeAddresses(tags) {
|
||||
function handleChangeAllowedIPs(tags) {
|
||||
let validInput = true
|
||||
tags.forEach(tag => {
|
||||
if(isCidr(tag) === 0) {
|
||||
if (isCidr(tag) === 0) {
|
||||
validInput = false
|
||||
notify({
|
||||
title: "Invalid CIDR",
|
||||
@@ -210,7 +219,7 @@ function handleChangeAllowedIPs(tags) {
|
||||
})
|
||||
}
|
||||
})
|
||||
if(validInput) {
|
||||
if (validInput) {
|
||||
formData.value.AllowedIPs.Value = tags
|
||||
}
|
||||
}
|
||||
@@ -218,7 +227,7 @@ function handleChangeAllowedIPs(tags) {
|
||||
function handleChangeExtraAllowedIPs(tags) {
|
||||
let validInput = true
|
||||
tags.forEach(tag => {
|
||||
if(isCidr(tag) === 0) {
|
||||
if (isCidr(tag) === 0) {
|
||||
validInput = false
|
||||
notify({
|
||||
title: "Invalid CIDR",
|
||||
@@ -227,7 +236,7 @@ function handleChangeExtraAllowedIPs(tags) {
|
||||
})
|
||||
}
|
||||
})
|
||||
if(validInput) {
|
||||
if (validInput) {
|
||||
formData.value.ExtraAllowedIPs = tags
|
||||
}
|
||||
}
|
||||
@@ -235,7 +244,7 @@ function handleChangeExtraAllowedIPs(tags) {
|
||||
function handleChangeDns(tags) {
|
||||
let validInput = true
|
||||
tags.forEach(tag => {
|
||||
if(!isIP(tag)) {
|
||||
if (!isIP(tag)) {
|
||||
validInput = false
|
||||
notify({
|
||||
title: "Invalid IP",
|
||||
@@ -244,7 +253,7 @@ function handleChangeDns(tags) {
|
||||
})
|
||||
}
|
||||
})
|
||||
if(validInput) {
|
||||
if (validInput) {
|
||||
formData.value.Dns.Value = tags
|
||||
}
|
||||
}
|
||||
@@ -255,14 +264,14 @@ function handleChangeDnsSearch(tags) {
|
||||
|
||||
async function save() {
|
||||
try {
|
||||
if (props.peerId!=='#NEW#') {
|
||||
if (props.peerId !== '#NEW#') {
|
||||
await peers.UpdatePeer(selectedPeer.value.Identifier, formData.value)
|
||||
} else {
|
||||
await peers.CreatePeer(selectedInterface.value.Identifier, formData.value)
|
||||
}
|
||||
close()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
// console.log(e)
|
||||
notify({
|
||||
title: "Failed to save peer!",
|
||||
text: e.toString(),
|
||||
@@ -276,7 +285,7 @@ async function del() {
|
||||
await peers.DeletePeer(selectedPeer.value.Identifier)
|
||||
close()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
// console.log(e)
|
||||
notify({
|
||||
title: "Failed to delete peer!",
|
||||
text: e.toString(),
|
||||
@@ -294,87 +303,86 @@ async function del() {
|
||||
<legend class="mt-4">{{ $t('modals.peer-edit.header-general') }}</legend>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.display-name.label') }}</label>
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.display-name.placeholder')" v-model="formData.DisplayName">
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.display-name.placeholder')"
|
||||
v-model="formData.DisplayName">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.linked-user.label') }}</label>
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.linked-user.placeholder')" v-model="formData.UserIdentifier">
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.linked-user.placeholder')"
|
||||
v-model="formData.UserIdentifier">
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="mt-4">{{ $t('modals.peer-edit.header-crypto') }}</legend>
|
||||
<div class="form-group" v-if="selectedInterface.Mode==='server'">
|
||||
<div class="form-group" v-if="selectedInterface.Mode === 'server'">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.private-key.label') }}</label>
|
||||
<input type="email" class="form-control" :placeholder="$t('modals.peer-edit.private-key.placeholder')" required v-model="formData.PrivateKey">
|
||||
<input type="email" class="form-control" :placeholder="$t('modals.peer-edit.private-key.placeholder')" required
|
||||
v-model="formData.PrivateKey">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.public-key.label') }}</label>
|
||||
<input type="email" class="form-control" :placeholder="$t('modals.peer-edit.public-key.placeholder')" required v-model="formData.PublicKey">
|
||||
<input type="email" class="form-control" :placeholder="$t('modals.peer-edit.public-key.placeholder')" required
|
||||
v-model="formData.PublicKey">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.preshared-key.label') }}</label>
|
||||
<input type="email" class="form-control" :placeholder="$t('modals.peer-edit.preshared-key.placeholder')" v-model="formData.PresharedKey">
|
||||
<input type="email" class="form-control" :placeholder="$t('modals.peer-edit.preshared-key.placeholder')"
|
||||
v-model="formData.PresharedKey">
|
||||
</div>
|
||||
<div class="form-group" v-if="formData.Mode==='client'">
|
||||
<div class="form-group" v-if="formData.Mode === 'client'">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.endpoint-public-key.label') }}</label>
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.endpoint-public-key.placeholder')" v-model="formData.EndpointPublicKey.Value">
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.endpoint-public-key.placeholder')"
|
||||
v-model="formData.EndpointPublicKey.Value">
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="mt-4">{{ $t('modals.peer-edit.header-network') }}</legend>
|
||||
<div class="form-group" v-if="selectedInterface.Mode==='client'">
|
||||
<div class="form-group" v-if="selectedInterface.Mode === 'client'">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.endpoint.label') }}</label>
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.endpoint.placeholder')" v-model="formData.Endpoint.Value">
|
||||
<input type="text" class="form-control" :placeholder="$t('modals.peer-edit.endpoint.placeholder')"
|
||||
v-model="formData.Endpoint.Value">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.ip.label') }}</label>
|
||||
<vue3-tags-input class="form-control" :tags="formData.Addresses"
|
||||
:placeholder="$t('modals.peer-edit.ip.placeholder')"
|
||||
:add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateCIDR"
|
||||
@on-tags-changed="handleChangeAddresses"/>
|
||||
:placeholder="$t('modals.peer-edit.ip.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateCIDR" @on-tags-changed="handleChangeAddresses" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.allowed-ip.label') }}</label>
|
||||
<vue3-tags-input class="form-control" :tags="formData.AllowedIPs.Value"
|
||||
:placeholder="$t('modals.peer-edit.allowed-ip.placeholder')"
|
||||
:add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateCIDR"
|
||||
@on-tags-changed="handleChangeAllowedIPs"/>
|
||||
:placeholder="$t('modals.peer-edit.allowed-ip.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateCIDR" @on-tags-changed="handleChangeAllowedIPs" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.extra-allowed-ip.label') }}</label>
|
||||
<vue3-tags-input class="form-control" :tags="formData.ExtraAllowedIPs"
|
||||
:placeholder="$t('modals.peer-edit.extra-allowed-ip.placeholder')"
|
||||
:add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateCIDR"
|
||||
@on-tags-changed="handleChangeExtraAllowedIPs"/>
|
||||
:placeholder="$t('modals.peer-edit.extra-allowed-ip.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateCIDR" @on-tags-changed="handleChangeExtraAllowedIPs" />
|
||||
<small class="form-text text-muted">{{ $t('modals.peer-edit.extra-allowed-ip.description') }}</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.dns.label') }}</label>
|
||||
<vue3-tags-input class="form-control" :tags="formData.Dns.Value"
|
||||
:placeholder="$t('modals.peer-edit.dns.placeholder')"
|
||||
:add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateIP"
|
||||
@on-tags-changed="handleChangeDns"/>
|
||||
:placeholder="$t('modals.peer-edit.dns.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateIP" @on-tags-changed="handleChangeDns" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div hidden class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.dns-search.label') }}</label>
|
||||
<vue3-tags-input class="form-control" :tags="formData.DnsSearch.Value"
|
||||
:placeholder="$t('modals.peer-edit.dns-search.label')"
|
||||
:add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateDomain"
|
||||
@on-tags-changed="handleChangeDnsSearch"/>
|
||||
:placeholder="$t('modals.peer-edit.dns-search.label')" :add-tag-on-keys="[13, 188, 32, 9]"
|
||||
:validate="validateDomain" @on-tags-changed="handleChangeDnsSearch" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.keep-alive.label') }}</label>
|
||||
<input type="number" class="form-control" :placeholder="$t('modals.peer-edit.keep-alive.label')" v-model="formData.PersistentKeepalive.Value">
|
||||
<input type="number" class="form-control" :placeholder="$t('modals.peer-edit.keep-alive.label')"
|
||||
v-model="formData.PersistentKeepalive.Value">
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.mtu.label') }}</label>
|
||||
<input type="number" class="form-control" :placeholder="$t('modals.peer-edit.mtu.label')" v-model="formData.Mtu.Value">
|
||||
<input type="number" class="form-control" :placeholder="$t('modals.peer-edit.mtu.label')"
|
||||
v-model="formData.Mtu.Value">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -382,19 +390,23 @@ async function del() {
|
||||
<legend class="mt-4">{{ $t('modals.peer-edit.header-hooks') }}</legend>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.pre-up.label') }}</label>
|
||||
<textarea v-model="formData.PreUp.Value" class="form-control" rows="2" :placeholder="$t('modals.peer-edit.pre-up.placeholder')"></textarea>
|
||||
<textarea v-model="formData.PreUp.Value" class="form-control" rows="2"
|
||||
:placeholder="$t('modals.peer-edit.pre-up.placeholder')"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.post-up.label') }}</label>
|
||||
<textarea v-model="formData.PostUp.Value" class="form-control" rows="2" :placeholder="$t('modals.peer-edit.post-up.placeholder')"></textarea>
|
||||
<textarea v-model="formData.PostUp.Value" class="form-control" rows="2"
|
||||
:placeholder="$t('modals.peer-edit.post-up.placeholder')"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.pre-down.label') }}</label>
|
||||
<textarea v-model="formData.PreDown.Value" class="form-control" rows="2" :placeholder="$t('modals.peer-edit.pre-down.placeholder')"></textarea>
|
||||
<textarea v-model="formData.PreDown.Value" class="form-control" rows="2"
|
||||
:placeholder="$t('modals.peer-edit.pre-down.placeholder')"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.peer-edit.post-down.label') }}</label>
|
||||
<textarea v-model="formData.PostDown.Value" class="form-control" rows="2" :placeholder="$t('modals.peer-edit.post-down.placeholder')"></textarea>
|
||||
<textarea v-model="formData.PostDown.Value" class="form-control" rows="2"
|
||||
:placeholder="$t('modals.peer-edit.post-down.placeholder')"></textarea>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@@ -403,7 +415,7 @@ async function del() {
|
||||
<div class="form-group col-md-6">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" v-model="formData.Disabled">
|
||||
<label class="form-check-label" >{{ $t('modals.peer-edit.disabled.label') }}</label>
|
||||
<label class="form-check-label">{{ $t('modals.peer-edit.disabled.label') }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" v-model="formData.IgnoreGlobalSettings">
|
||||
@@ -412,14 +424,16 @@ async function del() {
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label class="form-label">{{ $t('modals.peer-edit.expires-at.label') }}</label>
|
||||
<input type="date" pattern="\d{4}-\d{2}-\d{2}" class="form-control" min="2023-01-01" v-model="formData.ExpiresAt">
|
||||
<input type="date" pattern="\d{4}-\d{2}-\d{2}" class="form-control" min="2023-01-01"
|
||||
v-model="formData.ExpiresAt">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex-fill text-start">
|
||||
<button v-if="props.peerId!=='#NEW#'" class="btn btn-danger me-1" type="button" @click.prevent="del">{{ $t('general.delete') }}</button>
|
||||
<button v-if="props.peerId !== '#NEW#'" class="btn btn-danger me-1" type="button" @click.prevent="del">{{
|
||||
$t('general.delete') }}</button>
|
||||
</div>
|
||||
<button class="btn btn-primary me-1" type="button" @click.prevent="save">{{ $t('general.save') }}</button>
|
||||
<button class="btn btn-secondary" type="button" @click.prevent="close">{{ $t('general.close') }}</button>
|
||||
@@ -427,5 +441,4 @@ async function del() {
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
<style></style>
|
||||
|
@@ -1,19 +1,23 @@
|
||||
<script setup>
|
||||
import Modal from "./Modal.vue";
|
||||
import {peerStore} from "@/stores/peers";
|
||||
import {interfaceStore} from "@/stores/interfaces";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import {freshInterface, freshPeer, freshStats} from '@/helpers/models';
|
||||
import { peerStore } from "@/stores/peers";
|
||||
import { interfaceStore } from "@/stores/interfaces";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { freshInterface, freshPeer, freshStats } from '@/helpers/models';
|
||||
import Prism from "vue-prism-component";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
import {settingsStore} from "@/stores/settings";
|
||||
import { notify } from "@kyvg/vue3-notification";
|
||||
import { settingsStore } from "@/stores/settings";
|
||||
import { profileStore } from "@/stores/profile";
|
||||
import { base64_url_encode } from '@/helpers/encoding';
|
||||
import { apiWrapper } from "@/helpers/fetch-wrapper";
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const settings = settingsStore()
|
||||
const peers = peerStore()
|
||||
const interfaces = interfaceStore()
|
||||
const profile = profileStore()
|
||||
|
||||
const props = defineProps({
|
||||
peerId: String,
|
||||
@@ -32,9 +36,12 @@ const selectedPeer = computed(() => {
|
||||
let p = peers.Find(props.peerId)
|
||||
|
||||
if (!p) {
|
||||
p = freshPeer() // dummy peer to avoid 'undefined' exceptions
|
||||
if (!!props.peerId || props.peerId.length) {
|
||||
p = profile.peers.find((p) => p.Identifier === props.peerId)
|
||||
} else {
|
||||
p = freshPeer() // dummy peer to avoid 'undefined' exceptions
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
})
|
||||
|
||||
@@ -42,9 +49,13 @@ const selectedStats = computed(() => {
|
||||
let s = peers.Statistics(props.peerId)
|
||||
|
||||
if (!s) {
|
||||
s = freshStats() // dummy peer to avoid 'undefined' exceptions
|
||||
}
|
||||
if (!!props.peerId || props.peerId.length) {
|
||||
p = profile.Statistics(props.peerId)
|
||||
} else {
|
||||
s = freshStats() // dummy peer to avoid 'undefined' exceptions
|
||||
}
|
||||
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
@@ -54,7 +65,6 @@ const selectedInterface = computed(() => {
|
||||
if (!i) {
|
||||
i = freshInterface() // dummy interface to avoid 'undefined' exceptions
|
||||
}
|
||||
|
||||
return i
|
||||
})
|
||||
|
||||
@@ -70,11 +80,11 @@ const title = computed(() => {
|
||||
})
|
||||
|
||||
watch(() => props.visible, async (newValue, oldValue) => {
|
||||
if (oldValue === false && newValue === true) { // if modal is shown
|
||||
await peers.LoadPeerConfig(selectedPeer.value.Identifier)
|
||||
configString.value = peers.configuration
|
||||
}
|
||||
}
|
||||
if (oldValue === false && newValue === true) { // if modal is shown
|
||||
await peers.LoadPeerConfig(selectedPeer.value.Identifier)
|
||||
configString.value = peers.configuration
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
function download() {
|
||||
@@ -82,10 +92,10 @@ function download() {
|
||||
let filename = 'WireGuard-Tunnel.conf'
|
||||
if (selectedPeer.value.DisplayName) {
|
||||
filename = selectedPeer.value.DisplayName
|
||||
.replace(/ /g,"_")
|
||||
.replace(/[^a-zA-Z0-9-_]/g,"")
|
||||
.substring(0, 16)
|
||||
+ ".conf"
|
||||
.replace(/ /g, "_")
|
||||
.replace(/[^a-zA-Z0-9-_]/g, "")
|
||||
.substring(0, 16)
|
||||
+ ".conf"
|
||||
}
|
||||
let text = configString.value
|
||||
|
||||
@@ -110,6 +120,13 @@ function email() {
|
||||
})
|
||||
}
|
||||
|
||||
function ConfigQrUrl() {
|
||||
if (props.peerId.length) {
|
||||
return apiWrapper.url(`/peer/config-qr/${base64_url_encode(props.peerId)}`)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -118,25 +135,30 @@ function email() {
|
||||
<div class="accordion" id="peerInformation">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseDetails" aria-expanded="true" aria-controls="collapseDetails">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseDetails"
|
||||
aria-expanded="true" aria-controls="collapseDetails">
|
||||
{{ $t('modals.peer-view.section-info') }}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseDetails" class="accordion-collapse collapse show" aria-labelledby="headingDetails" data-bs-parent="#peerInformation" style="">
|
||||
<div id="collapseDetails" class="accordion-collapse collapse show" aria-labelledby="headingDetails"
|
||||
data-bs-parent="#peerInformation" style="">
|
||||
<div class="accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<ul>
|
||||
<li>{{ $t('modals.peer-view.identifier') }}: {{ selectedPeer.PublicKey }}</li>
|
||||
<li>{{ $t('modals.peer-view.ip') }}: <span v-for="ip in selectedPeer.Addresses" :key="ip" class="badge rounded-pill bg-light">{{ ip }}</span></li>
|
||||
<li>{{ $t('modals.peer-view.ip') }}: <span v-for="ip in selectedPeer.Addresses" :key="ip"
|
||||
class="badge rounded-pill bg-light">{{ ip }}</span></li>
|
||||
<li>{{ $t('modals.peer-view.user') }}: {{ selectedPeer.UserIdentifier }}</li>
|
||||
<li v-if="selectedPeer.Notes">{{ $t('modals.peer-view.notes') }}: {{ selectedPeer.Notes }}</li>
|
||||
<li v-if="selectedPeer.ExpiresAt">{{ $t('modals.peer-view.expiry-status') }}: {{ selectedPeer.ExpiresAt }}</li>
|
||||
<li v-if="selectedPeer.Disabled">{{ $t('modals.peer-view.disabled-status') }}: {{ selectedPeer.DisabledReason }}</li>
|
||||
<li v-if="selectedPeer.ExpiresAt">{{ $t('modals.peer-view.expiry-status') }}: {{
|
||||
selectedPeer.ExpiresAt }}</li>
|
||||
<li v-if="selectedPeer.Disabled">{{ $t('modals.peer-view.disabled-status') }}: {{
|
||||
selectedPeer.DisabledReason }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img class="config-qr-img" :src="peers.ConfigQrUrl(props.peerId)" loading="lazy" alt="Configuration QR Code">
|
||||
<img class="config-qr-img" :src="ConfigQrUrl()" loading="lazy" alt="Configuration QR Code">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -144,16 +166,20 @@ function email() {
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingStatus">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseStatus" aria-expanded="false" aria-controls="collapseStatus">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseStatus" aria-expanded="false" aria-controls="collapseStatus">
|
||||
{{ $t('modals.peer-view.section-status') }}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseStatus" class="accordion-collapse collapse" aria-labelledby="headingStatus" data-bs-parent="#peerInformation" style="">
|
||||
<div id="collapseStatus" class="accordion-collapse collapse" aria-labelledby="headingStatus"
|
||||
data-bs-parent="#peerInformation" style="">
|
||||
<div class="accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h4>{{ $t('modals.peer-view.traffic') }}</h4>
|
||||
<p><i class="fas fa-long-arrow-alt-down" :title="$t('modals.peer-view.download')"></i> {{ selectedStats.BytesReceived }} Bytes / <i class="fas fa-long-arrow-alt-up" :title="$t('modals.peer-view.upload')"></i> {{ selectedStats.BytesTransmitted }} Bytes</p>
|
||||
<p><i class="fas fa-long-arrow-alt-down" :title="$t('modals.peer-view.download')"></i> {{
|
||||
selectedStats.BytesReceived }} Bytes / <i class="fas fa-long-arrow-alt-up"
|
||||
:title="$t('modals.peer-view.upload')"></i> {{ selectedStats.BytesTransmitted }} Bytes</p>
|
||||
<h4>{{ $t('modals.peer-view.connection-status') }}</h4>
|
||||
<ul>
|
||||
<li>{{ $t('modals.peer-view.pingable') }}: {{ selectedStats.IsPingable }}</li>
|
||||
@@ -166,13 +192,15 @@ function email() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="selectedInterface.Mode==='server'" class="accordion-item">
|
||||
<div v-if="selectedInterface.Mode === 'server'" class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingConfig">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseConfig" aria-expanded="false" aria-controls="collapseConfig">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseConfig" aria-expanded="false" aria-controls="collapseConfig">
|
||||
{{ $t('modals.peer-view.section-config') }}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseConfig" class="accordion-collapse collapse" aria-labelledby="headingConfig" data-bs-parent="#peerInformation" style="">
|
||||
<div id="collapseConfig" class="accordion-collapse collapse" aria-labelledby="headingConfig"
|
||||
data-bs-parent="#peerInformation" style="">
|
||||
<div class="accordion-body">
|
||||
<Prism language="ini" :code="configString"></Prism>
|
||||
</div>
|
||||
@@ -182,18 +210,17 @@ function email() {
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex-fill text-start">
|
||||
<button @click.prevent="download" type="button" class="btn btn-primary me-1">{{ $t('modals.peer-view.button-download') }}</button>
|
||||
<button @click.prevent="email" type="button" class="btn btn-primary me-1">{{ $t('modals.peer-view.button-email') }}</button>
|
||||
<button @click.prevent="download" type="button" class="btn btn-primary me-1">{{
|
||||
$t('modals.peer-view.button-download') }}</button>
|
||||
<button @click.prevent="email" hidden type="button" class="btn btn-primary me-1">{{
|
||||
$t('modals.peer-view.button-email') }}</button>
|
||||
</div>
|
||||
<button @click.prevent="close" type="button" class="btn btn-secondary">{{ $t('general.close') }}</button>
|
||||
|
||||
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
</template>
|
||||
</Modal></template>
|
||||
|
||||
<style>
|
||||
.config-qr-img {
|
||||
<style>.config-qr-img {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
}</style>
|
||||
|
Reference in New Issue
Block a user