Files
iAOP/web/auth/users.js
T

122 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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();
});
})();