mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-22 15:20:09 +01:00
Finished restrict & allow access of peers
This commit is contained in:
parent
c7ca20b45a
commit
9a280e99ad
@ -238,6 +238,12 @@ class WireguardConfiguration:
|
|||||||
self.Status = self.Name in psutil.net_if_addrs().keys()
|
self.Status = self.Name in psutil.net_if_addrs().keys()
|
||||||
return self.Status
|
return self.Status
|
||||||
|
|
||||||
|
def __getRestrictedPeers(self):
|
||||||
|
self.RestrictedPeers = []
|
||||||
|
restricted = cursor.execute("SELECT * FROM %s_restrict_access" % self.Name).fetchall()
|
||||||
|
for i in restricted:
|
||||||
|
self.RestrictedPeers.append(Peer(i, self))
|
||||||
|
|
||||||
def __getPeers(self):
|
def __getPeers(self):
|
||||||
self.Peers = []
|
self.Peers = []
|
||||||
with open(os.path.join(WG_CONF_PATH, f'{self.Name}.conf'), 'r') as configFile:
|
with open(os.path.join(WG_CONF_PATH, f'{self.Name}.conf'), 'r') as configFile:
|
||||||
@ -309,6 +315,55 @@ class WireguardConfiguration:
|
|||||||
return True, i
|
return True, i
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
|
def allowAccessPeers(self, listOfPublicKeys):
|
||||||
|
# numOfAllowedPeers = 0
|
||||||
|
# numOfFailedToAllowPeers = 0
|
||||||
|
for i in listOfPublicKeys:
|
||||||
|
p = cursor.execute("SELECT * FROM %s_restrict_access WHERE id = ?" % self.Name, (i,)).fetchone()
|
||||||
|
if p is not None:
|
||||||
|
cursor.execute("INSERT INTO %s SELECT * FROM %s_restrict_access WHERE id = ?"
|
||||||
|
% (self.Name, self.Name,), (p['id'],))
|
||||||
|
cursor.execute("DELETE FROM %s_restrict_access WHERE id = ?"
|
||||||
|
% self.Name, (p['id'],))
|
||||||
|
subprocess.check_output(f"wg set {self.Name} peer {p['id']} allowed-ips {p['allowed_ip']}",
|
||||||
|
shell=True, stderr=subprocess.STDOUT)
|
||||||
|
else:
|
||||||
|
return ResponseObject(False, "Failed to allow access of peer " + i)
|
||||||
|
if not self.__wgSave():
|
||||||
|
return ResponseObject(False, "Failed to save configuration through WireGuard")
|
||||||
|
|
||||||
|
self.__getPeers()
|
||||||
|
return ResponseObject(True, "Allow access successfully!")
|
||||||
|
|
||||||
|
def restrictPeers(self, listOfPublicKeys):
|
||||||
|
numOfRestrictedPeers = 0
|
||||||
|
numOfFailedToRestrictPeers = 0
|
||||||
|
for p in listOfPublicKeys:
|
||||||
|
found, pf = self.searchPeer(p)
|
||||||
|
if found:
|
||||||
|
try:
|
||||||
|
subprocess.check_output(f"wg set {self.Name} peer {pf.id} remove",
|
||||||
|
shell=True, stderr=subprocess.STDOUT)
|
||||||
|
cursor.execute("INSERT INTO %s_restrict_access SELECT * FROM %s WHERE id = ?" %
|
||||||
|
(self.Name, self.Name,), (pf.id,))
|
||||||
|
cursor.execute("UPDATE %s_restrict_access SET status = 'stopped' WHERE id = ?" %
|
||||||
|
(self.Name,), (pf.id,))
|
||||||
|
cursor.execute("DELETE FROM %s WHERE id = ?" % self.Name, (pf.id,))
|
||||||
|
numOfRestrictedPeers += 1
|
||||||
|
except Exception as e:
|
||||||
|
numOfFailedToRestrictPeers += 1
|
||||||
|
|
||||||
|
if not self.__wgSave():
|
||||||
|
return ResponseObject(False, "Failed to save configuration through WireGuard")
|
||||||
|
|
||||||
|
self.__getPeers()
|
||||||
|
|
||||||
|
if numOfRestrictedPeers == len(listOfPublicKeys):
|
||||||
|
return ResponseObject(True, f"Restricted {numOfRestrictedPeers} peer(s)")
|
||||||
|
return ResponseObject(False,
|
||||||
|
f"Restricted {numOfRestrictedPeers} peer(s) successfully. Failed to restrict {numOfFailedToRestrictPeers} peer(s)")
|
||||||
|
pass
|
||||||
|
|
||||||
def deletePeers(self, listOfPublicKeys):
|
def deletePeers(self, listOfPublicKeys):
|
||||||
numOfDeletedPeers = 0
|
numOfDeletedPeers = 0
|
||||||
numOfFailedToDeletePeers = 0
|
numOfFailedToDeletePeers = 0
|
||||||
@ -468,6 +523,10 @@ class WireguardConfiguration:
|
|||||||
self.__getPeers()
|
self.__getPeers()
|
||||||
return self.Peers
|
return self.Peers
|
||||||
|
|
||||||
|
def getRestrictedPeersList(self) -> list:
|
||||||
|
self.__getRestrictedPeers()
|
||||||
|
return self.RestrictedPeers
|
||||||
|
|
||||||
def toJson(self):
|
def toJson(self):
|
||||||
self.Status = self.getStatus()
|
self.Status = self.getStatus()
|
||||||
return {
|
return {
|
||||||
@ -1047,6 +1106,30 @@ def API_deletePeers(configName: str) -> ResponseObject:
|
|||||||
return ResponseObject(False, "Configuration does not exist")
|
return ResponseObject(False, "Configuration does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/restrictPeers/<configName>', methods=['POST'])
|
||||||
|
def API_restrictPeers(configName: str) -> ResponseObject:
|
||||||
|
data = request.get_json()
|
||||||
|
peers = data['peers']
|
||||||
|
if configName in WireguardConfigurations.keys():
|
||||||
|
if len(peers) == 0:
|
||||||
|
return ResponseObject(False, "Please specify more than one peer")
|
||||||
|
configuration = WireguardConfigurations.get(configName)
|
||||||
|
return configuration.restrictPeers(peers)
|
||||||
|
return ResponseObject(False, "Configuration does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/allowAccessPeers/<configName>', methods=['POST'])
|
||||||
|
def API_allowAccessPeers(configName: str) -> ResponseObject:
|
||||||
|
data = request.get_json()
|
||||||
|
peers = data['peers']
|
||||||
|
if configName in WireguardConfigurations.keys():
|
||||||
|
if len(peers) == 0:
|
||||||
|
return ResponseObject(False, "Please specify more than one peer")
|
||||||
|
configuration = WireguardConfigurations.get(configName)
|
||||||
|
return configuration.allowAccessPeers(peers)
|
||||||
|
return ResponseObject(False, "Configuration does not exist")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/addPeers/<configName>', methods=['POST'])
|
@app.route('/api/addPeers/<configName>', methods=['POST'])
|
||||||
def API_addPeers(configName):
|
def API_addPeers(configName):
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
@ -1184,7 +1267,8 @@ def API_getConfigurationInfo():
|
|||||||
return ResponseObject(False, "Please provide configuration name")
|
return ResponseObject(False, "Please provide configuration name")
|
||||||
return ResponseObject(data={
|
return ResponseObject(data={
|
||||||
"configurationInfo": WireguardConfigurations[configurationName],
|
"configurationInfo": WireguardConfigurations[configurationName],
|
||||||
"configurationPeers": WireguardConfigurations[configurationName].getPeersList()
|
"configurationPeers": WireguardConfigurations[configurationName].getPeersList(),
|
||||||
|
"configurationRestrictedPeers": WireguardConfigurations[configurationName].getRestrictedPeersList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,22 +34,31 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="card shadow-sm rounded-3">
|
<div class="card shadow-sm rounded-3"
|
||||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0">
|
:class="{'border-warning': Peer.restricted}"
|
||||||
<div class="dot ms-0" :class="{active: Peer.status === 'running'}"></div>
|
>
|
||||||
<div style="font-size: 0.8rem" class="ms-auto d-flex gap-2">
|
<div>
|
||||||
<span class="text-primary">
|
<div v-if="!Peer.restricted" class="card-header bg-transparent d-flex align-items-center gap-2 border-0">
|
||||||
<i class="bi bi-arrow-down"></i><strong>
|
<div class="dot ms-0" :class="{active: Peer.status === 'running'}"></div>
|
||||||
{{(Peer.cumu_receive + Peer.total_receive).toFixed(4)}}</strong> GB
|
<div style="font-size: 0.8rem" class="ms-auto d-flex gap-2">
|
||||||
</span>
|
<span class="text-primary">
|
||||||
<span class="text-success">
|
<i class="bi bi-arrow-down"></i><strong>
|
||||||
<i class="bi bi-arrow-up"></i><strong>
|
{{(Peer.cumu_receive + Peer.total_receive).toFixed(4)}}</strong> GB
|
||||||
{{(Peer.cumu_sent + Peer.total_sent).toFixed(4)}}</strong> GB
|
</span>
|
||||||
</span>
|
<span class="text-success">
|
||||||
<span class="text-secondary" v-if="Peer.latest_handshake !== 'No Handshake'">
|
<i class="bi bi-arrow-up"></i><strong>
|
||||||
<i class="bi bi-arrows-angle-contract"></i>
|
{{(Peer.cumu_sent + Peer.total_sent).toFixed(4)}}</strong> GB
|
||||||
{{getLatestHandshake}} ago
|
</span>
|
||||||
</span>
|
<span class="text-secondary" v-if="Peer.latest_handshake !== 'No Handshake'">
|
||||||
|
<i class="bi bi-arrows-angle-contract"></i>
|
||||||
|
{{getLatestHandshake}} ago
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="border-0 card-header bg-transparent text-warning fw-bold"
|
||||||
|
style="font-size: 0.8rem">
|
||||||
|
<i class="bi-lock-fill me-2"></i>
|
||||||
|
Access Restricted
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body pt-1" style="font-size: 0.9rem">
|
<div class="card-body pt-1" style="font-size: 0.9rem">
|
||||||
|
@ -118,15 +118,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// console.log('mounted')
|
|
||||||
// this.loading = true;
|
|
||||||
// let id = this.$route.params.id;
|
|
||||||
// this.configurationInfo = [];
|
|
||||||
// this.configurationPeers = [];
|
|
||||||
// if (id){
|
|
||||||
// this.getPeers(id)
|
|
||||||
// this.setInterval();
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route': {
|
'$route': {
|
||||||
@ -176,6 +168,13 @@ export default {
|
|||||||
}, (res) => {
|
}, (res) => {
|
||||||
this.configurationInfo = res.data.configurationInfo;
|
this.configurationInfo = res.data.configurationInfo;
|
||||||
this.configurationPeers = res.data.configurationPeers;
|
this.configurationPeers = res.data.configurationPeers;
|
||||||
|
this.configurationPeers.forEach(x => {
|
||||||
|
x.restricted = false;
|
||||||
|
})
|
||||||
|
res.data.configurationRestrictedPeers.forEach(x => {
|
||||||
|
x.restricted = true;
|
||||||
|
this.configurationPeers.push(x)
|
||||||
|
})
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (this.configurationPeers.length > 0){
|
if (this.configurationPeers.length > 0){
|
||||||
const sent = this.configurationPeers.map(x => x.total_sent + x.cumu_sent).reduce((x,y) => x + y).toFixed(4);
|
const sent = this.configurationPeers.map(x => x.total_sent + x.cumu_sent).reduce((x,y) => x + y).toFixed(4);
|
||||||
@ -336,8 +335,23 @@ export default {
|
|||||||
keys: ["name", "id", "allowed_ip"]
|
keys: ["name", "id", "allowed_ip"]
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = this.wireguardConfigurationStore.searchString ? fuse.search(this.wireguardConfigurationStore.searchString).map(x => x.item) : this.configurationPeers;
|
const result = this.wireguardConfigurationStore.searchString ?
|
||||||
|
fuse.search(this.wireguardConfigurationStore.searchString).map(x => x.item) : this.configurationPeers;
|
||||||
|
|
||||||
|
if (this.dashboardConfigurationStore.Configuration.Server.dashboard_sort === "restricted"){
|
||||||
|
return result.slice().sort((a, b) => {
|
||||||
|
if ( a[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort]
|
||||||
|
< b[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort] ){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( a[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort]
|
||||||
|
> b[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort]){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return result.slice().sort((a, b) => {
|
return result.slice().sort((a, b) => {
|
||||||
if ( a[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort]
|
if ( a[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort]
|
||||||
< b[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort] ){
|
< b[this.dashboardConfigurationStore.Configuration.Server.dashboard_sort] ){
|
||||||
@ -460,7 +474,7 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row gx-2 gy-2 mb-5">
|
<div class="row gx-2 gy-2 mb-3">
|
||||||
<div class="col-12 col-lg-6">
|
<div class="col-12 col-lg-6">
|
||||||
<div class="card rounded-3 bg-transparent shadow-sm" style="height: 270px">
|
<div class="card rounded-3 bg-transparent shadow-sm" style="height: 270px">
|
||||||
<div class="card-header bg-transparent border-0"><small class="text-muted">Peers Total Data Usage</small></div>
|
<div class="card-header bg-transparent border-0"><small class="text-muted">Peers Total Data Usage</small></div>
|
||||||
@ -498,14 +512,9 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<div class="d-flex align-items-center gap-3 mb-2 ">
|
<!-- <div class="d-flex align-items-center gap-3 mb-2">-->
|
||||||
<h3>Peers</h3>
|
<!-- <h3>Peers</h3>-->
|
||||||
|
<!-- </div>-->
|
||||||
<RouterLink
|
|
||||||
to="create"
|
|
||||||
class="text-decoration-none ms-auto btn btn-primary rounded-3">
|
|
||||||
<i class="bi bi-plus-circle-fill me-2"></i>Peers</RouterLink>
|
|
||||||
</div>
|
|
||||||
<PeerSearch></PeerSearch>
|
<PeerSearch></PeerSearch>
|
||||||
<TransitionGroup name="list" tag="div" class="row gx-2 gy-2 z-0">
|
<TransitionGroup name="list" tag="div" class="row gx-2 gy-2 z-0">
|
||||||
<div class="col-12 col-lg-6 col-xl-4"
|
<div class="col-12 col-lg-6 col-xl-4"
|
||||||
|
@ -18,7 +18,8 @@ export default {
|
|||||||
sort: {
|
sort: {
|
||||||
status: "Status",
|
status: "Status",
|
||||||
name: "Name",
|
name: "Name",
|
||||||
allowed_ip: "Allowed IP"
|
allowed_ip: "Allowed IP",
|
||||||
|
restricted: "Restricted"
|
||||||
},
|
},
|
||||||
interval: {
|
interval: {
|
||||||
'5000': '5 Seconds',
|
'5000': '5 Seconds',
|
||||||
@ -59,47 +60,59 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="d-flex gap-2 mb-3 z-3">
|
<div>
|
||||||
<div class="dropdown">
|
<div class="d-flex gap-2 mb-3 z-3">
|
||||||
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<h4 class="mb-0">Peers</h4>
|
||||||
<i class="bi bi-filter-circle me-2"></i>
|
<RouterLink
|
||||||
Sort
|
to="create"
|
||||||
</button>
|
class=" ms-auto text-decoration-none btn btn-primary rounded-3 btn-sm">
|
||||||
<ul class="dropdown-menu mt-2 shadow rounded-3">
|
<i class="bi bi-plus-lg me-2"></i>Peers
|
||||||
<li v-for="(value, key) in this.sort">
|
</RouterLink>
|
||||||
<a class="dropdown-item d-flex" role="button" @click="this.updateSort(key)">
|
|
||||||
<span class="me-auto">{{value}}</span>
|
<div class="dropdown">
|
||||||
<i class="bi bi-check text-primary"
|
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
v-if="store.Configuration.Server.dashboard_sort === key"></i>
|
<i class="bi bi-filter-circle me-2"></i>
|
||||||
</a>
|
Sort
|
||||||
</li>
|
</button>
|
||||||
</ul>
|
<ul class="dropdown-menu mt-2 shadow rounded-3">
|
||||||
</div>
|
<li v-for="(value, key) in this.sort">
|
||||||
<div class="dropdown">
|
<a class="dropdown-item d-flex" role="button" @click="this.updateSort(key)">
|
||||||
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<span class="me-auto">{{value}}</span>
|
||||||
<i class="bi bi-arrow-repeat me-2"></i>Refresh Interval
|
<i class="bi bi-check text-primary"
|
||||||
</button>
|
v-if="store.Configuration.Server.dashboard_sort === key"></i>
|
||||||
<ul class="dropdown-menu shadow mt-2 rounded-3">
|
</a>
|
||||||
<li v-for="(value, key) in this.interval">
|
</li>
|
||||||
<a class="dropdown-item d-flex" role="button" @click="updateRefreshInterval(key)">
|
</ul>
|
||||||
<span class="me-auto">{{value}}</span>
|
</div>
|
||||||
<i class="bi bi-check text-primary"
|
<div class="dropdown">
|
||||||
v-if="store.Configuration.Server.dashboard_refresh_interval === key"></i>
|
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
</a></li>
|
<i class="bi bi-arrow-repeat me-2"></i>Refresh Interval
|
||||||
</ul>
|
</button>
|
||||||
</div>
|
<ul class="dropdown-menu shadow mt-2 rounded-3">
|
||||||
<!-- <button class="btn btn-outline-secondary btn-sm rounded-3" type="button"-->
|
<li v-for="(value, key) in this.interval">
|
||||||
<!-- @click="this.store.Peers.Selecting = !this.store.Peers.Selecting"-->
|
<a class="dropdown-item d-flex" role="button" @click="updateRefreshInterval(key)">
|
||||||
<!-- >-->
|
<span class="me-auto">{{value}}</span>
|
||||||
<!-- <i class="bi bi-app-indicator me-2"></i>-->
|
<i class="bi bi-check text-primary"
|
||||||
<!-- Select-->
|
v-if="store.Configuration.Server.dashboard_refresh_interval === key"></i>
|
||||||
<!-- </button>-->
|
</a></li>
|
||||||
|
</ul>
|
||||||
<div class="ms-auto d-flex align-items-center">
|
</div>
|
||||||
<label class="d-flex me-2 text-muted" for="searchPeers"><i class="bi bi-search me-1"></i></label>
|
|
||||||
<input class="form-control form-control-sm rounded-3"
|
<!-- <button class="btn btn-outline-secondary btn-sm rounded-3" type="button"-->
|
||||||
id="searchPeers"
|
<!-- @click="this.store.Peers.Selecting = !this.store.Peers.Selecting"-->
|
||||||
v-model="this.wireguardConfigurationStore.searchString">
|
<!-- >-->
|
||||||
|
<!-- <i class="bi bi-app-indicator me-2"></i>-->
|
||||||
|
<!-- Select-->
|
||||||
|
<!-- </button>-->
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<!-- <label class="d-flex me-2 text-muted" for="searchPeers"><i class="bi bi-search me-1"></i></label>-->
|
||||||
|
<input class="form-control form-control-sm rounded-3"
|
||||||
|
placeholder="Search..."
|
||||||
|
id="searchPeers"
|
||||||
|
v-model="this.wireguardConfigurationStore.searchString">
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,9 @@ export default {
|
|||||||
},
|
},
|
||||||
data(){
|
data(){
|
||||||
return{
|
return{
|
||||||
deleteBtnDisabled: false
|
deleteBtnDisabled: false,
|
||||||
|
restrictBtnDisabled: false,
|
||||||
|
allowAccessBtnDisabled: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -55,6 +57,26 @@ export default {
|
|||||||
this.$emit("refresh")
|
this.$emit("refresh")
|
||||||
this.deleteBtnDisabled = false
|
this.deleteBtnDisabled = false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
restrictPeer(){
|
||||||
|
this.restrictBtnDisabled = true
|
||||||
|
fetchPost(`/api/restrictPeers/${this.$route.params.id}`, {
|
||||||
|
peers: [this.Peer.id]
|
||||||
|
}, (res) => {
|
||||||
|
this.dashboardStore.newMessage("Server", res.message, res.status ? "success":"danger")
|
||||||
|
this.$emit("refresh")
|
||||||
|
this.restrictBtnDisabled = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
allowAccessPeer(){
|
||||||
|
this.allowAccessBtnDisabled = true
|
||||||
|
fetchPost(`/api/allowAccessPeers/${this.$route.params.id}`, {
|
||||||
|
peers: [this.Peer.id]
|
||||||
|
}, (res) => {
|
||||||
|
this.dashboardStore.newMessage("Server", res.message, res.status ? "success":"danger")
|
||||||
|
this.$emit("refresh")
|
||||||
|
this.allowAccessBtnDisabled = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,61 +84,75 @@ export default {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ul class="dropdown-menu mt-2 shadow-lg d-block rounded-3" style="max-width: 200px">
|
<ul class="dropdown-menu mt-2 shadow-lg d-block rounded-3" style="max-width: 200px">
|
||||||
<template v-if="!this.Peer.private_key">
|
<template v-if="!this.Peer.restricted">
|
||||||
<li>
|
<template v-if="!this.Peer.private_key">
|
||||||
<small class="w-100 dropdown-item text-muted"
|
<li>
|
||||||
style="white-space: break-spaces; font-size: 0.7rem"
|
<small class="w-100 dropdown-item text-muted"
|
||||||
>Download & QR Code is not available due to no <code>private key</code>
|
style="white-space: break-spaces; font-size: 0.7rem"
|
||||||
set for this peer
|
>Download & QR Code is not available due to no <code>private key</code>
|
||||||
</small>
|
set for this peer
|
||||||
</li>
|
</small>
|
||||||
<li><hr class="dropdown-divider"></li>
|
</li>
|
||||||
</template>
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
</template>
|
||||||
<li>
|
|
||||||
<a class="dropdown-item d-flex" role="button"
|
|
||||||
@click="this.$emit('setting')"
|
|
||||||
>
|
|
||||||
<i class="me-auto bi bi-pen"></i> Edit
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<template v-if="this.Peer.private_key">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item d-flex" role="button" @click="this.downloadPeer()">
|
|
||||||
<i class="me-auto bi bi-download"></i> Download
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item d-flex" role="button"
|
<a class="dropdown-item d-flex" role="button"
|
||||||
@click="this.downloadQRCode()"
|
@click="this.$emit('setting')"
|
||||||
>
|
>
|
||||||
<i class="me-auto bi bi-qr-code"></i> QR Code
|
<i class="me-auto bi bi-pen"></i> Edit
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<template v-if="this.Peer.private_key">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item d-flex" role="button" @click="this.downloadPeer()">
|
||||||
|
<i class="me-auto bi bi-download"></i> Download
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item d-flex" role="button"
|
||||||
|
@click="this.downloadQRCode()"
|
||||||
|
>
|
||||||
|
<i class="me-auto bi bi-qr-code"></i> QR Code
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item d-flex text-warning"
|
||||||
|
@click="this.restrictPeer()"
|
||||||
|
:class="{disabled: this.restrictBtnDisabled}"
|
||||||
|
role="button">
|
||||||
|
<i class="me-auto bi bi-lock"></i> {{!this.restrictBtnDisabled ? "Restrict Access":"Restricting..."}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item d-flex fw-bold text-danger"
|
||||||
|
@click="this.deletePeer()"
|
||||||
|
:class="{disabled: this.deleteBtnDisabled}"
|
||||||
|
role="button">
|
||||||
|
<i class="me-auto bi bi-trash"></i> {{!this.deleteBtnDisabled ? "Delete":"Deleting..."}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item d-flex text-warning"
|
||||||
|
@click="this.allowAccessPeer()"
|
||||||
|
:class="{disabled: this.restrictBtnDisabled}"
|
||||||
|
role="button">
|
||||||
|
<i class="me-auto bi bi-unlock"></i>
|
||||||
|
{{!this.allowAccessBtnDisabled ? "Allow Access":"Allowing..."}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<li><hr class="dropdown-divider"></li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item d-flex text-warning"
|
|
||||||
|
|
||||||
role="button">
|
|
||||||
<i class="me-auto bi bi-lock"></i> Lock
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item d-flex fw-bold text-danger"
|
|
||||||
@click="this.deletePeer()"
|
|
||||||
:class="{disabled: this.deleteBtnDisabled}"
|
|
||||||
role="button">
|
|
||||||
<i class="me-auto bi bi-trash"></i> {{!this.deleteBtnDisabled ? "Delete":"Deleting..."}}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.dropdown-menu{
|
.dropdown-menu{
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item.disabled, .dropdown-item:disabled{
|
.dropdown-item.disabled, .dropdown-item:disabled{
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "restrictedPeers"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="mb-4">
|
||||||
|
<RouterLink to="peers" is="div" class="d-flex align-items-center gap-4 text-decoration-none">
|
||||||
|
<h3 class="mb-0 text-body">
|
||||||
|
<i class="bi bi-chevron-left"></i>
|
||||||
|
</h3>
|
||||||
|
<h3 class="text-body mb-0">Restricted Peers</h3>
|
||||||
|
</RouterLink>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -14,6 +14,7 @@ import Configuration from "@/views/configuration.vue";
|
|||||||
import PeerSettings from "@/components/configurationComponents/peerSettings.vue";
|
import PeerSettings from "@/components/configurationComponents/peerSettings.vue";
|
||||||
import PeerList from "@/components/configurationComponents/peerList.vue";
|
import PeerList from "@/components/configurationComponents/peerList.vue";
|
||||||
import PeerCreate from "@/components/configurationComponents/peerCreate.vue";
|
import PeerCreate from "@/components/configurationComponents/peerCreate.vue";
|
||||||
|
import RestrictedPeers from "@/components/configurationComponents/restrictedPeers.vue";
|
||||||
|
|
||||||
const checkAuth = async () => {
|
const checkAuth = async () => {
|
||||||
let result = false
|
let result = false
|
||||||
|
Loading…
Reference in New Issue
Block a user