fix(hephaestus): strip any CashAddr prefix from preferred_username

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.
This commit is contained in:
Local Dev 2026-08-31 04:26:36 +02:00
parent 9baa5db887
commit 11b7b5b85e

View file

@ -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,