From 6a34d0a46d39815549c46f053f2d5c4f06db57da Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 11 Nov 2026 08:47:57 -0700 Subject: [PATCH] Yaak Proxy: the rejected card claims decryption only when the list decrypts Once an address is no longer passed through, the foot said the next connection will be decrypted even when the list excludes it or the certificate is untrusted. It now says so only when the list still decrypts the connection, and keeps the trust line while untrusted. Co-Authored-By: Claude Fable 5.2 --- apps/yaak-proxy/lib/encryptedCard.test.ts | 12 ++++++++++++ apps/yaak-proxy/lib/encryptedCard.ts | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/apps/yaak-proxy/lib/encryptedCard.test.ts b/apps/yaak-proxy/lib/encryptedCard.test.ts index 2f9991063..c1dd6fe4e 100644 --- a/apps/yaak-proxy/lib/encryptedCard.test.ts +++ b/apps/yaak-proxy/lib/encryptedCard.test.ts @@ -265,6 +265,18 @@ describe("the card of a refused handshake", () => { expect(c.foot).toEqual(["The next connection will be decrypted."]); }); + test("no longer passed through but excluded since: no claim that it will be decrypted", () => { + const excluded = [...user("*", "!app:Acme"), ...BUILT_INS]; + const c = card({ flow: refused, list: excluded, passthrough: [] }); + expect(c.actions).toEqual([]); + expect(c.foot).toEqual([]); + }); + + test("an untrusted certificate keeps its line once no longer passed through", () => { + const c = card({ flow: refused, list: listed, trusted: false, passthrough: [] }); + expect(c.foot).toEqual(["This host stays encrypted until the certificate is trusted."]); + }); + test("a program: its own trust store, Copy Environment first", () => { const python = { ...refused, diff --git a/apps/yaak-proxy/lib/encryptedCard.ts b/apps/yaak-proxy/lib/encryptedCard.ts index 3d1f570fd..e04b51fff 100644 --- a/apps/yaak-proxy/lib/encryptedCard.ts +++ b/apps/yaak-proxy/lib/encryptedCard.ts @@ -360,7 +360,14 @@ function rejectedCard(input: EncryptedCardInput): EncryptedCardModel { passedThrough === false ? null : { kind: "try_again", label: "Retry", hint: "next connection", icon: "refresh" }; - const until = passedThrough === false ? "The next connection will be decrypted." : null; + // No longer passed through: the next connection is decrypted while the list still decrypts + // it. Excluded since, it stays encrypted, and there is nothing to add. + const until: string[] | null = + passedThrough === false + ? stop == null + ? [] + : ["The next connection will be decrypted."] + : null; if (canTrust && trusted === false && decryptsAnything(list)) { return { @@ -371,7 +378,8 @@ function rejectedCard(input: EncryptedCardInput): EncryptedCardModel { { kind: "trust", label: "Trust Certificate", hint: null, primary: true, icon: "shield" }, ...(stop == null ? [] : [stop]), ], - foot: [until ?? "This host stays encrypted until the certificate is trusted."], + // Whether or not it is still passed through: untrusted, the next one is rejected too. + foot: ["This host stays encrypted until the certificate is trusted."], }; } @@ -392,7 +400,7 @@ function rejectedCard(input: EncryptedCardInput): EncryptedCardModel { ...(stop == null ? [] : [stop]), ...(tryAgain == null ? [] : [tryAgain]), ], - foot: until == null ? [`Paste it into a terminal, then rerun ${refuser.name}.`] : [until], + foot: until ?? [`Paste it into a terminal, then rerun ${refuser.name}.`], }; } return { @@ -410,6 +418,6 @@ function rejectedCard(input: EncryptedCardInput): EncryptedCardModel { ...(stop == null ? [] : [{ ...stop, primary: true }]), ...(tryAgain == null ? [] : [tryAgain]), ], - foot: [until ?? "This host stays encrypted until Yaak Proxy is relaunched."], + foot: until ?? ["This host stays encrypted until Yaak Proxy is relaunched."], }; }