Added client profile update

This commit is contained in:
Donald Zou 2025-08-11 14:35:30 +08:00
parent e313776982
commit f59111025b
8 changed files with 109 additions and 24 deletions

View File

@ -1325,6 +1325,14 @@ def API_Clients_GeneratePasswordResetLink():
return ResponseObject(data=token) return ResponseObject(data=token)
return ResponseObject(False, "Failed to generate link") return ResponseObject(False, "Failed to generate link")
@app.post(f'{APP_PREFIX}/api/clients/updateProfileName')
def API_Clients_UpdateProfile():
data = request.get_json()
clientId = data.get("ClientID")
if not clientId:
return ResponseObject(False, "Please provide ClientID")
value = data.get('Name')
return ResponseObject(status=DashboardClients.UpdateClientProfile(clientId, value))
''' '''
Index Page Index Page
''' '''

View File

@ -331,6 +331,22 @@ class DashboardClients:
return False, "Signed up failed." return False, "Signed up failed."
return True, None return True, None
def UpdateClientProfile(self, ClientID, Name):
try:
with self.engine.begin() as conn:
conn.execute(
self.dashboardClientsInfoTable.update().values({
"Name": Name
}).where(
self.dashboardClientsInfoTable.c.ClientID == ClientID
)
)
self.logger.log(Message=f"User {ClientID} updated name to {Name}")
except Exception as e:
self.logger.log(Status="false", Message=f"User {ClientID} updated name to {Name} failed")
return False
return True
''' '''
For WGDashboard Admin to Manage Clients For WGDashboard Admin to Manage Clients
''' '''

View File

@ -80,6 +80,9 @@ class DashboardConfig:
"admin_enable": "false", "admin_enable": "false",
"client_enable": "false" "client_enable": "false"
}, },
"Clients": {
"allow_local_sign_up": "true"
},
"WireGuardConfiguration": { "WireGuardConfiguration": {
"autostart": "" "autostart": ""
} }

View File

@ -3,6 +3,7 @@
"version": "4.3", "version": "4.3",
"private": true, "private": true,
"type": "module", "type": "module",
"module": "es2022",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",

View File

