test(auth): pin the loose-mode test to the mechanism that survived
No behavior change. Round 7 removed the loose-mode `console.warn` from selection — it was encryption-blind and duplicated the caveat printed moments later. This test kept asserting `warn` was called with "0644" and kept passing, because the caveat also contains the mode. So it was green while describing a code path that no longer exists: named "warns once at selection", commented as if the selection warning were the thing under test, and pinned to a substring loose enough that either line would satisfy it. Asserts the caveat's full sentence now, so it is fastened to the surviving mechanism rather than to whichever line happens to mention the mode. Also records what it took to reach this state at all, since it is not obvious and I had it wrong: as the file's owner you *cannot* stage a loose-mode descriptor, because `tightenSecretFilePermissions` repairs a 0644 file to 0600 during selection and the report is then correctly "owner-only". It is only real for a file owned by another user or on a read-only mount, which is why the chmod is mocked — standing in for a privilege a test cannot drop. Found by @mcp-inspector-v2-f1, who tried to screenshot the state for the PR body and got "Owner-only permissions." instead. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
6efc65d2af
commit
5f4a6ea09b
1 changed files with 20 additions and 5 deletions
|
|
@ -882,10 +882,19 @@ describe("the descriptor reports a mode it could not verify", () => {
|
|||
});
|
||||
|
||||
describe("the descriptor reports a mode it could not tighten", () => {
|
||||
it("carries looseMode into the descriptor and warns once at selection", async () => {
|
||||
// The warning alone was not enough: the caveat under the secret field
|
||||
// states the mode as fact, and on this box that statement was untrue
|
||||
// while the browser had no way to know.
|
||||
it("carries looseMode into the descriptor, and the caveat states the mode", async () => {
|
||||
// Reaching this state at all requires the chmod to *fail*: as the file's
|
||||
// owner you cannot stage it, because `tightenSecretFilePermissions`
|
||||
// repairs a 0644 file to 0600 during selection and the descriptor then
|
||||
// correctly reports owner-only. It is only real for a file owned by
|
||||
// another user or on a read-only mount — hence the mocked chmod, which
|
||||
// is standing in for a privilege we cannot drop inside a test.
|
||||
//
|
||||
// The warning is asserted through the *caveat* path deliberately.
|
||||
// Selection used to warn here too, and that line was removed in round 7
|
||||
// for being encryption-blind and duplicating this one — so asserting the
|
||||
// caveat text is what keeps this test pinned to the surviving mechanism
|
||||
// rather than passing on whichever line happens to mention the mode.
|
||||
const filePath = path.join(tmpDir, "secrets.json");
|
||||
process.env.MCP_INSPECTOR_SECRET_FILE = filePath;
|
||||
process.env.MCP_INSPECTOR_SECRET_STORE = "file";
|
||||
|
|
@ -925,7 +934,13 @@ describe("the descriptor reports a mode it could not tighten", () => {
|
|||
await import("@inspector/core/auth/node/secret-store-selection.js");
|
||||
const info = await mod.getSecretStorageInfo();
|
||||
expect(info.looseMode).toBe(0o644);
|
||||
expect(warn).toHaveBeenCalledWith(expect.stringContaining("0644"));
|
||||
// The plaintext wording, in full: this file is unencrypted, so a
|
||||
// reader really does get the secrets.
|
||||
expect(warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
"mode 0644, not 0600, and could not be tightened — anyone who can read it can read the secrets in it",
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
vi.doUnmock("node:fs/promises");
|
||||
vi.doUnmock("@inspector/core/auth/node/secret-store.js");
|
||||
|
|
|
|||
Loading…
Reference in a new issue