@mcp-abap-adt/auth-providers 3.0.0 → 4.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 (44) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +620 -77
  3. package/dist/auth/saml2Auth.d.ts +6 -2
  4. package/dist/auth/saml2Auth.d.ts.map +1 -1
  5. package/dist/auth/saml2Auth.js +9 -20
  6. package/dist/auth/samlBearerAssertion.d.ts.map +1 -1
  7. package/dist/auth/samlBearerAssertion.js +2 -1
  8. package/dist/auth/strictXml.d.ts +13 -0
  9. package/dist/auth/strictXml.d.ts.map +1 -0
  10. package/dist/auth/strictXml.js +21 -0
  11. package/dist/errors/AssertionValidationError.d.ts +15 -0
  12. package/dist/errors/AssertionValidationError.d.ts.map +1 -0
  13. package/dist/errors/AssertionValidationError.js +24 -0
  14. package/dist/errors/TokenProviderErrors.d.ts +2 -0
  15. package/dist/errors/TokenProviderErrors.d.ts.map +1 -1
  16. package/dist/errors/TokenProviderErrors.js +3 -1
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +11 -1
  20. package/dist/providers/Saml2BearerProvider.d.ts +1 -0
  21. package/dist/providers/Saml2BearerProvider.d.ts.map +1 -1
  22. package/dist/providers/Saml2BearerProvider.js +17 -2
  23. package/dist/providers/Saml2PureProvider.d.ts +1 -0
  24. package/dist/providers/Saml2PureProvider.d.ts.map +1 -1
  25. package/dist/providers/Saml2PureProvider.js +19 -5
  26. package/dist/providers/saml2Utils.d.ts +49 -2
  27. package/dist/providers/saml2Utils.d.ts.map +1 -1
  28. package/dist/providers/saml2Utils.js +94 -2
  29. package/dist/validation/assertionValidator.d.ts +28 -0
  30. package/dist/validation/assertionValidator.d.ts.map +1 -0
  31. package/dist/validation/assertionValidator.js +444 -0
  32. package/dist/validation/documentIds.d.ts +15 -0
  33. package/dist/validation/documentIds.d.ts.map +1 -0
  34. package/dist/validation/documentIds.js +32 -0
  35. package/dist/validation/inMemoryReplayStore.d.ts +22 -0
  36. package/dist/validation/inMemoryReplayStore.d.ts.map +1 -0
  37. package/dist/validation/inMemoryReplayStore.js +49 -0
  38. package/dist/validation/signedNode.d.ts +54 -0
  39. package/dist/validation/signedNode.d.ts.map +1 -0
  40. package/dist/validation/signedNode.js +171 -0
  41. package/dist/validation/xsdDateTime.d.ts +17 -0
  42. package/dist/validation/xsdDateTime.d.ts.map +1 -0
  43. package/dist/validation/xsdDateTime.js +67 -0
  44. package/package.json +5 -4
@@ -9,7 +9,11 @@ export interface Saml2AuthConfig {
9
9
  relayState?: string;
10
10
  authorizationUrl?: string;
11
11
  }
12
- export declare function buildSamlAuthorizationUrl(config: Saml2AuthConfig): string;
12
+ export interface BuiltAuthorizationUrl {
13
+ readonly url: string;
14
+ /** Present only when this function minted the request. */
15
+ readonly requestId?: string;
16
+ }
17
+ export declare function buildSamlAuthorizationUrl(config: Saml2AuthConfig): BuiltAuthorizationUrl;
13
18
  export declare const withSamlCallbackServer: CallbackServerFactory<string>;
14
- export declare function parseSamlNotOnOrAfter(samlResponse: string): number | undefined;
15
19
  //# sourceMappingURL=saml2Auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"saml2Auth.d.ts","sourceRoot":"","sources":["../../src/auth/saml2Auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAyBD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAazE;AAED,eAAO,MAAM,sBAAsB,EAAE,qBAAqB,CAAC,MAAM,CAgC9D,CAAC;AAEJ,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,GACnB,MAAM,GAAG,SAAS,CAYpB"}
