@mcp-abap-adt/auth-providers 1.2.0 → 2.0.0

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +373 -62
  3. package/bin/auth-authorization-code.ts +5 -3
  4. package/dist/__tests__/helpers/netHelpers.d.ts +16 -0
  5. package/dist/__tests__/helpers/netHelpers.d.ts.map +1 -1
  6. package/dist/__tests__/helpers/netHelpers.js +29 -0
  7. package/dist/auth/announce.d.ts +11 -0
  8. package/dist/auth/announce.d.ts.map +1 -0
  9. package/dist/auth/announce.js +19 -0
  10. package/dist/auth/browserAuth.d.ts +21 -14
  11. package/dist/auth/browserAuth.d.ts.map +1 -1
  12. package/dist/auth/browserAuth.js +25 -111
  13. package/dist/auth/callbackServer.d.ts +6 -0
  14. package/dist/auth/callbackServer.d.ts.map +1 -1
  15. package/dist/auth/callbackServer.js +31 -21
  16. package/dist/auth/oidcBrowserAuth.d.ts +2 -9
  17. package/dist/auth/oidcBrowserAuth.d.ts.map +1 -1
  18. package/dist/auth/oidcBrowserAuth.js +16 -125
  19. package/dist/auth/saml2Auth.d.ts +2 -9
  20. package/dist/auth/saml2Auth.d.ts.map +1 -1
  21. package/dist/auth/saml2Auth.js +10 -130
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +21 -1
  25. package/dist/providers/AuthorizationCodeProvider.d.ts +7 -3
  26. package/dist/providers/AuthorizationCodeProvider.d.ts.map +1 -1
  27. package/dist/providers/AuthorizationCodeProvider.js +51 -40
  28. package/dist/providers/DeviceFlowProvider.d.ts +2 -1
  29. package/dist/providers/DeviceFlowProvider.d.ts.map +1 -1
  30. package/dist/providers/DeviceFlowProvider.js +13 -10
  31. package/dist/providers/OidcBrowserProvider.d.ts +4 -7
  32. package/dist/providers/OidcBrowserProvider.d.ts.map +1 -1
  33. package/dist/providers/OidcBrowserProvider.js +54 -57
  34. package/dist/providers/OidcDeviceFlowProvider.d.ts.map +1 -1
  35. package/dist/providers/OidcDeviceFlowProvider.js +9 -7
  36. package/dist/providers/Saml2BearerProvider.d.ts +2 -2
  37. package/dist/providers/Saml2BearerProvider.d.ts.map +1 -1
  38. package/dist/providers/Saml2BearerProvider.js +3 -0
  39. package/dist/providers/Saml2PureProvider.d.ts +2 -2
  40. package/dist/providers/Saml2PureProvider.d.ts.map +1 -1
  41. package/dist/providers/Saml2PureProvider.js +3 -0
  42. package/dist/providers/saml2Utils.d.ts +12 -12
  43. package/dist/providers/saml2Utils.d.ts.map +1 -1
  44. package/dist/providers/saml2Utils.js +46 -26
  45. package/dist/strategies/BrowserCallbackStrategy.d.ts +64 -0
  46. package/dist/strategies/BrowserCallbackStrategy.d.ts.map +1 -0
  47. package/dist/strategies/BrowserCallbackStrategy.js +210 -0
  48. package/dist/strategies/asOidcResult.d.ts +11 -0
  49. package/dist/strategies/asOidcResult.d.ts.map +1 -0
  50. package/dist/strategies/asOidcResult.js +30 -0
  51. package/dist/strategies/codeStrategies.d.ts +22 -0
  52. package/dist/strategies/codeStrategies.d.ts.map +1 -0
  53. package/dist/strategies/codeStrategies.js +39 -0
  54. package/dist/strategies/index.d.ts +8 -0
  55. package/dist/strategies/index.d.ts.map +1 -0
  56. package/dist/strategies/index.js +18 -0
  57. package/dist/strategies/manualStrategies.d.ts +20 -0
  58. package/dist/strategies/manualStrategies.d.ts.map +1 -0
  59. package/dist/strategies/manualStrategies.js +77 -0
  60. package/package.json +2 -2
  61. package/dist/auth/manualInput.d.ts +0 -5
  62. package/dist/auth/manualInput.d.ts.map +0 -1
  63. package/dist/auth/manualInput.js +0 -19
