@mcp-abap-adt/auth-providers 1.1.0 → 2.0.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +376 -61
  3. package/bin/auth-authorization-code.ts +5 -3
  4. package/dist/__tests__/helpers/netHelpers.d.ts +16 -0
  5. package/dist/__tests__/helpers/netHelpers.d.ts.map +1 -1
  6. package/dist/__tests__/helpers/netHelpers.js +29 -0
  7. package/dist/auth/announce.d.ts +11 -0
  8. package/dist/auth/announce.d.ts.map +1 -0
  9. package/dist/auth/announce.js +19 -0
  10. package/dist/auth/browserAuth.d.ts +22 -16
  11. package/dist/auth/browserAuth.d.ts.map +1 -1
  12. package/dist/auth/browserAuth.js +101 -536
  13. package/dist/auth/callbackServer.d.ts +46 -0
  14. package/dist/auth/callbackServer.d.ts.map +1 -0
  15. package/dist/auth/callbackServer.js +332 -0
  16. package/dist/auth/oidcBrowserAuth.d.ts +4 -3
  17. package/dist/auth/oidcBrowserAuth.d.ts.map +1 -1
  18. package/dist/auth/oidcBrowserAuth.js +25 -134
  19. package/dist/auth/saml2Auth.d.ts +2 -2
  20. package/dist/auth/saml2Auth.d.ts.map +1 -1
  21. package/dist/auth/saml2Auth.js +21 -141
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +21 -1
  25. package/dist/providers/AuthorizationCodeProvider.d.ts +7 -3
  26. package/dist/providers/AuthorizationCodeProvider.d.ts.map +1 -1
  27. package/dist/providers/AuthorizationCodeProvider.js +51 -41
  28. package/dist/providers/DeviceFlowProvider.d.ts +2 -1
  29. package/dist/providers/DeviceFlowProvider.d.ts.map +1 -1
  30. package/dist/providers/DeviceFlowProvider.js +13 -10
  31. package/dist/providers/OidcBrowserProvider.d.ts +4 -7
  32. package/dist/providers/OidcBrowserProvider.d.ts.map +1 -1
  33. package/dist/providers/OidcBrowserProvider.js +54 -57
  34. package/dist/providers/OidcDeviceFlowProvider.d.ts.map +1 -1
  35. package/dist/providers/OidcDeviceFlowProvider.js +9 -7
  36. package/dist/providers/Saml2BearerProvider.d.ts +2 -2
  37. package/dist/providers/Saml2BearerProvider.d.ts.map +1 -1
  38. package/dist/providers/Saml2BearerProvider.js +3 -0
  39. package/dist/providers/Saml2PureProvider.d.ts +2 -2
  40. package/dist/providers/Saml2PureProvider.d.ts.map +1 -1
  41. package/dist/providers/Saml2PureProvider.js +3 -0
  42. package/dist/providers/saml2Utils.d.ts +12 -12
  43. package/dist/providers/saml2Utils.d.ts.map +1 -1
  44. package/dist/providers/saml2Utils.js +46 -26
  45. package/dist/strategies/BrowserCallbackStrategy.d.ts +64 -0
  46. package/dist/strategies/BrowserCallbackStrategy.d.ts.map +1 -0
  47. package/dist/strategies/BrowserCallbackStrategy.js +210 -0
  48. package/dist/strategies/asOidcResult.d.ts +11 -0
  49. package/dist/strategies/asOidcResult.d.ts.map +1 -0
  50. package/dist/strategies/asOidcResult.js +30 -0
  51. package/dist/strategies/codeStrategies.d.ts +22 -0
  52. package/dist/strategies/codeStrategies.d.ts.map +1 -0
  53. package/dist/strategies/codeStrategies.js +39 -0
  54. package/dist/strategies/index.d.ts +8 -0
  55. package/dist/strategies/index.d.ts.map +1 -0
  56. package/dist/strategies/index.js +18 -0
  57. package/dist/strategies/manualStrategies.d.ts +20 -0
  58. package/dist/strategies/manualStrategies.d.ts.map +1 -0
  59. package/dist/strategies/manualStrategies.js +77 -0
  60. package/package.json +4 -4
  61. package/dist/auth/manualInput.d.ts +0 -5
  62. package/dist/auth/manualInput.d.ts.map +0 -1
  63. package/dist/auth/manualInput.js +0 -19
