@assinafy/sdk 2.2.0 → 2.4.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,106 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.4.0] - 2026-09-21
11
+
12
+ ### Fixed
13
+
14
+ - **`assignments.estimateCost` now sends `signers` for `collect` too.** The
15
+ published contract marks `signers` as required only for `virtual`, but the
16
+ API rejects *any* estimate without it — `collect` requests came back as
17
+ `400 Pelo menos um signatários precisa ser informado.` Pricing is per signer
18
+ in both modes (`Whatsapp` costs 0.45 credits per signer,
19
+ `DigitalCertificate` two), so a signer-less body could never be priced.
20
+
21
+ ### Changed
22
+
23
+ - `IEstimateAssignmentCostPayload.signers` is now required. TypeScript callers
24
+ that omitted it for `collect` will stop compiling; those calls were already
25
+ failing at runtime, so no working code changes behaviour. Pass one descriptor
26
+ per signer —
27
+ `{}` prices the default Email channel:
28
+
29
+ ```ts
30
+ await client.assignments.estimateCost(documentId, {
31
+ method: 'collect',
32
+ signers: [{}, { verification_method: 'Whatsapp' }],
33
+ entries,
34
+ });
35
+ ```
36
+
37
+ - `buildAssignmentEstimatePayload` throws `ValidationError` for an empty
38
+ signer list in either mode, so JavaScript callers get a local error instead
39
+ of an opaque upstream rejection. The message is now method-neutral:
40
+ `At least one signer is required for a cost estimate`.
41
+
42
+ ## [2.3.0] - 2026-09-20
43
+
44
+ ### Added
45
+
46
+ - **OAuth 2.1 support — `client.oauth`.** Applications that act inside *other
47
+ people's* workspaces can now run the whole authorization-code flow through
48
+ the SDK instead of assembling it by hand:
49
+ - `createAuthorizationUrl(options)` mints a fresh PKCE verifier (S256), a
50
+ `state` and, for `openid`, a `nonce`, then builds the consent URL. It
51
+ returns everything the callback and token exchange need, so nothing has to
52
+ be re-derived later.
53
+ - `readAuthorizationCallback(params, expected)` validates the redirect before
54
+ anything on it is trusted: `state` in constant time, then `iss` (RFC 9207).
55
+ A declined consent surfaces as an `OAuthError`, not a silent success. It
56
+ accepts an Express `req.query`, a `URLSearchParams`, a `URL`, a full
57
+ callback URL or a bare query string.
58
+ - `exchangeCode(options)`, `refreshToken(options)` and `revokeToken(options)`
59
+ call `POST /oauth/token` and `POST /oauth/revoke` on a credential-free
60
+ transport, so an integrator's own `X-Api-Key` is never sent to a route that
61
+ authenticates the application.
62
+ - `getUserInfo(accessToken?)` reads the OpenID Connect claims.
63
+ - `getProtectedResourceMetadata()` (RFC 9728, served at the API host root)
64
+ and `getAuthorizationServerMetadata(issuer?)` (RFC 8414) discover the
65
+ endpoints instead of hardcoding them, and the second one rejects a document
66
+ whose `issuer` disagrees with where it was fetched from.
67
+ - **`OAuthError`** — the OAuth endpoints answer with a flat
68
+ `{ error, error_description }` body rather than the `{ status, message, data }`
69
+ envelope, so the RFC 6749 code is exposed as `error` and the explanation as
70
+ `errorDescription`. It extends `ApiError`, so existing `catch` blocks keep
71
+ matching.
72
+ - **`ApiError.challenge`** — the parsed `WWW-Authenticate` header, when the API
73
+ sends one. On a `403` it names the scope the token is missing
74
+ (`insufficient_scope`), which is the only way to tell "reconnect asking for
75
+ more" apart from a permission an OAuth token can never hold. The parser is
76
+ also exported as `parseWwwAuthenticate`.
77
+ - Both READMEs document the complete OAuth flow: registering the application,
78
+ the scope catalogue, workspace binding, refresh-token rotation, revocation,
79
+ and what each failure means.
80
+
81
+ ### Changed
82
+
83
+ - **Signer verification and notification channels are now validated as a
84
+ pair.** The API couples them — the verification code travels on the
85
+ notification channel — so `Email` verification only allows `Email`
86
+ notification, `Whatsapp` only `Whatsapp`, and `DigitalCertificate` either
87
+ one. Exactly one notification method is allowed per signer. The SDK rejected
88
+ unknown channel names but let an impossible pairing (and an empty or
89
+ two-element `notification_methods`) through to a `400`. The rule now lives in
90
+ `validateAssignmentSignerOptions()` and therefore applies to assignment
91
+ creation, cost estimation and template-driven document creation alike; the
92
+ duplicate one-method check in the template path was removed.
93
+ - A payload the API would have rejected now fails locally with a
94
+ `ValidationError` naming the pairing.
95
+ - `AssignmentVerificationMethod` and `AssignmentNotificationMethod` document
96
+ the channel matrix, its costs and its prerequisites. ICP-Brasil **A1** and
97
+ **A3** are recorded explicitly as certificate media — a file in software or a
98
+ token/smartcard, chosen by the signer in the browser — both modelled by the
99
+ single `DigitalCertificate` value, with no separate field to send.
100
+ - `bun run audit:api` additionally fetches the two OAuth discovery documents
101
+ and checks the issuer, the authorization and token endpoints, PKCE `S256` and
102
+ the RFC 9207 `iss` parameter against the published contract. They are the
103
+ only part of the OAuth surface that does not live in the OpenAPI document.
104
+ - `docs/API_COVERAGE.md` maps the four new OAuth operations, bringing the
105
+ ledger to 93 of 93.
106
+ - The Portuguese README is now the complete reference rather than a summary
107
+ pointing at the English one: installation through the end-to-end signature
108
+ flow, every resource, errors, environments and development.
109
+
10
110
  ## [2.2.0] - 2026-08-27
11
111
 
12
112
  ### Security
@@ -553,7 +653,9 @@ fields (`cpf`, `whatsapp_phone_number`) with the PHP SDK and n8n node.
553
653
  - High-level `uploadAndRequestSignatures` helper on `AssinafyClient`.
554
654
  - `PaginatedResult<T>` with parsed `X-Pagination-*` header meta.
555
655
 
556
- [Unreleased]: https://github.com/assinafy/typescript-sdk/compare/v2.2.0...HEAD
656
+ [Unreleased]: https://github.com/assinafy/typescript-sdk/compare/v2.4.0...HEAD
657
+ [2.4.0]: https://github.com/assinafy/typescript-sdk/compare/v2.3.0...v2.4.0
658
+ [2.3.0]: https://github.com/assinafy/typescript-sdk/compare/v2.2.0...v2.3.0
557
659
  [2.2.0]: https://github.com/assinafy/typescript-sdk/compare/v2.1.2...v2.2.0
558
660
  [2.1.2]: https://github.com/assinafy/typescript-sdk/compare/v2.1.1...v2.1.2
559
661
  [2.1.1]: https://github.com/assinafy/typescript-sdk/compare/v2.1.0...v2.1.1