Repository navigation
JWT signature verification, slug collisions, URL table, output cap - #22
Merged
Merged
Conversation
Rewrites the 55 classes the Tailwind editor extension flagged as having a canonical spelling (w-[220px] → w-55, rounded-[2px] → rounded-xs, bg-[length:…] → bg-size-[…], [scrollbar-width:none] → scrollbar-none, [&>*]: → *:, and so on). Computed styles are identical before and after on 14 routes at 1280px and 400px. scripts/tailwind.ts runs Tailwind's own canonicalizer (the engine behind the editor hints) over every string and template literal in src/**/*.tsx, parsed with oxc so JSX text is never touched. `pnpm tw:fix` reports them and `--write` rewrites them; scripts/tailwind.test.ts fails CI when one appears, so new code, including agent-written tools, stays canonical. Adds @tailwindcss/node 4.3.3 as a dev dependency for its design-system loader.
Map.groupBy is ES2024 and the repo targets the ES2023 lib, so the script failed typecheck.
The test generated two ULIDs with the same seed but the real clock, so a millisecond tick between the calls changed the time prefix and lower !== upper.toLowerCase(). Both calls now use the fixed clock the rest of the file uses.
…oxes
The permission grid shows bare r / w / x, so screen readers announced each checkbox as a single letter. Toggle now takes an aria-label, and each grid checkbox is named for its row and column ("Owner read").
The JWT tool verifies against a pasted JWKS; fetching one by URL would need the CSP's connect-src opened to third parties.
In filename mode, safeFilenameLines now returns collisions: groups of 1-based line numbers whose cleaned names are identical (they collide everywhere), and, separately, groups whose names differ only by case (they collide on Windows and on a default macOS volume). Names are compared after NFC with toLowerCase; a comment explains why not full case folding. The tool shows each kind as a warning under the summary, e.g. "2 names collide on Windows/macOS: lines 3, 7", listing at most a dozen line numbers.
The parameter table stopped at 300 rows with a "first 300" note. It is now a virtualised list (@tanstack/react-virtual), so every parameter is reachable, each with its own Copy button, raw-vs-decoded display and malformed badge as before. Rows are measured as they render, since long values wrap and raw forms add a line. The URL parts above share the scroll, so a ResizeObserver keeps the list's scroll margin in step as they change height. The table is a role="table" grid of divs, because absolutely positioned rows cannot be <tr>s. Checked by hand with a generated 5,000-parameter URL: the last row is reachable and rows never overlap.
Binary output is about 9 characters per input byte, so a few-MB paste put tens of MB in the output textarea. Once the output passes INLINE_MAX_BYTES (1 MB) of characters, in either direction, the textarea shows only the first 64K characters, with "Showing the first N of M characters. Copy and Download include all of it." under it. Copy still copies the whole output from the click handler, and a new Download button saves it all as a .txt (bytes.<format>.txt or text.txt). Swap is disabled while the output is capped, because it would feed the whole output back into the input textarea. Checked in a production build: a 3 MB multi-line text encodes to 28 M characters and renders in about 0.6 s; a 1.2 M-character decode in about 0.4 s.
Add verifyJwt(token, key, options) to @fadeltd/devtools-core/jwt. The key can be a JWK, a JWKS (picked by the header kid, or every compatible key tried when there is none), a PEM public key, a PKCS#1 RSA PUBLIC KEY, an X.509 certificate, or an HS secret as text, base64 or base64url. HS, RS, PS and ES at 256/384/512 and EdDSA (Ed25519) are verified with WebCrypto over the original header and payload segments, never re-encoded. It refuses alg none, algorithm confusion (an HMAC alg with a public key), a curve or key type that does not fit the alg, and a JWK whose alg, use or key_ops conflicts with the header. A DER-encoded ECDSA signature is reported as such. Every failure comes back as a result with a reason; nothing throws. The JWT Decoder gains a Verify signature panel: a key box with format detection, an encoding select for secrets, and a Signature valid / invalid badge kept separate from the expiry badge. The key is held in memory only, like the token. Fetching a JWKS URL is not offered, because the CSP's connect-src 'self' blocks it, and the panel says so.
Documents JWT signature verification, slug case collisions, the virtualised URL table and the Text to Binary / Hex output cap in both changelogs and READMEs, and updates the JWT blurb and search keywords to mention verification.
fadeltd
force-pushed
the
feat/batch-1-followups
branch
from
October 29, 2026 17:31
7c8d3dc to
18cf92f
Compare
# Conflicts: # src/tools/url/UrlTool.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Added
Changed
Fixed