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 @@
+
+
+
+
+
+
+
+
+
+
+
+