@mcp-abap-adt/auth-providers 1.0.0 → 1.0.2
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 +16 -0
- package/README.md +27 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/providers/CfPasscodeProvider.d.ts +27 -0
- package/dist/providers/CfPasscodeProvider.d.ts.map +1 -0
- package/dist/providers/CfPasscodeProvider.js +72 -0
- package/dist/providers/OidcBrowserProvider.d.ts +7 -1
- package/dist/providers/OidcBrowserProvider.d.ts.map +1 -1
- package/dist/providers/OidcBrowserProvider.js +60 -10
- package/dist/providers/OidcDeviceFlowProvider.d.ts +3 -1
- package/dist/providers/OidcDeviceFlowProvider.d.ts.map +1 -1
- package/dist/providers/OidcDeviceFlowProvider.js +38 -7
- package/dist/providers/OidcPasswordProvider.d.ts +2 -1
- package/dist/providers/OidcPasswordProvider.d.ts.map +1 -1
- package/dist/providers/OidcPasswordProvider.js +30 -4
- package/dist/providers/OidcTokenExchangeProvider.d.ts +2 -1
- package/dist/providers/OidcTokenExchangeProvider.d.ts.map +1 -1
- package/dist/providers/OidcTokenExchangeProvider.js +15 -2
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.2] - 2026-02-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- OIDC providers now support explicit endpoints (`authorizationEndpoint`, `tokenEndpoint`, `deviceAuthorizationEndpoint`) without discovery.
|
|
14
|
+
- OIDC browser flow supports manual authorization code input via `authorizationCode` / `authorizationCodeProvider`.
|
|
15
|
+
- OIDC browser flow supports custom `redirectUri` (required for manual code / OOB flows).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- OIDC provider configs accept optional `issuerUrl` when explicit endpoints are provided.
|
|
19
|
+
- Dependency updates: `axios` ^1.13.5, `@biomejs/biome` ^2.3.14, `@mcp-abap-adt/auth-stores` ^1.0.1, `@types/node` ^25.2.3, `pino` ^10.3.1.
|
|
20
|
+
|
|
10
21
|
## [1.0.0] - 2026-02-10
|
|
11
22
|
|
|
12
23
|
### Added
|
|
@@ -15,6 +26,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
26
|
- SAML2 flows: browser/manual/assertion input, bearer exchange, and pure SAML (cookie-based) output.
|
|
16
27
|
- `BaseTokenProvider` now supports `tokenType` and `expiresAt` from `ITokenResult`.
|
|
17
28
|
|
|
29
|
+
## [1.0.1] - 2026-02-10
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- GitHub Actions CI workflow (build + test on push/PR).
|
|
33
|
+
|
|
18
34
|
## [0.2.10] - 2025-12-25
|
|
19
35
|
|
|
20
36
|
### Changed
|
package/README.md
CHANGED
|
@@ -108,6 +108,7 @@ Available providers:
|
|
|
108
108
|
- `OidcDeviceFlowProvider`
|
|
109
109
|
- `OidcPasswordProvider`
|
|
110
110
|
- `OidcTokenExchangeProvider`
|
|
111
|
+
- `CfPasscodeProvider` (Cloud Foundry SSO passcode)
|
|
111
112
|
- `Saml2BearerProvider` (SAML assertion exchange)
|
|
112
113
|
- `Saml2PureProvider` (returns SAMLResponse as token)
|
|
113
114
|
|
|
@@ -132,6 +133,32 @@ const tokenProvider = SsoProviderFactory.create({
|
|
|
132
133
|
const broker = new AuthBroker({ tokenProvider }, 'none');
|
|
133
134
|
```
|
|
134
135
|
|
|
136
|
+
OIDC browser example (manual code + explicit endpoints):
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { OidcBrowserProvider } from '@mcp-abap-adt/auth-providers';
|
|
140
|
+
|
|
141
|
+
const provider = new OidcBrowserProvider({
|
|
142
|
+
clientId: '...',
|
|
143
|
+
tokenEndpoint: 'https://issuer/oauth/token',
|
|
144
|
+
authorizationEndpoint: 'https://issuer/oauth/authorize',
|
|
145
|
+
authorizationCode: '<paste-code-here>',
|
|
146
|
+
redirectUri: 'urn:ietf:wg:oauth:2.0:oob',
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Cloud Foundry passcode example:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { CfPasscodeProvider } from '@mcp-abap-adt/auth-providers';
|
|
154
|
+
|
|
155
|
+
const provider = new CfPasscodeProvider({
|
|
156
|
+
uaaUrl: 'https://uaa.cf.example.com',
|
|
157
|
+
clientId: 'cf',
|
|
158
|
+
passcode: '<paste-passcode-here>',
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
135
162
|
SAML bearer example (manual flow):
|
|
136
163
|
|
|
137
164
|
```typescript
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Provides token providers
|
|
6
6
|
*/
|
|
7
7
|
export { BrowserAuthError, RefreshError, ServiceKeyError, SessionDataError, TokenProviderError, ValidationError, } from './errors/TokenProviderErrors';
|
|
8
|
-
export type { AuthorizationCodeProviderConfig, ClientCredentialsProviderConfig, DeviceFlowProviderConfig, OidcBrowserProviderConfig, OidcDeviceFlowProviderConfig, OidcPasswordProviderConfig, OidcTokenExchangeProviderConfig, Saml2BearerProviderConfig, Saml2PureProviderConfig, } from './providers';
|
|
9
|
-
export { AuthorizationCodeProvider, BaseTokenProvider, ClientCredentialsProvider, DeviceFlowProvider, OidcBrowserProvider, OidcDeviceFlowProvider, OidcPasswordProvider, OidcTokenExchangeProvider, Saml2BearerProvider, Saml2PureProvider, } from './providers';
|
|
8
|
+
export type { AuthorizationCodeProviderConfig, CfPasscodeProviderConfig, ClientCredentialsProviderConfig, DeviceFlowProviderConfig, OidcBrowserProviderConfig, OidcDeviceFlowProviderConfig, OidcPasswordProviderConfig, OidcTokenExchangeProviderConfig, Saml2BearerProviderConfig, Saml2PureProviderConfig, } from './providers';
|
|
9
|
+
export { AuthorizationCodeProvider, BaseTokenProvider, CfPasscodeProvider, ClientCredentialsProvider, DeviceFlowProvider, OidcBrowserProvider, OidcDeviceFlowProvider, OidcPasswordProvider, OidcTokenExchangeProvider, Saml2BearerProvider, Saml2PureProvider, } from './providers';
|
|
10
10
|
export { SsoProviderFactory } from './sso/SsoProviderFactory';
|
|
11
11
|
export type { SsoProviderConfig, SsoProviderInstance } from './sso/types';
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GAChB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,+BAA+B,EAC/B,+BAA+B,EAC/B,wBAAwB,EACxB,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GAChB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,+BAA+B,EAC/B,wBAAwB,EACxB,+BAA+B,EAC/B,wBAAwB,EACxB,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Provides token providers
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.SsoProviderFactory = exports.Saml2PureProvider = exports.Saml2BearerProvider = exports.OidcTokenExchangeProvider = exports.OidcPasswordProvider = exports.OidcDeviceFlowProvider = exports.OidcBrowserProvider = exports.DeviceFlowProvider = exports.ClientCredentialsProvider = exports.BaseTokenProvider = exports.AuthorizationCodeProvider = exports.ValidationError = exports.TokenProviderError = exports.SessionDataError = exports.ServiceKeyError = exports.RefreshError = exports.BrowserAuthError = void 0;
|
|
9
|
+
exports.SsoProviderFactory = exports.Saml2PureProvider = exports.Saml2BearerProvider = exports.OidcTokenExchangeProvider = exports.OidcPasswordProvider = exports.OidcDeviceFlowProvider = exports.OidcBrowserProvider = exports.DeviceFlowProvider = exports.ClientCredentialsProvider = exports.CfPasscodeProvider = exports.BaseTokenProvider = exports.AuthorizationCodeProvider = exports.ValidationError = exports.TokenProviderError = exports.SessionDataError = exports.ServiceKeyError = exports.RefreshError = exports.BrowserAuthError = void 0;
|
|
10
10
|
// Errors
|
|
11
11
|
var TokenProviderErrors_1 = require("./errors/TokenProviderErrors");
|
|
12
12
|
Object.defineProperty(exports, "BrowserAuthError", { enumerable: true, get: function () { return TokenProviderErrors_1.BrowserAuthError; } });
|
|
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: funct
|
|
|
19
19
|
var providers_1 = require("./providers");
|
|
20
20
|
Object.defineProperty(exports, "AuthorizationCodeProvider", { enumerable: true, get: function () { return providers_1.AuthorizationCodeProvider; } });
|
|
21
21
|
Object.defineProperty(exports, "BaseTokenProvider", { enumerable: true, get: function () { return providers_1.BaseTokenProvider; } });
|
|
22
|
+
Object.defineProperty(exports, "CfPasscodeProvider", { enumerable: true, get: function () { return providers_1.CfPasscodeProvider; } });
|
|
22
23
|
Object.defineProperty(exports, "ClientCredentialsProvider", { enumerable: true, get: function () { return providers_1.ClientCredentialsProvider; } });
|
|
23
24
|
Object.defineProperty(exports, "DeviceFlowProvider", { enumerable: true, get: function () { return providers_1.DeviceFlowProvider; } });
|
|
24
25
|
Object.defineProperty(exports, "OidcBrowserProvider", { enumerable: true, get: function () { return providers_1.OidcBrowserProvider; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CF Passcode (SSO) Provider
|
|
3
|
+
*/
|
|
4
|
+
import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
|
|
5
|
+
import { BaseTokenProvider } from './BaseTokenProvider';
|
|
6
|
+
export interface CfPasscodeProviderConfig {
|
|
7
|
+
uaaUrl: string;
|
|
8
|
+
clientId: string;
|
|
9
|
+
clientSecret?: string;
|
|
10
|
+
passcode?: string;
|
|
11
|
+
passcodeProvider?: () => Promise<string>;
|
|
12
|
+
username?: string;
|
|
13
|
+
scope?: string;
|
|
14
|
+
accessToken?: string;
|
|
15
|
+
refreshToken?: string;
|
|
16
|
+
logger?: ILogger;
|
|
17
|
+
}
|
|
18
|
+
export declare class CfPasscodeProvider extends BaseTokenProvider {
|
|
19
|
+
private config;
|
|
20
|
+
constructor(config: CfPasscodeProviderConfig);
|
|
21
|
+
protected getAuthType(): OAuth2GrantType;
|
|
22
|
+
protected performLogin(): Promise<ITokenResult>;
|
|
23
|
+
protected performRefresh(): Promise<ITokenResult>;
|
|
24
|
+
private buildTokenEndpoint;
|
|
25
|
+
private resolvePasscode;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=CfPasscodeProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CfPasscodeProvider.d.ts","sourceRoot":"","sources":["../../src/providers/CfPasscodeProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,kBAAmB,SAAQ,iBAAiB;IACvD,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,EAAE,wBAAwB;IAc5C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAwBrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;IAuBvD,OAAO,CAAC,kBAAkB;YAKZ,eAAe;CAa9B"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CF Passcode (SSO) Provider
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CfPasscodeProvider = void 0;
|
|
7
|
+
const interfaces_1 = require("@mcp-abap-adt/interfaces");
|
|
8
|
+
const oidcToken_1 = require("../auth/oidcToken");
|
|
9
|
+
const BaseTokenProvider_1 = require("./BaseTokenProvider");
|
|
10
|
+
class CfPasscodeProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super();
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.logger = config.logger;
|
|
16
|
+
if (config.accessToken) {
|
|
17
|
+
this.authorizationToken = config.accessToken;
|
|
18
|
+
this.expiresAt = this.parseExpirationFromJWT(config.accessToken);
|
|
19
|
+
}
|
|
20
|
+
if (config.refreshToken) {
|
|
21
|
+
this.refreshToken = config.refreshToken;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
getAuthType() {
|
|
25
|
+
return interfaces_1.AUTH_TYPE_PASSWORD;
|
|
26
|
+
}
|
|
27
|
+
async performLogin() {
|
|
28
|
+
const passcode = await this.resolvePasscode();
|
|
29
|
+
const tokenEndpoint = this.buildTokenEndpoint();
|
|
30
|
+
const username = this.config.username || 'passcode';
|
|
31
|
+
const tokens = await (0, oidcToken_1.passwordGrant)(tokenEndpoint, this.config.clientId, this.config.clientSecret, username, passcode, this.config.scope, this.logger);
|
|
32
|
+
return {
|
|
33
|
+
authorizationToken: tokens.accessToken,
|
|
34
|
+
refreshToken: tokens.refreshToken,
|
|
35
|
+
authType: interfaces_1.AUTH_TYPE_PASSWORD,
|
|
36
|
+
expiresIn: tokens.expiresIn,
|
|
37
|
+
tokenType: 'jwt',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async performRefresh() {
|
|
41
|
+
if (!this.refreshToken) {
|
|
42
|
+
return this.performLogin();
|
|
43
|
+
}
|
|
44
|
+
const tokenEndpoint = this.buildTokenEndpoint();
|
|
45
|
+
const tokens = await (0, oidcToken_1.refreshOidcToken)(tokenEndpoint, this.config.clientId, this.config.clientSecret, this.refreshToken, this.logger);
|
|
46
|
+
return {
|
|
47
|
+
authorizationToken: tokens.accessToken,
|
|
48
|
+
refreshToken: tokens.refreshToken || this.refreshToken,
|
|
49
|
+
authType: interfaces_1.AUTH_TYPE_PASSWORD,
|
|
50
|
+
expiresIn: tokens.expiresIn,
|
|
51
|
+
tokenType: 'jwt',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
buildTokenEndpoint() {
|
|
55
|
+
const base = this.config.uaaUrl.replace(/\/$/, '');
|
|
56
|
+
return `${base}/oauth/token`;
|
|
57
|
+
}
|
|
58
|
+
async resolvePasscode() {
|
|
59
|
+
if (this.config.passcode) {
|
|
60
|
+
return this.config.passcode;
|
|
61
|
+
}
|
|
62
|
+
if (this.config.passcodeProvider) {
|
|
63
|
+
const code = await this.config.passcodeProvider();
|
|
64
|
+
if (!code) {
|
|
65
|
+
throw new Error('Passcode provider returned empty value');
|
|
66
|
+
}
|
|
67
|
+
return code;
|
|
68
|
+
}
|
|
69
|
+
throw new Error('Passcode is required for CF SSO flow');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.CfPasscodeProvider = CfPasscodeProvider;
|
|
@@ -4,12 +4,17 @@
|
|
|
4
4
|
import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
|
|
5
5
|
import { BaseTokenProvider } from './BaseTokenProvider';
|
|
6
6
|
export interface OidcBrowserProviderConfig {
|
|
7
|
-
issuerUrl
|
|
7
|
+
issuerUrl?: string;
|
|
8
8
|
clientId: string;
|
|
9
9
|
clientSecret?: string;
|
|
10
10
|
scopes?: string[];
|
|
11
11
|
browser?: string;
|
|
12
12
|
redirectPort?: number;
|
|
13
|
+
redirectUri?: string;
|
|
14
|
+
authorizationCode?: string;
|
|
15
|
+
authorizationCodeProvider?: () => Promise<string>;
|
|
16
|
+
authorizationEndpoint?: string;
|
|
17
|
+
tokenEndpoint?: string;
|
|
13
18
|
accessToken?: string;
|
|
14
19
|
refreshToken?: string;
|
|
15
20
|
logger?: ILogger;
|
|
@@ -20,5 +25,6 @@ export declare class OidcBrowserProvider extends BaseTokenProvider {
|
|
|
20
25
|
protected getAuthType(): OAuth2GrantType;
|
|
21
26
|
protected performLogin(): Promise<ITokenResult>;
|
|
22
27
|
protected performRefresh(): Promise<ITokenResult>;
|
|
28
|
+
private resolveAuthorizationCode;
|
|
23
29
|
}
|
|
24
30
|
//# sourceMappingURL=OidcBrowserProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcBrowserProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcBrowserProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"OidcBrowserProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcBrowserProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,OAAO,CAAC,MAAM,CAA4B;gBAE9B,MAAM,EAAE,yBAAyB;IAc7C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAsFrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;YAoCzC,wBAAwB;CA8BvC"}
|
|
@@ -28,12 +28,33 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
28
28
|
return interfaces_1.AUTH_TYPE_AUTHORIZATION_CODE_PKCE;
|
|
29
29
|
}
|
|
30
30
|
async performLogin() {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const needsAuthorizationEndpoint = !this.config.authorizationCode && !this.config.authorizationCodeProvider;
|
|
32
|
+
const requiresDiscovery = (needsAuthorizationEndpoint && !this.config.authorizationEndpoint) ||
|
|
33
|
+
!this.config.tokenEndpoint;
|
|
34
|
+
let discovery = null;
|
|
35
|
+
if (requiresDiscovery) {
|
|
36
|
+
if (!this.config.issuerUrl) {
|
|
37
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
38
|
+
}
|
|
39
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
40
|
+
}
|
|
41
|
+
const authorizationEndpoint = needsAuthorizationEndpoint
|
|
42
|
+
? this.config.authorizationEndpoint || discovery?.authorization_endpoint
|
|
43
|
+
: undefined;
|
|
44
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
45
|
+
if (needsAuthorizationEndpoint && !authorizationEndpoint) {
|
|
46
|
+
throw new Error('OIDC authorization endpoint is required (authorizationEndpoint or discovery)');
|
|
47
|
+
}
|
|
48
|
+
if (!tokenEndpoint) {
|
|
49
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
34
50
|
}
|
|
35
51
|
const redirectPort = this.config.redirectPort || 3001;
|
|
36
|
-
const redirectUri = `http://localhost:${redirectPort}/callback`;
|
|
52
|
+
const redirectUri = this.config.redirectUri || `http://localhost:${redirectPort}/callback`;
|
|
53
|
+
if (needsAuthorizationEndpoint && this.config.redirectUri) {
|
|
54
|
+
if (!redirectUri.startsWith('http://localhost:')) {
|
|
55
|
+
throw new Error('OIDC redirectUri must be localhost for browser callback flow');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
37
58
|
const scope = (this.config.scopes && this.config.scopes.length > 0
|
|
38
59
|
? this.config.scopes
|
|
39
60
|
: ['openid', 'profile', 'email']).join(' ');
|
|
@@ -46,10 +67,11 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
46
67
|
params.append('scope', scope);
|
|
47
68
|
params.append('code_challenge', challenge);
|
|
48
69
|
params.append('code_challenge_method', 'S256');
|
|
49
|
-
const authorizationUrl =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
70
|
+
const authorizationUrl = needsAuthorizationEndpoint
|
|
71
|
+
? `${authorizationEndpoint}?${params.toString()}`
|
|
72
|
+
: undefined;
|
|
73
|
+
const code = await this.resolveAuthorizationCode(authorizationUrl, redirectPort);
|
|
74
|
+
const tokens = await (0, oidcToken_1.exchangeAuthorizationCode)(tokenEndpoint, this.config.clientId, this.config.clientSecret, code, redirectUri, verifier, this.logger);
|
|
53
75
|
return {
|
|
54
76
|
authorizationToken: tokens.accessToken,
|
|
55
77
|
refreshToken: tokens.refreshToken,
|
|
@@ -62,8 +84,18 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
62
84
|
if (!this.refreshToken) {
|
|
63
85
|
return this.performLogin();
|
|
64
86
|
}
|
|
65
|
-
|
|
66
|
-
|
|
87
|
+
let discovery = null;
|
|
88
|
+
if (this.config.tokenEndpoint === undefined) {
|
|
89
|
+
if (!this.config.issuerUrl) {
|
|
90
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
91
|
+
}
|
|
92
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
93
|
+
}
|
|
94
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
95
|
+
if (!tokenEndpoint) {
|
|
96
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
97
|
+
}
|
|
98
|
+
const tokens = await (0, oidcToken_1.refreshOidcToken)(tokenEndpoint, this.config.clientId, this.config.clientSecret, this.refreshToken, this.logger);
|
|
67
99
|
return {
|
|
68
100
|
authorizationToken: tokens.accessToken,
|
|
69
101
|
refreshToken: tokens.refreshToken || this.refreshToken,
|
|
@@ -72,5 +104,23 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
72
104
|
tokenType: 'jwt',
|
|
73
105
|
};
|
|
74
106
|
}
|
|
107
|
+
async resolveAuthorizationCode(authorizationUrl, redirectPort) {
|
|
108
|
+
if (this.config.authorizationCode) {
|
|
109
|
+
return this.config.authorizationCode;
|
|
110
|
+
}
|
|
111
|
+
if (this.config.authorizationCodeProvider) {
|
|
112
|
+
const code = await this.config.authorizationCodeProvider();
|
|
113
|
+
if (!code) {
|
|
114
|
+
throw new Error('Authorization code provider returned empty value');
|
|
115
|
+
}
|
|
116
|
+
return code;
|
|
117
|
+
}
|
|
118
|
+
if (!authorizationUrl) {
|
|
119
|
+
throw new Error('OIDC authorization URL is required when using browser flow');
|
|
120
|
+
}
|
|
121
|
+
const browser = this.config.browser || 'auto';
|
|
122
|
+
const { code } = await (0, oidcBrowserAuth_1.startOidcBrowserAuth)(authorizationUrl, browser, this.logger, redirectPort);
|
|
123
|
+
return code;
|
|
124
|
+
}
|
|
75
125
|
}
|
|
76
126
|
exports.OidcBrowserProvider = OidcBrowserProvider;
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
|
|
5
5
|
import { BaseTokenProvider } from './BaseTokenProvider';
|
|
6
6
|
export interface OidcDeviceFlowProviderConfig {
|
|
7
|
-
issuerUrl
|
|
7
|
+
issuerUrl?: string;
|
|
8
8
|
clientId: string;
|
|
9
9
|
clientSecret?: string;
|
|
10
10
|
scopes?: string[];
|
|
11
|
+
deviceAuthorizationEndpoint?: string;
|
|
12
|
+
tokenEndpoint?: string;
|
|
11
13
|
accessToken?: string;
|
|
12
14
|
refreshToken?: string;
|
|
13
15
|
logger?: ILogger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcDeviceFlowProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcDeviceFlowProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAQlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"OidcDeviceFlowProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcDeviceFlowProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAQlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,MAAM,CAA+B;gBAEjC,MAAM,EAAE,4BAA4B;IAchD,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAuErC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAqCxD"}
|
|
@@ -26,12 +26,30 @@ class OidcDeviceFlowProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
26
26
|
return interfaces_1.AUTH_TYPE_AUTHORIZATION_CODE;
|
|
27
27
|
}
|
|
28
28
|
async performLogin() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
if (!this.config.deviceAuthorizationEndpoint &&
|
|
30
|
+
!this.config.tokenEndpoint &&
|
|
31
|
+
!this.config.issuerUrl) {
|
|
32
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
33
|
+
}
|
|
34
|
+
let discovery = null;
|
|
35
|
+
if (!this.config.deviceAuthorizationEndpoint &&
|
|
36
|
+
!this.config.tokenEndpoint) {
|
|
37
|
+
if (!this.config.issuerUrl) {
|
|
38
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
39
|
+
}
|
|
40
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
41
|
+
}
|
|
42
|
+
const deviceAuthorizationEndpoint = this.config.deviceAuthorizationEndpoint ||
|
|
43
|
+
discovery?.device_authorization_endpoint;
|
|
44
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
45
|
+
if (!deviceAuthorizationEndpoint) {
|
|
46
|
+
throw new Error('OIDC device authorization endpoint is required (deviceAuthorizationEndpoint or discovery)');
|
|
47
|
+
}
|
|
48
|
+
if (!tokenEndpoint) {
|
|
49
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
32
50
|
}
|
|
33
51
|
const scope = this.config.scopes?.join(' ');
|
|
34
|
-
const deviceFlow = await (0, oidcToken_1.initiateDeviceAuthorization)(
|
|
52
|
+
const deviceFlow = await (0, oidcToken_1.initiateDeviceAuthorization)(deviceAuthorizationEndpoint, this.config.clientId, scope, this.logger);
|
|
35
53
|
// Manual user guidance
|
|
36
54
|
console.log('');
|
|
37
55
|
console.log('OIDC device authorization');
|
|
@@ -41,7 +59,7 @@ class OidcDeviceFlowProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
41
59
|
}
|
|
42
60
|
console.log('Enter code:', deviceFlow.userCode);
|
|
43
61
|
console.log('');
|
|
44
|
-
const tokens = await (0, oidcToken_1.pollDeviceTokens)(
|
|
62
|
+
const tokens = await (0, oidcToken_1.pollDeviceTokens)(tokenEndpoint, this.config.clientId, this.config.clientSecret, deviceFlow.deviceCode, deviceFlow.interval || 5, this.logger);
|
|
45
63
|
return {
|
|
46
64
|
authorizationToken: tokens.accessToken,
|
|
47
65
|
refreshToken: tokens.refreshToken,
|
|
@@ -54,8 +72,21 @@ class OidcDeviceFlowProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
54
72
|
if (!this.refreshToken) {
|
|
55
73
|
return this.performLogin();
|
|
56
74
|
}
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
if (!this.config.tokenEndpoint && !this.config.issuerUrl) {
|
|
76
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
77
|
+
}
|
|
78
|
+
let discovery = null;
|
|
79
|
+
if (this.config.tokenEndpoint === undefined) {
|
|
80
|
+
if (!this.config.issuerUrl) {
|
|
81
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
82
|
+
}
|
|
83
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
84
|
+
}
|
|
85
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
86
|
+
if (!tokenEndpoint) {
|
|
87
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
88
|
+
}
|
|
89
|
+
const tokens = await (0, oidcToken_1.refreshOidcToken)(tokenEndpoint, this.config.clientId, this.config.clientSecret, this.refreshToken, this.logger);
|
|
59
90
|
return {
|
|
60
91
|
authorizationToken: tokens.accessToken,
|
|
61
92
|
refreshToken: tokens.refreshToken || this.refreshToken,
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
|
|
5
5
|
import { BaseTokenProvider } from './BaseTokenProvider';
|
|
6
6
|
export interface OidcPasswordProviderConfig {
|
|
7
|
-
issuerUrl
|
|
7
|
+
issuerUrl?: string;
|
|
8
8
|
clientId: string;
|
|
9
9
|
clientSecret?: string;
|
|
10
10
|
username: string;
|
|
11
11
|
password: string;
|
|
12
12
|
scopes?: string[];
|
|
13
|
+
tokenEndpoint?: string;
|
|
13
14
|
accessToken?: string;
|
|
14
15
|
refreshToken?: string;
|
|
15
16
|
logger?: ILogger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcPasswordProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcPasswordProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"OidcPasswordProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcPasswordProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,oBAAqB,SAAQ,iBAAiB;IACzD,OAAO,CAAC,MAAM,CAA6B;gBAE/B,MAAM,EAAE,0BAA0B;IAc9C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAsCrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAsCxD"}
|
|
@@ -26,9 +26,22 @@ class OidcPasswordProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
26
26
|
return interfaces_1.AUTH_TYPE_PASSWORD;
|
|
27
27
|
}
|
|
28
28
|
async performLogin() {
|
|
29
|
-
|
|
29
|
+
if (!this.config.tokenEndpoint && !this.config.issuerUrl) {
|
|
30
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
31
|
+
}
|
|
32
|
+
let discovery = null;
|
|
33
|
+
if (this.config.tokenEndpoint === undefined) {
|
|
34
|
+
if (!this.config.issuerUrl) {
|
|
35
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
36
|
+
}
|
|
37
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
38
|
+
}
|
|
39
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
40
|
+
if (!tokenEndpoint) {
|
|
41
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
42
|
+
}
|
|
30
43
|
const scope = this.config.scopes?.join(' ');
|
|
31
|
-
const tokens = await (0, oidcToken_1.passwordGrant)(
|
|
44
|
+
const tokens = await (0, oidcToken_1.passwordGrant)(tokenEndpoint, this.config.clientId, this.config.clientSecret, this.config.username, this.config.password, scope, this.logger);
|
|
32
45
|
return {
|
|
33
46
|
authorizationToken: tokens.accessToken,
|
|
34
47
|
refreshToken: tokens.refreshToken,
|
|
@@ -41,8 +54,21 @@ class OidcPasswordProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
41
54
|
if (!this.refreshToken) {
|
|
42
55
|
return this.performLogin();
|
|
43
56
|
}
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
if (!this.config.tokenEndpoint && !this.config.issuerUrl) {
|
|
58
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
59
|
+
}
|
|
60
|
+
let discovery = null;
|
|
61
|
+
if (this.config.tokenEndpoint === undefined) {
|
|
62
|
+
if (!this.config.issuerUrl) {
|
|
63
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
64
|
+
}
|
|
65
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
66
|
+
}
|
|
67
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
68
|
+
if (!tokenEndpoint) {
|
|
69
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
70
|
+
}
|
|
71
|
+
const tokens = await (0, oidcToken_1.refreshOidcToken)(tokenEndpoint, this.config.clientId, this.config.clientSecret, this.refreshToken, this.logger);
|
|
46
72
|
return {
|
|
47
73
|
authorizationToken: tokens.accessToken,
|
|
48
74
|
refreshToken: tokens.refreshToken || this.refreshToken,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
|
|
5
5
|
import { BaseTokenProvider } from './BaseTokenProvider';
|
|
6
6
|
export interface OidcTokenExchangeProviderConfig {
|
|
7
|
-
issuerUrl
|
|
7
|
+
issuerUrl?: string;
|
|
8
8
|
clientId: string;
|
|
9
9
|
clientSecret?: string;
|
|
10
10
|
subjectToken: string;
|
|
@@ -13,6 +13,7 @@ export interface OidcTokenExchangeProviderConfig {
|
|
|
13
13
|
audience?: string;
|
|
14
14
|
actorToken?: string;
|
|
15
15
|
actorTokenType?: string;
|
|
16
|
+
tokenEndpoint?: string;
|
|
16
17
|
accessToken?: string;
|
|
17
18
|
refreshToken?: string;
|
|
18
19
|
logger?: ILogger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcTokenExchangeProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcTokenExchangeProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"OidcTokenExchangeProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcTokenExchangeProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,+BAA+B;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,yBAA0B,SAAQ,iBAAiB;IAC9D,OAAO,CAAC,MAAM,CAAkC;gBAEpC,MAAM,EAAE,+BAA+B;IAcnD,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAwCrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAGxD"}
|
|
@@ -26,8 +26,21 @@ class OidcTokenExchangeProvider extends BaseTokenProvider_1.BaseTokenProvider {
|
|
|
26
26
|
return interfaces_1.AUTH_TYPE_USER_TOKEN;
|
|
27
27
|
}
|
|
28
28
|
async performLogin() {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
if (!this.config.tokenEndpoint && !this.config.issuerUrl) {
|
|
30
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
31
|
+
}
|
|
32
|
+
let discovery = null;
|
|
33
|
+
if (this.config.tokenEndpoint === undefined) {
|
|
34
|
+
if (!this.config.issuerUrl) {
|
|
35
|
+
throw new Error('OIDC issuerUrl is required when discovery is used');
|
|
36
|
+
}
|
|
37
|
+
discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
|
|
38
|
+
}
|
|
39
|
+
const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
|
|
40
|
+
if (!tokenEndpoint) {
|
|
41
|
+
throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
|
|
42
|
+
}
|
|
43
|
+
const tokens = await (0, oidcToken_1.tokenExchange)(tokenEndpoint, this.config.clientId, this.config.clientSecret, this.config.subjectToken, this.config.subjectTokenType, this.config.scope, this.config.audience, this.config.actorToken, this.config.actorTokenType, this.logger);
|
|
31
44
|
return {
|
|
32
45
|
authorizationToken: tokens.accessToken,
|
|
33
46
|
refreshToken: tokens.refreshToken,
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
export type { AuthorizationCodeProviderConfig } from './AuthorizationCodeProvider';
|
|
8
8
|
export { AuthorizationCodeProvider } from './AuthorizationCodeProvider';
|
|
9
9
|
export { BaseTokenProvider } from './BaseTokenProvider';
|
|
10
|
+
export type { CfPasscodeProviderConfig } from './CfPasscodeProvider';
|
|
11
|
+
export { CfPasscodeProvider } from './CfPasscodeProvider';
|
|
10
12
|
export type { ClientCredentialsProviderConfig } from './ClientCredentialsProvider';
|
|
11
13
|
export { ClientCredentialsProvider } from './ClientCredentialsProvider';
|
|
12
14
|
export type { DeviceFlowProviderConfig } from './DeviceFlowProvider';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/providers/index.js
CHANGED
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
* All providers extend BaseTokenProvider and implement ITokenProvider.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.Saml2PureProvider = exports.Saml2BearerProvider = exports.OidcTokenExchangeProvider = exports.OidcPasswordProvider = exports.OidcDeviceFlowProvider = exports.OidcBrowserProvider = exports.DeviceFlowProvider = exports.ClientCredentialsProvider = exports.BaseTokenProvider = exports.AuthorizationCodeProvider = void 0;
|
|
9
|
+
exports.Saml2PureProvider = exports.Saml2BearerProvider = exports.OidcTokenExchangeProvider = exports.OidcPasswordProvider = exports.OidcDeviceFlowProvider = exports.OidcBrowserProvider = exports.DeviceFlowProvider = exports.ClientCredentialsProvider = exports.CfPasscodeProvider = exports.BaseTokenProvider = exports.AuthorizationCodeProvider = void 0;
|
|
10
10
|
var AuthorizationCodeProvider_1 = require("./AuthorizationCodeProvider");
|
|
11
11
|
Object.defineProperty(exports, "AuthorizationCodeProvider", { enumerable: true, get: function () { return AuthorizationCodeProvider_1.AuthorizationCodeProvider; } });
|
|
12
12
|
var BaseTokenProvider_1 = require("./BaseTokenProvider");
|
|
13
13
|
Object.defineProperty(exports, "BaseTokenProvider", { enumerable: true, get: function () { return BaseTokenProvider_1.BaseTokenProvider; } });
|
|
14
|
+
var CfPasscodeProvider_1 = require("./CfPasscodeProvider");
|
|
15
|
+
Object.defineProperty(exports, "CfPasscodeProvider", { enumerable: true, get: function () { return CfPasscodeProvider_1.CfPasscodeProvider; } });
|
|
14
16
|
var ClientCredentialsProvider_1 = require("./ClientCredentialsProvider");
|
|
15
17
|
Object.defineProperty(exports, "ClientCredentialsProvider", { enumerable: true, get: function () { return ClientCredentialsProvider_1.ClientCredentialsProvider; } });
|
|
16
18
|
var DeviceFlowProvider_1 = require("./DeviceFlowProvider");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/auth-providers",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Token providers for MCP ABAP ADT auth-broker",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -59,23 +59,23 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@mcp-abap-adt/interfaces": "^2.3.0",
|
|
62
|
-
"axios": "^1.
|
|
62
|
+
"axios": "^1.13.5",
|
|
63
63
|
"express": "^5.1.0",
|
|
64
64
|
"open": "^11.0.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@biomejs/biome": "^2.3.
|
|
68
|
-
"@mcp-abap-adt/auth-stores": "^1.0.
|
|
67
|
+
"@biomejs/biome": "^2.3.14",
|
|
68
|
+
"@mcp-abap-adt/auth-stores": "^1.0.1",
|
|
69
69
|
"@mcp-abap-adt/logger": "^0.1.4",
|
|
70
70
|
"@types/express": "^5.0.5",
|
|
71
71
|
"@types/jest": "^30.0.0",
|
|
72
72
|
"@types/js-yaml": "^4.0.9",
|
|
73
|
-
"@types/node": "^
|
|
73
|
+
"@types/node": "^25.2.3",
|
|
74
74
|
"@jest/globals": "^30.2.0",
|
|
75
75
|
"jest": "^30.2.0",
|
|
76
76
|
"jest-util": "^30.2.0",
|
|
77
77
|
"js-yaml": "^4.1.1",
|
|
78
|
-
"pino": "^10.1
|
|
78
|
+
"pino": "^10.3.1",
|
|
79
79
|
"pino-pretty": "^13.1.3",
|
|
80
80
|
"ts-jest": "^29.2.5",
|
|
81
81
|
"tsx": "^4.19.2",
|