多用户与角色:owner / admin / reader 三级,用户管理页 + 密码上库
- users 表加 password_hash 列;后台账号(owner+admin)密码 bcrypt 存行内, 首次登录把 env / settings 引导凭据自迁移成行哈希 - 会话 token 从用户名改为携带用户 ID,角色与停用状态每请求查库, 改角色 / 停用账号即时生效(存量会话立即 401) - 登录:先查 users 表,再走 settings 哈希 / env 引导链; admin/admin 开发模式在任何账号设过密码后失效 - 权限:系统设置、用户管理仅 owner;内容管理 admin+owner; admin 后台新增 用户 页(创建 / 重置密码 / 停用 / 删除), 设置页「登录与存储」tab 对管理员隐藏 - 账户页加修改密码表单(旧密码校验,OAuth/Passkey 首设免旧密码); 评论区管理员身份跟随各自账号,不再统一挂站主名下 - 修复:providers 为 nil 时账户页白屏(Go nil slice 序列化成 null)
This commit is contained in:
1 parent
e5dee4daf1
commit
4bb2ff4145
23 files changed
+917
-222
No files matched your search
@@ -18,13 +18,39 @@ const uploading = ref(false)
|
||||
const regBusy = ref(false)
|
||||
const fileInput = ref(null)
|
||||
|
||||
// 修改登录密码(owner / admin 都在这里改;密码存在自己的账号行上)
|
||||
const pw = ref({ old: '', next: '', confirm: '' })
|
||||
const pwBusy = ref(false)
|
||||
async function changePassword() {
|
||||
if (pw.value.next !== pw.value.confirm) {
|
||||
toastErr('两次输入的新密码不一致')
|
||||
return
|
||||
}
|
||||
if (pw.value.next.length < 6) {
|
||||
toastErr('新密码至少 6 位')
|
||||
return
|
||||
}
|
||||
pwBusy.value = true
|
||||
try {
|
||||
await adminApi.changePassword({ old_password: pw.value.old, new_password: pw.value.next })
|
||||
toastOk('密码已更新,下次登录用新密码')
|
||||
pw.value = { old: '', next: '', confirm: '' }
|
||||
} catch (e) {
|
||||
toastErr(e.message || '修改失败')
|
||||
} finally {
|
||||
pwBusy.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
async function load() {
|
||||
console.warn('ACCT: load() start')
|
||||
loading.value = true
|
||||
try {
|
||||
acct.value = await adminApi.account()
|
||||
console.warn('ACCT: loaded', !!acct.value)
|
||||
} catch (e) {
|
||||
toastErr(e.message || '读取账户信息失败')
|
||||
} finally {
|
||||
@@ -185,8 +211,8 @@ onMounted(async () => {
|
||||
<label>用户名(handle)</label>
|
||||
<input :value="acct.handle" class="input" disabled />
|
||||
<p class="field-hint">
|
||||
登录用户名在「设置 → 登录与存储」里改;这里是站主在评论区的
|
||||
身份标识(handle),改它要连登录名一起换。
|
||||
后台账号的用户名即登录名:站主的在「设置 → 登录与存储」里改,
|
||||
管理员账号由站主在「用户」页创建。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -195,6 +221,26 @@ onMounted(async () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- ---------- 登录密码 ---------- -->
|
||||
<div class="panel" style="margin-top: 18px;">
|
||||
<div class="panel-title"><h2>登录密码</h2></div>
|
||||
<div class="field">
|
||||
<label>旧密码</label>
|
||||
<input v-model="pw.old" class="input" type="password" autocomplete="current-password" placeholder="从未设过密码可不填" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>新密码(6-72 位)</label>
|
||||
<input v-model="pw.next" class="input" type="password" autocomplete="new-password" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>确认新密码</label>
|
||||
<input v-model="pw.confirm" class="input" type="password" autocomplete="new-password" />
|
||||
</div>
|
||||
<button class="btn btn-primary" :disabled="pwBusy" @click="changePassword">
|
||||
{{ pwBusy ? '提交中…' : '更新密码' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- ---------- 登录方式 ---------- -->
|
||||
<div class="panel" style="margin-top: 18px;">
|
||||
<div class="panel-title"><h2>登录方式</h2></div>
|
||||
|
||||
Reference in new issue
Block a user