feat: choose your own pool account; skills with "token" in a doc name upload; System Health off Linux
- Skill snapshot/upload: a key file's name (.env, *.pem, id_rsa, .netrc, .credentials.json…) is always refused, but a word like token/secret/ password/credential only in a data file's name — design-tokens.md or count_tokens.py is skill content, not a key. - System Health: off Linux the History, CPU threads and Busiest processes cards (all read from /proc) are left out instead of shown empty; the CPU bar without a sample and Windows' always-zero Load row go too. - Users pick their own pool account per tool (/api/me/pool-accounts, Settings → AI tools), within their groups, refused while pinned. - Admin user detail, 9router update, session replay and Antigravity catalog changes from parallel sessions.
This commit is contained in:
@@ -137,6 +137,47 @@ describe("server mode", () => {
|
||||
assert.equal(a.status, 404);
|
||||
});
|
||||
|
||||
it("lets any user press Update all AI tools and Update 9router, nothing else there", async () => {
|
||||
// The guard alone, called directly: a real request would start the job.
|
||||
const member = await loginAs("mia", "member-pass-1");
|
||||
const guard = (method, p) => {
|
||||
let passed = false;
|
||||
let status = null;
|
||||
const req = { method, path: p, headers: { cookie: member }, socket: {} };
|
||||
const res = {
|
||||
status(s) {
|
||||
status = s;
|
||||
return this;
|
||||
},
|
||||
json() {
|
||||
return this;
|
||||
},
|
||||
};
|
||||
auth.authGuard(req, res, () => {
|
||||
passed = true;
|
||||
});
|
||||
return passed ? "next" : status;
|
||||
};
|
||||
for (const p of [
|
||||
"/ai-tools/update-all",
|
||||
"/AI-Tools/update-all/",
|
||||
"/ai-proxies/9router/update",
|
||||
"/ai-routers/9router/update",
|
||||
]) {
|
||||
assert.equal(guard("POST", p), "next", p);
|
||||
}
|
||||
for (const [method, p] of [
|
||||
["POST", "/ai-tools/claude/update"],
|
||||
["POST", "/ai-tools/claude/install"],
|
||||
["PUT", "/ai-tools/claude"],
|
||||
["PUT", "/ai-tools/omp-sharing"],
|
||||
["DELETE", "/ai-tools/update-all"],
|
||||
["POST", "/ai-proxies/9router/update/x"],
|
||||
]) {
|
||||
assert.equal(guard(method, p), 403, `${method} ${p}`);
|
||||
}
|
||||
});
|
||||
|
||||
it("takes hooks from this machine only", async () => {
|
||||
const remote = await call("POST", "/api/hooks/event", {
|
||||
body: {},
|
||||
|
||||
Reference in New Issue
Block a user