@mcp-abap-adt/auth-broker 5.0.1 → 5.0.5
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 +69 -0
- package/README.md +42 -13
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,75 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
Thank you to all contributors! See [CONTRIBUTORS.md](../../CONTRIBUTORS.md) for the complete list.
|
|
11
11
|
|
|
12
|
+
## [5.0.5] - 2026-10-12
|
|
13
|
+
|
|
14
|
+
The library's code and runtime dependencies are the same as 5.0.4. What changed is the
|
|
15
|
+
docs, the README's connection note included, and the tests.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- The tests and live checks run on `@mcp-abap-adt/connection` 15.0.0 (dev dependency
|
|
19
|
+
`^15.0.0`, on `@mcp-abap-adt/interfaces-adt-connection` 2.0.0, one copy). Their
|
|
20
|
+
end-to-end suite is renamed `adtConnector.test.ts`.
|
|
21
|
+
- The docs name `connection` 14 or 15 as the connector `getProvider`'s provider is for.
|
|
22
|
+
The README says why a consumer that also uses `adt-clients` should take 15.
|
|
23
|
+
|
|
24
|
+
## [5.0.4] - 2026-10-12
|
|
25
|
+
|
|
26
|
+
The first published release after 5.0.1. The code is the same as 5.0.2 and 5.0.3, which were
|
|
27
|
+
tagged but not published. It is released together with auth-broker-cli 3.1.1, so that one
|
|
28
|
+
publish from the main checkout carries both. 5.0.2 (built and tested on auth-stores 5) and
|
|
29
|
+
5.0.3 (tests on connection 14.1.0, the README's connection note) arrive with 5.0.4.
|
|
30
|
+
|
|
31
|
+
## [5.0.3] - 2026-10-12
|
|
32
|
+
|
|
33
|
+
Development only; the published library is unchanged.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- The tests run on `@mcp-abap-adt/connection` 14.1.0 (a dev dependency, `^14.1.0`):
|
|
37
|
+
its `disconnect()` sends the session's logoff, so a connection the broker's
|
|
38
|
+
tests and live checks close no longer leaves its SAP session open until the
|
|
39
|
+
server's timeout. The connection is the consumer's; the broker does not
|
|
40
|
+
depend on it.
|
|
41
|
+
- README: a consumer should use `@mcp-abap-adt/connection` 14.1.0 or later. From
|
|
42
|
+
14.1.0, `disconnect()` ends the SAP session.
|
|
43
|
+
|
|
44
|
+
## [5.0.2] - 2026-10-11
|
|
45
|
+
|
|
46
|
+
Built and tested on `@mcp-abap-adt/auth-stores` 5.0.0; the code is the same as
|
|
47
|
+
5.0.1. auth-stores is not a dependency of the library: the consumer composes
|
|
48
|
+
the stores, and 5.0.2 works with auth-stores 4 or 5 alike.
|
|
49
|
+
|
|
50
|
+
### Migration (for a consumer moving to auth-stores 5)
|
|
51
|
+
|
|
52
|
+
- **A session file with no binding keys beside its credential** — written by
|
|
53
|
+
auth-stores 2.x/3.0.0, auth-broker 3.x, or by hand — is no longer composed a
|
|
54
|
+
binding by the store and read as unbound (one login). auth-stores 5 refuses
|
|
55
|
+
the record whole with a `StorageError` (`code: 'STORAGE_ERROR'`,
|
|
56
|
+
`reason: 'record-format'`, fixed words, no value of the record), and the
|
|
57
|
+
broker passes it unchanged to the caller of `getProvider` and the token API
|
|
58
|
+
(every row that reads the session; the broker's own `client_credentials`
|
|
59
|
+
reads none, and its new credential replaces the record). This is 5.0.0's
|
|
60
|
+
rule that a store's read failure other than `FILE_NOT_FOUND` reaches the
|
|
61
|
+
caller, not a change of the broker.
|
|
62
|
+
- **What to do:** regenerate the session with
|
|
63
|
+
`mcp-auth --service-key <key.json> --output <file> --type abap|xsuaa`, or
|
|
64
|
+
remove its session lines; a file holding only the means is no session.
|
|
65
|
+
`@mcp-abap-adt/auth-broker-cli` 3.1.0 (released together) does it for you:
|
|
66
|
+
`mcp-auth --env <file>` or `--destination <name>` over such a file discards
|
|
67
|
+
its session and logs in anew, the means kept byte for byte.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- Dev dependency `@mcp-abap-adt/auth-stores` ^5.0.0.
|
|
71
|
+
- Tests: a pre-3.1.0 session file, and a 4.x token beside `issuedFor` alone,
|
|
72
|
+
now assert the store's `record-format` error reaching the caller — no
|
|
73
|
+
request, no login, no write, the file byte for byte, no record value in the
|
|
74
|
+
error or the log — where they asserted a login over a composed binding.
|
|
75
|
+
|
|
76
|
+
### Documentation
|
|
77
|
+
- README (*Errors*, *A Credential Stays Bound to Its Identity*, the upgrade
|
|
78
|
+
note), `docs/` and `CLAUDE.md` describe the record-format refusal and name
|
|
79
|
+
auth-stores 5.
|
|
80
|
+
|
|
12
81
|
## [5.0.1] - 2026-10-09
|
|
13
82
|
|
|
14
83
|
Development only; the code is the same as 5.0.0.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
A per-destination credential broker for SAP BTP and ABAP systems. For a destination — a name,
|
|
5
5
|
such as `TRIAL` — `getProvider` builds the `IAuthProvider` the destination states (basic, SNC, a
|
|
6
6
|
UAA, OIDC or SAML grant, or a credential handed over) from the *means* in the service key store
|
|
7
|
-
and the *secret* in the session store, ready for a `@mcp-abap-adt/connection` 14 connector, and
|
|
7
|
+
and the *secret* in the session store, ready for a `@mcp-abap-adt/connection` 14 or 15 connector, and
|
|
8
8
|
stores back every token or set of SAML session cookies that provider obtains or renews. The
|
|
9
9
|
token API (`getToken`, `refreshToken`, `createTokenRefresher`) serves whoever wants a token and
|
|
10
10
|
nothing else. It decides nothing about tokens itself: whether the cached token is still good,
|
|
@@ -16,10 +16,14 @@ the renewal strategy's you give it; where means and secrets live is the stores'
|
|
|
16
16
|
short — a token destination needs two options the broker has no default for (`renewal`,
|
|
17
17
|
`onWriteFailure`); every failure is an `AuthProviderFailure` read through
|
|
18
18
|
`@mcp-abap-adt/auth-errors`; every session written before 5.0.0 reads as unbound once, so each
|
|
19
|
-
token destination logs in once after the upgrade.
|
|
19
|
+
token destination logs in once after the upgrade. A session file with no binding keys at all
|
|
20
|
+
(written before auth-stores 3.1.0, or by hand) is refused by auth-stores 5 as a whole, and that
|
|
21
|
+
error reaches you: regenerate it with `mcp-auth` (see [*Errors*](#errors)) — from
|
|
22
|
+
auth-broker-cli 3.1.1, `mcp-auth --env <file>` (or `--destination <name>`) over such a file
|
|
23
|
+
discards its session and logs in anew.
|
|
20
24
|
|
|
21
25
|
The `mcp-auth` command that writes destination files is
|
|
22
|
-
[`@mcp-abap-adt/auth-broker-cli`](../auth-broker-cli/README.md) (3.
|
|
26
|
+
[`@mcp-abap-adt/auth-broker-cli`](../auth-broker-cli/README.md) (3.1.1, on this version), in the
|
|
23
27
|
same repository. This package has no `bin`.
|
|
24
28
|
|
|
25
29
|
## Features
|
|
@@ -39,8 +43,8 @@ same repository. This package has no `bin`.
|
|
|
39
43
|
npm install @mcp-abap-adt/auth-broker @mcp-abap-adt/auth-providers @mcp-abap-adt/auth-errors @mcp-abap-adt/auth-stores
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
5.0.
|
|
43
|
-
`^2.
|
|
46
|
+
5.0.5 depends on `@mcp-abap-adt/auth-providers` `^6.0.0`, `@mcp-abap-adt/auth-errors`
|
|
47
|
+
`^2.2.0`, `@mcp-abap-adt/interfaces-auth` `^7.5.0`, `@mcp-abap-adt/interfaces-auth-sap`
|
|
44
48
|
`^3.3.0`, `@mcp-abap-adt/interfaces-auth-broker` `^1.3.0` and
|
|
45
49
|
`@mcp-abap-adt/interfaces-utils` `^1.1.0`. Declare `auth-providers` yourself — the renewal
|
|
46
50
|
strategies (`refreshThenLogin`, `refreshOnly`) and the interactive strategies come from it —
|
|
@@ -96,7 +100,7 @@ const provider = await broker.getProvider('TRIAL', { signal: session.signal });
|
|
|
96
100
|
```
|
|
97
101
|
|
|
98
102
|
`getProvider(destination)` returns the `IAuthProvider` (from `@mcp-abap-adt/interfaces-auth`
|
|
99
|
-
7) that a `@mcp-abap-adt/connection` 14 connector takes as it is. The broker reads two stores,
|
|
103
|
+
7) that a `@mcp-abap-adt/connection` 14 or 15 connector takes as it is. The broker reads two stores,
|
|
100
104
|
each for one role:
|
|
101
105
|
|
|
102
106
|
- **the means** — `authType`, `grantType`, basic's user and password, the SNC, OIDC and SAML
|
|
@@ -312,7 +316,7 @@ success — and the write runs on, landing or failing on its own.
|
|
|
312
316
|
|
|
313
317
|
**The store's contract.** `saveSession` settles: it resolves or rejects. A store whose
|
|
314
318
|
`saveSession` never settles holds its destination's queue; avoiding that is yours (each waiting
|
|
315
|
-
caller is still released by its own signal). auth-stores
|
|
319
|
+
caller is still released by its own signal). auth-stores 5's `saveSession` **merges** — a field
|
|
316
320
|
left out keeps what is stored — so the broker states every field that must not survive:
|
|
317
321
|
|
|
318
322
|
| What the provider reported | What one `saveSession` writes |
|
|
@@ -439,6 +443,18 @@ means lacking what the record needs, or no `serviceUrl`) gets a `debug` line ins
|
|
|
439
443
|
start. An OIDC destination with explicit endpoints and a client but no issuer is fully stated,
|
|
440
444
|
and is reused after a restart when its means are unchanged.
|
|
441
445
|
|
|
446
|
+
**A record the store refuses is not "no session".** auth-stores 5 reads a session only in its
|
|
447
|
+
own format — beside a token or cookies, both binding keys (`SAP_ISSUED_FOR` / `SAP_ISSUED_BY`,
|
|
448
|
+
or the `XSUAA_*` pair), present even when empty — and refuses any other record as a whole with
|
|
449
|
+
a `StorageError` (`reason: 'record-format'`): a file written by auth-stores 2.x/3.0.0 or
|
|
450
|
+
auth-broker 3.x, or by hand. The broker does not read that as an absent session and log in over
|
|
451
|
+
it; `getProvider` and the token API reject with the store's error, unchanged, before any
|
|
452
|
+
request (every row that reads the session; the broker's own `client_credentials` reads none,
|
|
453
|
+
and its new credential replaces the record). Regenerate the session with `mcp-auth`: from
|
|
454
|
+
auth-broker-cli 3.1.1, a run over the file (`--env`, `--destination`) discards its session — the
|
|
455
|
+
session keys alone, in a private copy, the original written only after the new login is stored —
|
|
456
|
+
and logs in anew.
|
|
457
|
+
|
|
442
458
|
**The `none` rows** present a credential the broker cannot obtain again, so a mismatch is
|
|
443
459
|
refused, not discarded: a `DestinationConfigError` naming `issuedFor` when the stored resource
|
|
444
460
|
differs or is absent (or the means state no `serviceUrl`), and `issuedBy` when the stored record
|
|
@@ -468,7 +484,7 @@ import { bindingOf } from '@mcp-abap-adt/auth-broker';
|
|
|
468
484
|
const means = await keyStore.getConnectionConfig('DEV'); // saml / none
|
|
469
485
|
await sessionStore.saveSession('DEV', {
|
|
470
486
|
sessionCookies: cookies,
|
|
471
|
-
refreshToken: '', // auth-stores
|
|
487
|
+
refreshToken: '', // auth-stores 5 merges: clear what an earlier session left
|
|
472
488
|
...bindingOf(means ?? {}),
|
|
473
489
|
// { issuedFor: 'https://dev.example.com:443?sap-client=100',
|
|
474
490
|
// issuedBy: 'mcp-abap-adt-binding/2;saml/none;;;;;;;;;;;;' }
|
|
@@ -826,9 +842,16 @@ const current = await tokenRefresher.getToken();
|
|
|
826
842
|
const renewed = await tokenRefresher.refreshToken();
|
|
827
843
|
```
|
|
828
844
|
|
|
829
|
-
A `@mcp-abap-adt/connection` 14 connector takes an `IAuthProvider` instead: give it `await
|
|
845
|
+
A `@mcp-abap-adt/connection` 14 or 15 connector takes an `IAuthProvider` instead: give it `await
|
|
830
846
|
broker.getProvider('TRIAL', { signal })`.
|
|
831
847
|
|
|
848
|
+
Use `@mcp-abap-adt/connection` 14.1.0 or later. From 14.1.0 its `disconnect()` sends the
|
|
849
|
+
session's logoff. An earlier 14.x left each closed connection's SAP session open until the
|
|
850
|
+
server's own timeout, so a process that connects again and again collects sessions.
|
|
851
|
+
Connection 15 is built on `@mcp-abap-adt/interfaces-adt-connection` 2, as `adt-clients` is.
|
|
852
|
+
If your consumer uses both, choose 15: with 14 it installs two copies of that contract.
|
|
853
|
+
The broker hands either one the same `IAuthProvider`.
|
|
854
|
+
|
|
832
855
|
## Errors
|
|
833
856
|
|
|
834
857
|
**A provider's failure passes as the same object.** Whatever a provider throws from
|
|
@@ -930,7 +953,13 @@ needs a clientAuthentication strategy`.
|
|
|
930
953
|
|
|
931
954
|
- **A store's read failure** (anything but `FILE_NOT_FOUND`, which is absence) reaches the
|
|
932
955
|
caller as the store raised it — your collaborator's error, returned to you, also through the
|
|
933
|
-
shared resolution.
|
|
956
|
+
shared resolution. With auth-stores 5 that includes a session record not of the store's
|
|
957
|
+
format: a `StorageError` with `code: 'STORAGE_ERROR'` and `reason: 'record-format'`, in the
|
|
958
|
+
store's fixed words (`AbapSessionStore: the stored session for "<destination>" is not in this
|
|
959
|
+
store's format; regenerate it with mcp-auth`) — no value of the record. Regenerate the session
|
|
960
|
+
(`mcp-auth --service-key <key.json> --output <file>`, or from auth-broker-cli 3.1.1
|
|
961
|
+
`mcp-auth --env <file>`, which discards the refused session and logs in anew), or remove its
|
|
962
|
+
session lines. A store that answers `null`, or fails with `FILE_NOT_FOUND` (logged at
|
|
934
963
|
debug), means "nothing here".
|
|
935
964
|
- **The constructor's argument checks** (`AuthBroker: sessionStore is required`, …) are plain
|
|
936
965
|
`Error`s naming option names: a programming error.
|
|
@@ -983,7 +1012,7 @@ its level from `AUTH_LOG_LEVEL`.)
|
|
|
983
1012
|
|
|
984
1013
|
### File Structure
|
|
985
1014
|
|
|
986
|
-
With `@mcp-abap-adt/auth-stores`
|
|
1015
|
+
With `@mcp-abap-adt/auth-stores` 5 one `<destination>.env` file can hold a destination whole,
|
|
987
1016
|
each store reading and writing only its own keys — the means through `EnvDestinationStore`, the
|
|
988
1017
|
secret through `AbapSessionStore` (or both in separate directories, as you compose them):
|
|
989
1018
|
|
|
@@ -1171,7 +1200,7 @@ What a 4.x consumer must now do, row by row. The full list of changes is the
|
|
|
1171
1200
|
|
|
1172
1201
|
| 4.x | 5.0.0 — what to do |
|
|
1173
1202
|
|---|---|
|
|
1174
|
-
| `@mcp-abap-adt/auth-providers` 5, `interfaces-auth` 3, `auth-stores` 3 | auth-providers `^6.0.0`, interfaces-auth `^7.5.0`, auth-errors `^2.1.1`, auth-stores `^4.0.0
|
|
1203
|
+
| `@mcp-abap-adt/auth-providers` 5, `interfaces-auth` 3, `auth-stores` 3 | auth-providers `^6.0.0`, interfaces-auth `^7.5.0`, auth-errors `^2.1.1`, auth-stores `^4.0.0` (`^5.0.0` from 5.0.4, the first published since 5.0.1: a session record without binding keys is refused, see *Errors*); one installed copy of each contract (`npm ls`) |
|
|
1175
1204
|
| token rows renewed by the provider's built-in rule | pass `renewal: () => refreshThenLogin()` — 4.x's steps; without `renewal` a token row is refused (`missingFields: ['renewal']`) |
|
|
1176
1205
|
| a `getProvider` provider's failed write never failed the authentication; the token API threw the store's error | pass `onWriteFailure`: `'continue'` keeps 4.x's connector behaviour (best effort); `'fail'` keeps 4.x's token-API behaviour and extends it to the connector and to every later call of the destination while the write is pending. Without it a destination that writes a secret is refused |
|
|
1177
1206
|
| errors of the token API: auth-providers 5.x classes (`ValidationError`, `BrowserAuthError`, `RefreshError`, …) | `AuthProviderFailure`: read it with `readFailure(error, operation)` and `matchKind` (auth-errors); auth-providers' *Migrating to 6.0.0* maps each class to its kind |
|
|
@@ -1215,7 +1244,7 @@ npm test -w @mcp-abap-adt/auth-broker -- AuthBroker.test.ts -t "name of the case
|
|
|
1215
1244
|
```
|
|
1216
1245
|
|
|
1217
1246
|
Tests run sequentially (`maxWorkers: 1`, `maxConcurrency: 1`). The broker suites need nothing:
|
|
1218
|
-
fake stores of the contract or auth-stores
|
|
1247
|
+
fake stores of the contract or auth-stores 5 in temporary directories, real providers, a token
|
|
1219
1248
|
endpoint the test starts on `127.0.0.1`. `AuthBroker.integration.test.ts` reads real service
|
|
1220
1249
|
keys and sessions only when `packages/auth-broker/tests/test-config.yaml` exists (from the
|
|
1221
1250
|
template beside it); without it every case returns at once. The stand (`npm run test:stand`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/auth-broker",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.5",
|
|
4
4
|
"description": "Per-destination credential broker for SAP BTP and ABAP: the IAuthProvider a destination states, built from its key store and session store, with every secret it obtains stored back; and a token API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@mcp-abap-adt/auth-mocks": "^0.4.0",
|
|
68
|
-
"@mcp-abap-adt/auth-stores": "^
|
|
69
|
-
"@mcp-abap-adt/connection": "^
|
|
68
|
+
"@mcp-abap-adt/auth-stores": "^5.0.0",
|
|
69
|
+
"@mcp-abap-adt/connection": "^15.0.0",
|
|
70
70
|
"@mcp-abap-adt/logger": "^0.4.0",
|
|
71
71
|
"@types/js-yaml": "^4.0.9",
|
|
72
72
|
"js-yaml": "^4.1.1",
|