@mcp-abap-adt/auth-broker 3.0.0 → 3.0.1

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
@@ -11,6 +11,27 @@ Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the co
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [3.0.1] - 2026-09-26
15
+
16
+ ### Fixed
17
+
18
+ - **A store failure other than a missing file reaches the caller as raised.**
19
+ The broker answered every store error as absence — logged, then `null` — so
20
+ a service key that is there but not valid JSON, or a file the process may
21
+ not read, surfaced only as its consequence: "Session for destination … is
22
+ missing required field 'serviceUrl'", which sends users to create a file
23
+ that already exists. Absence is still `null` or `FILE_NOT_FOUND`, and the
24
+ flow goes on to the next source; anything else is thrown unchanged — before
25
+ the provider is asked when it comes from the reads that precede the token,
26
+ and after the provider answered and the token was written when it comes
27
+ from the reads that save the refresh token.
28
+
29
+ Measured on auth-stores 1.2.3: the service key stores throw on an invalid or
30
+ unreadable file (`Invalid JSON in file …`, `EACCES`), so this change is what
31
+ a broker user sees. The session stores answer an unreadable or unparsable
32
+ file with `null` themselves; that is theirs to change, and this release does
33
+ not see it.
34
+
14
35
  ## [3.0.0] - 2026-09-26
15
36
 
16
37
  ### Security
package/README.md CHANGED
@@ -513,13 +513,20 @@ The session's configuration, else the service key's, else `null`.
513
513
 
514
514
  - **Provider errors propagate unchanged** — the same object, with its class,
515
515
  `code`, `missingFields` and `cause`: auth-providers' `ValidationError`,