1
+ {"version":3,"file":"saml2Auth.d.ts","sourceRoot":"","sources":["../../src/auth/saml2Auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4BD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,eAAe,GACtB,qBAAqB,CAkBvB;AAED,eAAO,MAAM,sBAAsB,EAAE,qBAAqB,CAAC,MAAM,CAgC9D,CAAC"}
@@ -8,7 +8,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.withSamlCallbackServer = void 0;
10
10
  exports.buildSamlAuthorizationUrl = buildSamlAuthorizationUrl;
11
- exports.parseSamlNotOnOrAfter = parseSamlNotOnOrAfter;
12
11
  const node_crypto_1 = require("node:crypto");
13
12
  const node_zlib_1 = require("node:zlib");
14
13
  const express_1 = __importDefault(require("express"));
@@ -18,9 +17,8 @@ function base64Encode(input) {
18
17
  ? input.toString('base64')
19
18
  : Buffer.from(input, 'utf8').toString('base64');
20
19
  }
21
- function buildAuthnRequestXml(spEntityId, acsUrl) {
20
+ function buildAuthnRequestXml(id, spEntityId, acsUrl) {
22
21
  const issueInstant = new Date().toISOString();
23
- const id = `_${(0, node_crypto_1.randomUUID)()}`;
24
22
  return [
25
23
  '<?xml version="1.0" encoding="UTF-8"?>',
26
24
  '<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"',
@@ -36,15 +34,20 @@ function buildAuthnRequestXml(spEntityId, acsUrl) {
36
34
  }
37
35
  function buildSamlAuthorizationUrl(config) {
38
36
  if (config.authorizationUrl) {
39
- return config.authorizationUrl;
37
+ // Somebody else built the request; its ID is not ours to know.
38
+ return { url: config.authorizationUrl };
40
39
  }
41
- const xml = buildAuthnRequestXml(config.spEntityId, config.acsUrl);
40
+ const requestId = `_${(0, node_crypto_1.randomUUID)()}`;
41
+ const xml = buildAuthnRequestXml(requestId, config.spEntityId, config.acsUrl);
42
42
  const deflated = (0, node_zlib_1.deflateRawSync)(Buffer.from(xml, 'utf8'));
43
43
  const samlRequest = encodeURIComponent(base64Encode(deflated));
44
44
  const relayState = config.relayState
45
45
  ? `&RelayState=${encodeURIComponent(config.relayState)}`
46
46
  : '';
47
- return `${config.idpSsoUrl}?SAMLRequest=${samlRequest}${relayState}`;
47
+ return {
48
+ url: `${config.idpSsoUrl}?SAMLRequest=${samlRequest}${relayState}`,
49
+ requestId,
50
+ };
48
51
  }
49
52
  const withSamlCallbackServer = (options, use) => (0, callbackServer_1.runCallbackScope)(options, (app, settle) => {
50
53
  app.use(express_1.default.urlencoded({ extended: false, limit: '5mb' }));
@@ -69,17 +72,3 @@ const withSamlCallbackServer = (options, use) => (0, callbackServer_1.runCallbac
69
72
  });
70
73
  }, use);
71
74
  exports.withSamlCallbackServer = withSamlCallbackServer;
72
- function parseSamlNotOnOrAfter(samlResponse) {
73
- try {
74
- const decoded = Buffer.from(samlResponse, 'base64').toString('utf8');
75
- const match = decoded.match(/NotOnOrAfter="([^"]+)"/);
76
- if (!match) {
77
- return undefined;
78
- }
79
- const date = Date.parse(match[1]);
80
- return Number.isNaN(date) ? undefined : date;
81
- }
82
- catch {
83
- return undefined;
84
- }
85
- }
@@ -1 +1 @@
1
- {"version":3,"file":"samlBearerAssertion.d.ts","sourceRoot":"","sources":["../../src/auth/samlBearerAssertion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmDzD"}
1
+ {"version":3,"file":"samlBearerAssertion.d.ts","sourceRoot":"","sources":["../../src/auth/samlBearerAssertion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmDzD"}
@@ -24,6 +24,7 @@
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.toBearerAssertion = toBearerAssertion;
26
26
  const xmldom_1 = require("@xmldom/xmldom");
27
+ const strictXml_1 = require("./strictXml");
27
28
  const SAML_ASSERTION_NS = 'urn:oasis:names:tc:SAML:2.0:assertion';
28
29
  const SAML_PROTOCOL_NS = 'urn:oasis:names:tc:SAML:2.0:protocol';
29
30
  function toBearerAssertion(payload) {
@@ -34,7 +35,7 @@ function toBearerAssertion(payload) {
34
35
  }
35
36
  let root;
36
37
  try {
37
- root = new xmldom_1.DOMParser().parseFromString(xml, 'text/xml').documentElement;
38
+ root = (0, strictXml_1.parseStrictXml)(xml).documentElement;
38
39
  }
39
40
  catch (error) {
40
41
  throw new Error(`SAML bearer payload is not well-formed XML: ${error instanceof Error ? error.message : String(error)}`);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Parsing untrusted XML so that any fault is a refusal.
3
+ *
4
+ * @xmldom/xmldom's defaults are wrong for a security boundary in two ways:
5
+ * without `onError` it reports every fault to the console — so a malformed
6
+ * callback from anyone writes to the process's stderr, past `ILogger` — and it
7
+ * recovers from `error`-level faults (an undeclared entity, say) by handing
8
+ * back a repaired document instead of failing. Throwing from `onError` turns
9
+ * every level into a `ParseError`, silently.
10
+ */
11
+ import { type Document } from '@xmldom/xmldom';
12
+ export declare function parseStrictXml(xml: string): Document;
13
+ //# sourceMappingURL=strictXml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strictXml.d.ts","sourceRoot":"","sources":["../../src/auth/strictXml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAMpD"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * Parsing untrusted XML so that any fault is a refusal.
4
+ *
5
+ * @xmldom/xmldom's defaults are wrong for a security boundary in two ways:
6
+ * without `onError` it reports every fault to the console — so a malformed
7
+ * callback from anyone writes to the process's stderr, past `ILogger` — and it
8
+ * recovers from `error`-level faults (an undeclared entity, say) by handing
9
+ * back a repaired document instead of failing. Throwing from `onError` turns
10
+ * every level into a `ParseError`, silently.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.parseStrictXml = parseStrictXml;
14
+ const xmldom_1 = require("@xmldom/xmldom");
15
+ function parseStrictXml(xml) {
16
+ return new xmldom_1.DOMParser({
17
+ onError: (level, message) => {
18
+ throw new Error(`XML ${level}: ${message}`);
19
+ },
20
+ }).parseFromString(xml, 'text/xml');
21
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * An assertion was refused, and by which check.
3
+ *
4
+ * The check is a field rather than something to read out of the message: a
5
+ * consumer telling "your identity provider declined" from "this was not
6
+ * addressed to us" should not be parsing prose to do it.
7
+ */
8
+ import { TokenProviderError } from './TokenProviderErrors';
9
+ /** The checks the shipped validator performs, in the order it performs them. */
10
+ export type AssertionCheck = 'document' | 'duplicateId' | 'signature' | 'signedNode' | 'status' | 'assertionId' | 'issuer' | 'conditions' | 'notBefore' | 'notOnOrAfter' | 'audience' | 'bearerConfirmation' | 'destination' | 'replay';
11
+ export declare class AssertionValidationError extends TokenProviderError {
12
+ readonly check: AssertionCheck;
13
+ constructor(check: AssertionCheck, message: string);
14
+ }
15
+ //# sourceMappingURL=AssertionValidationError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssertionValidationError.d.ts","sourceRoot":"","sources":["../../src/errors/AssertionValidationError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,gFAAgF;AAChF,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,aAAa,GACb,WAAW,GACX,YAAY,GACZ,QAAQ,GACR,aAAa,GACb,QAAQ,GACR,YAAY,GACZ,WAAW,GACX,cAAc,GACd,UAAU,GACV,oBAAoB,GACpB,aAAa,GACb,QAAQ,CAAC;AAEb,qBAAa,wBAAyB,SAAQ,kBAAkB;IAC9D,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;gBAEnB,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM;CAQnD"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * An assertion was refused, and by which check.
4
+ *
5
+ * The check is a field rather than something to read out of the message: a
6
+ * consumer telling "your identity provider declined" from "this was not
7
+ * addressed to us" should not be parsing prose to do it.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.AssertionValidationError = void 0;
11
+ const interfaces_auth_1 = require("@mcp-abap-adt/interfaces-auth");
12
+ const TokenProviderErrors_1 = require("./TokenProviderErrors");
13
+ class AssertionValidationError extends TokenProviderErrors_1.TokenProviderError {
14
+ check;
15
+ constructor(check, message) {
16
+ super(message, interfaces_auth_1.ASSERTION_ERROR_CODES.VALIDATION_ERROR);
17
+ this.name = 'AssertionValidationError';
18
+ this.check = check;
19
+ // Every sibling in TokenProviderErrors.ts does this; without it
20
+ // `instanceof` fails across a compiled boundary.
21
+ Object.setPrototypeOf(this, AssertionValidationError.prototype);
22
+ }
23
+ }
24
+ exports.AssertionValidationError = AssertionValidationError;
@@ -46,4 +46,6 @@ export declare class BrowserAuthError extends TokenProviderError {
46
46
  readonly cause?: Error | undefined;
47
47
  constructor(message: string, cause?: Error | undefined);
48
48
  }
49
+ export type { AssertionCheck } from './AssertionValidationError';
50
+ export { AssertionValidationError } from './AssertionValidationError';
49
51
  //# sourceMappingURL=TokenProviderErrors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TokenProviderErrors.d.ts","sourceRoot":"","sources":["../../src/errors/TokenProviderErrors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAM/B;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,kBAAkB;aAGnC,aAAa,CAAC,EAAE,MAAM,EAAE;gBADxC,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAA;CAM3C;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,kBAAkB;aAGhC,KAAK,CAAC,EAAE,KAAK;gBAD7B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAMhC;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,kBAAkB;aAGpC,aAAa,CAAC,EAAE,MAAM,EAAE;gBADxC,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAA;CAM3C;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,kBAAkB;aAGnC,aAAa,CAAC,EAAE,MAAM,EAAE;gBADxC,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAA;CAM3C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,kBAAkB;aAGpC,KAAK,CAAC,EAAE,KAAK;gBAD7B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAMhC"}
1
+ {"version":3,"file":"TokenProviderErrors.d.ts","sourceRoot":"","sources":["../../src/errors/TokenProviderErrors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAM/B;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,kBAAkB;aAGnC,aAAa,CAAC,EAAE,MAAM,EAAE;gBADxC,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAA;CAM3C;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,kBAAkB;aAGhC,KAAK,CAAC,EAAE,KAAK;gBAD7B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAMhC;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,kBAAkB;aAGpC,aAAa,CAAC,EAAE,MAAM,EAAE;gBADxC,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAA;CAM3C;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,kBAAkB;aAGnC,aAAa,CAAC,EAAE,MAAM,EAAE;gBADxC,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAA;CAM3C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,kBAAkB;aAGpC,KAAK,CAAC,EAAE,KAAK;gBAD7B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAMhC;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -6,7 +6,7 @@
6
6
  * to enable better error handling and debugging.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.BrowserAuthError = exports.ServiceKeyError = exports.SessionDataError = exports.RefreshError = exports.ValidationError = exports.TokenProviderError = void 0;
9
+ exports.AssertionValidationError = exports.BrowserAuthError = exports.ServiceKeyError = exports.SessionDataError = exports.RefreshError = exports.ValidationError = exports.TokenProviderError = void 0;
10
10
  const interfaces_auth_1 = require("@mcp-abap-adt/interfaces-auth");
11
11
  /**
12
12
  * Base class for all token provider errors
@@ -86,3 +86,5 @@ class BrowserAuthError extends TokenProviderError {
86
86
  }
87
87
  }
88
88
  exports.BrowserAuthError = BrowserAuthError;
89
+ var AssertionValidationError_1 = require("./AssertionValidationError");
90
+ Object.defineProperty(exports, "AssertionValidationError", { enumerable: true, get: function () { return AssertionValidationError_1.AssertionValidationError; } });
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { withBrowserCallbackServer } from './auth/callbackServer';
8
8
  export type { OidcCallbackResult } from './auth/oidcBrowserAuth';
9
9
  export { withOidcCallbackServer } from './auth/oidcBrowserAuth';
10
10
  export { withSamlCallbackServer } from './auth/saml2Auth';
11
+ export { type AssertionCheck, AssertionValidationError, } from './errors/AssertionValidationError';
11
12
  export { BrowserAuthError, RefreshError, ServiceKeyError, SessionDataError, TokenProviderError, ValidationError, } from './errors/TokenProviderErrors';
12
13
  export type { AuthorizationCodeProviderConfig, ClientCredentialsProviderConfig, OidcBrowserProviderConfig, OidcDeviceFlowProviderConfig, OidcPasswordProviderConfig, OidcTokenExchangeProviderConfig, Saml2BearerProviderConfig, Saml2PureProviderConfig, UaaPasscodeProviderConfig, } from './providers';
13
14
  export { AuthorizationCodeProvider, BaseTokenProvider, ClientCredentialsProvider, OidcBrowserProvider, OidcDeviceFlowProvider, OidcPasswordProvider, OidcTokenExchangeProvider, Saml2BearerProvider, Saml2PureProvider, UaaPasscodeProvider, } from './providers';
@@ -15,4 +16,6 @@ export { SsoProviderFactory } from './sso/SsoProviderFactory';
15
16
  export type { SsoProviderConfig, SsoProviderInstance } from './sso/types';
16
17
  export type { BrowserCallbackStrategyOptions, CallbackStrategyOptions, ExternalCodeStrategyOptions, ManualStrategyOptions, StaticCodeStrategyOptions, } from './strategies';
17
18
  export { asOidcResult, BrowserCallbackStrategy, browserCallbackStrategy, DEFAULT_CALLBACK_PORT, DEFAULT_LOGIN_TIMEOUT_MS, externalCodeStrategy, manualPasscodeStrategy, manualPasteStrategy, manualSamlResponseStrategy, oidcCallbackStrategy, samlCallbackStrategy, staticCodeStrategy, } from './strategies';
19
+ export { createSignedAssertionValidator, createSignedResponseValidator, type ShippedValidatorOptions, } from './validation/assertionValidator';
20
+ export { createInMemoryReplayStore, defaultReplayStore, } from './validation/inMemoryReplayStore';
18
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,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,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EACV,8BAA8B,EAC9B,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,KAAK,cAAc,EACnB,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,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,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EACV,8BAA8B,EAC9B,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,kCAAkC,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.staticCodeStrategy = exports.samlCallbackStrategy = exports.oidcCallbackStrategy = exports.manualSamlResponseStrategy = exports.manualPasteStrategy = exports.manualPasscodeStrategy = exports.externalCodeStrategy = exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.DEFAULT_CALLBACK_PORT = exports.browserCallbackStrategy = exports.BrowserCallbackStrategy = exports.asOidcResult = exports.SsoProviderFactory = exports.UaaPasscodeProvider = exports.Saml2PureProvider = exports.Saml2BearerProvider = exports.OidcTokenExchangeProvider = exports.OidcPasswordProvider = exports.OidcDeviceFlowProvider = exports.OidcBrowserProvider = exports.ClientCredentialsProvider = exports.BaseTokenProvider = exports.AuthorizationCodeProvider = exports.ValidationError = exports.TokenProviderError = exports.SessionDataError = exports.ServiceKeyError = exports.RefreshError = exports.BrowserAuthError = exports.withSamlCallbackServer = exports.withOidcCallbackServer = exports.withBrowserCallbackServer = void 0;
9
+ exports.defaultReplayStore = exports.createInMemoryReplayStore = exports.createSignedResponseValidator = exports.createSignedAssertionValidator = exports.staticCodeStrategy = exports.samlCallbackStrategy = exports.oidcCallbackStrategy = exports.manualSamlResponseStrategy = exports.manualPasteStrategy = exports.manualPasscodeStrategy = exports.externalCodeStrategy = exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.DEFAULT_CALLBACK_PORT = exports.browserCallbackStrategy = exports.BrowserCallbackStrategy = exports.asOidcResult = exports.SsoProviderFactory = exports.UaaPasscodeProvider = exports.Saml2PureProvider = exports.Saml2BearerProvider = exports.OidcTokenExchangeProvider = exports.OidcPasswordProvider = exports.OidcDeviceFlowProvider = exports.OidcBrowserProvider = exports.ClientCredentialsProvider = exports.BaseTokenProvider = exports.AuthorizationCodeProvider = exports.ValidationError = exports.TokenProviderError = exports.SessionDataError = exports.ServiceKeyError = exports.RefreshError = exports.BrowserAuthError = exports.AssertionValidationError = exports.withSamlCallbackServer = exports.withOidcCallbackServer = exports.withBrowserCallbackServer = void 0;
10
10
  // Callback server factories — "take the transport this package gives".
11
11
  var callbackServer_1 = require("./auth/callbackServer");
12
12
  Object.defineProperty(exports, "withBrowserCallbackServer", { enumerable: true, get: function () { return callbackServer_1.withBrowserCallbackServer; } });
@@ -15,6 +15,8 @@ Object.defineProperty(exports, "withOidcCallbackServer", { enumerable: true, get
15
15
  var saml2Auth_1 = require("./auth/saml2Auth");
16
16
  Object.defineProperty(exports, "withSamlCallbackServer", { enumerable: true, get: function () { return saml2Auth_1.withSamlCallbackServer; } });
17
17
  // Errors
18
+ var AssertionValidationError_1 = require("./errors/AssertionValidationError");
19
+ Object.defineProperty(exports, "AssertionValidationError", { enumerable: true, get: function () { return AssertionValidationError_1.AssertionValidationError; } });
18
20
  var TokenProviderErrors_1 = require("./errors/TokenProviderErrors");
19
21
  Object.defineProperty(exports, "BrowserAuthError", { enumerable: true, get: function () { return TokenProviderErrors_1.BrowserAuthError; } });
20
22
  Object.defineProperty(exports, "RefreshError", { enumerable: true, get: function () { return TokenProviderErrors_1.RefreshError; } });
@@ -51,3 +53,11 @@ Object.defineProperty(exports, "manualSamlResponseStrategy", { enumerable: true,
51
53
  Object.defineProperty(exports, "oidcCallbackStrategy", { enumerable: true, get: function () { return strategies_1.oidcCallbackStrategy; } });
52
54
  Object.defineProperty(exports, "samlCallbackStrategy", { enumerable: true, get: function () { return strategies_1.samlCallbackStrategy; } });
53
55
  Object.defineProperty(exports, "staticCodeStrategy", { enumerable: true, get: function () { return strategies_1.staticCodeStrategy; } });
56
+ // SAML assertion validation — the two shipped validators and the replay store,
57
+ // or bring your own IAssertionValidator / IAssertionReplayStore.
58
+ var assertionValidator_1 = require("./validation/assertionValidator");
59
+ Object.defineProperty(exports, "createSignedAssertionValidator", { enumerable: true, get: function () { return assertionValidator_1.createSignedAssertionValidator; } });
60
+ Object.defineProperty(exports, "createSignedResponseValidator", { enumerable: true, get: function () { return assertionValidator_1.createSignedResponseValidator; } });
61
+ var inMemoryReplayStore_1 = require("./validation/inMemoryReplayStore");
62
+ Object.defineProperty(exports, "createInMemoryReplayStore", { enumerable: true, get: function () { return inMemoryReplayStore_1.createInMemoryReplayStore; } });
63
+ Object.defineProperty(exports, "defaultReplayStore", { enumerable: true, get: function () { return inMemoryReplayStore_1.defaultReplayStore; } });
@@ -14,6 +14,7 @@ export interface Saml2BearerProviderConfig extends Saml2CommonConfig, Saml2Beare
14
14
  }
15
15
  export declare class Saml2BearerProvider extends BaseTokenProvider {
16
16
  private config;
17
+ private readonly validator;
17
18
  constructor(config: Saml2BearerProviderConfig);
18
19
  protected getAuthType(): OAuth2GrantType;
19
20
  protected performLogin(): Promise<ITokenResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"Saml2BearerProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2BearerProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAM9D,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;IAsBrD;;;;OAIG;cACa,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAqBxD"}
1
+ {"version":3,"file":"Saml2BearerProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2BearerProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,YAAY,EACZ,eAAe,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAM9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,yBAAyB,EACzB,iBAAiB,EAClB,MAAM,cAAc,CAAC;AAQtB,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;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;gBAEpC,MAAM,EAAE,yBAAyB;IAqB7C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAgCrD;;;;OAIG;cACa,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAqBxD"}
@@ -13,11 +13,16 @@ const BaseTokenProvider_1 = require("./BaseTokenProvider");
13
13
  const saml2Utils_1 = require("./saml2Utils");
14
14
  class Saml2BearerProvider extends BaseTokenProvider_1.BaseTokenProvider {
15
15
  config;
16
+ validator;
16
17
  constructor(config) {
17
18
  super();
18
19
  // A pre-built URL with no declared ACS cannot be verified against whatever
19
20
  // the strategy binds, so it is refused here rather than at login time.
20
21
  (0, saml2Utils_1.validateSamlConfig)(config);
22
+ // Before anything reaches a browser or a network: a missing certificate is
23
+ // the consumer's mistake, and finding it after a completed login wastes
24
+ // theirs.
25
+ this.validator = (0, saml2Utils_1.resolveAssertionValidator)(config, 'bearer');
21
26
  this.config = config;
22
27
  this.logger = config.logger;
23
28
  if (config.accessToken) {
@@ -32,11 +37,21 @@ class Saml2BearerProvider extends BaseTokenProvider_1.BaseTokenProvider {
32
37
  return interfaces_auth_1.AUTH_TYPE_SAML2_BEARER;
33
38
  }
34
39
  async performLogin() {
35
- const samlResponse = await (0, saml2Utils_1.getSamlAssertion)(this.config);
40
+ const { payload, requestId, acsUrl } = await (0, saml2Utils_1.getSamlAssertion)(this.config);
41
+ // Validation establishes trust before anything reaches the token
42
+ // endpoint; it does not change what is sent beyond toBearerAssertion's
43
+ // conversion below.
44
+ await this.validator.validate(payload, {
45
+ expectedInResponseTo: requestId,
46
+ audience: this.config.spEntityId,
47
+ acsUrl,
48
+ expectedIssuer: this.config.idpEntityId,
49
+ logger: this.logger,
50
+ });
36
51
  const tokenUrl = (0, saml2Utils_1.resolveTokenUrl)(this.config);
37
52
  // RFC 7522 takes one base64url Assertion; a login delivers the whole
38
53
  // Response in standard base64, which a conforming endpoint refuses.
39
- const tokens = await (0, saml2TokenExchange_1.exchangeSamlAssertion)((0, samlBearerAssertion_1.toBearerAssertion)(samlResponse), tokenUrl, this.config.clientId, this.config.clientSecret, this.logger);
54
+ const tokens = await (0, saml2TokenExchange_1.exchangeSamlAssertion)((0, samlBearerAssertion_1.toBearerAssertion)(payload), tokenUrl, this.config.clientId, this.config.clientSecret, this.logger);
40
55
  return {
41
56
  authorizationToken: tokens.accessToken,
42
57
  refreshToken: tokens.refreshToken,
@@ -13,6 +13,7 @@ export interface Saml2PureProviderConfig extends Saml2CommonConfig {
13
13
  }
14
14
  export declare class Saml2PureProvider extends BaseTokenProvider {
15
15
  private config;
16
+ private readonly validator;
16
17
  constructor(config: Saml2PureProviderConfig);
17
18
  protected getAuthType(): OAuth2GrantType;
18
19
  protected performLogin(): Promise<ITokenResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"Saml2PureProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2PureProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,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"}
1
+ {"version":3,"file":"Saml2PureProvider.d.ts","sourceRoot":"","sources":["../../src/providers/Saml2PureProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,YAAY,EACZ,eAAe,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAOtD,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;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;gBAEpC,MAAM,EAAE,uBAAuB;IAc3C,SAAS,CAAC,WAAW,IAAI,eAAe;cAIxB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAuBrC,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAGxD"}
@@ -7,16 +7,20 @@
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.Saml2PureProvider = void 0;
9
9
  const interfaces_auth_1 = require("@mcp-abap-adt/interfaces-auth");
10
- const saml2Auth_1 = require("../auth/saml2Auth");
11
10
  const BaseTokenProvider_1 = require("./BaseTokenProvider");
12
11
  const saml2Utils_1 = require("./saml2Utils");
13
12
  class Saml2PureProvider extends BaseTokenProvider_1.BaseTokenProvider {
14
13
  config;
14
+ validator;
15
15
  constructor(config) {
16
16
  super();
17
17
  // A pre-built URL with no declared ACS cannot be verified against whatever
18
18
  // the strategy binds, so it is refused here rather than at login time.
19
19
  (0, saml2Utils_1.validateSamlConfig)(config);
20
+ // Before anything reaches a browser or a network: a missing certificate is
21
+ // the consumer's mistake, and finding it after a completed login wastes
22
+ // theirs.
23
+ this.validator = (0, saml2Utils_1.resolveAssertionValidator)(config, 'pure');
20
24
  this.config = config;
21
25
  this.logger = config.logger;
22
26
  this.tokenType = 'saml';
@@ -25,14 +29,24 @@ class Saml2PureProvider extends BaseTokenProvider_1.BaseTokenProvider {
25
29
  return interfaces_auth_1.AUTH_TYPE_USER_TOKEN;
26
30
  }
27
31
  async performLogin() {
28
- const samlResponse = await (0, saml2Utils_1.getSamlAssertion)(this.config);
29
- const expiresAt = (0, saml2Auth_1.parseSamlNotOnOrAfter)(samlResponse);
30
- const sessionCookies = await this.config.cookieProvider(samlResponse);
32
+ const { payload, requestId, acsUrl } = await (0, saml2Utils_1.getSamlAssertion)(this.config);
33
+ // acsUrl is where the strategy actually listened — with an ephemeral port
34
+ // the configured value is usually absent and never authoritative.
35
+ const validated = await this.validator.validate(payload, {
36
+ expectedInResponseTo: requestId,
37
+ audience: this.config.spEntityId,
38
+ acsUrl,
39
+ expectedIssuer: this.config.idpEntityId,
40
+ logger: this.logger,
41
+ });
42
+ const sessionCookies = await this.config.cookieProvider(payload);
31
43
  return {
32
44
  authorizationToken: sessionCookies,
33
45
  authType: interfaces_auth_1.AUTH_TYPE_USER_TOKEN,
34
46
  tokenType: 'saml',
35
- expiresAt,
47
+ // ITokenResult.expiresAt is an epoch-ms number, unlike
48
+ // ValidatedAssertion.expiresAt, which is a Date.
49
+ expiresAt: validated.expiresAt.getTime(),
36
50
  };
37
51
  }
38
52
  async performRefresh() {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * SAML2 provider shared helpers.
3
3
  */
4
- import type { IAuthorizationStrategy } from '@mcp-abap-adt/interfaces-auth';
4
+ import type { IAssertionReplayStore, IAssertionValidator, IAuthorizationStrategy } from '@mcp-abap-adt/interfaces-auth';
5
5
  import type { ILogger } from '@mcp-abap-adt/interfaces-utils';
6
6
  export interface Saml2CommonConfig {
7
7
  idpSsoUrl: string;
@@ -17,6 +17,32 @@ export interface Saml2CommonConfig {
17
17
  /** How the login is conducted. Omitted means a browser callback. */
18
18
  authorization?: IAuthorizationStrategy<string>;
19
19
  logger?: ILogger;
20
+ /** PEM or bare base64 DER. Required when no `assertionValidator` is supplied. */
21
+ idpCertificates?: string[];
22
+ /**
23
+ * The `Issuer` the assertion must name. Required unless the supplied
24
+ * `assertionValidator` is a custom one: a shipped validator supplied there
25
+ * still needs it, since it fails closed without an expected issuer.
26
+ */
27
+ idpEntityId?: string;
28
+ /** Finite, non-negative, integer. Defaults to 0. */
29
+ clockSkewMs?: number;
30
+ /**
31
+ * The AuthnRequest ID this login answers, when this package did not mint one
32
+ * itself — a pre-built `authorizationUrl`, or a strategy that obtained the
33
+ * response some other way after a request the consumer sent.
34
+ */
35
+ authnRequestId?: string;
36
+ /**
37
+ * Declares that no AuthnRequest is sent: the assertion must carry no
38
+ * `InResponseTo`. Default `false`. Combining this with a minted or declared
39
+ * request ID is a configuration error: the two describe different logins.
40
+ */
41
+ idpInitiated?: boolean;
42
+ /** Which validator to use. Omitted means the provider's own default. */
43
+ assertionValidator?: IAssertionValidator;
44
+ /** A consumer's own replay store, for a deployment running more than one process. */
45
+ assertionReplayStore?: IAssertionReplayStore;
20
46
  }
21
47
  export interface Saml2BearerExchangeConfig {
22
48
  tokenUrl?: string;
@@ -26,6 +52,27 @@ export interface Saml2BearerExchangeConfig {
26
52
  }
27
53
  /** Throw at construction rather than half-verify at runtime. */
28
54
  export declare function validateSamlConfig(config: Saml2CommonConfig): void;
55
+ /**
56
+ * The consumer's validator when supplied, otherwise the provider's default —
57
+ * `createSignedAssertionValidator` for `"bearer"`, since the token endpoint
58
+ * receives the Assertion alone (#40) and its own signature is what that
59
+ * endpoint verifies; `createSignedResponseValidator` for `"pure"`, since the
60
+ * whole response is handed on and `Status`/`Destination` must be inside a
61
+ * signature. See the spec's "A bare Assertion, and which validator each
62
+ * provider defaults to".
63
+ */
64
+ export declare function resolveAssertionValidator(config: Saml2CommonConfig, provider: 'bearer' | 'pure'): IAssertionValidator;
29
65
  export declare function resolveTokenUrl(config: Saml2BearerExchangeConfig): string;
30
- export declare function getSamlAssertion(config: Saml2CommonConfig): Promise<string>;
66
+ /** What `getSamlAssertion` hands back: the wire payload, plus what it knows about the login. */
67
+ export interface SamlAssertionResult {
68
+ readonly payload: string;
69
+ /**
70
+ * `undefined` exactly when the login is declared `idpInitiated` and no ID
71
+ * was minted or declared for it.
72
+ */
73
+ readonly requestId?: string;
74
+ /** Where the strategy actually listened — `outcome.redirectUri`, never `config.acsUrl`. */
75
+ readonly acsUrl: string;
76
+ }
77
+ export declare function getSamlAssertion(config: Saml2CommonConfig): Promise<SamlAssertionResult>;
31
78
  //# 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,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAI9D,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
+ {"version":3,"file":"saml2Utils.d.ts","sourceRoot":"","sources":["../../src/providers/saml2Utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAU9D,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;IACjB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;IACzC,qFAAqF;IACrF,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;CAC9C;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;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAC1B,mBAAmB,CAsCrB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAQzE;AAED,gGAAgG;AAChG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAuE9B"}