Skip to content

Verify api keys with the ping-then-payments probe in the credentials validator - #142

Merged
loevgaard merged 2 commits into
2.xfrom
fix-credentials-validator
Aug 24, 2026
Merged

Verify api keys with the ping-then-payments probe in the credentials validator#142
loevgaard merged 2 commits into
2.xfrom
fix-credentials-validator

Conversation

@loevgaard

Copy link
Copy Markdown
Member

Closes #141.

The bug

Quickpay answers 401 on GET /ping both for an invalid api key and for a valid key whose api user lacks the /ping permission — verified live: the test account's working key (payments, links, captures all fine) gets 401 on /ping and 200 on /payments. QuickpayCredentialsValidator treated any 401/403 from the ping as "Quickpay rejects the key", so a merchant with a locked-down api user could not save a perfectly valid payment method through the admin form.

The fix

The doctor command's two-step probe (from #140) is extracted to Quickpay\ApiKeyVerifier (+ interface and alias, per the repo convention): ping first, and on 401/403 fall back to a one-item /payments read — a permission every integration needs anyway. Both consumers share it:

  • QuickpayCredentialsValidator raises a violation only when the probe reports an explicit 401/403 (i.e. /payments also rejects the key); everything else keeps failing open, so neither a locked-down api user nor an unreachable Quickpay blocks saving.
  • DoctorCommand keeps its distinct messages ("accepted", "accepted via /payments — the api user lacks the /ping permission, which is harmless", rejected, unanswered) keyed off the verifier's result/exceptions.

The verifier's contract encodes the outcome in types: returns whether the /ping permission exists, throws UnauthorizedException/ForbiddenException for a rejected key, and lets anything else propagate as "nothing proven either way" — which is exactly the distinction both consumers already made.

Tests

  • ApiKeyVerifierTest drives the probe through the real SDK client (queued-response PSR-18 double): ping-ok, fallback-ok, rejected on both endpoints, unanswered ping, unanswered fallback.
  • The validator test pins the new behavior: a key verified through the fallback raises no violation.
  • The doctor and form type tests are rewired onto the verifier with unchanged expectations.

README (form-save paragraph) and CLAUDE.md updated to describe the shared probe.

…validator

Quickpay answers 401 on /ping both for an invalid api key and for a valid key
whose api user lacks the /ping permission (verified live), so the form-save
validator rejected perfectly valid configurations for locked-down api users.

The doctor command's two-step probe is extracted to Quickpay\ApiKeyVerifier
(ping, falling back to a one-item /payments read - a permission every
integration needs) and both consumers now share it: the validator raises a
violation only when the probe reports an explicit 401/403, and the doctor keeps
its distinct ok/fail/warn messages.

Closes #141
@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.14%. Comparing base (ea88648) to head (23df5be).

Additional details and impacted files
@@             Coverage Diff              @@
##                2.x     #142      +/-   ##
============================================
+ Coverage     95.12%   95.14%   +0.01%     
- Complexity      272      273       +1     
============================================
  Files            28       29       +1     
  Lines           985      988       +3     
============================================
+ Hits            937      940       +3     
  Misses           48       48              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

verify() returned false for a key that had just passed verification - the bool
answered "does the api user have the /ping permission", not "is the key valid",
and the method name hid that. It now returns an ApiKeyVerification enum whose
two cases both read as verified (ViaPing / ViaPayments), with the rejected and
unanswered outcomes staying exceptions as before.
@loevgaard
loevgaard force-pushed the fix-credentials-validator branch from dfd55a9 to 23df5be Compare August 24, 2026 10:56
@loevgaard
loevgaard merged commit 5244f59 into 2.x Aug 24, 2026
29 of 30 checks passed
@loevgaard
loevgaard deleted the fix-credentials-validator branch August 24, 2026 10:58
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.

QuickpayCredentialsValidator rejects valid api keys whose api user lacks the /ping permission

1 participant