refactor(okr): trekk path-confinement ut til delt modul

This commit is contained in:
Kjell Tore Guttormsen 2026-08-02 10:15:59 +02:00
commit 892acf1d87
2 changed files with 57 additions and 22 deletions

View file

@ -38,6 +38,10 @@ import path from 'node:path';
import { homedir } from 'node:os';
import { writeFrontmatter, parseFrontmatter } from './frontmatter.mjs';
import {
resolveUnderBundle as resolveUnderBundleShared,
assertRealUnderBundle as assertRealUnderBundleShared,
} from './path-confinement.mjs';
// Den home-kanoniske org-profil-rota. Ingestion skal ALDRI skrive hit (den eies
// av write-org-profile.mjs); prosjekt-bundlen er .claude/okr under cwd.
@ -53,28 +57,14 @@ function writeAtomic(target, data) {
renameSync(tmp, target);
}
// Resolver en bundle-relativ sti og asserter at den blir UNDER bundle-rota.
// Avviser '..'-escape og absolutt-override (path.resolve lar en absolutt rel
// vinne -- containment-sjekken fanger det).
function resolveUnderBundle(resolvedBundle, rel) {
const resolved = path.resolve(resolvedBundle, rel);
if (resolved !== resolvedBundle && !resolved.startsWith(resolvedBundle + path.sep)) {
throw new Error(`innboks-write: maal-sti utenfor bundle-rot avvist: ${rel}`);
}
return resolved;
}
// M2 (A1): den leksikalske sjekken over slipper symlinks -- en symlinket
// katalog/original INNE i bundlen kan peke UT av den. realpathSync paa den
// faktiske noden (destinasjons-parent etter mkdir / original foer peker-skriv)
// maa ogsaa lande under bundle-rotas realpath, ellers avvises skrivet.
function assertRealUnderBundle(realBundle, p, what) {
const real = realpathSync(p);
if (real !== realBundle && !real.startsWith(realBundle + path.sep)) {
throw new Error(`innboks-write: ${what} resolverer utenfor bundle-rot (symlink-escape avvist): ${p}`);
}
return real;
}
// M2 (A1): tolags path-confinement (leksikalsk + symlink) bor i
// lib/path-confinement.mjs -- delt med lib/arkivklar.mjs, som trenger NOEYAKTIG
// samme regel paa lesesiden. Wrapperne her binder bare modulnavnet inn i
// feilmeldingen, saa den kallende modulen fortsatt er identifiserbar.
const resolveUnderBundle = (resolvedBundle, rel) =>
resolveUnderBundleShared(resolvedBundle, rel, 'innboks-write');
const assertRealUnderBundle = (realBundle, p, what) =>
assertRealUnderBundleShared(realBundle, p, what, 'innboks-write');
// Destinasjons-parent opprettes, realpath-sjekkes, DERETTER skrives det atomisk.
function writeConfined(realBundle, target, data, what) {