@mcp-abap-adt/auth-broker 5.0.1 → 5.0.4
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 +57 -0
- package/README.md +36 -10
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,63 @@ 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.4] - 2026-10-12
|
|
13
|
+
|
|
14
|
+
The first published release after 5.0.1. The code is the same as 5.0.2 and 5.0.3, which were
|
|
15
|
+
tagged but not published. It is released together with auth-broker-cli 3.1.1, so that one
|
|
16
|
+
publish from the main checkout carries both. 5.0.2 (built and tested on auth-stores 5) and
|
|
17
|
+
5.0.3 (tests on connection 14.1.0, the README's connection note) arrive with 5.0.4.
|
|
18
|
+
|
|
19
|
+
## [5.0.3] - 2026-10-12
|
|
20
|
+
|
|
21
|
+
Development only; the published library is unchanged.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- The tests run on `@mcp-abap-adt/connection` 14.1.0 (a dev dependency, `^14.1.0`):
|
|
25
|
+
its `disconnect()` sends the session's logoff, so a connection the broker's
|
|
26
|
+
tests and live checks close no longer leaves its SAP session open until the
|
|
27
|
+
server's timeout. The connection is the consumer's; the broker does not
|
|
28
|
+
depend on it.
|
|
29
|
+
- README: a consumer should use `@mcp-abap-adt/connection` 14.1.0 or later. From
|
|
30
|
+
14.1.0, `disconnect()` ends the SAP session.
|
|
31
|
+
|
|
32
|
+
## [5.0.2] - 2026-10-11
|
|
33
|
+
|
|
34
|
+
Built and tested on `@mcp-abap-adt/auth-stores` 5.0.0; the code is the same as
|
|
35
|
+
5.0.1. auth-stores is not a dependency of the library: the consumer composes
|
|
36
|
+
the stores, and 5.0.2 works with auth-stores 4 or 5 alike.
|
|
37
|
+
|
|
38
|
+
### Migration (for a consumer moving to auth-stores 5)
|
|
39
|
+
|
|
40
|
+
- **A session file with no binding keys beside its credential** — written by
|
|
41
|
+
auth-stores 2.x/3.0.0, auth-broker 3.x, or by hand — is no longer composed a
|
|
42
|
+
binding by the store and read as unbound (one login). auth-stores 5 refuses
|
|
43
|
+
the record whole with a `StorageError` (`code: 'STORAGE_ERROR'`,
|
|
44
|
+
`reason: 'record-format'`, fixed words, no value of the record), and the
|
|
45
|
+
broker passes it unchanged to the caller of `getProvider` and the token API
|
|
46
|
+
(every row that reads the session; the broker's own `client_credentials`
|
|
47
|
+
reads none, and its new credential replaces the record). This is 5.0.0's
|
|
48
|
+
rule that a store's read failure other than `FILE_NOT_FOUND` reaches the
|
|
49
|
+
caller, not a change of the broker.
|
|
50
|
+
- **What to do:** regenerate the session with
|
|
51
|
+
`mcp-auth --service-key <key.json> --output <file> --type abap|xsuaa`, or
|
|
52
|
+
remove its session lines; a file holding only the means is no session.
|
|
53
|
+
`@mcp-abap-adt/auth-broker-cli` 3.1.0 (released together) does it for you:
|
|
54
|
+
`mcp-auth --env <file>` or `--destination <name>` over such a file discards
|
|
55
|
+
its session and logs in anew, the means kept byte for byte.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- Dev dependency `@mcp-abap-adt/auth-stores` ^5.0.0.
|
|
59
|
+
- Tests: a pre-3.1.0 session file, and a 4.x token beside `issuedFor` alone,
|
|
60
|
+
now assert the store's `record-format` error reaching the caller — no
|
|
61
|
+
request, no login, no write, the file byte for byte, no record value in the
|
|
62
|
+
error or the log — where they asserted a login over a composed binding.
|
|
63
|
+
|
|
64
|
+
### Documentation
|
|
65
|
+
- README (*Errors*, *A Credential Stays Bound to Its Identity*, the upgrade
|
|
66
|
+
note), `docs/` and `CLAUDE.md` describe the record-format refusal and name
|
|
67
|
+
auth-stores 5.
|
|
68
|
+
|
|
12
69
|
## [5.0.1] - 2026-10-09
|
|
13
70
|
|
|
14
71
|
Development only; the code is the same as 5.0.0.
|
package/README.md
CHANGED
|
@@ -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.4 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 —
|
|
@@ -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;;;;;;;;;;;;' }
|
|
@@ -829,6 +845,10 @@ const renewed = await tokenRefresher.refreshToken();
|
|
|
829
845
|
A `@mcp-abap-adt/connection` 14 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
|
+
|
|
832
852
|
## Errors
|
|
833
853
|
|
|
834
854
|
**A provider's failure passes as the same object.** Whatever a provider throws from
|
|
@@ -930,7 +950,13 @@ needs a clientAuthentication strategy`.
|
|
|
930
950
|
|
|
931
951
|
- **A store's read failure** (anything but `FILE_NOT_FOUND`, which is absence) reaches the
|
|
932
952
|
caller as the store raised it — your collaborator's error, returned to you, also through the
|
|
933
|
-
shared resolution.
|
|
953
|
+
shared resolution. With auth-stores 5 that includes a session record not of the store's
|
|
954
|
+
format: a `StorageError` with `code: 'STORAGE_ERROR'` and `reason: 'record-format'`, in the
|
|
955
|
+
store's fixed words (`AbapSessionStore: the stored session for "<destination>" is not in this
|
|
956
|
+
store's format; regenerate it with mcp-auth`) — no value of the record. Regenerate the session
|
|
957
|
+
(`mcp-auth --service-key <key.json> --output <file>`, or from auth-broker-cli 3.1.1
|
|
958
|
+
`mcp-auth --env <file>`, which discards the refused session and logs in anew), or remove its
|
|
959
|
+
session lines. A store that answers `null`, or fails with `FILE_NOT_FOUND` (logged at
|
|
934
960
|
debug), means "nothing here".
|
|
935
961
|
- **The constructor's argument checks** (`AuthBroker: sessionStore is required`, …) are plain
|
|
936
962
|
`Error`s naming option names: a programming error.
|
|
@@ -983,7 +1009,7 @@ its level from `AUTH_LOG_LEVEL`.)
|
|
|
983
1009
|
|
|
984
1010
|
### File Structure
|
|
985
1011
|
|
|
986
|
-
With `@mcp-abap-adt/auth-stores`
|
|
1012
|
+
With `@mcp-abap-adt/auth-stores` 5 one `<destination>.env` file can hold a destination whole,
|
|
987
1013
|
each store reading and writing only its own keys — the means through `EnvDestinationStore`, the
|
|
988
1014
|
secret through `AbapSessionStore` (or both in separate directories, as you compose them):
|
|
989
1015
|
|
|
@@ -1171,7 +1197,7 @@ What a 4.x consumer must now do, row by row. The full list of changes is the
|
|
|
1171
1197
|
|
|
1172
1198
|
| 4.x | 5.0.0 — what to do |
|
|
1173
1199
|
|---|---|
|
|
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
|
|
1200
|
+
| `@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
1201
|
| 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
1202
|
| 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
1203
|
| 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 +1241,7 @@ npm test -w @mcp-abap-adt/auth-broker -- AuthBroker.test.ts -t "name of the case
|
|
|
1215
1241
|
```
|
|
1216
1242
|
|
|
1217
1243
|
Tests run sequentially (`maxWorkers: 1`, `maxConcurrency: 1`). The broker suites need nothing:
|
|
1218
|
-
fake stores of the contract or auth-stores
|
|
1244
|
+
fake stores of the contract or auth-stores 5 in temporary directories, real providers, a token
|
|
1219
1245
|
endpoint the test starts on `127.0.0.1`. `AuthBroker.integration.test.ts` reads real service
|
|
1220
1246
|
keys and sessions only when `packages/auth-broker/tests/test-config.yaml` exists (from the
|
|
1221
1247
|
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.4",
|
|
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": "^14.
|
|
68
|
+
"@mcp-abap-adt/auth-stores": "^5.0.0",
|
|
69
|
+
"@mcp-abap-adt/connection": "^14.1.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",
|