btcpayserver-plugin-builder/PluginBuilder/DataModels/HttpClientNames.cs
r1ckstardev b84538f2c2 btcmaps v1: IHttpClientFactory + markdown-safe PR body + idempotent branch + ISO whitelist
Addresses post-#224 review feedback from @rollforsats + CodeRabbit:

- IHttpClientFactory + named HttpClientNames.BtcMapsDirectory client
  replaces per-request `new HttpClient()`. 15s per-call timeout caps the
  ~5-7 GitHub round-trips at a bounded worst case instead of the default
  100s x N. Bearer token stays per-request (the BTCMAPS token is distinct
  from the global PluginBuilder GitHub token; must not leak into the
  singleton handler).
- Markdown injection guard on the PR body. User fields (Name, Type,
  SubType, Country, Twitter, GitHub) are wrapped in inline code spans
  with backtick-escape so a doctored merchant name can't render as a
  clickable link in the maintainer-facing PR description. Description
  goes inside a fenced code block. URL is rendered as <bare-url> autolink
  so the maintainer always sees the actual destination.
- Idempotent branch name: SHA-1-derived suffix from the normalized URL
  replaces the random GUID. Two concurrent same-URL submissions now
  collide on `git/refs` create instead of racing through preflight and
  opening duplicate PRs. The 422 "Reference already exists" surface is
  caught and mapped to the open-PR lookup or `branch-exists-no-open-pr`.
- NormalizeUrl lowercases scheme + host only and preserves path + query
  case verbatim. Lowercasing the whole URL falsely de-duplicates
  case-sensitive paths.
- Country code validation moves to an actual ISO 3166-1 alpha-2 set
  built from CultureInfo at startup. Replaces the
  `length==2 && IsUpper` shape that accepted reserved/unassigned codes
  like ZZ.
- Missing BTCMAPS:DirectoryGithubToken throws
  DirectoryTokenMissingException at the service layer; controller maps
  it to 503 with `directory-not-configured`. Previously surfaced as a
  200 OK with `Skipped` which a client could misread as "accepted".

5 new tests:
- Validate_RejectsNonAssignedTwoLetterCountry (ZZ)
- NormalizeUrl_PreservesPathCase
- NormalizeUrl_PreservesQueryCase
- BuildBranchName_DeterministicForSameUrl
- BuildBranchName_DiffersForDifferentUrls

25/25 BtcMapsServiceTests pass on Release build.
2026-05-11 16:32:04 +00:00

9 lines
244 B
C#

namespace PluginBuilder.DataModels;
public static class HttpClientNames
{
public const string GitHub = nameof(GitHub);
public const string GitLab = nameof(GitLab);
public const string BtcMapsDirectory = nameof(BtcMapsDirectory);
}