@@ -8,6 +8,7 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.DeviceFlowProvider = void 0;
10
10
  const interfaces_1 = require("@mcp-abap-adt/interfaces");
11
+ const announce_1 = require("../auth/announce");
11
12
  const deviceFlowAuth_1 = require("../auth/deviceFlowAuth");
12
13
  const tokenRefresher_1 = require("../auth/tokenRefresher");
13
14
  const BaseTokenProvider_1 = require("./BaseTokenProvider");
@@ -22,6 +23,7 @@ class DeviceFlowProvider extends BaseTokenProvider_1.BaseTokenProvider {
22
23
  constructor(config) {
23
24
  super();
24
25
  this.config = config;
26
+ this.logger = config.logger;
25
27
  if (config.accessToken) {
26
28
  this.authorizationToken = config.accessToken;
27
29
  this.expiresAt = this.parseExpirationFromJWT(config.accessToken);
@@ -38,19 +40,20 @@ class DeviceFlowProvider extends BaseTokenProvider_1.BaseTokenProvider {
38
40
  }
39
41
  async performLogin() {
40
42
  // Initiate device flow
41
- const deviceFlow = await (0, deviceFlowAuth_1.initiateDeviceFlow)(this.config.uaaUrl, this.config.clientId, this.config.scope, undefined);
42
- // Display user code and verification URI
43
- console.log('\nšŸ” Device Flow Authorization');
44
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
45
- console.log(`šŸ“± Go to: ${deviceFlow.verificationUri}`);
43
+ const deviceFlow = await (0, deviceFlowAuth_1.initiateDeviceFlow)(this.config.uaaUrl, this.config.clientId, this.config.scope, this.logger);
44
+ // Display user code and verification URI. This is a prompt the user must
45
+ // see to complete the flow, not a log line — it goes to the logger when
46
+ // there is one and to stderr otherwise, never to stdout.
47
+ const announce = (0, announce_1.announcer)(this.logger);
48
+ announce('Device Flow Authorization');
49
+ announce(`Go to: ${deviceFlow.verificationUri}`);
46
50
  if (deviceFlow.verificationUriComplete) {
47
- console.log(` Or use complete URL: ${deviceFlow.verificationUriComplete}`);
51
+ announce(`Or use complete URL: ${deviceFlow.verificationUriComplete}`);
48
52
  }
49
- console.log(`šŸ”‘ Enter code: ${deviceFlow.userCode}`);
50
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
51
- console.log('ā³ Waiting for authorization...\n');
53
+ announce(`Enter code: ${deviceFlow.userCode}`);
54
+ announce('Waiting for authorization...');
52
55
  // Poll for tokens
53
- const result = await (0, deviceFlowAuth_1.pollForDeviceTokens)(this.config.uaaUrl, this.config.clientId, this.config.clientSecret, deviceFlow.deviceCode, deviceFlow.interval, undefined);
56
+ const result = await (0, deviceFlowAuth_1.pollForDeviceTokens)(this.config.uaaUrl, this.config.clientId, this.config.clientSecret, deviceFlow.deviceCode, deviceFlow.interval, this.logger);
54
57
  const expiresIn = this.calculateExpiresIn(result.accessToken);
55
58
  return {
56
59
  authorizationToken: result.accessToken,
@@ -1,20 +1,18 @@
1
1
  /**
2
2
  * OIDC Authorization Code Provider (with PKCE)
3
3
  */
4
- import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
4
+ import type { IAuthorizationStrategy, ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
5
+ import type { OidcCallbackResult } from '../auth/oidcBrowserAuth';
5
6
  import { BaseTokenProvider } from './BaseTokenProvider';
6
7
  export interface OidcBrowserProviderConfig {
7
8
  issuerUrl?: string;
8
9
  clientId: string;
9
10
  clientSecret?: string;
10
11
  scopes?: string[];
11
- browser?: string;
12
- redirectPort?: number;
13
- redirectUri?: string;
14
- authorizationCode?: string;
15
- authorizationCodeProvider?: () => Promise<string>;
16
12
  authorizationEndpoint?: string;
17
13
  tokenEndpoint?: string;
14
+ /** How the login is conducted. Omitted means a browser callback on the default port. */
15
+ authorization?: IAuthorizationStrategy<OidcCallbackResult>;
18
16
  accessToken?: string;
19
17
  refreshToken?: string;
20
18
  logger?: ILogger;
@@ -25,6 +23,5 @@ export declare class OidcBrowserProvider extends BaseTokenProvider {
25
23
  protected getAuthType(): OAuth2GrantType;
26
24
  protected performLogin(): Promise<ITokenResult>;
27
25
  protected performRefresh(): Promise<ITokenResult>;
28
- private resolveAuthorizationCode;
29
26
  }
30
27
  //# 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,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"}
1
+ {"version":3,"file":"OidcBrowserProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcBrowserProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAKlE,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,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,aAAa,CAAC,EAAE,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;IAC3D,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;cAyFrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAsCxD"}
@@ -5,10 +5,10 @@
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.OidcBrowserProvider = void 0;
7
7
  const interfaces_1 = require("@mcp-abap-adt/interfaces");
8
- const oidcBrowserAuth_1 = require("../auth/oidcBrowserAuth");
9
8
  const oidcDiscovery_1 = require("../auth/oidcDiscovery");
10
9
  const oidcPkce_1 = require("../auth/oidcPkce");
11
10
  const oidcToken_1 = require("../auth/oidcToken");
11
+ const strategies_1 = require("../strategies");
12
12
  const BaseTokenProvider_1 = require("./BaseTokenProvider");
13
13
  class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
14
14
  config;
@@ -28,50 +28,62 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
28
28
  return interfaces_1.AUTH_TYPE_AUTHORIZATION_CODE_PKCE;
29
29
  }
30
30
  async performLogin() {
31
- const needsAuthorizationEndpoint = !this.config.authorizationCode && !this.config.authorizationCodeProvider;
32
- const requiresDiscovery = (needsAuthorizationEndpoint && !this.config.authorizationEndpoint) ||
33
- !this.config.tokenEndpoint;
31
+ // One memoised discovery per login, started on first use rather than up
32
+ // front: a strategy that already holds a code must not drag in a request —
33
+ // nor the `issuerUrl` requirement that comes with it.
34
34
  let discovery = null;
35
- if (requiresDiscovery) {
36
- if (!this.config.issuerUrl) {
37
- throw new Error('OIDC issuerUrl is required when discovery is used');
35
+ const discover = () => {
36
+ if (!discovery) {
37
+ if (!this.config.issuerUrl) {
38
+ throw new Error('OIDC issuerUrl is required when discovery is used');
39
+ }
40
+ discovery = (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
38
41
  }
39
- discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
42
+ return discovery;
43
+ };
44
+ const verifier = (0, oidcPkce_1.generatePkceVerifier)();
45
+ const challenge = (0, oidcPkce_1.generatePkceChallenge)(verifier);
46
+ const scope = (this.config.scopes && this.config.scopes.length > 0
47
+ ? this.config.scopes
48
+ : ['openid', 'profile', 'email']).join(' ');
49
+ const request = {
50
+ logger: this.logger,
51
+ buildAuthorizationUrl: async (redirectUri) => {
52
+ const endpoint = this.config.authorizationEndpoint ??
53
+ (await discover()).authorization_endpoint;
54
+ if (!endpoint) {
55
+ throw new Error('OIDC authorization endpoint is required (authorizationEndpoint or discovery)');
56
+ }
57
+ const params = new URLSearchParams();
58
+ params.append('response_type', 'code');
59
+ params.append('client_id', this.config.clientId);
60
+ params.append('redirect_uri', redirectUri);
61
+ params.append('scope', scope);
62
+ params.append('code_challenge', challenge);
63
+ params.append('code_challenge_method', 'S256');
64
+ return `${endpoint}?${params.toString()}`;
65
+ },
66
+ };
67
+ const supplied = this.config.authorization;
68
+ const strategy = supplied ?? (0, strategies_1.oidcCallbackStrategy)();
69
+ let outcome;
70
+ try {
71
+ outcome = await strategy.authorize(request);
40
72
  }
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)');
73
+ finally {
74
+ if (!supplied) {
75
+ await strategy.dispose?.().catch((error) => {
76
+ this.logger?.warn('[OidcBrowserProvider] dispose failed', {
77
+ error: error instanceof Error ? error.message : String(error),
78
+ });
79
+ });
80
+ }
47
81
  }
82
+ const tokenEndpoint = this.config.tokenEndpoint ?? (await discover()).token_endpoint;
48
83
  if (!tokenEndpoint) {
49
84
  throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
50
85
  }
51
- const redirectPort = this.config.redirectPort || 3001;
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
- }
58
- const scope = (this.config.scopes && this.config.scopes.length > 0
59
- ? this.config.scopes
60
- : ['openid', 'profile', 'email']).join(' ');
61
- const verifier = (0, oidcPkce_1.generatePkceVerifier)();
62
- const challenge = (0, oidcPkce_1.generatePkceChallenge)(verifier);
63
- const params = new URLSearchParams();
64
- params.append('response_type', 'code');
65
- params.append('client_id', this.config.clientId);
66
- params.append('redirect_uri', redirectUri);
67
- params.append('scope', scope);
68
- params.append('code_challenge', challenge);
69
- params.append('code_challenge_method', 'S256');
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);
86
+ const tokens = await (0, oidcToken_1.exchangeAuthorizationCode)(tokenEndpoint, this.config.clientId, this.config.clientSecret, outcome.payload.code, outcome.redirectUri, verifier, this.logger);
75
87
  return {
76
88
  authorizationToken: tokens.accessToken,
77
89
  refreshToken: tokens.refreshToken,
@@ -91,7 +103,10 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
91
103
  }
92
104
  discovery = await (0, oidcDiscovery_1.discoverOidc)(this.config.issuerUrl, this.logger);
93
105
  }
94
- const tokenEndpoint = this.config.tokenEndpoint || discovery?.token_endpoint;
106
+ // `??`, matching the `=== undefined` gate above and the login path: `||`
107
+ // treated a configured-but-empty endpoint as absent while the gate had
108
+ // already decided it was present, so the two disagreed about the same value.
109
+ const tokenEndpoint = this.config.tokenEndpoint ?? discovery?.token_endpoint;
95
110
  if (!tokenEndpoint) {
96
111
  throw new Error('OIDC token endpoint is required (tokenEndpoint or discovery)');
97
112
  }
@@ -104,23 +119,5 @@ class OidcBrowserProvider extends BaseTokenProvider_1.BaseTokenProvider {
104
119
  tokenType: 'jwt',
105
120
  };
106
121
  }
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
- }
125
122
  }
126
123
  exports.OidcBrowserProvider = OidcBrowserProvider;
@@ -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,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"}
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;AASlC,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;cAwErC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAqCxD"}
@@ -5,6 +5,7 @@
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.OidcDeviceFlowProvider = void 0;
7
7
  const interfaces_1 = require("@mcp-abap-adt/interfaces");
8
+ const announce_1 = require("../auth/announce");
8
9
  const oidcDiscovery_1 = require("../auth/oidcDiscovery");
9
10
  const oidcToken_1 = require("../auth/oidcToken");
10
11
  const BaseTokenProvider_1 = require("./BaseTokenProvider");
@@ -50,15 +51,16 @@ class OidcDeviceFlowProvider extends BaseTokenProvider_1.BaseTokenProvider {
50
51
  }
51
52
  const scope = this.config.scopes?.join(' ');
52
53
  const deviceFlow = await (0, oidcToken_1.initiateDeviceAuthorization)(deviceAuthorizationEndpoint, this.config.clientId, scope, this.logger);
53
- // Manual user guidance
54
- console.log('');
55
- console.log('OIDC device authorization');
56
- console.log('Go to:', deviceFlow.verificationUri);
54
+ // Manual user guidance. This is a prompt the user must see to complete
55
+ // the flow, not a log line — it goes to the logger when there is one and
56
+ // to stderr otherwise, never to stdout.
57
+ const announce = (0, announce_1.announcer)(this.logger);
58
+ announce('OIDC device authorization');
59
+ announce(`Go to: ${deviceFlow.verificationUri}`);
57
60
  if (deviceFlow.verificationUriComplete) {
58
- console.log('Or use:', deviceFlow.verificationUriComplete);
61
+ announce(`Or use: ${deviceFlow.verificationUriComplete}`);
59
62
  }
60
- console.log('Enter code:', deviceFlow.userCode);
61
- console.log('');
63
+ announce(`Enter code: ${deviceFlow.userCode}`);
62
64
  const tokens = await (0, oidcToken_1.pollDeviceTokens)(tokenEndpoint, this.config.clientId, this.config.clientSecret, deviceFlow.deviceCode, deviceFlow.interval || 5, this.logger);
63
65
  return {
64
66
  authorizationToken: tokens.accessToken,
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
7
7
  import { BaseTokenProvider } from './BaseTokenProvider';
8
- import type { Saml2AssertionConfig, Saml2BearerExchangeConfig } from './saml2Utils';
9
- export interface Saml2BearerProviderConfig extends Saml2AssertionConfig, Saml2BearerExchangeConfig {
8
+ import type { Saml2BearerExchangeConfig, Saml2CommonConfig } from './saml2Utils';
9
+ export interface Saml2BearerProviderConfig extends Saml2CommonConfig, Saml2BearerExchangeConfig {
10
10
  logger?: ILogger;
11
11
  accessToken?: string;
12
12
  refreshToken?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Saml2BearerProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2BearerProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,yBACf,SAAQ,oBAAoB,EAC1B,yBAAyB;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;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;cAoBrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAMxD"}
1
+ {"version":3,"file":"Saml2BearerProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2BearerProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,yBAAyB,EACzB,iBAAiB,EAClB,MAAM,cAAc,CAAC;AAOtB,MAAM,WAAW,yBACf,SAAQ,iBAAiB,EACvB,yBAAyB;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,OAAO,CAAC,MAAM,CAA4B;gBAE9B,MAAM,EAAE,yBAAyB;IAiB7C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAoBrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAMxD"}
@@ -14,6 +14,9 @@ class Saml2BearerProvider extends BaseTokenProvider_1.BaseTokenProvider {
14
14
  config;
15
15
  constructor(config) {
16
16
  super();
17
+ // A pre-built URL with no declared ACS cannot be verified against whatever
18
+ // the strategy binds, so it is refused here rather than at login time.
19
+ (0, saml2Utils_1.validateSamlConfig)(config);
17
20
  this.config = config;
18
21
  this.logger = config.logger;
19
22
  if (config.accessToken) {
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import type { ILogger, ITokenResult, OAuth2GrantType } from '@mcp-abap-adt/interfaces';
7
7
  import { BaseTokenProvider } from './BaseTokenProvider';
8
- import type { Saml2AssertionConfig } from './saml2Utils';
9
- export interface Saml2PureProviderConfig extends Saml2AssertionConfig {
8
+ import type { Saml2CommonConfig } from './saml2Utils';
9
+ export interface Saml2PureProviderConfig extends Saml2CommonConfig {
10
10
  logger?: ILogger;
11
11
  cookieProvider: (samlResponse: string) => Promise<string>;
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Saml2PureProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2PureProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3D;AAED,qBAAa,iBAAkB,SAAQ,iBAAiB;IACtD,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,EAAE,uBAAuB;IAO3C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAarC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAGxD"}
1
+ {"version":3,"file":"Saml2PureProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2PureProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3D;AAED,qBAAa,iBAAkB,SAAQ,iBAAiB;IACtD,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,EAAE,uBAAuB;IAU3C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAarC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAGxD"}
@@ -14,6 +14,9 @@ class Saml2PureProvider extends BaseTokenProvider_1.BaseTokenProvider {
14
14
  config;
15
15
  constructor(config) {
16
16
  super();
17
+ // A pre-built URL with no declared ACS cannot be verified against whatever
18
+ // the strategy binds, so it is refused here rather than at login time.
19
+ (0, saml2Utils_1.validateSamlConfig)(config);
17
20
  this.config = config;
18
21
  this.logger = config.logger;
19
22
  this.tokenType = 'saml';
@@ -1,30 +1,30 @@
1
1
  /**
2
- * SAML2 provider shared helpers
2
+ * SAML2 provider shared helpers.
3
3
  */
4
- import type { ILogger } from '@mcp-abap-adt/interfaces';
5
- export type Saml2AssertionFlow = 'browser' | 'manual' | 'assertion';
4
+ import type { IAuthorizationStrategy, ILogger } from '@mcp-abap-adt/interfaces';
6
5
  export interface Saml2CommonConfig {
7
6
  idpSsoUrl: string;
8
7
  spEntityId: string;
8
+ /**
9
+ * Where the assertion is delivered. Required when `authorizationUrl` is set:
10
+ * the ACS is then buried in a deflated `SAMLRequest` this package did not
11
+ * build and cannot read, so it must be declared rather than inferred.
12
+ */
9
13
  acsUrl?: string;
10
14
  relayState?: string;
11
15
  authorizationUrl?: string;
12
- browser?: string;
13
- redirectPort?: number;
16
+ /** How the login is conducted. Omitted means a browser callback. */
17
+ authorization?: IAuthorizationStrategy<string>;
14
18
  logger?: ILogger;
15
19
  }
16
- export interface Saml2AssertionConfig extends Saml2CommonConfig {
17
- assertionFlow: Saml2AssertionFlow;
18
- assertionProvider?: () => Promise<string>;
19
- manualInput?: () => Promise<string>;
20
- }
21
20
  export interface Saml2BearerExchangeConfig {
22
21
  tokenUrl?: string;
23
22
  uaaUrl?: string;
24
23
  clientId?: string;
25
24
  clientSecret?: string;
26
25
  }
27
- export declare function resolveAcsUrl(config: Saml2CommonConfig): string;
26
+ /** Throw at construction rather than half-verify at runtime. */
27
+ export declare function validateSamlConfig(config: Saml2CommonConfig): void;
28
28
  export declare function resolveTokenUrl(config: Saml2BearerExchangeConfig): string;
29
- export declare function getSamlAssertion(config: Saml2AssertionConfig): Promise<string>;
29
+ export declare function getSamlAssertion(config: Saml2CommonConfig): Promise<string>;
30
30
  //# sourceMappingURL=saml2Utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"saml2Utils.d.ts","sourceRoot":"","sources":["../../src/providers/saml2Utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAOxD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,aAAa,EAAE,kBAAkB,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAG/D;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAQzE;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAiCjB"}
1
+ {"version":3,"file":"saml2Utils.d.ts","sourceRoot":"","sources":["../../src/providers/saml2Utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAIhF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,aAAa,CAAC,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAOlE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAQzE;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
@@ -1,16 +1,19 @@
1
1
  "use strict";
2
2
  /**
3
- * SAML2 provider shared helpers
3
+ * SAML2 provider shared helpers.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.resolveAcsUrl = resolveAcsUrl;
6
+ exports.validateSamlConfig = validateSamlConfig;
7
7
  exports.resolveTokenUrl = resolveTokenUrl;
8
8
  exports.getSamlAssertion = getSamlAssertion;
9
- const manualInput_1 = require("../auth/manualInput");
10
9
  const saml2Auth_1 = require("../auth/saml2Auth");
11
- function resolveAcsUrl(config) {
12
- const port = config.redirectPort || 3001;
13
- return config.acsUrl || `http://localhost:${port}/callback`;
10
+ const strategies_1 = require("../strategies");
11
+ /** Throw at construction rather than half-verify at runtime. */
12
+ function validateSamlConfig(config) {
13
+ if (config.authorizationUrl && !config.acsUrl) {
14
+ throw new Error('acsUrl is required when authorizationUrl is set: the ACS inside a ' +
15
+ 'pre-built SAML request cannot be read, so it must be declared.');
16
+ }
14
17
  }
15
18
  function resolveTokenUrl(config) {
16
19
  if (config.tokenUrl) {
@@ -22,28 +25,45 @@ function resolveTokenUrl(config) {
22
25
  throw new Error('Missing tokenUrl or uaaUrl for SAML bearer exchange');
23
26
  }
24
27
  async function getSamlAssertion(config) {
25
- const acsUrl = resolveAcsUrl(config);
26
- const authConfig = {
27
- idpSsoUrl: config.idpSsoUrl,
28
- spEntityId: config.spEntityId,
29
- acsUrl,
30
- relayState: config.relayState,
31
- authorizationUrl: config.authorizationUrl,
28
+ const declaredAcs = config.acsUrl;
29
+ const request = {
30
+ logger: config.logger,
31
+ buildAuthorizationUrl: async (redirectUri) => {
32
+ // A declared ACS is registered with the IdP; the strategy must be
33
+ // listening exactly there, and an ephemeral port cannot be.
34
+ const acsUrl = declaredAcs ?? redirectUri;
35
+ if (declaredAcs && declaredAcs !== redirectUri) {
36
+ throw new Error(`SAML acsUrl is ${declaredAcs}, but the authorization strategy is ` +
37
+ `listening on ${redirectUri}. They must match.`);
38
+ }
39
+ return (0, saml2Auth_1.buildSamlAuthorizationUrl)({
40
+ idpSsoUrl: config.idpSsoUrl,
41
+ spEntityId: config.spEntityId,
42
+ acsUrl,
43
+ relayState: config.relayState,
44
+ authorizationUrl: config.authorizationUrl,
45
+ });
46
+ },
32
47
  };
33
- if (config.assertionFlow === 'assertion') {
34
- if (!config.assertionProvider) {
35
- throw new Error('assertionProvider is required for assertion flow');
48
+ const supplied = config.authorization;
49
+ const strategy = supplied ?? (0, strategies_1.samlCallbackStrategy)();
50
+ try {
51
+ const outcome = await strategy.authorize(request);
52
+ // The second net, for a strategy that never called the builder and so
53
+ // never met the check inside it.
54
+ if (declaredAcs && declaredAcs !== outcome.redirectUri) {
55
+ throw new Error(`SAML acsUrl is ${declaredAcs}, but the authorization strategy used ` +
56
+ `${outcome.redirectUri}. They must match.`);
36
57
  }
37
- return await config.assertionProvider();
58
+ return outcome.payload;
38
59
  }
39
- if (config.assertionFlow === 'manual') {
40
- const authorizationUrl = (0, saml2Auth_1.buildSamlAuthorizationUrl)(authConfig);
41
- config.logger?.info('[SAML] Open URL to authenticate', {
42
- authorizationUrl,
43
- });
44
- const input = config.manualInput || manualInput_1.readManualInput;
45
- return await input('Paste SAMLResponse: ');
60
+ finally {
61
+ if (!supplied) {
62
+ await strategy.dispose?.().catch((error) => {
63
+ config.logger?.warn('[SAML] dispose failed', {
64
+ error: error instanceof Error ? error.message : String(error),
65
+ });
66
+ });
67
+ }
46
68
  }
47
- const browser = config.browser || 'auto';
48
- return await (0, saml2Auth_1.startSamlBrowserAuth)(authConfig, browser, config.logger, config.redirectPort || 3001);
49
69
  }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Reaching the authorization URL with a browser, receiving the redirect on a
3
+ * local socket.
4
+ *
5
+ * The transport is injected rather than assumed: a consumer that already runs
6
+ * an HTTP server can pass its own `CallbackServerFactory` and keep everything
7
+ * else here.
8
+ */
9
+ import type { AuthorizationOutcome, AuthorizationRequest, CallbackServerFactory, IAuthorizationStrategy } from '@mcp-abap-adt/interfaces';
10
+ import type { OidcCallbackResult } from '../auth/oidcBrowserAuth';
11
+ /**
12
+ * Above Linux's `ip_local_port_range` (32768–60999), so an outbound connection
13
+ * never squats on it, and far from the 3001/3333 range application servers use.
14
+ */
15
+ export declare const DEFAULT_CALLBACK_PORT = 61001;
16
+ /** How long an interactive login may wait for its callback. */
17
+ export declare const DEFAULT_LOGIN_TIMEOUT_MS = 30000;
18
+ export interface CallbackStrategyOptions<TResult = string> {
19
+ /** `0` binds an ephemeral port. Unusable where the IdP has a registered URI. */
20
+ port?: number;
21
+ timeoutMs?: number;
22
+ /** 'none' | 'headless' print the URL; 'auto' | 'system' | 'chrome' | … open it. */
23
+ browser?: string;
24
+ /**
25
+ * The transport. Omitted means the one this package ships for the flow; a
26
+ * consumer that already runs an HTTP server passes its own here and keeps
27
+ * everything else — which is the point of the ready constructors existing at
28
+ * all rather than forcing everyone through the class.
29
+ */
30
+ callbackServer?: CallbackServerFactory<TResult>;
31
+ /** Receives the bound redirect URI too, since with `port: 0` nobody knew it earlier. */
32
+ openUrl?: (url: string, browser: string, redirectUri: string) => Promise<void>;
33
+ /**
34
+ * Extra guidance for 'none'/'headless', built from the URI actually bound —
35
+ * "if your browser is elsewhere, do this instead".
36
+ *
37
+ * It describes a *route*, so it belongs to whoever supplied the transport. A
38
+ * consumer injecting its own `callbackServer` states its own hint here; the
39
+ * package supplies one only for the transport it ships, and never guesses on
40
+ * behalf of an injected one.
41
+ */
42
+ remoteHint?: (redirectUri: string) => string;
43
+ signal?: AbortSignal;
44
+ }
45
+ export interface BrowserCallbackStrategyOptions<TResult> extends CallbackStrategyOptions<TResult> {
46
+ callbackServer: CallbackServerFactory<TResult>;
47
+ }
48
+ export declare class BrowserCallbackStrategy<TResult> implements IAuthorizationStrategy<TResult> {
49
+ private readonly options;
50
+ private inFlight;
51
+ private controller;
52
+ private disposed;
53
+ constructor(options: BrowserCallbackStrategyOptions<TResult>);
54
+ authorize(request: AuthorizationRequest): Promise<AuthorizationOutcome<TResult>>;
55
+ /**
56
+ * Idempotent; ends an authorization in flight and resolves only once the
57
+ * factory has settled — which it does after the socket is free.
58
+ */
59
+ dispose(): Promise<void>;
60
+ }
61
+ export declare function browserCallbackStrategy(options?: CallbackStrategyOptions<string>): IAuthorizationStrategy<string>;
62
+ export declare function oidcCallbackStrategy(options?: CallbackStrategyOptions<OidcCallbackResult>): IAuthorizationStrategy<OidcCallbackResult>;
63
+ export declare function samlCallbackStrategy(options?: CallbackStrategyOptions<string>): IAuthorizationStrategy<string>;
64
+ //# sourceMappingURL=BrowserCallbackStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserCallbackStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/BrowserCallbackStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAIlE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,MAAM,WAAW,uBAAuB,CAAC,OAAO,GAAG,MAAM;IACvD,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAChD,wFAAwF;IACxF,OAAO,CAAC,EAAE,CACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,KAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,8BAA8B,CAAC,OAAO,CACrD,SAAQ,uBAAuB,CAAC,OAAO,CAAC;IACxC,cAAc,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;CAChD;AAwBD,qBAAa,uBAAuB,CAAC,OAAO,CAC1C,YAAW,sBAAsB,CAAC,OAAO,CAAC;IAOxC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,QAAQ,CAAuD;IACvE,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,QAAQ,CAAS;gBAGN,OAAO,EAAE,8BAA8B,CAAC,OAAO,CAAC;IAG7D,SAAS,CACb,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IA8FzC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B;AAyBD,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,uBAAuB,CAAC,MAAM,CAAM,GAC5C,sBAAsB,CAAC,MAAM,CAAC,CAWhC;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,uBAAuB,CAAC,kBAAkB,CAAM,GACxD,sBAAsB,CAAC,kBAAkB,CAAC,CAK5C;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,uBAAuB,CAAC,MAAM,CAAM,GAC5C,sBAAsB,CAAC,MAAM,CAAC,CAKhC"}