@assinafy/sdk 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,102 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.2.0] - 2026-08-27
11
+
12
+ ### Security
13
+
14
+ - **`baseUrl` now requires `https` for any remote host.** Every request on the
15
+ authenticated transport carries the caller's `X-Api-Key` or bearer token, so
16
+ a plaintext `http://` base URL put a long-lived credential on the wire in
17
+ cleartext. `http` remains accepted when the host is loopback (`localhost`,
18
+ the `127.0.0.0/8` block, or `::1`) so local mock servers and the packed
19
+ consumer smoke test keep working; anything else is rejected with a
20
+ `ValidationError` at construction time. `SECURITY.md` already required HTTPS
21
+ endpoints — the client now enforces it rather than trusting configuration.
22
+ - Callers pointing at a remote `http://` host must switch to `https://`.
23
+
24
+ ### Fixed
25
+
26
+ - **`signers.findByEmail()` requested 100 rows per page and received 50.** The
27
+ API clamps `per-page` to 50 and answers `200`, so the lookup scanned half the
28
+ window its documentation claimed. It now pins the real maximum, and the
29
+ method and `signers.list()` documentation state the clamp instead of naming
30
+ 100 as the API maximum. `documents.list()` carried the same incorrect claim.
31
+ - **Unstructured error bodies were reported as the generic "API request
32
+ failed".** A gateway or proxy in front of the API answers with `text/plain`
33
+ or HTML rather than the Assinafy JSON envelope. `ApiError.fromResponse()`
34
+ only read `message`/`error` off an object, so exactly the failures with no
35
+ structured body to explain them lost their only explanation. A non-JSON body
36
+ is now used as the message, with whitespace collapsed and the text capped at
37
+ 500 characters; the untouched body remains on `ApiError.responseData`.
38
+
39
+ ### Added
40
+
41
+ - **`MAX_LIST_PAGE_SIZE`** — the largest page any list endpoint returns (50).
42
+ Exported so callers can size pagination loops against the value the server
43
+ actually honours rather than the one they request.
44
+
45
+ ### Changed
46
+
47
+ - The email and E.164 phone-number patterns had five and two copies across the
48
+ resource files. They are now `isEmail()`, `assertEmail()`, and
49
+ `isE164PhoneNumber()` in `src/utils.ts`, so the accepted shape of a contact
50
+ value is defined in one place. Validation behaviour and error messages are
51
+ unchanged.
52
+ - `decodeBinaryErrorBody()` returns a non-JSON binary body as a string instead
53
+ of wrapping it in `{ message }`, so both unstructured-body paths converge on
54
+ the single rule in `ApiError.fromResponse()`.
55
+ - GitLab CI reads the Bun version from `package.json`'s `packageManager` field
56
+ instead of repeating the literal, matching how GitHub Actions' `setup-bun`
57
+ resolves it. Both CIs now move together when that field is bumped.
58
+ - README gained a contents map linking the setup, end-to-end workflow, and
59
+ per-resource sections; list examples use the `per-page` spelling the API
60
+ reads and document the page-size clamp.
61
+
62
+ ## [2.1.2] - 2026-08-26
63
+
64
+ ### Added
65
+
66
+ - `SDK_USER_AGENT` — every transport, including public and signer-access-code
67
+ requests, now identifies itself as `Assinafy-Typescript-SDK/v<VERSION>`.
68
+ - `scripts/node-consumer-smoke.mjs`, exercised by CI and the release workflow:
69
+ it installs the packed tarball into an isolated consumer and drives the real
70
+ Node HTTP, auth, and multipart paths through both CJS and ESM entrypoints.
71
+ - A manual **Sandbox integration** workflow with `read-only` and
72
+ `disposable-full` modes, gated on a protected environment.
73
+
74
+ ### Security
75
+
76
+ - Requests on the authenticated transport are pinned to the configured API
77
+ origin. A cross-origin URL is rejected before dispatch, and `Authorization`
78
+ and `X-Api-Key` are marked redirect-sensitive so the redirect stack strips
79
+ them.
80
+ - Cross-origin redirects are blocked unless they are a `GET`/`HEAD` to an
81
+ `https` target whose source URL carries no sensitive query parameter.
82
+ - Public, login, and signer-access-code flows run on a transport whose
83
+ credential headers are removed at construction, so a configured API key
84
+ cannot reach a public endpoint.
85
+ - `AxiosError` is no longer attached as an SDK error `cause`. It retains the
86
+ full request config, including credentials and body, which error reporters
87
+ commonly serialize. Transport failures now carry a sanitized cause with
88
+ credential-shaped values redacted from the message.
89
+ - Caller-supplied loggers receive an allowlist of numeric operational counters
90
+ only. Logger exceptions and rejected promises are swallowed so telemetry
91
+ cannot change request semantics.
92
+
93
+ ### Fixed
94
+
95
+ - `AssinafyClient.create()` no longer let its options bag override the
96
+ `apiKey`/`accountId` passed positionally, and it rejects missing or malformed
97
+ credentials instead of constructing an unusable client.
98
+ - Constructor options are validated up front: a non-object bag, a blank
99
+ credential, or an invalid `timeout`/`maxRetries` throws `ValidationError`.
100
+ - `uploadAndRequestSignatures()` validates every signer before uploading, so an
101
+ invalid later signer no longer leaves an orphaned document behind, and it no
102
+ longer waits for `metadata_ready` before creating a virtual assignment.
103
+ - HTTP 429 replay is limited to `GET`, `HEAD`, `OPTIONS`, and `DELETE`, with
104
+ `GET /sign` excluded because that read records a signer view.
105
+
10
106
  ## [2.1.1] - 2026-08-06
11
107
 
12
108
  Maintenance only. The published `dist/` is byte-identical to 2.1.0; no runtime,
@@ -457,7 +553,9 @@ fields (`cpf`, `whatsapp_phone_number`) with the PHP SDK and n8n node.
457
553
  - High-level `uploadAndRequestSignatures` helper on `AssinafyClient`.
458
554
  - `PaginatedResult<T>` with parsed `X-Pagination-*` header meta.
459
555
 
460
- [Unreleased]: https://github.com/assinafy/typescript-sdk/compare/v2.1.1...HEAD
556
+ [Unreleased]: https://github.com/assinafy/typescript-sdk/compare/v2.2.0...HEAD
557
+ [2.2.0]: https://github.com/assinafy/typescript-sdk/compare/v2.1.2...v2.2.0
558
+ [2.1.2]: https://github.com/assinafy/typescript-sdk/compare/v2.1.1...v2.1.2
461
559
  [2.1.1]: https://github.com/assinafy/typescript-sdk/compare/v2.1.0...v2.1.1
462
560
  [2.1.0]: https://github.com/assinafy/typescript-sdk/compare/v2.0.0...v2.1.0
463
561
  [2.0.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v2.0.0