@mcp-abap-adt/auth-broker 4.0.0 → 5.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.
package/dist/binding.d.ts CHANGED
@@ -1,95 +1,168 @@
1
1
  /**
2
- * A secret is bound to the resource it was obtained for and to who issued it.
2
+ * A secret is bound to the resource it was obtained for and to everything that
3
+ * decides where it goes and whose it is.
3
4
  *
4
- * The session store keeps two strings beside the secret — `issuedFor`, the
5
- * resource, and `issuedBy`, the issuer and its client — and the broker uses a
6
- * stored secret only when both equal what this destination's means give. The
7
- * store keeps them as given; the broker canonicalises **both sides** before it
8
- * compares, with the one function here (the broker's only, decided), so a store
9
- * need not canonicalise and a legacy file's composed URI compares equal.
5
+ * The session store keeps two strings beside the secret, and the broker uses a
6
+ * stored secret only when both equal what this destination's means give:
10
7
  *
11
- * The canonical URI:
12
- * - scheme and host lower-cased (by `URL`, for http and https);
13
- * - the port explicit — `443` for `https`, `80` for `http` when the URL has
14
- * none; another scheme keeps the port it states;
15
- * - the path without a trailing `/` (the root path is empty), its case kept;
16
- * - one query parameter at most — `sap-client=<n>` for a resource,
17
- * `client_id=<id>` for an issuer, none for a SAML ACS — parsed and
18
- * re-encoded with `URLSearchParams`, so a value percent-encoded on one side
19
- * and plain on the other compares equal;
20
- * - no user info, no other parameter, no fragment.
8
+ * - **`issuedFor`**, the resource: `serviceUrl` with the SAP client, in the
9
+ * canonical form 4.x wrote (`resourceUri`). Both sides are canonicalised
10
+ * before they are compared, so a stored value written by any 4.x-era
11
+ * consumer compares equal.
12
+ * - **`issuedBy`**, a versioned record only the broker produces
13
+ * (`bindingRecord`):
21
14
  *
22
- * A URL that does not parse, or has no host, has no canonical form: the
23
- * binding is then absent, never guessed.
15
+ * ```
16
+ * mcp-abap-adt-binding/2;<row>;<eleven address fields>;<trust>
17
+ * ```
18
+ *
19
+ * `row` is `authType/grantType` (or `provider/…` for the token API's
20
+ * consumer provider); each address field is the exact string the row hands
21
+ * its provider — `encodeURIComponent`-encoded, `""` when it hands none, never
22
+ * canonicalised — in the fixed order of `RECORD_FIELDS`; `trust` is the
23
+ * SHA-256 of the row's non-secret trust input (`trustDigest`), or `""`.
24
+ * The record is compared by exact equality and never parsed, split or
25
+ * matched; no regular expression touches it.
26
+ *
27
+ * No secret takes part in either string, nor a hash of one: a hash in a
28
+ * session file can be checked offline against guesses.
24
29
  */
25
30
  import type { IConfig, IConnectionConfig } from '@mcp-abap-adt/interfaces-auth-broker';
26
31
  import type { IAuthorizationConfig } from '@mcp-abap-adt/interfaces-auth-sap';
32
+ /** What a binding reads of a client: who it is, never its secret. */
33
+ export type BoundClient = Pick<IAuthorizationConfig, 'uaaUrl' | 'uaaClientId'>;
27
34
  /**
28
- * The resource: `serviceUrl` with the SAP client as `sap-client` — the
29
- * destination's `sapClient` when it states one, over a `sap-client` already in
30
- * the URL. For a stored value, call it without `sapClient`.
35
+ * The certificate client a build read for the `clientAuthentication`
36
+ * strategy, as the store answered it: where its token endpoint is, and its
37
+ * public certificate — never its key.
31
38
  */