516
- `RefreshError`, `AssertionValidationError`, network errors (`ECONNREFUSED`,
516
+ `BrowserAuthError`, `AssertionValidationError`, network errors (`ECONNREFUSED`,
517
517
  `ETIMEDOUT`, `ENOTFOUND`), and whatever your authorization strategy throws.
518
518
  The broker does not retry a failed call.
519
- - **Store reads do not stop the flow**: a missing (`FILE_NOT_FOUND`, logged at
520
- debug) or unreadable entry (logged as a warning) is treated as absent, and
521
- whatever needed it fails later with its own message — for instance the
522
- missing `serviceUrl`.
519
+ - **Store reads: absence is an answer, a failure is not.** A store that answers
520
+ `null`, or fails with `FILE_NOT_FOUND` (logged at debug), means "nothing
521
+ here", and the broker goes on to the next source. Any other store failure —
522
+ a service key that is not valid JSON, a file the process may not read — is
523
+ thrown unchanged. A failure in the reads that come before the token (the
524
+ session's connection config, the service key) stops the call before the
525
+ provider is asked; one in the reads that save it (the session's
526
+ authorization config, the session) arrives after the provider answered and
527
+ the new token was written. (The session stores of
528
+ auth-stores answer an unreadable session file with `null` themselves, so it
529
+ reads as absent before the broker sees it.)
523
530
  - **Store writes propagate**: a token that cannot be saved is an error.
524
531
  - **A provider result without a token** is an error.
525
532
 
@@ -89,9 +89,15 @@ export declare class AuthBroker {
89
89
  */
90
90
  private persist;
91
91
  /**
92
- * A store read that does not stop the flow: a missing or unreadable entry is
93
- * logged and answered as absent, and whatever needed it fails with its own
94
- * message later.
92
+ * A store read where absence is an answer and anything else is not.
93
+ *
94
+ * A store says "nothing here" with `null`, or with `FILE_NOT_FOUND`, and the
95
+ * flow goes on to the next source. Any other failure — a service key that is
96
+ * not valid JSON, a file the process may not read — is a different problem
97
+ * with a different fix, and reaches the caller as the store raised it. It
98
+ * used to be logged and answered as absent, so the caller saw only the
99
+ * consequence ("missing required field 'serviceUrl'") and went looking for a
100
+ * file that was there.
95
101
  */
96
102
  private read;
97
103
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EAEhB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EACV,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAS7B;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,oBAAoB,GAAG,IAAI,EACvC,UAAU,EAAE,iBAAiB,KAC1B,yBAAyB,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,YAAY,EAAE,aAAa,CAAC;IAC5B,yEAAyE;IACzE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,EAAE,yBAAyB,GAAG,oBAAoB,CAAC;CAC5D;AAcD;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA+B;IAC/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmD;IAC5E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAE1E;;;OAGG;gBACS,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,OAAO;IA2DtD;;;;;;OAMG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpD;;;;OAIG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAI1C,MAAM;YA2BN,WAAW;IA4BzB;;;;;;OAMG;YACW,0BAA0B;YAiC1B,iBAAiB;IAuB/B;;;;;;;OAOG;YACW,OAAO;IAoDrB;;;;OAIG;YACW,IAAI;IAoBlB;;;OAGG;IACG,sBAAsB,CAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAkBvC;;;OAGG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAkBpC;;;;OAIG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe;CAM3D"}
1
+ {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EAEhB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EACV,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAS7B;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,oBAAoB,GAAG,IAAI,EACvC,UAAU,EAAE,iBAAiB,KAC1B,yBAAyB,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,YAAY,EAAE,aAAa,CAAC;IAC5B,yEAAyE;IACzE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,EAAE,yBAAyB,GAAG,oBAAoB,CAAC;CAC5D;AAUD;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA+B;IAC/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmD;IAC5E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAE1E;;;OAGG;gBACS,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,OAAO;IA2DtD;;;;;;OAMG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpD;;;;OAIG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAI1C,MAAM;YA2BN,WAAW;IA4BzB;;;;;;OAMG;YACW,0BAA0B;YAiC1B,iBAAiB;IAuB/B;;;;;;;OAOG;YACW,OAAO;IAoDrB;;;;;;;;;;OAUG;YACW,IAAI;IAgBlB;;;OAGG;IACG,sBAAsB,CAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAkBvC;;;OAGG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAkBpC;;;;OAIG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe;CAM3D"}
@@ -18,9 +18,6 @@ const noOpLogger = {
18
18
  warn: () => { },
19
19
  debug: () => { },
20
20
  };
21
- function errorMessage(error) {
22
- return error instanceof Error ? error.message : String(error);
23
- }
24
21
  function errorCode(error) {
25
22
  if (error !== null && typeof error === 'object' && 'code' in error) {
26
23
  const code = error.code;
@@ -232,23 +229,26 @@ class AuthBroker {
232
229
  });
233
230
  }
234
231
  /**
235
- * A store read that does not stop the flow: a missing or unreadable entry is
236
- * logged and answered as absent, and whatever needed it fails with its own
237
- * message later.
232
+ * A store read where absence is an answer and anything else is not.
233
+ *
234
+ * A store says "nothing here" with `null`, or with `FILE_NOT_FOUND`, and the
235
+ * flow goes on to the next source. Any other failure — a service key that is
236
+ * not valid JSON, a file the process may not read — is a different problem
237
+ * with a different fix, and reaches the caller as the store raised it. It
238
+ * used to be logged and answered as absent, so the caller saw only the
239
+ * consequence ("missing required field 'serviceUrl'") and went looking for a
240
+ * file that was there.
238
241
  */
239
242
  async read(destination, what, fn) {
240
243
  try {
241
244
  return await fn();
242
245
  }
243
246
  catch (error) {
244
- const code = errorCode(error);
245
- if (code === interfaces_auth_1.STORE_ERROR_CODES.FILE_NOT_FOUND) {
247
+ if (errorCode(error) === interfaces_auth_1.STORE_ERROR_CODES.FILE_NOT_FOUND) {
246
248
  this.logger.debug(`No ${what} for ${destination}: file not found`);
249
+ return null;
247
250
  }
248
- else {
249
- this.logger.warn(`Failed to read ${what} for ${destination}: ${errorMessage(error)}`);
250
- }
251
- return null;
251
+ throw error;
252
252
  }
253
253
  }
254
254
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/auth-broker",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Per-destination token broker for SAP BTP and ABAP: sessions and service keys from stores, tokens from an injected provider, results persisted - plus the mcp-auth and mcp-sso CLIs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",