@ -1,28 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import {ref, watch} from "vue" import {ref, watch} from "vue"
import LocaleText from "@/components/text/localeText.vue"; import LocaleText from "@/components/text/localeText.vue";
const props = defineProps(['mode'])
import { fetchGet } from "@/utilities/fetch.js" import { fetchGet } from "@/utilities/fetch.js"
import { DashboardConfigurationStore } from "@/stores/DashboardConfigurationStore" import { DashboardConfigurationStore } from "@/stores/DashboardConfigurationStore"
const props = defineProps(['mode'])
const dashboardConfigurationStore = DashboardConfigurationStore() const dashboardConfigurationStore = DashboardConfigurationStore()
const oidcStatus = ref(false) const oidcStatus = ref(false)
const oidcStatusLoading = ref(false) const oidcStatusLoading = ref(false)
const getStatus = async () => { const getStatus = async () => {
await fetchGet("/api/oidc/status", { await fetchGet("/api/oidc/status", {
mode: "Client" mode: props.mode
}, (res) => { }, (res) => {
oidcStatus.value = res.data oidcStatus.value = res.data
oidcStatusLoading.value = false oidcStatusLoading.value = false
}) })
} }
await getStatus() await getStatus()
const toggle = async () => { const toggle = async () => {
oidcStatusLoading.value = true oidcStatusLoading.value = true
await fetchGet('/api/oidc/toggle', { await fetchGet('/api/oidc/toggle', {
mode: "Client" mode: props.mode
}, (res) => { }, (res) => {
if (!res.status){ if (!res.status){
oidcStatus.value = !oidcStatus.value oidcStatus.value = !oidcStatus.value
@ -31,7 +30,6 @@ const toggle = async () => {
oidcStatusLoading.value = false oidcStatusLoading.value = false
}) })
} }
</script> </script>
<template> <template>
@ -54,12 +52,9 @@ const toggle = async () => {
<div> <div>
<div class="alert alert-dark rounded-3 mb-0"> <div class="alert alert-dark rounded-3 mb-0">
<LocaleText t="Due to security reason, in order to edit OIDC configuration, you will need to edit "></LocaleText> <LocaleText t="Due to security reason, in order to edit OIDC configuration, you will need to edit "></LocaleText>
<code>wg-dashboard-oidc-providers.json</code> <LocaleText t="directly. If you updated the file, click the update button below to reload the configuration."></LocaleText> <code>wg-dashboard-oidc-providers.json</code> <LocaleText t="directly, then restart WGDashboard to apply the latest settings."></LocaleText>
</div> </div>
</div> </div>
<button class="rounded-3 btn bg-success-subtle text-success-emphasis border-success-subtle">
<i class="bi bi-arrow-clockwise me-2"></i><LocaleText t="Refresh"></LocaleText>
</button>
</div> </div>
</template> </template>

View File

@ -1,8 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive } from "vue"
import LocaleText from "@/components/text/localeText.vue"; import LocaleText from "@/components/text/localeText.vue";
import OidcSettings from "@/components/clientComponents/clientSettingComponents/oidcSettings.vue"; import OidcSettings from "@/components/clientComponents/clientSettingComponents/oidcSettings.vue";
const emits = defineEmits(['close']) const emits = defineEmits(['close'])
import { DashboardConfigurationStore } from "@/stores/DashboardConfigurationStore"
const dashboardConfigurationStore = DashboardConfigurationStore()
const loading = ref(false)
const values = reactive({
allow_local_sign_up: dashboardConfigurationStore.Configuration.Clients.allow_local_sign_up
})
</script> </script>
<template> <template>
@ -17,7 +23,23 @@ const emits = defineEmits(['close'])
<div class="card-body px-4"> <div class="card-body px-4">
<div class="py-2"> <div class="py-2">
<OidcSettings mode="Client"></OidcSettings> <OidcSettings mode="Client"></OidcSettings>
<hr> <!-- <hr>-->
<!-- <div>-->
<!-- <div class="d-flex">-->
<!-- <h6 class="mb-0">-->
<!-- <LocaleText t="Allow Local Accounts Sign Up"></LocaleText>-->
<!-- </h6>-->
<!-- <div class="form-check form-switch ms-auto">-->
<!-- <label class="form-check-label" for="allow_local_sign_up">-->
<!-- <LocaleText :t="values.allow_local_sign_up ? 'Enabled':'Disabled'"></LocaleText>-->
<!-- </label>-->
<!-- <input-->
<!-- :disabled="loading"-->
<!-- v-model="values.allow_local_sign_up"-->
<!-- class="form-check-input" type="checkbox" role="switch" id="allow_local_sign_up">-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,20 +1,22 @@
<script setup lang="ts" async> <script setup lang="ts" async>
import {useRoute} from "vue-router"; import {useRoute} from "vue-router";
import { fetchGet } from "@/utilities/fetch.js" import { fetchGet, fetchPost } from "@/utilities/fetch.js"
import {DashboardClientAssignmentStore} from "@/stores/DashboardClientAssignmentStore.js"; import {DashboardClientAssignmentStore} from "@/stores/DashboardClientAssignmentStore.js";
import {computed, ref, watch} from "vue"; import { DashboardConfigurationStore } from "@/stores/DashboardConfigurationStore.js"
import {computed, reactive, ref, watch} from "vue";
import LocaleText from "@/components/text/localeText.vue"; import LocaleText from "@/components/text/localeText.vue";
import ClientAssignedPeers from "@/components/clientComponents/clientAssignedPeers.vue"; import ClientAssignedPeers from "@/components/clientComponents/clientAssignedPeers.vue";
import ClientResetPassword from "@/components/clientComponents/clientResetPassword.vue"; import ClientResetPassword from "@/components/clientComponents/clientResetPassword.vue";
const assignmentStore = DashboardClientAssignmentStore() const assignmentStore = DashboardClientAssignmentStore()
const route = useRoute() const dashboardConfigurationStore = DashboardConfigurationStore()
const route = useRoute()
const client = computed(() => { const client = computed(() => {
return assignmentStore.getClientById(route.params.id) return assignmentStore.getClientById(route.params.id)
}) })
const clientAssignedPeers = ref({}) const clientAssignedPeers = ref({})
const getAssignedPeers = async () => { const getAssignedPeers = async () => {
await fetchGet('/api/clients/assignedPeers', { await fetchGet('/api/clients/assignedPeers', {
@ -24,12 +26,36 @@ const getAssignedPeers = async () => {
}) })
} }
const clientProfile = reactive({
Name: client.value.Name
})
if (client.value){ if (client.value){
watch(() => client.value.ClientID, async () => { watch(() => client.value.ClientID, async () => {
clientProfile.Name = client.value.Name;
await getAssignedPeers() await getAssignedPeers()
}) })
await getAssignedPeers() await getAssignedPeers()
} }
const updatingProfile = ref(false)
const updateProfile = async () => {
updatingProfile.value = true
await fetchPost("/api/clients/updateProfileName", {
ClientID: client.value.ClientID,
Name: clientProfile.Name
}, (res) => {
if (res.status){
client.value.Name = clientProfile.Name;
dashboardConfigurationStore.newMessage("Server", "Client name update success", "success")
}else{
clientProfile.Name = client.value.Name;
dashboardConfigurationStore.newMessage("Server", "Client name update failed", "danger")
}
updatingProfile.value = false
})
}
</script> </script>
<template> <template>
@ -46,6 +72,7 @@ if (client.value){
<h1> <h1>
{{ client.Email }} {{ client.Email }}
</h1> </h1>
<div class="d-flex flex-column gap-2">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<small class="text-muted"> <small class="text-muted">
<LocaleText t="Client ID"></LocaleText> <LocaleText t="Client ID"></LocaleText>
@ -54,6 +81,21 @@ if (client.value){
<samp>{{ client.ClientID }}</samp> <samp>{{ client.ClientID }}</samp>
</small> </small>
</div> </div>
<div class="d-flex align-items-center gap-2">
<small class="text-muted">
<LocaleText t="Client Name"></LocaleText>
</small>
<input class="form-control form-control-sm rounded-3 ms-auto"
style="width: 300px"
type="text" v-model="clientProfile.Name">
<button
@click="updateProfile()"
aria-label="Save Client Name"
class="btn btn-sm rounded-3 bg-success-subtle border-success-subtle text-success-emphasis">
<i class="bi bi-save-fill"></i>
</button>
</div>
</div>
</div> </div>
<div style="flex: 1 0 0; overflow-y: scroll;"> <div style="flex: 1 0 0; overflow-y: scroll;">
<ClientAssignedPeers <ClientAssignedPeers

View File

@ -1,7 +1,6 @@
<script> <script>
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js"; import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import PeersDefaultSettingsInput from "@/components/settingsComponent/peersDefaultSettingsInput.vue"; import PeersDefaultSettingsInput from "@/components/settingsComponent/peersDefaultSettingsInput.vue";
import {ipV46RegexCheck} from "@/utilities/ipCheck.js";
import AccountSettingsInputUsername from "@/components/settingsComponent/accountSettingsInputUsername.vue"; import AccountSettingsInputUsername from "@/components/settingsComponent/accountSettingsInputUsername.vue";
import AccountSettingsInputPassword from "@/components/settingsComponent/accountSettingsInputPassword.vue"; import AccountSettingsInputPassword from "@/components/settingsComponent/accountSettingsInputPassword.vue";
import DashboardSettingsInputWireguardConfigurationPath import DashboardSettingsInputWireguardConfigurationPath
@ -20,7 +19,6 @@ import DashboardEmailSettings from "@/components/settingsComponent/dashboardEmai
export default { export default {
name: "settings", name: "settings",
methods: {ipV46RegexCheck},
components: { components: {
DashboardEmailSettings, DashboardEmailSettings,
DashboardSettingsWireguardConfigurationAutostart, DashboardSettingsWireguardConfigurationAutostart,