diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a8124647..5056a444 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.98.0" + ".": "0.98.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index aae63e8a..cce06fa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.98.1 (2025-12-12) + +Full Changelog: [v0.98.0...v0.98.1](https://github.com/lithic-com/lithic-go/compare/v0.98.0...v0.98.1) + +### Bug Fixes + +* **api:** include schema and base URL in GetEmbedURL ([09f2a83](https://github.com/lithic-com/lithic-go/commit/09f2a83e006afa2339f0dd388c564779e1dc0511)) + ## 0.98.0 (2025-12-10) Full Changelog: [v0.97.0...v0.98.0](https://github.com/lithic-com/lithic-go/compare/v0.97.0...v0.98.0) diff --git a/README.md b/README.md index ade8ac3b..e82d02ec 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Or to pin the version: ```sh -go get -u 'github.com/lithic-com/lithic-go@v0.98.0' +go get -u 'github.com/lithic-com/lithic-go@v0.98.1' ``` diff --git a/card.go b/card.go index 953a5492..2a8fe962 100644 --- a/card.go +++ b/card.go @@ -222,6 +222,7 @@ func (r *CardService) GetEmbedHTML(ctx context.Context, params CardGetEmbedHTMLP // but **do not ever embed your API key into front end code, as doing so introduces // a serious security vulnerability**. func (r *CardService) GetEmbedURL(ctx context.Context, params CardGetEmbedURLParams, opts ...option.RequestOption) (res *url.URL, err error) { + opts = slices.Concat(r.Options, opts) buf, err := params.MarshalJSON() if err != nil { return nil, err @@ -240,7 +241,14 @@ func (r *CardService) GetEmbedURL(ctx context.Context, params CardGetEmbedURLPar if err != nil { return nil, err } - return cfg.Request.URL, nil + baseURL := cfg.BaseURL + if baseURL == nil { + baseURL = cfg.DefaultBaseURL + } + if baseURL == nil { + return nil, errors.New("base url is not set") + } + return baseURL.Parse(cfg.Request.URL.String()) } // Allow your cardholders to directly add payment cards to the device's digital diff --git a/card_test.go b/card_test.go index 8bad85b4..801d36ec 100644 --- a/card_test.go +++ b/card_test.go @@ -259,31 +259,58 @@ func TestCardGetEmbedHTMLWithOptionalParams(t *testing.T) { } } -func TestCardGetEmbedURLWithOptionalParams(t *testing.T) { - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } +func TestCardGetEmbedURL_URLConstruction(t *testing.T) { + // Use fixed inputs to verify URL construction and signature client := lithic.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My Lithic API Key"), + option.WithBaseURL("https://sandbox.lithic.com"), + option.WithAPIKey("test-api-key-12345"), ) - _, err := client.Cards.GetEmbedURL(context.TODO(), lithic.CardGetEmbedURLParams{ - Token: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"), - Css: lithic.F("string"), - Expiration: lithic.F(time.Now()), - TargetOrigin: lithic.F("string"), + + expiration, err := time.Parse(time.RFC3339, "2025-01-01T00:00:00Z") + if err != nil { + t.Fatalf("failed to parse expiration: %s", err.Error()) + } + + url, err := client.Cards.GetEmbedURL(context.TODO(), lithic.CardGetEmbedURLParams{ + Token: lithic.F("test-card-token-abc123"), + Css: lithic.F("https://example.com/style.css"), + Expiration: lithic.F(expiration), + TargetOrigin: lithic.F("https://example.com"), }) if err != nil { - var apierr *lithic.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } t.Fatalf("err should be nil: %s", err.Error()) } + + // Verify URL structure + if url.Scheme != "https" { + t.Errorf("expected scheme 'https', got '%s'", url.Scheme) + } + if url.Host != "sandbox.lithic.com" { + t.Errorf("expected host 'sandbox.lithic.com', got '%s'", url.Host) + } + if url.Path != "/v1/embed/card" { + t.Errorf("expected path '/v1/embed/card', got '%s'", url.Path) + } + + // Verify query params exist + query := url.Query() + if query.Get("embed_request") == "" { + t.Error("expected 'embed_request' query param to be present") + } + if query.Get("hmac") == "" { + t.Error("expected 'hmac' query param to be present") + } + + // Verify exact values to prevent signature regressions + expectedEmbedRequest := "eyJjc3MiOiJodHRwczovL2V4YW1wbGUuY29tL3N0eWxlLmNzcyIsImV4cGlyYXRpb24iOiIyMDI1LTAxLTAxVDAwOjAwOjAwWiIsInRhcmdldF9vcmlnaW4iOiJodHRwczovL2V4YW1wbGUuY29tIiwidG9rZW4iOiJ0ZXN0LWNhcmQtdG9rZW4tYWJjMTIzIn0=" + expectedHmac := "tHf1AsLDIO7gHDA+N/3d5RT446tSmorVbjELGXF/UKQ=" + + if query.Get("embed_request") != expectedEmbedRequest { + t.Errorf("embed_request mismatch:\n got: %s\n want: %s", query.Get("embed_request"), expectedEmbedRequest) + } + if query.Get("hmac") != expectedHmac { + t.Errorf("hmac mismatch:\n got: %s\n want: %s", query.Get("hmac"), expectedHmac) + } } func TestCardProvisionWithOptionalParams(t *testing.T) { diff --git a/internal/version.go b/internal/version.go index a6eb9edd..a87bf824 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.98.0" // x-release-please-version +const PackageVersion = "0.98.1" // x-release-please-version