From 48d9800b71c87f753cb2c74441f61622d2bd594e Mon Sep 17 00:00:00 2001 From: Donald Zou Date: Mon, 11 Aug 2025 17:29:15 +0800 Subject: [PATCH] Finished client deletion --- src/client.py | 28 ++- src/dashboard.py | 21 +- src/modules/DashboardClients.py | 31 ++- src/modules/DashboardClientsPeerAssignment.py | 14 ++ src/static/app/package-lock.json | 220 ++++++++++++++---- src/static/app/package.json | 3 +- .../clientComponents/clientDelete.vue | 62 +++++ .../clientComponents/clientViewer.vue | 20 +- src/static/app/src/views/clients.vue | 3 +- 9 files changed, 338 insertions(+), 64 deletions(-) create mode 100644 src/static/app/src/components/clientComponents/clientDelete.vue diff --git a/src/client.py b/src/client.py index 32f6f73..7485e79 100644 --- a/src/client.py +++ b/src/client.py @@ -18,20 +18,26 @@ def ResponseObject(status=True, message=None, data=None, status_code = 200) -> F response.content_type = "application/json" return response -def login_required(f): - @wraps(f) - def func(*args, **kwargs): - if session.get("Email") is None or session.get("TotpVerified") is None or not session.get("TotpVerified") or session.get("Role") != "client": - return ResponseObject(False, "Unauthorized access.", data=None, status_code=401) - return f(*args, **kwargs) - return func + from modules.DashboardClients import DashboardClients def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration], dashboardConfig: DashboardConfig, dashboardClients: DashboardClients): client = Blueprint('client', __name__, template_folder=os.path.abspath("./static/client/dist")) prefix = f'{dashboardConfig.GetConfig("Server", "app_prefix")[1]}/client' - + + def login_required(f): + @wraps(f) + def func(*args, **kwargs): + if session.get("Email") is None or session.get("TotpVerified") is None or not session.get("TotpVerified") or session.get("Role") != "client": + return ResponseObject(False, "Unauthorized access.", data=None, status_code=401) + + if not dashboardClients.GetClient(session.get("ClientID")): + session.clear() + return ResponseObject(False, "Unauthorized access.", data=None, status_code=401) + + return f(*args, **kwargs) + return func @client.before_request def clientBeforeRequest(): @@ -107,9 +113,11 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration], if session.get('Email') is None: return ResponseObject(False, "Sign in status is invalid", status_code=401) session['TotpVerified'] = True + profile = dashboardClients.GetClientProfile(session.get("ClientID")) + return ResponseObject(True, data={ "Email": session.get('Email'), - "Profile": dashboardClients.GetClientProfile(session.get("ClientID")) + "Profile": profile }) return ResponseObject(status, msg) @@ -145,7 +153,7 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration], @client.post(f'{prefix}/api/settings/updatePassword') @login_required def ClientAPI_Settings_UpdatePassword(): - data = request.json + data = request.get_json() status, message = dashboardClients.UpdateClientPassword(session['Email'], **data) return ResponseObject(status, message) diff --git a/src/dashboard.py b/src/dashboard.py index 06e4c70..698a510 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -1263,6 +1263,8 @@ def API_Clients_AssignClient(): client = data.get('ClientID') if not all([configurationName, id, client]): return ResponseObject(False, "Please provide all required fields") + if not DashboardClients.GetClient(client): + return ResponseObject(False, "Client does not exist") status, data = DashboardClients.AssignClient(configurationName, id, client) if not status: @@ -1307,7 +1309,8 @@ def API_Clients_AssignedPeers(): clientId = data.get("ClientID") if not clientId: return ResponseObject(False, "Please provide ClientID") - + if not DashboardClients.GetClient(clientId): + return ResponseObject(False, "Client does not exist") d = DashboardClients.GetClientAssignedPeersGrouped(clientId) if d is None: return ResponseObject(False, "Client does not exist") @@ -1319,6 +1322,8 @@ def API_Clients_GeneratePasswordResetLink(): clientId = data.get("ClientID") if not clientId: return ResponseObject(False, "Please provide ClientID") + if not DashboardClients.GetClient(clientId): + return ResponseObject(False, "Client does not exist") token = DashboardClients.GenerateClientPasswordResetLink(clientId) if token: @@ -1331,8 +1336,22 @@ def API_Clients_UpdateProfile(): clientId = data.get("ClientID") if not clientId: return ResponseObject(False, "Please provide ClientID") + if not DashboardClients.GetClient(clientId): + return ResponseObject(False, "Client does not exist") + value = data.get('Name') return ResponseObject(status=DashboardClients.UpdateClientProfile(clientId, value)) + +@app.post(f'{APP_PREFIX}/api/clients/deleteClient') +def API_Clients_DeleteClient(): + data = request.get_json() + clientId = data.get("ClientID") + if not clientId: + return ResponseObject(False, "Please provide ClientID") + if not DashboardClients.GetClient(clientId): + return ResponseObject(False, "Client does not exist") + return ResponseObject(status=DashboardClients.DeleteClient(clientId)) + ''' Index Page ''' diff --git a/src/modules/DashboardClients.py b/src/modules/DashboardClients.py index bb1ab06..a2b26ee 100644 --- a/src/modules/DashboardClients.py +++ b/src/modules/DashboardClients.py @@ -189,6 +189,7 @@ class DashboardClients: }) ) self.logger.log(Message=f"User {data.get('email', '')} from {data.get('iss', '')} signed up") + self.__getClients() return True, newClientUUID return False, "User already signed up" @@ -294,6 +295,7 @@ class DashboardClients: }) ) self.logger.log(Message=f"User {Email} signed up") + self.__getClients() except Exception as e: self.logger.log(Status="false", Message=f"Signed up failed, reason: {str(e)}") return False, "Signe up failed." @@ -346,7 +348,34 @@ class DashboardClients: self.logger.log(Status="false", Message=f"User {ClientID} updated name to {Name} failed") return False return True - + + def DeleteClient(self, ClientID): + try: + with self.engine.begin() as conn: + client = self.GetClient(ClientID) + if client.get("ClientGroup") == "Local": + conn.execute( + self.dashboardClientsTable.delete().where( + self.dashboardClientsTable.c.ClientID == ClientID + ) + ) + else: + conn.execute( + self.dashboardOIDCClientsTable.delete().where( + self.dashboardOIDCClientsTable.c.ClientID == ClientID + ) + ) + conn.execute( + self.dashboardClientsInfoTable.delete().where( + self.dashboardClientsInfoTable.c.ClientID == ClientID + ) + ) + self.DashboardClientsPeerAssignment.UnassignPeers(ClientID) + except Exception as e: + self.logger.log(Status="false", Message=f"Failed to delete {ClientID}") + return False + return True + ''' For WGDashboard Admin to Manage Clients ''' diff --git a/src/modules/DashboardClientsPeerAssignment.py b/src/modules/DashboardClientsPeerAssignment.py index c10b993..80722d0 100644 --- a/src/modules/DashboardClientsPeerAssignment.py +++ b/src/modules/DashboardClientsPeerAssignment.py @@ -108,6 +108,20 @@ class DashboardClientsPeerAssignment: self.__getAssignments() return True + def UnassignPeers(self, ClientID): + with self.engine.begin() as conn: + conn.execute( + self.dashboardClientsPeerAssignmentTable.update().values({ + "UnassignedDate": datetime.datetime.now() + }).where( + db.and_( + self.dashboardClientsPeerAssignmentTable.c.ClientID == ClientID, + self.dashboardClientsPeerAssignmentTable.c.UnassignedDate.is_(db.null()) + ) + ) + ) + self.__getAssignments() + return True def GetAssignedClients(self, ConfigurationName, PeerID) -> list[Assignment]: self.__getAssignments() diff --git a/src/static/app/package-lock.json b/src/static/app/package-lock.json index 4ecc16d..cad6fd7 100644 --- a/src/static/app/package-lock.json +++ b/src/static/app/package-lock.json @@ -8,7 +8,8 @@ "name": "app", "version": "4.3", "dependencies": { - "@vue/language-server": "^3.0.3", + "@volar/language-server": "2.4.23", + "@vue/language-server": "3.0.5", "@vuepic/vue-datepicker": "^11.0.2", "@vueuse/core": "^13.5.0", "@vueuse/shared": "^13.5.0", @@ -1594,23 +1595,23 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.20", - "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.20.tgz", - "integrity": "sha512-dRDF1G33xaAIDqR6+mXUIjXYdu9vzSxlMGfMEwBxQsfY/JMUEXSpLTR057oTKlUQ2nIvCmP9k94A8h8z2VrNSA==", + "version": "2.4.23", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.23.tgz", + "integrity": "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==", "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.20" + "@volar/source-map": "2.4.23" } }, "node_modules/@volar/language-server": { - "version": "2.4.20", - "resolved": "https://registry.npmmirror.com/@volar/language-server/-/language-server-2.4.20.tgz", - "integrity": "sha512-fNNFzEad0sO4pVZnpHggglbIeaKjLs4vH1JPPN+zd/4hSEI2u8+Qck10JhswCSO6xFTFbKxVquvWu2U2tT0EHQ==", + "version": "2.4.23", + "resolved": "https://registry.npmmirror.com/@volar/language-server/-/language-server-2.4.23.tgz", + "integrity": "sha512-k0iO+tybMGMMyrNdWOxgFkP0XJTdbH0w+WZlM54RzJU3WZSjHEupwL30klpM7ep4FO6qyQa03h+VcGHD4Q8gEg==", "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.20", - "@volar/language-service": "2.4.20", - "@volar/typescript": "2.4.20", + "@volar/language-core": "2.4.23", + "@volar/language-service": "2.4.23", + "@volar/typescript": "2.4.23", "path-browserify": "^1.0.1", "request-light": "^0.7.0", "vscode-languageserver": "^9.0.1", @@ -1620,30 +1621,30 @@ } }, "node_modules/@volar/language-service": { - "version": "2.4.20", - "resolved": "https://registry.npmmirror.com/@volar/language-service/-/language-service-2.4.20.tgz", - "integrity": "sha512-LoCD4rEI1Bj5ld6b+2GH1SbDGnoisvJ5skHlrkFEtJWw0T2+bhqGUXwekFudV/bRtp8fPhvD5ZUtjWSW0VRztg==", + "version": "2.4.23", + "resolved": "https://registry.npmmirror.com/@volar/language-service/-/language-service-2.4.23.tgz", + "integrity": "sha512-h5mU9DZ/6u3LCB9xomJtorNG6awBNnk9VuCioGsp6UtFiM8amvS5FcsaC3dabdL9zO0z+Gq9vIEMb/5u9K6jGQ==", "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.20", + "@volar/language-core": "2.4.23", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" } }, "node_modules/@volar/source-map": { - "version": "2.4.20", - "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.20.tgz", - "integrity": "sha512-mVjmFQH8mC+nUaVwmbxoYUy8cww+abaO8dWzqPUjilsavjxH0jCJ3Mp8HFuHsdewZs2c+SP+EO7hCd8Z92whJg==", + "version": "2.4.23", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.23.tgz", + "integrity": "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==", "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.20", - "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.20.tgz", - "integrity": "sha512-Oc4DczPwQyXcVbd+5RsNEqX6ia0+w3p+klwdZQ6ZKhFjWoBP9PCPQYlKYRi/tDemWphW93P/Vv13vcE9I9D2GQ==", + "version": "2.4.23", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.23.tgz", + "integrity": "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==", "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.20", + "@volar/language-core": "2.4.23", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } @@ -1758,12 +1759,12 @@ } }, "node_modules/@vue/language-core": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.0.3.tgz", - "integrity": "sha512-I9wY0ULMN9tMSua+2C7g+ez1cIziVMUzIHlDYGSl2rtru3Eh4sXj95vZ+4GBuXwwPnEmYfzSApVbXiVbI8V5Gg==", + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.0.5.tgz", + "integrity": "sha512-gCEjn9Ik7I/seHVNIEipOm8W+f3/kg60e8s1IgIkMYma2wu9ZGUTMv3mSL2bX+Md2L8fslceJ4SU8j1fgSRoiw==", "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.20", + "@volar/language-core": "2.4.22", "@vue/compiler-dom": "^3.5.0", "@vue/compiler-vue2": "^2.7.16", "@vue/shared": "^3.5.0", @@ -1781,16 +1782,31 @@ } } }, - "node_modules/@vue/language-server": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/@vue/language-server/-/language-server-3.0.3.tgz", - "integrity": "sha512-u/gyF/R89+UVlXd9Fc+8Se5Y+SxePSM1rtR361MFVu7qc92LmcxRqBIibiz8LY+KTkpMhHIqs/jObtX0d40QBg==", + "node_modules/@vue/language-core/node_modules/@volar/language-core": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.22.tgz", + "integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==", "license": "MIT", "dependencies": { - "@volar/language-server": "2.4.20", - "@vue/language-core": "3.0.3", - "@vue/language-service": "3.0.3", - "@vue/typescript-plugin": "3.0.3", + "@volar/source-map": "2.4.22" + } + }, + "node_modules/@vue/language-core/node_modules/@volar/source-map": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.22.tgz", + "integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==", + "license": "MIT" + }, + "node_modules/@vue/language-server": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/@vue/language-server/-/language-server-3.0.5.tgz", + "integrity": "sha512-f3SeLh8w4qjE82hZWVTDjTXnJ6PcKuqoDSXs69JPGfSH4yuy7VXC2IIoMhtvnupMxXTYjtJQJKjhe0p/h4whhw==", + "license": "MIT", + "dependencies": { + "@volar/language-server": "2.4.22", + "@vue/language-core": "3.0.5", + "@vue/language-service": "3.0.5", + "@vue/typescript-plugin": "3.0.5", "vscode-uri": "^3.0.8" }, "bin": { @@ -1800,14 +1816,69 @@ "typescript": "*" } }, - "node_modules/@vue/language-service": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/@vue/language-service/-/language-service-3.0.3.tgz", - "integrity": "sha512-DsJOPZUmSCEa61nDh0UqMPS7pS9Ti7uEHVRXBEc6oRp2SsZH8IGooaxHNT1Nbj0OtQfcMcopytPwD6H4EBQjNw==", + "node_modules/@vue/language-server/node_modules/@volar/language-core": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.22.tgz", + "integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==", "license": "MIT", "dependencies": { - "@volar/language-service": "2.4.20", - "@vue/language-core": "3.0.3", + "@volar/source-map": "2.4.22" + } + }, + "node_modules/@vue/language-server/node_modules/@volar/language-server": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-server/-/language-server-2.4.22.tgz", + "integrity": "sha512-THIGWcQsEJKZU7SjVKPcy4MIamX4qpusKErj33ru7fi2WcD+FmFjYY/F2LIk/C15xEcb34JT1uZBlbO2dfzYSQ==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.22", + "@volar/language-service": "2.4.22", + "@volar/typescript": "2.4.22", + "path-browserify": "^1.0.1", + "request-light": "^0.7.0", + "vscode-languageserver": "^9.0.1", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/language-server/node_modules/@volar/language-service": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-service/-/language-service-2.4.22.tgz", + "integrity": "sha512-8TmvOf/6uqaJMBVQIP9kgVpRzMrqLI3nCmWuSIPAldlmwjZTOiN17GA4AL4sTFJUg61xCSyMQWbProNFQ88yew==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.22", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/language-server/node_modules/@volar/source-map": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.22.tgz", + "integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==", + "license": "MIT" + }, + "node_modules/@vue/language-server/node_modules/@volar/typescript": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.22.tgz", + "integrity": "sha512-6ZczlJW1/GWTrNnkmZxJp4qyBt/SGVlcTuCWpI5zLrdPdCZsj66Aff9ZsfFaT3TyjG8zVYgBMYPuCm/eRkpcpQ==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.22", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/language-service": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/@vue/language-service/-/language-service-3.0.5.tgz", + "integrity": "sha512-3EFghz2F8oqQtqrSQjZiDZ+6jjCOrgdqPyJThPsy46EQfwslwFTW1ks87FzJtZR9xyfIpF3+0rxrFUyrWNFU3w==", + "license": "MIT", + "dependencies": { + "@volar/language-service": "2.4.22", + "@vue/language-core": "3.0.5", "@vue/shared": "^3.5.0", "path-browserify": "^1.0.1", "volar-service-css": "0.0.65", @@ -1821,6 +1892,33 @@ "vscode-uri": "^3.0.8" } }, + "node_modules/@vue/language-service/node_modules/@volar/language-core": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.22.tgz", + "integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==", + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.22" + } + }, + "node_modules/@vue/language-service/node_modules/@volar/language-service": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-service/-/language-service-2.4.22.tgz", + "integrity": "sha512-8TmvOf/6uqaJMBVQIP9kgVpRzMrqLI3nCmWuSIPAldlmwjZTOiN17GA4AL4sTFJUg61xCSyMQWbProNFQ88yew==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.22", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/language-service/node_modules/@volar/source-map": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.22.tgz", + "integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==", + "license": "MIT" + }, "node_modules/@vue/reactivity": { "version": "3.5.17", "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.17.tgz", @@ -1872,17 +1970,43 @@ "license": "MIT" }, "node_modules/@vue/typescript-plugin": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/@vue/typescript-plugin/-/typescript-plugin-3.0.3.tgz", - "integrity": "sha512-UgMxoIxrR0HoTV50DH7MTeT/YU917VAJxJg+lQFwTkxJTNPsaZ+QCmnsR46/s6MBRIHCJinn+up2aC22XXf4PA==", + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/@vue/typescript-plugin/-/typescript-plugin-3.0.5.tgz", + "integrity": "sha512-iR34R1dtgU75r2zxl62mGXyJVznh4Ne+1cUVQeBN6Ci3R3AAzP3v3vVVNu+QwdS37CtQAiTXfOJdiySQQ64NwQ==", "license": "MIT", "dependencies": { - "@volar/typescript": "2.4.20", - "@vue/language-core": "3.0.3", + "@volar/typescript": "2.4.22", + "@vue/language-core": "3.0.5", "@vue/shared": "^3.5.0", "path-browserify": "^1.0.1" } }, + "node_modules/@vue/typescript-plugin/node_modules/@volar/language-core": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.22.tgz", + "integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==", + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.22" + } + }, + "node_modules/@vue/typescript-plugin/node_modules/@volar/source-map": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.22.tgz", + "integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==", + "license": "MIT" + }, + "node_modules/@vue/typescript-plugin/node_modules/@volar/typescript": { + "version": "2.4.22", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.22.tgz", + "integrity": "sha512-6ZczlJW1/GWTrNnkmZxJp4qyBt/SGVlcTuCWpI5zLrdPdCZsj66Aff9ZsfFaT3TyjG8zVYgBMYPuCm/eRkpcpQ==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.22", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, "node_modules/@vuepic/vue-datepicker": { "version": "11.0.2", "resolved": "https://registry.npmmirror.com/@vuepic/vue-datepicker/-/vue-datepicker-11.0.2.tgz", @@ -2029,9 +2153,9 @@ } }, "node_modules/alien-signals": { - "version": "2.0.5", - "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-2.0.5.tgz", - "integrity": "sha512-PdJB6+06nUNAClInE3Dweq7/2xVAYM64vvvS1IHVHSJmgeOtEdrAGyp7Z2oJtYm0B342/Exd2NT0uMJaThcjLQ==", + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-2.0.6.tgz", + "integrity": "sha512-P3TxJSe31bUHBiblg59oU1PpaWPtmxF9GhJ/cB7OkgJ0qN/ifFSKUI25/v8ZhsT+lIG6ac8DpTOplXxORX6F3Q==", "license": "MIT" }, "node_modules/animate.css": { diff --git a/src/static/app/package.json b/src/static/app/package.json index 28d2ae1..8e71089 100644 --- a/src/static/app/package.json +++ b/src/static/app/package.json @@ -12,7 +12,8 @@ "preview": "vite preview" }, "dependencies": { - "@vue/language-server": "^3.0.3", + "@volar/language-server": "2.4.23", + "@vue/language-server": "3.0.5", "@vuepic/vue-datepicker": "^11.0.2", "@vueuse/core": "^13.5.0", "@vueuse/shared": "^13.5.0", diff --git a/src/static/app/src/components/clientComponents/clientDelete.vue b/src/static/app/src/components/clientComponents/clientDelete.vue new file mode 100644 index 0000000..ae7c4f9 --- /dev/null +++ b/src/static/app/src/components/clientComponents/clientDelete.vue @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/src/static/app/src/components/clientComponents/clientViewer.vue b/src/static/app/src/components/clientComponents/clientViewer.vue index b30a3b8..d12de7b 100644 --- a/src/static/app/src/components/clientComponents/clientViewer.vue +++ b/src/static/app/src/components/clientComponents/clientViewer.vue @@ -1,5 +1,5 @@ @@ -104,6 +117,9 @@ const updateProfile = async () => { :client="client"> +
diff --git a/src/static/app/src/views/clients.vue b/src/static/app/src/views/clients.vue index d378d76..e700432 100644 --- a/src/static/app/src/views/clients.vue +++ b/src/static/app/src/views/clients.vue @@ -52,6 +52,7 @@ const oidc = computed(() => { class="col-sm-4 border-end d-flex flex-column clientListContainer">
{
- +