nextcloud: keep onlyoffice's jwt_secret off every argv (issue 1831)

occ's config:app:set put the secret on the docker exec command line, so
it sat in the docker CLI's argv, the container's php argv and docker's
exec record. Apply jwt_secret through config:import on occ's stdin
instead; the other three onlyoffice keys still go through
config:app:set.
This commit is contained in:
jochen
2026-10-22 16:27:15 +02:00
parent 77578a882f
commit 8928e6f972
2 changed files with 53 additions and 6 deletions
+18 -4
View File
@@ -92,11 +92,20 @@ export class NextcloudClient {
return new NextcloudClient(container, ocsUrl.replace(/\/$/, ""), adminUser, adminPassword);
}
/** Run occ inside the container as the web user, returning its stdout, throwing its own message. */
occ(args: string[]): string {
/**
* Run occ inside the container as the web user, returning its stdout, throwing its own message.
* With `opts.input` given, occ reads it from stdin (`docker exec -i`) instead of taking it on the
* command line — the only way a secret value reaches occ without sitting in the docker CLI's argv,
* the container's php argv and docker's exec record (novox/hq issue 1831).
*/
occ(args: string[], opts: { input?: string } = {}): string {
const dockerArgs = opts.input !== undefined
? ["exec", "-i", "-u", "www-data", this.container, "php", "occ", ...args]
: ["exec", "-u", "www-data", this.container, "php", "occ", ...args];
try {
return execFileSync("docker", ["exec", "-u", "www-data", this.container, "php", "occ", ...args], {
return execFileSync("docker", dockerArgs, {
encoding: "utf8", timeout: 60_000,
...(opts.input !== undefined ? { input: opts.input } : {}),
}).trim();
} catch (err: any) {
const detail = String(err?.stderr ?? err?.stdout ?? err?.message ?? "").trim();
@@ -126,7 +135,12 @@ export class NextcloudClient {
const changed: string[] = [];
for (const [occKey, value] of desired) {
if (this.currentAppConfig(occKey) !== value) {
this.occ(["config:app:set", "onlyoffice", occKey, `--value=${value}`]);
// jwt_secret is a secret: apply it by stdin of config:import, never on an argv (issue 1831).
if (occKey === "jwt_secret") {
this.occ(["config:import"], { input: JSON.stringify({ apps: { onlyoffice: { jwt_secret: value } } }) });
} else {
this.occ(["config:app:set", "onlyoffice", occKey, `--value=${value}`]);
}
changed.push(occKey);
}
}