32
- export declare function resourceUri(serviceUrl: unknown, sapClient?: string): string | undefined;
39
+ export interface BoundCertificate {
40
+ readonly certUrl: unknown;
41
+ readonly certificate: unknown;
42
+ }
43
+ /** The eleven address fields of the record, in their fixed order. */
44
+ export declare const RECORD_FIELDS: readonly ["clientId", "uaaUrl", "oidcIssuerUrl", "oidcTokenEndpoint", "oidcAuthorizationEndpoint", "oidcDeviceAuthorizationEndpoint", "oidcAudience", "samlIdpSsoUrl", "samlAcsUrl", "samlTokenUrl", "certUrl"];
45
+ /** The address values a row hands its provider; any one may be absent. */
46
+ export type RecordFields = Partial<Record<(typeof RECORD_FIELDS)[number], unknown>>;
47
+ /**
48
+ * The `issuedBy` record: the version, the row, the eleven address fields in
49
+ * their fixed order — each the exact string, encoded, `""` when absent or
50
+ * `''` — and the trust digest. Every field is always present, and none holds
51
+ * `;`, so the string is unambiguous without being parsed.
52
+ */
53
+ export declare function bindingRecord(row: string, fields: RecordFields, trust: string): string;
33
54
  /**
34
- * The issuer and its client: the authorization server's base URL with
35
- * `client_id`. For a stored value, call it without `clientId`.
55
+ * The trust digest: lower-case hex SHA-256 of the UTF-8 bytes of
56
+ * `"mcp-abap-adt-binding/2/trust\n"` and the JSON of the `[name, value]` pairs
57
+ * in the row's fixed order — no trimming, no canonicalisation. JSON of arrays
58
+ * and primitives has one output (lone surrogates escaped), so equal inputs
59
+ * give equal bytes.
36
60
  */
37
- export declare function issuerUri(issuerUrl: unknown, clientId?: string): string | undefined;
38
- /** The ACS of the system that set SAML session cookies: origin and path. */
39
- export declare function acsUri(acsUrl: unknown): string | undefined;
40
- /** How a stored `issuedBy` is read: as an issuer with its client, or as an ACS. */
41
- export type IssuerKind = 'issuer' | 'acs';
42
- /** What this destination's means bind a secret to, canonical; absent where they cannot say. */
61
+ export declare function trustDigest(pairs: readonly (readonly [string, unknown])[]): string;
62
+ /** What this destination's means bind a secret to. */
43
63
  export interface Binding {
44
- issuedFor?: string;
45
- issuedBy?: string;
46
- /** How the stored `issuedBy` is canonicalised before it is compared. */
47
- issuerKind: IssuerKind;
64
+ /** The canonical resource; absent when the means state none. */
65
+ issuedFor?: string | undefined;
66
+ /** The record: always present — at least the row. */
67
+ issuedBy: string;
68
+ /**
69
+ * The record holds the client the row authenticates and every server
70
+ * address its provider sends a credential to. Only such a
71
+ * binding is seeded from a stored session, or carries its refresh token.
72
+ */
73
+ fullyStated: boolean;
48
74
  /**
49
- * The means state an issuer — for a `none` row, whether `issuedBy` is
50
- * compared at all. True even when the stated URL does not parse: then it
51
- * matches nothing.
75
+ * Set on the `clientAuthentication` strategy path only: a resource neither
76
+ * side states — no `issuedFor` computed and none stored — matches, so the
77
+ * record alone decides. A resource stated on one side only never matches.
52
78
  */
53
- issuerStated: boolean;
79
+ unstatedResourceMatches?: true;
54
80
  }
