Skip to content

feat(account): reveal full license key on click#261

Merged
kilbot merged 3 commits into
mainfrom
feat/reveal-license-key
Jul 5, 2026
Merged

feat(account): reveal full license key on click#261
kilbot merged 3 commits into
mainfrom
feat/reveal-license-key

Conversation

@kilbot

@kilbot kilbot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What

On the account Licenses page, license keys were always masked as ****-****-XXXX with no way to see or copy the full value. Each licence card now has:

  • Reveal toggle — clicking the key badge reveals the full key for that card; clicking again re-masks it.
  • Copy button — copies the full key to the clipboard (works whether or not the key is revealed) and flashes a "Copied" confirmation for ~2s.

How

  • licenses-client.tsx:
    • The icon + key badge is a <button> toggling a per-licence revealedKeys set, so cards reveal independently. Full key wraps with break-all; masked ↔ full swaps on keyRevealed.
    • A sibling copy button calls navigator.clipboard.writeText(license.key), sets a per-licence copiedKey confirmation (auto-cleared after 2s, guarded so a later copy of another card can't be clobbered), and falls back to an inline error on failure.
    • The full key was already present in props, so no data/API change was needed.
  • Accessible: aria-pressed on the reveal toggle; both buttons carry title/aria-label that reflect state (Show/Hide, Copy/Copied) with hover + focus-ring affordances.
  • Added showKeyAria, hideKeyAria, copyKeyAria, copiedKey, copyError to all 10 locale files (parity test enforces this).

Testing

  • vitest — 41 passed, including new tests: reveal-then-re-mask, per-card independence, and clipboard copy + "Copied" confirmation. Existing "renders masked" test still green.
  • messages-parity.test.ts — all 10 locales in sync.
  • eslint + tsc --noEmit clean.

Not browser-verified live: /account/licenses is auth-gated and server-fetches real license data, so it can't be rendered locally without a session + Medusa backend. Behaviour is covered by the component unit tests, which render LicensesClient directly and simulate the clicks.

Summary by CodeRabbit

  • New Features
    • Added per-license show/hide controls for masked license keys.
    • Added “Copy license key” with visual success feedback and improved ARIA/accessibility labels.
    • Updated license key UI translations (e.g., show/hide/copy ARIA text plus “copied” and copy-error messaging) across supported languages.
  • Bug Fixes
    • Reveal and copy interactions are scoped to the selected license card (no cross-card leakage).
  • Tests
    • Added/extended tests for per-card reveal state, aria-pressed behavior, and clipboard copy with “Copied” UI updates.

The Licenses page always masked keys as ****-****-XXXX with no way to
see the full value. Make the key badge a toggle button: clicking reveals
the full key for that card, clicking again re-masks it. Reveal state is
tracked per licence id so cards toggle independently.

Adds showKeyAria/hideKeyAria strings across all 10 locales and unit
coverage for the reveal/re-mask and per-card independence.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 407a025a-67a0-430f-8ba9-0339e7465db7

📥 Commits

Reviewing files that changed from the base of the PR and between cd4633e and d08423a.

📒 Files selected for processing (12)
  • messages/de.json
  • messages/en.json
  • messages/es.json
  • messages/fr.json
  • messages/it.json
  • messages/ja.json
  • messages/ko.json
  • messages/nl.json
  • messages/pt.json
  • messages/zh.json
  • src/components/account/licenses-client.test.tsx
  • src/components/account/licenses-client.tsx

📝 Walkthrough

Walkthrough

Adds per-license license-key reveal and copy controls in LicensesClient, updates the card UI and tests, and extends localized account.licenses strings for the new interactions.

Changes

License Key Reveal and Copy Feature

Layer / File(s) Summary
State and handlers
src/components/account/licenses-client.tsx
Adds per-license reveal state, copy state, and handlers for toggling visibility and copying keys to the clipboard.
Card UI and tests
src/components/account/licenses-client.tsx, src/components/account/licenses-client.test.tsx
Reworks the key display into reveal/copy controls and adds tests for masking, reveal/hide behavior, clipboard copy, and per-card independence.
Localized license strings
messages/de.json, messages/en.json, messages/es.json, messages/fr.json, messages/it.json, messages/ja.json, messages/ko.json, messages/nl.json, messages/pt.json, messages/zh.json
Adds showKeyAria, hideKeyAria, copyKeyAria, copiedKey, and copyError entries under account.licenses in each locale.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant LicensesClient
  participant Clipboard

  User->>LicensesClient: click Show license key
  LicensesClient->>LicensesClient: toggleRevealKey(licenseId)
  LicensesClient-->>User: render full key and aria-pressed=true

  User->>LicensesClient: click Copy license key
  LicensesClient->>Clipboard: writeText(key)
  Clipboard-->>LicensesClient: success
  LicensesClient-->>User: render Copied state
Loading

Related Issues: None referenced.

Related PRs: None referenced.

Suggested labels: i18n, accessibility, tests

Suggested reviewers: None identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main user-facing change: clicking now reveals the full license key.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/reveal-license-key

Comment @coderabbitai help to get the list of available commands.

Alongside the reveal toggle, each licence card gets a copy button that
writes the full key to the clipboard (works whether or not the key is
revealed) and flashes a 'Copied' confirmation for 2s. Adds
copyKeyAria/copiedKey/copyError strings across all 10 locales and a unit
test asserting the clipboard write + confirmation state.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/components/account/licenses-client.tsx (1)

259-277: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Ambiguous accessible name across multiple license cards.

aria-label/title are static ("Show license key" / "Hide license key") regardless of which license the button belongs to. With multiple licenses on the page, screen-reader users navigating by role/name (or automated a11y tooling) cannot distinguish which card a given toggle button controls — confirmed by the test needing getAllByRole to disambiguate identical names.

Consider including a distinguishing fragment (e.g. masked key suffix or plan/date) in the label.

♿ Proposed fix to disambiguate labels
-                    title={t(keyRevealed ? 'hideKeyAria' : 'showKeyAria')}
-                    aria-label={t(keyRevealed ? 'hideKeyAria' : 'showKeyAria')}
+                    title={t(keyRevealed ? 'hideKeyAriaFor' : 'showKeyAriaFor', {
+                      suffix: maskKey(license.key).slice(-4),
+                    })}
+                    aria-label={t(keyRevealed ? 'hideKeyAriaFor' : 'showKeyAriaFor', {
+                      suffix: maskKey(license.key).slice(-4),
+                    })}

Would require adding a parameterized showKeyAriaFor/hideKeyAriaFor string to all locale files instead of (or alongside) the current static ones.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/account/licenses-client.tsx` around lines 259 - 277, The
license key toggle in LicensesClient uses the same aria-label/title for every
card, so each button is indistinguishable to assistive tech. Update the button
in licenses-client.tsx inside the license card render to use a per-license
accessible name by passing a unique fragment from the current license (for
example a masked key suffix, plan name, or date) into the label text. Adjust the
i18n strings used by toggleRevealKey so showKeyAria/hideKeyAria become
parameterized (or add showKeyAriaFor/hideKeyAriaFor) and wire them into the
button’s aria-label and title.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/account/licenses-client.tsx`:
- Around line 259-277: The license key toggle in LicensesClient uses the same
aria-label/title for every card, so each button is indistinguishable to
assistive tech. Update the button in licenses-client.tsx inside the license card
render to use a per-license accessible name by passing a unique fragment from
the current license (for example a masked key suffix, plan name, or date) into
the label text. Adjust the i18n strings used by toggleRevealKey so
showKeyAria/hideKeyAria become parameterized (or add
showKeyAriaFor/hideKeyAriaFor) and wire them into the button’s aria-label and
title.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1728a051-1d1f-4550-8220-42f4c8750dd0

📥 Commits

Reviewing files that changed from the base of the PR and between d68f4b6 and ddcee12.

📒 Files selected for processing (12)
  • messages/de.json
  • messages/en.json
  • messages/es.json
  • messages/fr.json
  • messages/it.json
  • messages/ja.json
  • messages/ko.json
  • messages/nl.json
  • messages/pt.json
  • messages/zh.json
  • src/components/account/licenses-client.test.tsx
  • src/components/account/licenses-client.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ddcee12b48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/account/licenses-client.tsx Outdated
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

🚀 Preview: https://wcpos-hoh33csjx-wcpos.vercel.app

@kilbot

kilbot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Fix triage

CI is green (Test, E2E, CodeQL). mergeStateStatus: BLOCKED is branch protection awaiting human approval, not a code blocker.

# Source File Class Category Decision Outcome
1 Codex (P2) licenses-client.tsx:265 Logic (a11y) Major Fix Parameterize the reveal toggle's aria-label/title with the key's last-4 suffix so each card's button has a distinct accessible name
2 CodeRabbit (nitpick) licenses-client.tsx:259-277 Logic (a11y) Minor Fix — same root cause as #1 Same fix; also applied to the copy button (adjacent scan, same file)

Both findings are the same root cause (static accessible name across cards). Fixing once for the reveal + copy buttons and updating the i18n strings in all 10 locales + the unit tests.

Codex (P2) and CodeRabbit flagged that the reveal/copy buttons shared an
identical accessible name across every licence card, so screen-reader
users on multi-licence accounts couldn't tell the controls apart.

Parameterize showKeyAria/hideKeyAria/copyKeyAria with the key's last-4
suffix in all 10 locales and pass it from the card, giving each card's
controls a distinct accessible name. Tests updated to target the
suffix-disambiguated names.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@kilbot kilbot merged commit 2ef1925 into main Jul 5, 2026
5 of 6 checks passed
@kilbot kilbot deleted the feat/reveal-license-key branch July 5, 2026 11:42
@kilbot

kilbot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Fix applied — d08423a

Both accessibility findings (Codex P2 inline + CodeRabbit nitpick, same root cause) are resolved:

  • Parameterized showKeyAria / hideKeyAria / copyKeyAria with the key's last-4 {suffix} across all 10 locales.
  • The reveal and copy buttons now pass keySuffix from each card, so every card's controls have a distinct accessible name (e.g. "Show license key ending in MNOP") — action text + identifying key fragment both present.
  • Unit tests updated to target the suffix-disambiguated names; the per-card test now asserts distinct labels without needing getAllByRole.

Verification: vitest 41/41 (incl. 10-locale parity), eslint clean, tsc --noEmit clean.

@coderabbitai this addresses the "Ambiguous accessible name across multiple license cards" nitpick.

# Source Decision Commit
1 Codex (P2) Fixed d08423a
2 CodeRabbit (nitpick) Fixed — same root cause d08423a

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd 'licenses-client.tsx' 
echo "---"
sed -n '1,320p' src/components/account/licenses-client.tsx 2>/dev/null

Length of output: 12047


@kilbot Confirmed — I checked src/components/account/licenses-client.tsx at the current state and the fix is solid:

  • keySuffix = license.key.slice(-4) is computed per card.
  • The reveal button's title/aria-label now resolves to t(keyRevealed ? 'hideKeyAria' : 'showKeyAria', { suffix: keySuffix }).
  • The copy button's title/aria-label resolves to keyCopied ? t('copiedKey') : t('copyKeyAria', { suffix: keySuffix }).

This gives each card's reveal/copy controls a distinct accessible name (e.g. "Show license key ending in MNOP"), which resolves the ambiguity concern. Thanks for the thorough writeup and for fixing both findings together.

(≧◡≦) nice work closing the loop on this one

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

🚀 Preview: https://wcpos-jy3ulu8rb-wcpos.vercel.app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant