122 lines
4.8 KiB
JavaScript
122 lines
4.8 KiB
JavaScript
/* iAOP 用户/角色管理页逻辑(issue #134)。
|
||
* 会话守卫复用 #150 的 IAOP_AUTH.requireLoginElseRedirect(core/auth 后端 /auth/me);
|
||
* 仅 admin(manage 权限)可访问;CRUD/审计/OIDC 走 user_store.js(Demo 存储)。
|
||
*/
|
||
"use strict";
|
||
|
||
(function () {
|
||
IAOP_AUTH.requireLoginElseRedirect("login.html").then(function (user) {
|
||
if (!user) return; // 正在跳转登录页
|
||
if (user.role !== "admin") {
|
||
alert("仅 Publisher(admin)可访问用户管理");
|
||
location.href = "../studio/index.html";
|
||
return;
|
||
}
|
||
document.getElementById("who").textContent =
|
||
user.username + " · " + UserStore.ROLE_LABELS[user.role];
|
||
|
||
function el(tag, text) {
|
||
var n = document.createElement(tag);
|
||
if (text !== undefined) n.textContent = text;
|
||
return n;
|
||
}
|
||
|
||
function renderUsers() {
|
||
var tbody = document.getElementById("user-tbody");
|
||
tbody.innerHTML = "";
|
||
UserStore.list().forEach(function (u) {
|
||
var tr = el("tr");
|
||
if (!u.active) tr.className = "disabled-user";
|
||
tr.appendChild(el("td", u.username));
|
||
// 角色分配(下拉即改)
|
||
var tdRole = el("td");
|
||
var sel = el("select");
|
||
UserStore.ROLES.forEach(function (r) {
|
||
var opt = el("option", UserStore.ROLE_LABELS[r]);
|
||
opt.value = r;
|
||
if (r === u.role) opt.selected = true;
|
||
sel.appendChild(opt);
|
||
});
|
||
sel.className = "role-" + u.role;
|
||
sel.onchange = function () {
|
||
UserStore.update(u.username, { role: sel.value }, user.username).then(renderUsers);
|
||
};
|
||
tdRole.appendChild(sel);
|
||
tr.appendChild(tdRole);
|
||
tr.appendChild(el("td", u.active ? "启用" : "禁用"));
|
||
tr.appendChild(el("td", (u.created_at || "").slice(0, 10)));
|
||
var tdOps = el("td");
|
||
var toggle = el("button", u.active ? "禁用" : "启用");
|
||
toggle.onclick = function () {
|
||
UserStore.update(u.username, { active: !u.active }, user.username).then(renderUsers);
|
||
};
|
||
var reset = el("button", "重置密码");
|
||
reset.onclick = function () {
|
||
var pwd = prompt("为 " + u.username + " 设置新密码(≥6 位)");
|
||
if (pwd) UserStore.update(u.username, { password: pwd }, user.username).then(renderUsers);
|
||
};
|
||
var del = el("button", "删除");
|
||
del.className = "danger";
|
||
del.onclick = function () {
|
||
if (u.username === user.username) { alert("不能删除当前登录账号"); return; }
|
||
if (confirm("确认删除用户 " + u.username + "?")) {
|
||
UserStore.remove(u.username, user.username).then(renderUsers);
|
||
}
|
||
};
|
||
[toggle, reset, del].forEach(function (b) {
|
||
b.style.marginRight = "4px"; tdOps.appendChild(b);
|
||
});
|
||
tr.appendChild(tdOps);
|
||
tbody.appendChild(tr);
|
||
});
|
||
renderAudit();
|
||
}
|
||
|
||
function renderAudit() {
|
||
var box = document.getElementById("audit-list");
|
||
box.innerHTML = "";
|
||
UserStore.auditLog().slice().reverse().forEach(function (e) {
|
||
box.appendChild(el("div",
|
||
e.time.slice(0, 19).replace("T", " ") + " | " + e.actor + " | " +
|
||
e.action + " | " + e.resource + " | " + e.reason));
|
||
});
|
||
}
|
||
|
||
document.getElementById("btn-add").onclick = function () {
|
||
var err = document.getElementById("form-err");
|
||
err.textContent = "";
|
||
UserStore.create(document.getElementById("new-username").value.trim(),
|
||
document.getElementById("new-password").value,
|
||
document.getElementById("new-role").value)
|
||
.then(function () {
|
||
document.getElementById("new-username").value = "";
|
||
document.getElementById("new-password").value = "";
|
||
renderUsers();
|
||
})
|
||
.catch(function (e) { err.textContent = e.message; });
|
||
};
|
||
|
||
// OIDC 配置点
|
||
var cfg = UserStore.oidcConfig() || {};
|
||
document.getElementById("oidc-issuer").value = cfg.issuer || "";
|
||
document.getElementById("oidc-client").value = cfg.client_id || "";
|
||
document.getElementById("oidc-redirect").value = cfg.redirect_uri || "";
|
||
document.getElementById("btn-oidc").onclick = function () {
|
||
UserStore.configureOidc({
|
||
issuer: document.getElementById("oidc-issuer").value.trim(),
|
||
client_id: document.getElementById("oidc-client").value.trim(),
|
||
redirect_uri: document.getElementById("oidc-redirect").value.trim()
|
||
}, user.username);
|
||
alert("OIDC 配置已保存;登录页将出现 SSO 入口");
|
||
};
|
||
|
||
document.getElementById("logout-btn").onclick = function () {
|
||
fetch((IAOP_AUTH.AUTH_BASE || "") + "/auth/logout",
|
||
{ method: "POST", credentials: "include" })
|
||
.finally(function () { location.href = "login.html"; });
|
||
};
|
||
|
||
renderUsers();
|
||
});
|
||
})();
|