55
81
  /**
56
- * The UAA grants (`authorization_code`, `client_credentials`, `passcode`) and
57
- * `saml2_bearer`, whose token UAA issues to its client: the resource, and `uaaUrl` with `uaaClientId` — both required to match.
82
+ * The canonical resource URI, as 4.x wrote it: scheme and host lower-cased
83
+ * (by `URL`, for http and https); the port explicit (`443` / `80` by
84
+ * default); the path without a trailing `/`, its case kept; one query
85
+ * parameter, `sap-client=<n>` — `sapClient` when given, else the one the URL
86
+ * carries — re-encoded with `URLSearchParams`; no user info, no other
87
+ * parameter, no fragment. A URL that does not parse, or has no host, has no
88
+ * canonical form: `undefined`, never guessed. For a stored value, call it
89
+ * without `sapClient`.
90
+ */
91
+ export declare function resourceUri(serviceUrl: unknown, sapClient?: string): string | undefined;
92
+ /**
93
+ * The UAA grants (`authorization_code`, `client_credentials`, `passcode`):
94
+ * the client id and `uaaUrl` as the provider receives them, and `certUrl`
95
+ * when the build read the certificate client; trust is the client
96
+ * certificate. Fully stated with the client, `uaaUrl` and — when read —
97
+ * `certUrl`.
58
98
  */
59
- export declare function uaaBinding(means: IConnectionConfig, client: IAuthorizationConfig | null): Binding;
99
+ export declare function uaaBinding(grant: string, means: IConnectionConfig, client: BoundClient | null, certificate: BoundCertificate | null): Binding;
60
100
  /**
61
- * The OIDC grants: the resource, and the issuer — `oidcIssuerUrl`, else
62
- * `uaaUrl` — with `uaaClientId`; both required to match. Means that state
63
- * neither issuer (explicit endpoints alone) bind no stored secret: one is then
64
- * never seeded.
101
+ * The OIDC grants: the client id, `oidcIssuerUrl`, `oidcTokenEndpoint`, and
102
+ * the grant's own endpoint (`oidcAuthorizationEndpoint`,
103
+ * `oidcDeviceAuthorizationEndpoint`) or audience (`oidcAudience`), and
104
+ * `certUrl` when read; trust is the scopes, the `password` grant's
105
+ * `username`, the token-exchange token types, and the client certificate.
106
+ *
107
+ * Fully stated with the client, each endpoint the grant sends to — explicit,
108
+ * or the issuer it is discovered from — and `certUrl` when read;
109
+ * `token_exchange` never: its subject token, a secret, decides whose
110
+ * credential it obtains.
65
111
  */
66
- export declare function oidcBinding(means: IConnectionConfig, client: IAuthorizationConfig | null): Binding;
112
+ export declare function oidcBinding(grant: string, means: IConnectionConfig, client: BoundClient | null, certificate: BoundCertificate | null): Binding;
67
113
  /**
68
- * `saml2_pure`: the resource, and the ACS of the system that sets the
69
- * cookies — `samlAcsUrl`, origin and path; both required to match.
114
+ * `saml2_pure`: the IdP's SSO URL and the ACS of the system that sets the
115
+ * cookies; trust is the SAML trust. Fully stated with both.
70
116
  */
71
117
  export declare function samlPureBinding(means: IConnectionConfig): Binding;
72
118
  /**
73
- * The token API with a consumer's provider: what the broker handed
74
- * that provider — the `serviceUrl` it resolved, with the SAP client, and for a
75
- * factory the client it resolved (`uaaUrl` with `uaaClientId`). An instance is
76
- * handed no client, so no issuer is claimed for what it obtains: `issuedBy` is
77
- * then absent, and `getProvider` never seeds from that secret.
119
+ * `saml2_bearer`: the client id, `uaaUrl`, the IdP's SSO URL, the ACS,
120
+ * `samlTokenUrl`, and `certUrl` when read; trust is the SAML trust and the
121
+ * client certificate. Fully stated with the client, the IdP, the token
122
+ * endpoint (`samlTokenUrl`, or `uaaUrl`) and — when read — `certUrl`.
123
+ */
124
+ export declare function samlBearerBinding(means: IConnectionConfig, client: BoundClient | null, certificate: BoundCertificate | null): Binding;
125
+ /**
126
+ * A `none` row: the resource, and the record — for `jwt` the client id,
127
+ * `uaaUrl` and `oidcIssuerUrl` as the means state them, for `saml` the ACS;
128
+ * no trust. A handed-over credential is compared by exact equality of the
129
+ * whole record; it is never seeded into a renewal, so it is not
130
+ * "fully stated".
131
+ */
132
+ export declare function handedOverBinding(authType: 'jwt' | 'saml', means: IConnectionConfig, client: BoundClient | null): Binding;
133
+ /**
134
+ * The token API with a consumer's provider: the `serviceUrl` it resolved,
135
+ * with the SAP client, and the record `provider/<row>` — for a factory the
136
+ * client id and `uaaUrl` of the client it was handed, for an instance (handed
137
+ * no client) none; no trust. Never fully stated: the broker cannot know what
138
+ * the factory composes, and an instance is handed no client.
139
+ */
140
+ export declare function consumerBinding(row: string, serviceUrl: string, sapClient: string | undefined, client: BoundClient | null): Binding;
141
+ /**
142
+ * A binding on the `clientAuthentication` strategy path: a resource that
143
+ * neither the means nor the stored session state matches
144
+ * (`Binding.unstatedResourceMatches`).
78
145
  */
