@mcp-abap-adt/auth-broker 0.2.7 → 0.2.9

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,31 @@ Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the co
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.2.9] - 2025-12-21
15
+
16
+ ### Added
17
+ - **`createTokenRefresher()` Method**: New factory method to create `ITokenRefresher` for dependency injection
18
+ - Returns `ITokenRefresher` implementation for a specific destination
19
+ - `getToken()` - returns cached token if valid, otherwise refreshes
20
+ - `refreshToken()` - forces token refresh and saves to session store
21
+ - Designed to be injected into `JwtAbapConnection` via DI
22
+ - Enables connections to handle 401/403 transparently without knowing auth internals
23
+
24
+ ### Changed
25
+ - **Dependencies**: Updated `@mcp-abap-adt/interfaces` to `^0.2.5`
26
+ - New `ITokenRefresher` interface for token management DI
27
+ - Simplified `IAbapConnection` interface (consumer-facing methods only)
28
+
29
+ ### Exports
30
+ - Re-export `ITokenRefresher` type from `@mcp-abap-adt/interfaces` for convenience
31
+
32
+ ## [0.2.8] - 2025-12-21
33
+
34
+ ### Changed
35
+ - **Dependencies**: Updated `@mcp-abap-adt/auth-stores` to `^0.2.8`
36
+ - EnvFileSessionStore now persists JWT tokens back to .env file after token refresh
37
+ - Removed duplicate BTP stores (now aliases to XSUAA equivalents)
38
+
14
39
  ## [0.2.7] - 2025-12-21
15
40
 
16
41
  ### Added
package/README.md CHANGED
@@ -110,6 +110,38 @@ const token = await broker.getToken('TRIAL');
110
110
  const newToken = await broker.refreshToken('TRIAL');
