/** * @file scope-users-root.test.js * @description A non-admin's own folder comes from `AGENTHUB_USERS_ROOT`, and * under S3 from server.conf's `USERS_ROOT` when that variable is missing — a * server with S3 installed but no variable in its settings file let every * developer browse the host account's whole home. * @author Nguyễn Ngọc Trí Vĩ */ const { describe, it, before, after, afterEach } = require("node:test"); const assert = require("node:assert/strict"); const path = require("node:path"); const fs = require("node:fs"); const os = require("node:os"); const TMP = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "scope-users-root-"))); const CONF = path.join(TMP, "server.conf"); process.env.AGENTHUB_SERVER_CONF = CONF; process.env.AGENTHUB_MODE = "server"; delete process.env.AGENTHUB_USERS_ROOT; const scope = require("../lib/scope"); const linux = require("../lib/linux-accounts"); const dev = { user: { id: 2, username: "vinnt", role: "developer" } }; const admin = { user: { id: 1, username: "boss", role: "admin" } }; describe("scope.ownFolder", () => { before(() => { fs.writeFileSync(CONF, "HOST_USER=host\nHOST_UID=1000\nUSERS_ROOT=/srv/agenthub/users\n"); linux.__resetConfCache(); }); afterEach(() => { delete process.env.AGENTHUB_USERS_ROOT; }); after(() => fs.rmSync(TMP, { recursive: true, force: true })); it("falls back to server.conf's USERS_ROOT under S3", () => { assert.equal(scope.ownFolder(dev), "/srv/agenthub/users/vinnt"); assert.equal(scope.folderAllowed(dev, os.homedir()), false); assert.equal(scope.folderAllowed(dev, "/srv/agenthub/users/vinnt/proj"), true); }); it("prefers AGENTHUB_USERS_ROOT when it is set", () => { process.env.AGENTHUB_USERS_ROOT = "/data/users"; assert.equal(scope.ownFolder(dev), "/data/users/vinnt"); }); it("never limits an admin", () => { assert.equal(scope.ownFolder(admin), null); }); it("has no folder without S3 or the variable", () => { fs.rmSync(CONF); linux.__resetConfCache(); assert.equal(scope.ownFolder(dev), null); }); });