package/CHANGELOG.md CHANGED
@@ -7,6 +7,127 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.0.0] - 2026-07-31
11
+
12
+ Callback reception leaves the providers. How an interactive login is conducted —
13
+ reaching the authorization URL, receiving what comes back, the port, the timeout
14
+ — is now an `IAuthorizationStrategy` the consumer may replace wholesale; the
15
+ provider keeps only what it can compute, the URL and the token exchange. (#11)
16
+
17
+ ### Breaking
18
+
19
+ - **`browser` and `redirectPort` are removed from every provider config**, along
20
+ with `redirectUri`, `authorizationCode` and `authorizationCodeProvider`
21
+ (OIDC) and `assertionFlow`, `assertionProvider` and `manualInput` (SAML).
22
+ All are replaced by a single `authorization` strategy. See the migration
23
+ table in the README.
24
+ - **The default callback port is now 61001, was 3001** — for the UAA flow and
25
+ for SAML alike, the latter because `resolveAcsUrl` (which defaulted the ACS to
26
+ `http://localhost:3001/callback`) is gone and the ACS now comes from the
27
+ strategy. If you relied on the default and registered
28
+ `http://localhost:3001/callback` with your identity provider, the **IdP**
29
+ rejects the redirect and the error you see comes from it, not from this
30
+ package. Pass `port: 3001` explicitly to keep the old behaviour.
31
+ - **`acsUrl` is required when `authorizationUrl` is set** on `Saml2BearerProvider`
32
+ and `Saml2PureProvider`, and is rejected at construction. The ACS inside a
33
+ pre-built, deflated `SAMLRequest` cannot be read, so it cannot be checked
34
+ against what the strategy binds; 1.x accepted the combination and quietly used
35
+ a default ACS that was usually not where the IdP posted.
36
+ - **The terminal-paste channel is gone from the browser callback strategy.** In
37
+ 1.x a `none` / `headless` login could also be completed by pasting the code on
38
+ stdin, and that worked without the consumer choosing anything; it is the
39
+ channel headless and SSH users reached for most. `browserCallbackStrategy`
40
+ reads no stdin at all — under an MCP or LSP stdio transport that stream
41
+ carries the protocol, so an authorization library must not consume it. The
42
+ capability moved to `manualPasteStrategy({ redirectUri, read })`, which is now
43
+ an explicit choice; the paste form served on `/` remains the other fallback
44
+ for a browser on a different machine.
45
+ - **Device flow prompts no longer go to stdout.** `DeviceFlowProviderConfig`
46
+ accepts `logger?: ILogger`; the verification URI and user code go to that
47
+ logger, or to stderr when none is supplied. `OidcDeviceFlowProvider` likewise.
48
+ Anything capturing stdout to read the device code must now read stderr or
49
+ supply a logger. stdout carries protocol traffic under an MCP or LSP stdio
50
+ transport.
51
+ - `Saml2AssertionConfig` and `Saml2AssertionFlow` are removed from the types, and
52
+ `src/auth/manualInput.ts` is gone; `manualPasteStrategy` and
53
+ `manualSamlResponseStrategy` replace them.
54
+ - Requires `@mcp-abap-adt/interfaces` `^11.6.0` (was `^11.4.0`).
55
+
56
+ ### Added
57
+
58
+ - `IAuthorizationStrategy` support in all four interactive providers
59
+ (`AuthorizationCodeProvider`, `OidcBrowserProvider`, `Saml2BearerProvider`,
60
+ `Saml2PureProvider`), with shipped strategies: `browserCallbackStrategy`,
61
+ `oidcCallbackStrategy`, `samlCallbackStrategy`, `manualPasteStrategy`,
62
+ `manualSamlResponseStrategy`, `externalCodeStrategy`, `staticCodeStrategy`,
63
+ and the `asOidcResult` adapter. `BrowserCallbackStrategy`,
64
+ `DEFAULT_CALLBACK_PORT` and `DEFAULT_LOGIN_TIMEOUT_MS` are exported too.
65
+ - `asOidcResult` bridges the code-producing strategies, which yield a `string`,
66
+ to `OidcBrowserProvider`, which takes `IAuthorizationStrategy<OidcCallbackResult>`.
67
+ It delegates `dispose`, so wrapping costs nothing in lifecycle terms.
68
+ - The three `CallbackServerFactory` implementations are exported —
69
+ `withBrowserCallbackServer`, `withOidcCallbackServer`, `withSamlCallbackServer`
70
+ — so a consumer can reuse the transport while replacing everything around it,
71
+ or inject its own into a shipped strategy via `callbackServer`.
72
+ - Ephemeral callback ports (`port: 0`), where the identity provider accepts a
73
+ loopback redirect on any port. The bound port is reported back, so the token
74
+ exchange can send the redirect URI that actually received the callback.
75
+ - `OidcBrowserProvider` discovers lazily: a strategy that already holds a code
76
+ no longer drags in a discovery request, nor the `issuerUrl` requirement.
77
+
78
+ ### Fixed
79
+
80
+ - A `/callback` carrying neither a code nor an error no longer ends the login;
81
+ it is answered, counted, and reported in the timeout message.
82
+ - The OIDC callback route now distinguishes an IdP refusal from a stray
83
+ request — it previously had no `error=` branch at all.
84
+ - The SAML callback route no longer shows a success page before checking
85
+ whether an assertion arrived; a request with no assertion is answered 400.
86
+ - Manual input prompts go to stderr; they went to stdout, which corrupts an
87
+ MCP/LSP stdio transport.
88
+ - The token exchange sends the redirect URI that actually received the
89
+ callback, rather than one rebuilt from an assumed port.
90
+ - The PKCE challenge is pinned to the verifier that reaches the exchange.
91
+ - A strategy disposed while its port probe was still awaiting used to report
92
+ everything released and then bind a socket behind it.
93
+ - The remote paste hint named `http://localhost:<port>/` — an address that
94
+ cannot work for the one reader it addresses, someone whose browser is on
95
+ another machine. It now names `http://<this-host>:<port>/`, keeping the real
96
+ port and leaving the host to the reader, as the 1.x wording did.
97
+
98
+ ### Docs
99
+
100
+ - `README.md` documents strategies throughout, adds *Choosing an authorization
101
+ strategy* and *Migrating from 1.x to 2.0*, and corrects two claims that were
102
+ already wrong in 1.x: the default `browser` mode is `'none'`, not `'system'`,
103
+ and `extractCode` is internal, not exported.
104
+ - `docs/REFACTORING_PROPOSAL.md` is deleted; the `ITokenProvider` refactor it
105
+ proposed shipped in 1.0.0.
106
+
107
+ ## [1.2.0] - 2026-07-28
108
+
109
+ ### Fixed
110
+ - **A callback server could hold its port after the login it was opened for had ended.** Three flows, three shapes of one defect: `browserAuth` leaked the socket when a callback carried neither `code` nor `error` — measured still bound at +5 s, +20 s, +35 s and +45 s, i.e. for the life of the process — while `oidcBrowserAuth` and `saml2Auth` had no timeout at all, so an abandoned login never settled and never released anything. (#11)
111
+ - **A rejected login could report a port that was not yet free.** Five exit paths closed the socket asynchronously *after* the promise had settled, leaving a window in which "already in use" was untrue.
112
+ - **`AuthorizationCodeProvider` raced `startBrowserAuth` against a second 30-second timer** of its own, so which fired was down to scheduling; when the outer one won it rejected while the socket was still bound. That timer was never cleared, keeping a login that succeeded in a second armed for the remaining 29.
113
+ - **A hung browser launcher could delay the timeout and the release.** The launch is no longer awaited on the critical path.
114
+
115
+ ### Changed
116
+ - All three flows now run inside a factory scope implementing `CallbackServerFactory` from `@mcp-abap-adt/interfaces`. The port is released when the scope ends — by success, error, timeout, cancellation, or a body that throws — instead of when a promise happens to settle, and the scope settles only once the socket is free. `timeoutMs` is mandatory and an `AbortSignal` is honoured before, during and after the bind.
117
+ - Shutdown is bounded: stop accepting, wait up to 500 ms for `close`, then force. A timeout can no longer hang on its own cleanup.
118
+ - Requires `@mcp-abap-adt/interfaces` `^11.4.0` (was `^2.3.0`).
119
+ - **`engines.node` is now `>=18.2.0`** (was `>=18.0.0`), for `server.closeAllConnections()`.
120
+ - `browserAuth.ts` is 395 lines, down from 790: the HTTP server, six separate close sites, two timers and the process-signal handlers are gone from it.
121
+
122
+ ### Removed
123
+ - **The callback server no longer installs `SIGTERM` / `SIGINT` / `SIGHUP` / `exit` handlers.** A terminating process releases its listening sockets to the OS regardless — measured at 0-1 ms after the process disappears — and these were part of the cleanup tangle being removed. A client that kills the process mid-login still gets its port back.
124
+ - **The manual paste channel no longer retries a bad code.** It used to re-render the form when the exchange failed; the code is now exchanged after the scope closes, so a wrong or expired paste ends the attempt. That retry loop was the only reason the socket outlived the code.
125
+
126
+ ### Notes
127
+ - Public API is unchanged: `AuthorizationCodeProviderConfig` keeps `browser` and `redirectPort`, still defaulting to 3001.
128
+ - The three factories stay internal. Exposing them so a consumer can supply its own callback receiver is issue #11 and is not part of this release.
129
+ - A callback carrying neither `code` nor `error` still ends the login with an error. Only the leaked socket was fixed, not the termination.
130
+
10
131
  ## [1.1.0] - 2026-06-02
11
132
 
12
133
  ### Added