Skip to content

feat(verify): show clear, actionable error for invalid verification links (#299) - #471

Open
CodingBabe-1 wants to merge 3 commits into
ToluLabs:mainfrom
CodingBabe-1:feat/299-verify-invalid-link-errors
Open

feat(verify): show clear, actionable error for invalid verification links (#299)#471
CodingBabe-1 wants to merge 3 commits into
ToluLabs:mainfrom
CodingBabe-1:feat/299-verify-invalid-link-errors

Conversation

@CodingBabe-1

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes #299: the /verify page now shows a clear, actionable error whenever a verification link's params are invalid, instead of a blank page, a stuck spinner, or a silent proceed.

The verify page consumed return_url, claim, and threshold / restricted params without validating them. A link with an unknown claim type silently dropped the lock and kept going, a malformed threshold could flow into issuance as garbage, and a missing return_url was silently accepted. This PR introduces a dedicated lib/verifyParams.ts validation module that parses every verification-link parameter and, on failure, returns a specific VerifyError describing exactly what is wrong. The page renders a VerifyLinkError screen that names the problem and offers a clear way back.

What changed

  • lib/verifyParams.ts (new) – Pure, testable parsing/validation of /verify query params. Distinguishes a plain self-service visit (nav/sidebar/CTA "Get verified", or a Persona ?inquiry-id resume) from a protocol verification link, and validates the protocol-link case:
    • missing return_urlmissing_return_url
    • malformed / insecure return_urlbad_return_url
    • unknown claim type → bad_claim
    • malformed numeric threshold (threshold_years / threshold / min_threshold) → bad_threshold
    • malformed restricted country-code list → bad_restricted
    • Normalises claimParams so only params that apply to the requested claim are carried into issuance.
  • app/verify/page.tsx – Calls parseVerifyParams up front; on any failure it renders the dedicated error screen and skips the form entirely (no silent proceed). Also enriches the wallet-not-connected state (tells the user which claim / returning domain is requested) and gives the Persona-resume path a clear "nothing to resume" state instead of a silent dead end.
  • app/verify/VerifyLinkError.tsx (new) – Standalone invalid-link error component (title, detail, "Go to your credentials" + "Back home").
  • Testslib/verifyParams.test.ts drives each malformed param through the validator and asserts the mapped error; app/verify/VerifyLinkError.test.tsx renders the error UI for every error code and asserts the exit points.
  • Test tooling – Adds a frontend vitest setup (vitest.config.ts, test/setup.ts, and a pnpm test script) so the app suite can run; the standalone @stellarcred/issuer package keeps its own node-environment runner.

Acceptance checklist

  • Every invalid verify link shows an actionable error screen (bad claim / bad threshold / missing return URL / bad return URL / bad restricted). No blank pages, stuck spinners, or silent proceeds.
  • Persona resume path and wallet-not-connected path have clear states rather than dead ends.
  • Tests render / drive each malformed param through to the error UI.
  • Self-service /verify (no params) behaves exactly as before.

Type of change

  • Bug fix
  • New feature / credential type
  • Refactor / cleanup
  • Docs
  • CI / tooling

Checklist

  • cargo test passes (contracts) — no contract changes
  • pnpm tsc --noEmit passes (frontend)
  • pnpm build passes (frontend)
  • pnpm test passes (frontend – includes issuer suite)
  • Circuit changes: none
  • No NEXT_PUBLIC_ prefix on server-only env vars
  • No identity fields stored or logged after KYC provider call

Notes for reviewers

  • A plain /verify visit (sidebar, homepage CTAs, "Get a credential") is intentionally not treated as invalid — only links carrying verification params (return_url / claim / thresholds / restricted) are validated strictly. Persona resume links (?inquiry-id=…) are also treated as self-service, as before.
  • The error UI is extracted into its own component so it is independently testable and reusable.

CodingBabe-1 and others added 2 commits August 31, 2026 09:09
The /verify page consumed return_url, claim, and threshold params without
validating them, so a malformed link (unknown claim type, bad threshold,
missing return URL) silently proceeded, showed a blank page, or hung on a
spinner.

Add lib/verifyParams.ts to parse and validate every verification-link
parameter and return a specific VerifyError (missing/bad return URL, bad
claim, bad threshold, bad restricted list). The verify page now renders a
dedicated VerifyLinkError screen naming exactly what is wrong and offering a
way back instead of a dead end. Also give the Persona-resume path and the
wallet-not-connected path clear states.

Coverage: unit tests drive each malformed param through parseVerifyParams and
assert the mapped error, plus a rendering test asserts the error UI for every
error code. Adds a vitest setup for the frontend app.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Sep 1, 2026

Copy link
Copy Markdown

@CodingBabe-1 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…fyParams (ToluLabs#299)

The merge of main into feat/299-verify-invalid-link-errors corrupted three
things: pnpm-workspace.yaml gained a duplicate `esbuild: true` key and the
lockfile accumulated 584 duplicated entries (both breaking `pnpm install
--frozen-lockfile`, which is what killed the frontend, a11y, and contract CI
jobs), and the merged lib/verifyParams.ts silently kept main's validate*
helpers while dropping the PR's parseVerifyParams/VerifyError API that the
verify page, VerifyLinkError, and their tests import.

Fix:
- Remove the duplicate esbuild allowBuilds entry and restore main's lockfile
  (package.json is unchanged, so main's lockfile is the correct one).
- Union both APIs in verifyParams.ts: keep main's validateVerifyParams helpers
  for inline field errors and re-add the PR's parseVerifyParams/VerifyError for
  the dedicated invalid-link screen.
- Wire parseVerifyParams into page.tsx so linkError renders VerifyLinkError
  for malformed verification links (the ToluLabs#299 feature).
- Raise the Verify route size budget 10 kB -> 11 kB for the new error screen
  component (977 B of genuine feature growth).

Verified locally: tsc, next build, lint, 375 vitest tests (incl. the new
verifyParams/VerifyLinkError tests), theme tests, issuer tests, bundle size,
axe-core e2e, and all 89 contract tests pass.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
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.

Verify page: show a clear error when the requested claim/params are invalid instead of a blank/stuck state

1 participant