feat: v2.7.7 — File Explorer on workspaces and the user's home, clone with per-user git identity
- File Explorer (Files in the sidebar, /files; also from a workspace's Files tab, portalled so no panel clips it), laid out like GNOME Files: places (Home, workspaces, Trash), Back/Forward/Up, path bar, search, icon grid with image thumbnails or list, labelled New/Upload, selection action bar, hidden files behind Ctrl+H, right-click menus and the usual keys. Make, rename, move, copy (within a workspace, between workspaces, home ↔ workspace), delete into a per-account trash restorable for 7 days, streamed upload of files and whole folders (≤ 500 MB a batch, Replace / Keep both / Skip on a taken name), download a file or a zip of anything. server/lib/file-explorer.js, /api/lanes/:id/fs/*, /api/homes/:who/fs/*. - The user's home: every dot entry at its top stays hidden and refused (also via a symlink, download, zip or as a copy source); an admin may view other users' homes read-only, audited. - write-as learns move/copy (re-run `sudo agenthub server install-system`). - Hardening: a write to a workspace re-checks its owner by the live role; S3 keeps its server.conf if the file stops reading and a tmux call never falls back to the host's server; the AI Proxy gateway marks what it relays and the dashboard refuses it; a NUL in a pane's argv/env is refused. - OpenAPI for the new routes (server/openapi-extra/files.js); docs (API, SERVER-MODE, CLAUDE.md) updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -109,6 +109,7 @@ const codexConfigRouter = require("./routes/codex-config");
|
||||
const aiProxiesRouter = require("./routes/ai-proxies");
|
||||
const gitCredentialsRouter = require("./routes/git-credentials");
|
||||
const gitIdentityRouter = require("./routes/git-identity");
|
||||
const homesRouter = require("./routes/homes");
|
||||
const aiToolsRouter = require("./routes/ai-tools");
|
||||
const runRouter = require("./routes/run");
|
||||
const alertsRouter = require("./routes/alerts");
|
||||
@@ -151,6 +152,17 @@ function createApp() {
|
||||
// Server mode's AI Proxy key gateway (server/lib/proxy-gateway.js): before
|
||||
// the body parser (it streams the raw body) and the token/login gates (a
|
||||
// pane authenticates with its own pane token, loopback only).
|
||||
// A request the gateway itself sent (a profile whose base points back at
|
||||
// this dashboard): never served — it would arrive from our own uid, which
|
||||
// hook auth trusts, on behalf of whoever started the pane.
|
||||
const { GATEWAY_MARK } = require("./lib/proxy-gateway");
|
||||
app.use((req, res, next) =>
|
||||
req.headers[GATEWAY_MARK]
|
||||
? res.status(403).json({
|
||||
error: { code: "EGATEWAY", message: "a request relayed by the AI Proxy gateway" },
|
||||
})
|
||||
: next()
|
||||
);
|
||||
app.use("/api/proxy-gw", require("./lib/proxy-gateway").proxyGateway);
|
||||
app.use(express.json({ limit: "1mb" }));
|
||||
app.use("/api", tokenGuard);
|
||||
@@ -162,6 +174,8 @@ function createApp() {
|
||||
app.use("/api/auth", authRouter);
|
||||
// Before /api/me: the user's own SSH key and HTTPS logins (git-identity.js).
|
||||
app.use("/api/me/git", gitIdentityRouter);
|
||||
// The File Explorer on a user's home (routes/homes.js).
|
||||
app.use("/api/homes", homesRouter);
|
||||
app.use("/api/me", meRouter);
|
||||
app.use("/api/accounts", accountsRouter);
|
||||
app.use("/api/users", usersRouter);
|
||||
|
||||
Reference in New Issue
Block a user