From 2fd202250d454b971bfc6cb58ae0800aa6b7468a Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 30 Mar 2026 22:15:41 +0800 Subject: [PATCH] feat(members): split username/display_name, sync updates to authentik, add password reset API and refresh docs --- src/api/members.js | 1 + src/pages/admin/MembersPage.vue | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/api/members.js b/src/api/members.js index 917e3b4..5105673 100644 --- a/src/api/members.js +++ b/src/api/members.js @@ -3,6 +3,7 @@ import { adminHttp } from './http' export const getMembers = () => adminHttp.get('/admin/members') export const upsertMember = (data) => adminHttp.post('/admin/members/upsert', data) export const updateMember = (authentikSub, data) => adminHttp.patch(`/admin/members/${authentikSub}`, data) +export const resetMemberPassword = (authentikSub) => adminHttp.post(`/admin/members/${authentikSub}/password/reset`) export const getMemberPermissionGroups = (authentikSub) => adminHttp.get(`/admin/members/${authentikSub}/permission-groups`) export const setMemberPermissionGroups = (authentikSub, groupKeys) => adminHttp.put(`/admin/members/${authentikSub}/permission-groups`, { group_keys: groupKeys }) diff --git a/src/pages/admin/MembersPage.vue b/src/pages/admin/MembersPage.vue index 7108b69..a7d20da 100644 --- a/src/pages/admin/MembersPage.vue +++ b/src/pages/admin/MembersPage.vue @@ -14,20 +14,23 @@ + - + + @@ -47,6 +50,7 @@ + @@ -73,6 +77,7 @@ import { getMembers, upsertMember, updateMember, + resetMemberPassword, getMemberPermissionGroups, setMemberPermissionGroups } from '@/api/members' @@ -88,6 +93,7 @@ const showCreateDialog = ref(false) const createFormRef = ref() const creating = ref(false) const createForm = ref({ + username: '', email: '', display_name: '', group_keys: [], @@ -95,6 +101,7 @@ const createForm = ref({ sync_to_authentik: true }) const createRules = { + username: [{ required: true, message: '請輸入 Username', trigger: 'blur' }], email: [{ required: true, message: '請輸入 Email', trigger: 'blur' }] } @@ -102,6 +109,7 @@ const showEditDialog = ref(false) const saving = ref(false) const editForm = ref({ authentik_sub: '', + username: '', email: '', display_name: '', group_keys: [], @@ -126,6 +134,7 @@ async function load() { function resetCreateForm() { createForm.value = { + username: '', email: '', display_name: '', group_keys: [], @@ -137,6 +146,7 @@ function resetCreateForm() { async function openEdit(row) { editForm.value = { authentik_sub: row.authentik_sub, + username: row.username || '', email: row.email || '', display_name: row.display_name || '', group_keys: [], @@ -155,6 +165,7 @@ async function openEdit(row) { function resetEditForm() { editForm.value = { authentik_sub: '', + username: '', email: '', display_name: '', group_keys: [], @@ -189,6 +200,7 @@ async function handleEdit() { saving.value = true try { await updateMember(editForm.value.authentik_sub, { + username: editForm.value.username || null, email: editForm.value.email || null, display_name: editForm.value.display_name || null, is_active: editForm.value.is_active, @@ -206,5 +218,21 @@ async function handleEdit() { } } +async function handleResetPassword(row) { + try { + const res = await resetMemberPassword(row.authentik_sub) + const pwd = res.data?.temporary_password || '' + if (!pwd) { + ElMessage.success('密碼已重設') + return + } + await navigator.clipboard.writeText(pwd) + ElMessage.success(`已重設密碼,臨時密碼已複製:${pwd}`) + } catch (err) { + const detail = err.response?.data?.detail + ElMessage.error(detail || '重設密碼失敗') + } +} + onMounted(load)