mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
fix(files): the editor never reaches Codeman's own .env by another spelling, and a save keeps the file's group (#797)
The four review items of #797, applied at merge. The editor's name rule lowercases, the data dir's .env pattern did not: .codeman/.ENV passed both, and on a case-insensitive filesystem (the macOS default) that is ~/.codeman/.env, the login file codeman attach reads. A session whose workspace is the home folder could open and save it. The pattern is case-insensitive now, pinned in the blocklist table and on the three editor routes. A save writes a new file and renames it over the old one, so the file took the server's own group: a 0640 .env owned you:www-data came back you:you and the web server lost read access. The save now puts the old user and group back where the account may (best effort), and the wiki says mode and group instead of permissions. Tests: an .env in an outside worktree is refused on edit=1 and PUT too, now that the editor's own gate lets dotenv through; the comment on why .env.example is blocked for downloads and attachments is back. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
1 parent
18b309fc02
commit
59d4bbca2d
7 files changed
+89
-6
No files matched your search
@@ -2455,6 +2455,13 @@ export function registerFileRoutes(app: FastifyInstance, ctx: SessionPort & Even
|
||||
// masked by the process umask; fsync so the rename never publishes a
|
||||
// partially-durable file. Trade-off (same as vim's default): the inode
|
||||
// changes, so hardlinks keep the old content.
|
||||
//
|
||||
// The new file would also take this process's own user and group, so a
|
||||
// `.env` shared by group (you:www-data, 0640) came back you:you and the
|
||||
// web server lost it. fchown puts both back where the account may: the
|
||||
// owner can give a file to a group they belong to, and only root can set
|
||||
// the user. Best effort, since a save that cannot keep the group is still
|
||||
// the save the user asked for.
|
||||
const fileMode = stat.mode & 0o777;
|
||||
const tmpPath = join(
|
||||
dirname(resolvedPath),
|
||||
@@ -2463,6 +2470,12 @@ export function registerFileRoutes(app: FastifyInstance, ctx: SessionPort & Even
|
||||
let handle;
|
||||
try {
|
||||
handle = await fs.open(tmpPath, 'wx', fileMode);
|
||||
const tmpHandle = handle;
|
||||
await tmpHandle
|
||||
.chown(stat.uid, stat.gid)
|
||||
.catch(() => tmpHandle.chown(-1, stat.gid))
|
||||
.catch(() => {});
|
||||
// After the chown: changing the owner can clear mode bits.
|
||||
await handle.chmod(fileMode);
|
||||
await handle.writeFile(outBuf);
|
||||
await handle.sync();
|
||||
|
||||
@@ -85,7 +85,10 @@ const SENSITIVE_PATTERNS: RegExp[] = [
|
||||
// The data dir's `.env` is the CODEMAN_USERNAME/PASSWORD fallback `codeman attach`
|
||||
// reads. Named here as well as in DOTENV_PATTERNS so `allowDotenv` (the File
|
||||
// Viewer editor) cannot reach it from a session whose workspace is $HOME.
|
||||
/\/\.codeman[^/]*\/\.env$/,
|
||||
// Case-insensitive, unlike its neighbours: the editor's name rule lowercases
|
||||
// (`isEditableFileName`), so `.codeman/.ENV` passes it, and on a case-insensitive
|
||||
// filesystem (the macOS default) that IS this file.
|
||||
/\/\.codeman[^/]*\/\.env$/i,
|
||||
// Codeman's own state files. Named once `.json` became previewable outside
|
||||
// the workspace: `SessionState.envOverrides` persists whatever the user set
|
||||
// for a session, and the env allowlist admits key-shaped names
|
||||
|
||||
Reference in new issue
Block a user