From 11b7b5b85e8a9d671d21f6ad888202dc1bdf56e6 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Mon, 31 Aug 2026 04:26:36 +0200 Subject: [PATCH] fix(hephaestus): strip any CashAddr prefix from preferred_username MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only bitcoincash: was being stripped; bchtest: (chipnet) addresses ended up producing preferred_username="bch_bchtest:qzew3dqcsj0g" — Forgejo rejected that with "name is invalid ... must be valid alpha or numeric or dash(-_) or dot characters" because of the colon, callback 500'd, session never finished. Regex-strip any [a-z]+: prefix so all three prefix families (bitcoincash, bchtest, bchreg) produce clean usernames. Verified end-to-end with a Node smoke test signing a real chipnet challenge with the main wallet from Argus/wallets.json: bchtest:qzew3dqcsj0guwe5y3uxf9q2xs5ajgy9lca4z093cu → bch_qzew3dqcsj0guwe5y3ux (auto-provisioned in Forgejo) → 303 to dashboard, session live. --- auth-proxy/src/oidc.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/auth-proxy/src/oidc.ts b/auth-proxy/src/oidc.ts index 6d74ab7..df397ad 100644 --- a/auth-proxy/src/oidc.ts +++ b/auth-proxy/src/oidc.ts @@ -61,9 +61,9 @@ export async function issueIdToken(params: { // sub = full cashaddr (immutable identity). preferred_username = a Forgejo-safe // rendering: "bch_" + first 20 chars of the address payload. Forgejo usernames // must match [a-zA-Z0-9-_.]+ (no colons) and be <= 40 chars. - const addressPayload = params.subject.startsWith("bitcoincash:") - ? params.subject.slice("bitcoincash:".length) - : params.subject; + // Strip ANY CashAddr prefix (bitcoincash: / bchtest: / bchreg:) — the payload + // after the colon is the part we want to render as a Forgejo username. + const addressPayload = params.subject.replace(/^[a-z]+:/, ""); const preferredUsername = `bch_${addressPayload.slice(0, 20)}`; const jwt = await new SignJWT({ preferred_username: preferredUsername,