From d01d865b4d339100b0c9cfc8de3b6d5d9beeceae Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Sun, 26 Jan 2025 11:35:24 +0100 Subject: [PATCH] fix self provisioning feature (#272) --- frontend/src/components/UserPeerEditModal.vue | 294 ++++++++++++++++++ frontend/src/stores/profile.js | 22 ++ frontend/src/views/ProfileView.vue | 26 +- .../app/api/v0/handlers/endpoint_peers.go | 4 +- .../app/api/v0/handlers/endpoint_users.go | 42 ++- internal/app/api/v0/model/models_interface.go | 6 +- internal/app/repos.go | 1 + .../app/wireguard/wireguard_interfaces.go | 28 ++ internal/app/wireguard/wireguard_peers.go | 53 +++- internal/domain/interface.go | 11 + internal/domain/peer.go | 13 + 11 files changed, 482 insertions(+), 18 deletions(-) create mode 100644 frontend/src/components/UserPeerEditModal.vue diff --git a/frontend/src/components/UserPeerEditModal.vue b/frontend/src/components/UserPeerEditModal.vue new file mode 100644 index 00000000..21cd0988 --- /dev/null +++ b/frontend/src/components/UserPeerEditModal.vue @@ -0,0 +1,294 @@ + + + + + diff --git a/frontend/src/stores/profile.js b/frontend/src/stores/profile.js index fcf58563..6c3d5895 100644 --- a/frontend/src/stores/profile.js +++ b/frontend/src/stores/profile.js @@ -12,6 +12,8 @@ export const profileStore = defineStore({ id: 'profile', state: () => ({ peers: [], + interfaces: [], + selectedInterfaceId: "", stats: {}, statsEnabled: false, user: {}, @@ -71,6 +73,7 @@ export const profileStore = defineStore({ return (id) => state.statsEnabled && (id in state.stats) ? state.stats[id] : freshStats() }, hasStatistics: (state) => state.statsEnabled, + CountInterfaces: (state) => state.interfaces.length, }, actions: { afterPageSizeChange() { @@ -116,6 +119,11 @@ export const profileStore = defineStore({ this.stats = statsResponse.Stats this.statsEnabled = statsResponse.Enabled }, + setInterfaces(interfaces) { + this.interfaces = interfaces + this.selectedInterfaceId = interfaces.length > 0 ? interfaces[0].Identifier : "" + this.fetching = false + }, async enableApi() { this.fetching = true let currentUser = authStore().user.Identifier @@ -186,5 +194,19 @@ export const profileStore = defineStore({ }) }) }, + async LoadInterfaces() { + this.fetching = true + let currentUser = authStore().user.Identifier + return apiWrapper.get(`${baseUrl}/${base64_url_encode(currentUser)}/interfaces`) + .then(this.setInterfaces) + .catch(error => { + this.setInterfaces([]) + console.log("Failed to load interfaces for ", currentUser, ": ", error) + notify({ + title: "Backend Connection Failure", + text: "Failed to load interfaces!", + }) + }) + }, } }) diff --git a/frontend/src/views/ProfileView.vue b/frontend/src/views/ProfileView.vue index 0516fd41..295d7438 100644 --- a/frontend/src/views/ProfileView.vue +++ b/frontend/src/views/ProfileView.vue @@ -3,7 +3,7 @@ import PeerViewModal from "../components/PeerViewModal.vue"; import { onMounted, ref } from "vue"; import { profileStore } from "@/stores/profile"; -import PeerEditModal from "@/components/PeerEditModal.vue"; +import UserPeerEditModal from "@/components/UserPeerEditModal.vue"; import { settingsStore } from "@/stores/settings"; import { humanFileSize } from "@/helpers/utils"; @@ -27,10 +27,18 @@ function sortBy(key) { profile.sortOrder = sortOrder.value; } +function friendlyInterfaceName(id, name) { + if (name) { + return name + } + return id +} + onMounted(async () => { await profile.LoadUser() await profile.LoadPeers() await profile.LoadStats() + await profile.LoadInterfaces() await profile.calculatePages(); // Forces to show initial page number }) @@ -38,7 +46,7 @@ onMounted(async () => {