mirror of
https://github.com/gethomepage/homepage.git
synced 2026-10-15 15:09:56 -07:00
Fix: preserve dollar sequences in environment and file secrets (#7242)
Docker CI / Docker Build & Push (push) Canceled after 0s
Lint / Linting Checks (push) Canceled after 0s
Release Drafter / Update Release Draft (push) Canceled after 0s
Release Drafter / Auto Label PR (push) Canceled after 0s
Tests / vitest (1) (push) Canceled after 0s
Tests / vitest (2) (push) Canceled after 0s
Tests / vitest (3) (push) Canceled after 0s
Tests / vitest (4) (push) Canceled after 0s
Docker CI / Docker Build & Push (push) Canceled after 0s
Lint / Linting Checks (push) Canceled after 0s
Release Drafter / Update Release Draft (push) Canceled after 0s
Release Drafter / Auto Label PR (push) Canceled after 0s
Tests / vitest (1) (push) Canceled after 0s
Tests / vitest (2) (push) Canceled after 0s
Tests / vitest (3) (push) Canceled after 0s
Tests / vitest (4) (push) Canceled after 0s
Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
@@ -69,11 +69,11 @@ export function substituteEnvironmentVars(str) {
|
|||||||
const cachedVars = getCachedEnvironmentVars();
|
const cachedVars = getCachedEnvironmentVars();
|
||||||
cachedVars.forEach(([key, value]) => {
|
cachedVars.forEach(([key, value]) => {
|
||||||
if (key.startsWith(homepageVarPrefix)) {
|
if (key.startsWith(homepageVarPrefix)) {
|
||||||
result = result.replaceAll(`{{${key}}}`, value);
|
result = result.replaceAll(`{{${key}}}`, () => value);
|
||||||
} else if (key.startsWith(homepageFilePrefix)) {
|
} else if (key.startsWith(homepageFilePrefix)) {
|
||||||
const filename = value;
|
const filename = value;
|
||||||
const fileContents = readFileSync(filename, "utf8");
|
const fileContents = readFileSync(filename, "utf8");
|
||||||
result = result.replaceAll(`{{${key}}}`, fileContents);
|
result = result.replaceAll(`{{${key}}}`, () => fileContents);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { mkdtempSync, writeFileSync } from "node:fs";
|
import { mkdtempSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
@@ -37,6 +37,39 @@ describe("utils/config/config", () => {
|
|||||||
expect(mod.substituteEnvironmentVars("token={{HOMEPAGE_FILE_SECRET}}")).toBe("token=secret");
|
expect(mod.substituteEnvironmentVars("token={{HOMEPAGE_FILE_SECRET}}")).toBe("token=secret");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each(["pa$$word", "pa$&word", "pa$`word", "pa$'word", "pa$1word"])(
|
||||||
|
"substituteEnvironmentVars preserves literal environment value %j in every occurrence",
|
||||||
|
async (secret) => {
|
||||||
|
process.env.HOMEPAGE_VAR_SECRET = secret;
|
||||||
|
|
||||||
|
const mod = await import("./config");
|
||||||
|
expect(
|
||||||
|
mod.substituteEnvironmentVars("before {{HOMEPAGE_VAR_SECRET}} between {{HOMEPAGE_VAR_SECRET}} after"),
|
||||||
|
).toBe(`before ${secret} between ${secret} after`);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(["pa$$word", "pa$&word", "pa$`word", "pa$'word", "pa$1word"])(
|
||||||
|
"substituteEnvironmentVars preserves literal secret file contents %j in every occurrence",
|
||||||
|
async (secret) => {
|
||||||
|
const dir = mkdtempSync(path.join(tmpdir(), "homepage-config-test-"));
|
||||||
|
const secretPath = path.join(dir, "secret.txt");
|
||||||
|
writeFileSync(secretPath, secret, "utf8");
|
||||||
|
|
||||||
|
try {
|
||||||
|
process.env.HOMEPAGE_FILE_SECRET = secretPath;
|
||||||
|
|
||||||
|
const mod = await import("./config");
|
||||||
|
expect(
|
||||||
|
mod.substituteEnvironmentVars("before {{HOMEPAGE_FILE_SECRET}} between {{HOMEPAGE_FILE_SECRET}} after"),
|
||||||
|
).toBe(`before ${secret} between ${secret} after`);
|
||||||
|
} finally {
|
||||||
|
unlinkSync(secretPath);
|
||||||
|
rmdirSync(dir);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
it("getSettings reads from HOMEPAGE_CONFIG_DIR and converts layout list to an object", async () => {
|
it("getSettings reads from HOMEPAGE_CONFIG_DIR and converts layout list to an object", async () => {
|
||||||
const dir = mkdtempSync(path.join(tmpdir(), "homepage-settings-test-"));
|
const dir = mkdtempSync(path.join(tmpdir(), "homepage-settings-test-"));
|
||||||
process.env.HOMEPAGE_CONFIG_DIR = dir;
|
process.env.HOMEPAGE_CONFIG_DIR = dir;
|
||||||
|
|||||||
Reference in New Issue
Block a user