79
- export declare function consumerBinding(serviceUrl: string, sapClient: string | undefined, client: IAuthorizationConfig | null): Binding;
146
+ export declare function strategyBinding(binding: Binding): Binding;
80
147
  /**
81
- * A `none` row: the resource always; the issuer only when the means state one
82
- * — `oidcIssuerUrl` (with `uaaClientId` when stated) or the client (`uaaUrl`
83
- * and `uaaClientId`) for `jwt`, `samlAcsUrl` for `saml`.
148
+ * The stored `issuedFor`, canonicalised, equals the destination's — or, with
149
+ * `unstatedResourceMatches`, neither states one.
84
150
  */
85
- export declare function handedOverBinding(authType: 'jwt' | 'saml', means: IConnectionConfig, client: IAuthorizationConfig | null): Binding;
86
- /** The stored `issuedFor`, canonicalised, equals the destination's. */
87
151
  export declare function sameResource(stored: IConfig | null, binding: Binding): boolean;
88
- /** The stored `issuedBy`, canonicalised as the destination's kind, equals it. */
89
- export declare function sameIssuer(stored: IConfig | null, binding: Binding): boolean;
152
+ /** The stored `issuedBy` is exactly this binding's record. */
153
+ export declare function sameRecord(stored: IConfig | null, binding: Binding): boolean;
154
+ /**
155
+ * Whether any stored secret could ever seed this binding's provider: the
156
+ * binding is fully stated and its resource can match — stated, or matching
157
+ * when neither side states one (`unstatedResourceMatches`). The condition
158
+ * `boundHere` needs beside the stored values.
159
+ */
160
+ export declare function couldBeSeeded(binding: Binding): boolean;
90
161
  /**
91
- * An obtained secret is this destination's only when **both** stored values
92
- * equal the computed ones; either absent, on either side, is not a match.
162
+ * A stored secret may seed this binding's provider — or have its refresh
163
+ * token carried — only when the binding is fully stated, the resource
164
+ * matches, and the stored `issuedBy` is exactly the record. A session with no
165
+ * `issuedBy`, or a 4.x one, never matches.
93
166
  */
94
167
  export declare function boundHere(stored: IConfig | null, binding: Binding): boolean;
95
168
  //# sourceMappingURL=binding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,iBAAiB,EAClB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AA6C9E;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,OAAO,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CAEpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,SAAS,EAAE,OAAO,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAEpB;AAED,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE1D;AAED,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE1C,+FAA+F;AAC/F,MAAM,WAAW,OAAO;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,UAAU,EAAE,UAAU,CAAC;IACvB;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAUD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAClC,OAAO,CAUT;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAClC,OAAO,CAWT;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAOjE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAClC,OAAO,CAET;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,KAAK,GAAG,MAAM,EACxB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAClC,OAAO,CA4BT;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,OAAO,GAAG,IAAI,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAI5E;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAE3E"}
1
+ {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"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"}