111
111
  ```
112
112
 
113
+ ### Creating Token Refresher for DI
114
+
115
+ The `createTokenRefresher()` method creates an `ITokenRefresher` implementation that can be injected into connections. This enables connections to handle token refresh transparently without knowing about authentication internals.
116
+
117
+ ```typescript
118
+ import { AuthBroker } from '@mcp-abap-adt/auth-broker';
119
+ import { JwtAbapConnection } from '@mcp-abap-adt/connection';
120
+
121
+ // Create broker
122
+ const broker = new AuthBroker({
123
+ sessionStore: mySessionStore,
124
+ serviceKeyStore: myServiceKeyStore,
125
+ tokenProvider: myTokenProvider,
126
+ });
127
+
128
+ // Create token refresher for specific destination
129
+ const tokenRefresher = broker.createTokenRefresher('TRIAL');
130
+
131
+ // Inject into connection (connection can handle 401/403 automatically)
132
+ const connection = new JwtAbapConnection(config, tokenRefresher);
133
+
134
+ // Token refresher methods:
135
+ // - getToken(): Returns cached token if valid, otherwise refreshes
136
+ // - refreshToken(): Forces token refresh and saves to session store
137
+ ```
138
+
139
+ **Benefits of Token Refresher:**
140
+ - 🔄 **Transparent Refresh**: Connection handles 401/403 errors automatically
141
+ - 🧩 **Dependency Injection**: Clean separation of concerns
142
+ - 💾 **Automatic Persistence**: Tokens saved to session store after refresh
143
+ - 🎯 **Destination-Scoped**: Each refresher is bound to specific destination
144
+
113
145
  ## Configuration
114
146
 
115
147
  ### Environment Variables
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Main AuthBroker class for managing JWT tokens based on destinations
3
3
  */
4
- import { ILogger } from '@mcp-abap-adt/interfaces';
4
+ import { ILogger, ITokenRefresher } from '@mcp-abap-adt/interfaces';
5
5
  import { IServiceKeyStore, ISessionStore, IAuthorizationConfig, IConnectionConfig } from './stores/interfaces';
6
6
  import { ITokenProvider } from './providers';
7
7
  /**
@@ -104,5 +104,23 @@ export declare class AuthBroker {
104
104
  * @returns Promise that resolves to IConnectionConfig or null if not found
105
105
  */
106
106
  getConnectionConfig(destination: string): Promise<IConnectionConfig | null>;
107
+ /**
108
+ * Create a token refresher for a specific destination.
109
+ *
110
+ * The token refresher is designed to be injected into JwtAbapConnection via DI,
111
+ * allowing the connection to handle token refresh transparently without knowing
112
+ * about authentication internals.
113
+ *
114
+ * **Usage:**
115
+ * ```typescript
116
+ * const broker = new AuthBroker(config);
117
+ * const tokenRefresher = broker.createTokenRefresher('TRIAL');
118
+ * const connection = new JwtAbapConnection(config, tokenRefresher);
119
+ * ```
120
+ *
121
+ * @param destination Destination name (e.g., "TRIAL")
122
+ * @returns ITokenRefresher implementation for the given destination
123
+ */
124
+ createTokenRefresher(destination: string): ITokenRefresher;
107
125
  }
108
126
  //# sourceMappingURL=AuthBroker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAA8C,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAa7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,YAAY,EAAE,aAAa,CAAC;IAC5B,uEAAuE;IACvE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,4IAA4I;IAC5I,aAAa,EAAE,cAAc,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAAU;IAElC;;;;;;;;;;;OAWG;gBAED,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO;IAuElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgYpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOxD;;;;OAIG;IACG,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA4CvF;;;;OAIG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CA0ClF"}
1
+ {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAA8C,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChH,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAa7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,YAAY,EAAE,aAAa,CAAC;IAC5B,uEAAuE;IACvE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,4IAA4I;IAC5I,aAAa,EAAE,cAAc,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAAU;IAElC;;;;;;;;;;;OAWG;gBAED,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO;IAuElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgYpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOxD;;;;OAIG;IACG,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA4CvF;;;;OAIG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IA0CjF;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe;CAsB3D"}
@@ -608,5 +608,41 @@ class AuthBroker {
608
608
  this.logger?.debug(`No connection config found for ${destination}`);
609
609
  return null;
610
610
  }
611
+ /**
612
+ * Create a token refresher for a specific destination.
613
+ *
614
+ * The token refresher is designed to be injected into JwtAbapConnection via DI,
615
+ * allowing the connection to handle token refresh transparently without knowing
616
+ * about authentication internals.
617
+ *
618
+ * **Usage:**
619
+ * ```typescript
620
+ * const broker = new AuthBroker(config);
621
+ * const tokenRefresher = broker.createTokenRefresher('TRIAL');
622
+ * const connection = new JwtAbapConnection(config, tokenRefresher);
623
+ * ```
624
+ *
625
+ * @param destination Destination name (e.g., "TRIAL")
626
+ * @returns ITokenRefresher implementation for the given destination
627
+ */
628
+ createTokenRefresher(destination) {
629
+ const broker = this;
630
+ return {
631
+ /**
632
+ * Get current valid token.
633
+ * Returns cached token if valid, otherwise refreshes and returns new token.
634
+ */
635
+ async getToken() {
636
+ return broker.getToken(destination);
637
+ },
638
+ /**
639
+ * Force refresh token and save to session store.
640
+ * Always performs refresh, ignoring cached token validity.
641
+ */
642
+ async refreshToken() {
643
+ return broker.refreshToken(destination);
644
+ }
645
+ };
646
+ }
611
647
  }
612
648
  exports.AuthBroker = AuthBroker;
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export { AuthBroker, type AuthBrokerConfig } from './AuthBroker';
6
6
  export type { IAuthorizationConfig, IConnectionConfig, IServiceKeyStore, ISessionStore } from './stores/interfaces';
7
7
  export type { IConfig } from './types';
8
8
  export type { ITokenProvider, TokenProviderOptions, TokenProviderResult } from './providers';
9
+ export type { ITokenRefresher } from '@mcp-abap-adt/interfaces';
9
10
  export type { ILogger } from '@mcp-abap-adt/interfaces';
10
11
  export type { AuthType } from '@mcp-abap-adt/interfaces';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGjE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpH,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE7F,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,YAAY,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGjE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpH,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE7F,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,YAAY,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/auth-broker",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "JWT authentication broker for MCP ABAP ADT - manages tokens based on destination headers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -51,17 +51,18 @@
51
51
  "node": ">=18.0.0"
52
52
  },
53
53
  "dependencies": {
54
- "@mcp-abap-adt/interfaces": "^0.2.4",
54
+ "@mcp-abap-adt/interfaces": "^0.2.5",
55
55
  "axios": "^1.13.2"
56
56
  },
57
57
  "devDependencies": {
58
- "@mcp-abap-adt/auth-providers": "^0.2.3",
59
- "@mcp-abap-adt/auth-stores": "^0.2.5",
58
+ "@mcp-abap-adt/auth-providers": "^0.2.4",
59
+ "@mcp-abap-adt/auth-stores": "^0.2.8",
60
60
  "@types/express": "^5.0.5",
61
61
  "@types/jest": "^30.0.0",
62
62
  "@types/js-yaml": "^4.0.9",
63
63
  "@types/node": "^24.2.1",
64
64
  "jest": "^30.2.0",
65
+ "jest-util": "^30.2.0",
65
66
  "js-yaml": "^4.1.1",
66
67
  "ts-jest": "^29.2.5",
67
68
  "tsx": "^4.21.0",