@mcp-abap-adt/connection 5.0.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +243 -1
- package/README.md +204 -48
- package/bin/sap-abap-auth.js +101 -13
- package/dist/auth/providers.d.ts +38 -9
- package/dist/auth/providers.d.ts.map +1 -1
- package/dist/auth/providers.js +46 -3
- package/dist/connection/AbstractAbapConnection.d.ts +83 -136
- package/dist/connection/AbstractAbapConnection.d.ts.map +1 -1
- package/dist/connection/AbstractAbapConnection.js +241 -763
- package/dist/connection/AdtCloudConnector.d.ts +12 -7
- package/dist/connection/AdtCloudConnector.d.ts.map +1 -1
- package/dist/connection/AdtCloudConnector.js +2 -6
- package/dist/connection/AdtOnPremConnector.d.ts +20 -7
- package/dist/connection/AdtOnPremConnector.d.ts.map +1 -1
- package/dist/connection/AdtOnPremConnector.js +2 -6
- package/dist/connection/CloudHttpTransport.d.ts +37 -0
- package/dist/connection/CloudHttpTransport.d.ts.map +1 -0
- package/dist/{session/CloudSecuritySessionStrategy.js → connection/CloudHttpTransport.js} +59 -49
- package/dist/connection/CredentialAbapConnection.d.ts +8 -41
- package/dist/connection/CredentialAbapConnection.d.ts.map +1 -1
- package/dist/connection/CredentialAbapConnection.js +44 -111
- package/dist/connection/HttpTransport.d.ts +178 -0
- package/dist/connection/HttpTransport.d.ts.map +1 -0
- package/dist/connection/HttpTransport.js +402 -0
- package/dist/connection/IAdtTransport.d.ts +232 -0
- package/dist/connection/IAdtTransport.d.ts.map +1 -0
- package/dist/connection/IAdtTransport.js +28 -0
- package/dist/connection/LegacyOnPremHttpTransport.d.ts +40 -0
- package/dist/connection/LegacyOnPremHttpTransport.d.ts.map +1 -0
- package/dist/connection/LegacyOnPremHttpTransport.js +57 -0
- package/dist/connection/OnPremHttpTransport.d.ts +45 -0
- package/dist/connection/OnPremHttpTransport.d.ts.map +1 -0
- package/dist/connection/OnPremHttpTransport.js +91 -0
- package/dist/connection/RfcTransport.d.ts +89 -0
- package/dist/connection/RfcTransport.d.ts.map +1 -0
- package/dist/connection/RfcTransport.js +270 -0
- package/dist/connection/rfcConversation.d.ts +44 -0
- package/dist/connection/rfcConversation.d.ts.map +1 -0
- package/dist/connection/rfcConversation.js +71 -0
- package/dist/index.d.ts +7 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -18
- package/dist/utils/timeouts.d.ts +6 -19
- package/dist/utils/timeouts.d.ts.map +1 -1
- package/dist/utils/timeouts.js +6 -22
- package/docs/INDEX.md +5 -2
- package/docs/INSTALLATION.md +28 -10
- package/docs/JWT_AUTH_TOOLS.md +20 -4
- package/docs/MIGRATION-6.0.md +359 -0
- package/docs/SCOPE.md +1 -1
- package/docs/STATEFUL_SESSION_GUIDE.md +86 -17
- package/docs/USAGE.md +260 -119
- package/examples/basic-connection.js +15 -3
- package/examples/jwt-with-token-refresh.js +15 -7
- package/examples/saml-connection.js +15 -2
- package/package.json +12 -11
- package/dist/__tests__/helpers/session.d.ts +0 -15
- package/dist/__tests__/helpers/session.d.ts.map +0 -1
- package/dist/__tests__/helpers/session.js +0 -19
- package/dist/auth/IAuthProvider.d.ts +0 -84
- package/dist/auth/IAuthProvider.d.ts.map +0 -1
- package/dist/auth/IAuthProvider.js +0 -21
- package/dist/connection/BaseAbapConnection.d.ts +0 -29
- package/dist/connection/BaseAbapConnection.d.ts.map +0 -1
- package/dist/connection/BaseAbapConnection.js +0 -81
- package/dist/connection/CertificateAbapConnection.d.ts +0 -35
- package/dist/connection/CertificateAbapConnection.d.ts.map +0 -1
- package/dist/connection/CertificateAbapConnection.js +0 -91
- package/dist/connection/JwtAbapConnection.d.ts +0 -131
- package/dist/connection/JwtAbapConnection.d.ts.map +0 -1
- package/dist/connection/JwtAbapConnection.js +0 -376
- package/dist/connection/KerberosAbapConnection.d.ts +0 -32
- package/dist/connection/KerberosAbapConnection.d.ts.map +0 -1
- package/dist/connection/KerberosAbapConnection.js +0 -128
- package/dist/connection/RfcAbapConnection.d.ts +0 -44
- package/dist/connection/RfcAbapConnection.d.ts.map +0 -1
- package/dist/connection/RfcAbapConnection.js +0 -324
- package/dist/connection/SamlAbapConnection.d.ts +0 -31
- package/dist/connection/SamlAbapConnection.d.ts.map +0 -1
- package/dist/connection/SamlAbapConnection.js +0 -81
- package/dist/connection/connectionFactory.d.ts +0 -25
- package/dist/connection/connectionFactory.d.ts.map +0 -1
- package/dist/connection/connectionFactory.js +0 -84
- package/dist/session/CloudSecuritySessionStrategy.d.ts +0 -32
- package/dist/session/CloudSecuritySessionStrategy.d.ts.map +0 -1
- package/dist/session/IcfSessionStrategy.d.ts +0 -27
- package/dist/session/IcfSessionStrategy.d.ts.map +0 -1
- package/dist/session/IcfSessionStrategy.js +0 -62
- package/dist/session/SessionStrategy.d.ts +0 -86
- package/dist/session/SessionStrategy.d.ts.map +0 -1
- package/dist/session/SessionStrategy.js +0 -33
- package/docs/superpowers/specs/2026-08-21-platform-connectors.md +0 -108
package/bin/sap-abap-auth.js
CHANGED
|
@@ -3,7 +3,6 @@ const fs = require("fs");
|
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const axios = require("axios");
|
|
5
5
|
const { program } = require("commander");
|
|
6
|
-
const express = require("express");
|
|
7
6
|
const open = require("open").default;
|
|
8
7
|
const http = require("http");
|
|
9
8
|
|
|
@@ -262,6 +261,57 @@ function getJwtAuthorizationUrl(serviceKey, port = 3001) {
|
|
|
262
261
|
)}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
263
262
|
}
|
|
264
263
|
|
|
264
|
+
/**
|
|
265
|
+
* How long to wait for the browser to come back.
|
|
266
|
+
*
|
|
267
|
+
* Five minutes was the fixed value, and a real BTP login does not fit in it:
|
|
268
|
+
* the identity provider, a password manager and whatever second factor the
|
|
269
|
+
* tenant asks for all happen before the redirect is issued. Measured twice —
|
|
270
|
+
* both times the window closed first, and the browser then had nowhere to
|
|
271
|
+
* redirect to, which reads to the user as the authentication having failed.
|
|
272
|
+
*
|
|
273
|
+
* So it is a decision the caller makes: `--timeout` in minutes, or
|
|
274
|
+
* `SAP_AUTH_TIMEOUT_MS` for a script that would rather not pass an argument.
|
|
275
|
+
* The default is fifteen, which covered the login this was measured against
|
|
276
|
+
* with room to spare and still bounds a run that has been abandoned.
|
|
277
|
+
*/
|
|
278
|
+
const DEFAULT_AUTH_TIMEOUT_MS = 15 * 60 * 1000;
|
|
279
|
+
|
|
280
|
+
function resolveAuthTimeout(minutes) {
|
|
281
|
+
if (minutes !== undefined) {
|
|
282
|
+
const value = Number(minutes);
|
|
283
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
284
|
+
throw new Error(
|
|
285
|
+
`--timeout must be a positive number of minutes, got: ${minutes}`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
return value * 60 * 1000;
|
|
289
|
+
}
|
|
290
|
+
const fromEnv = process.env.SAP_AUTH_TIMEOUT_MS;
|
|
291
|
+
if (fromEnv !== undefined && fromEnv !== "") {
|
|
292
|
+
const value = Number(fromEnv);
|
|
293
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`SAP_AUTH_TIMEOUT_MS must be a positive number of milliseconds, got: ${fromEnv}`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
return value;
|
|
299
|
+
}
|
|
300
|
+
return DEFAULT_AUTH_TIMEOUT_MS;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* One reply, with the header express used to set on our behalf.
|
|
305
|
+
*
|
|
306
|
+
* `res.send()` chose a Content-Type from what it was handed; `node:http` sends
|
|
307
|
+
* exactly what it is told, so the type is stated here. Without it a browser is
|
|
308
|
+
* free to render the success page as plain text.
|
|
309
|
+
*/
|
|
310
|
+
function send(res, status, contentType, body) {
|
|
311
|
+
res.writeHead(status, { "Content-Type": contentType });
|
|
312
|
+
res.end(body);
|
|
313
|
+
}
|
|
314
|
+
|
|
265
315
|
/**
|
|
266
316
|
* Starts a local server to intercept the authentication response
|
|
267
317
|
* @param {Object} serviceKey SAP BTP service key object
|
|
@@ -269,26 +319,42 @@ function getJwtAuthorizationUrl(serviceKey, port = 3001) {
|
|
|
269
319
|
* @param {string} flow Flow type: jwt (OAuth2)
|
|
270
320
|
* @returns {Promise<{accessToken: string, refreshToken?: string}>} Promise that resolves to tokens
|
|
271
321
|
*/
|
|
272
|
-
async function startAuthServer(
|
|
322
|
+
async function startAuthServer(
|
|
323
|
+
serviceKey,
|
|
324
|
+
browser = undefined,
|
|
325
|
+
flow = "jwt",
|
|
326
|
+
timeoutMs = DEFAULT_AUTH_TIMEOUT_MS
|
|
327
|
+
) {
|
|
273
328
|
return new Promise((resolve, reject) => {
|
|
274
|
-
const app = express();
|
|
275
|
-
const server = http.createServer(app);
|
|
276
329
|
const PORT = 3001;
|
|
277
330
|
let serverInstance = null;
|
|
278
331
|
|
|
279
332
|
// Choose the authorization URL
|
|
280
333
|
const authorizationUrl = getJwtAuthorizationUrl(serviceKey, PORT);
|
|
281
334
|
|
|
282
|
-
// JWT OAuth2 flow (get code, exchange for token)
|
|
283
|
-
|
|
335
|
+
// JWT OAuth2 flow (get code, exchange for token). One route, and the
|
|
336
|
+
// routing express did is two comparisons: a browser fetching /favicon.ico
|
|
337
|
+
// must not be mistaken for the redirect we are waiting for.
|
|
338
|
+
const server = http.createServer(async (req, res) => {
|
|
339
|
+
const url = new URL(req.url, `http://localhost:${PORT}`);
|
|
340
|
+
if (req.method !== "GET" || url.pathname !== "/callback") {
|
|
341
|
+
send(res, 404, "text/plain; charset=utf-8", "Not Found");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
284
345
|
try {
|
|
285
|
-
const
|
|
346
|
+
const code = url.searchParams.get("code");
|
|
286
347
|
if (!code) {
|
|
287
|
-
|
|
348
|
+
send(
|
|
349
|
+
res,
|
|
350
|
+
400,
|
|
351
|
+
"text/plain; charset=utf-8",
|
|
352
|
+
"Error: Authorization code missing"
|
|
353
|
+
);
|
|
288
354
|
return reject(new Error("Authorization code missing"));
|
|
289
355
|
}
|
|
290
356
|
console.log("Authorization code received");
|
|
291
|
-
|
|
357
|
+
send(res, 200, "text/html; charset=utf-8", `<!DOCTYPE html>
|
|
292
358
|
<html lang="en">
|
|
293
359
|
<head>
|
|
294
360
|
<meta charset="UTF-8">
|
|
@@ -363,7 +429,12 @@ async function startAuthServer(serviceKey, browser = undefined, flow = "jwt") {
|
|
|
363
429
|
}
|
|
364
430
|
} catch (error) {
|
|
365
431
|
console.error("Error handling callback:", error);
|
|
366
|
-
|
|
432
|
+
send(
|
|
433
|
+
res,
|
|
434
|
+
500,
|
|
435
|
+
"text/plain; charset=utf-8",
|
|
436
|
+
"Error processing authentication"
|
|
437
|
+
);
|
|
367
438
|
reject(error);
|
|
368
439
|
}
|
|
369
440
|
});
|
|
@@ -395,9 +466,17 @@ async function startAuthServer(serviceKey, browser = undefined, flow = "jwt") {
|
|
|
395
466
|
setTimeout(() => {
|
|
396
467
|
if (serverInstance) {
|
|
397
468
|
serverInstance.close();
|
|
398
|
-
reject(
|
|
469
|
+
reject(
|
|
470
|
+
new Error(
|
|
471
|
+
`Authentication timeout after ${
|
|
472
|
+
timeoutMs >= 60000
|
|
473
|
+
? `${Math.round(timeoutMs / 60000)} min`
|
|
474
|
+
: `${Math.round(timeoutMs / 1000)}s`
|
|
475
|
+
}. Process aborted. Raise it with --timeout <minutes> or SAP_AUTH_TIMEOUT_MS if the login needs longer.`
|
|
476
|
+
)
|
|
477
|
+
);
|
|
399
478
|
}
|
|
400
|
-
},
|
|
479
|
+
}, timeoutMs);
|
|
401
480
|
});
|
|
402
481
|
}
|
|
403
482
|
|
|
@@ -540,6 +619,10 @@ async function main() {
|
|
|
540
619
|
"-f, --force",
|
|
541
620
|
"Force browser authentication even if valid tokens exist in .env"
|
|
542
621
|
)
|
|
622
|
+
.option(
|
|
623
|
+
"-t, --timeout <minutes>",
|
|
624
|
+
"How long to wait for the browser redirect, in minutes (default: 15, or SAP_AUTH_TIMEOUT_MS in ms)"
|
|
625
|
+
)
|
|
543
626
|
.helpOption("-h, --help", "Show help for the auth command")
|
|
544
627
|
.action(async (options) => {
|
|
545
628
|
try {
|
|
@@ -594,7 +677,12 @@ async function main() {
|
|
|
594
677
|
// Fallback to browser authentication if refresh failed or was skipped
|
|
595
678
|
if (!tokens) {
|
|
596
679
|
console.log("🌐 Starting browser authentication...");
|
|
597
|
-
tokens = await startAuthServer(
|
|
680
|
+
tokens = await startAuthServer(
|
|
681
|
+
serviceKey,
|
|
682
|
+
options.browser,
|
|
683
|
+
"jwt",
|
|
684
|
+
resolveAuthTimeout(options.timeout)
|
|
685
|
+
);
|
|
598
686
|
if (!tokens || !tokens.accessToken) {
|
|
599
687
|
console.error("JWT token was not obtained. Authentication failed.");
|
|
600
688
|
process.exit(1);
|
package/dist/auth/providers.d.ts
CHANGED
|
@@ -7,16 +7,20 @@
|
|
|
7
7
|
* `CertificateAuthProvider` returns are what `CertificateAbapConnection`
|
|
8
8
|
* returned. Nothing about how a credential works changed; only who owns it.
|
|
9
9
|
*/
|
|
10
|
-
import type {
|
|
11
|
-
import type { ICertificateMaterialLoader, ISapConfig, ITokenRefresher } from '@mcp-abap-adt/interfaces';
|
|
12
|
-
import type { IAuthProvider } from './IAuthProvider.js';
|
|
10
|
+
import type { IAuthProvider, ICertificateMaterial, ICertificateMaterialLoader, IRenewableCredential, ISapConfig, ITokenRefresher } from '@mcp-abap-adt/interfaces';
|
|
13
11
|
/** Username and password, as `Basic base64(user:pass)`. */
|
|
14
12
|
export declare class BasicAuthProvider implements IAuthProvider {
|
|
15
13
|
private readonly username;
|
|
16
14
|
private readonly password;
|
|
17
15
|
readonly kind = "basic";
|
|
16
|
+
/** Nothing to get ready: this credential is complete as constructed. */
|
|
17
|
+
prepare(): Promise<void>;
|
|
18
|
+
/** Not cookies. This one authenticates with a header. */
|
|
19
|
+
cookies(): string | null;
|
|
20
|
+
/** No TLS material: this credential lives in a header, not in the transport. */
|
|
21
|
+
transportMaterial(): ICertificateMaterial;
|
|
18
22
|
constructor(username: string, password: string);
|
|
19
|
-
authorizationHeader(): Promise<string>;
|
|
23
|
+
authorizationHeader(): Promise<string | null>;
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
22
26
|
* A bearer token, kept current by whoever issued it.
|
|
@@ -30,9 +34,15 @@ export declare class BasicAuthProvider implements IAuthProvider {
|
|
|
30
34
|
* credential behind it is renewed mid-flight is the connection's business and
|
|
31
35
|
* stays there; see `JwtAbapConnection`, which still owns that machinery.
|
|
32
36
|
*/
|
|
33
|
-
export declare class TokenAuthProvider implements
|
|
37
|
+
export declare class TokenAuthProvider implements IRenewableCredential {
|
|
34
38
|
private readonly source;
|
|
35
39
|
readonly kind = "token";
|
|
40
|
+
/** Nothing to get ready: this credential is complete as constructed. */
|
|
41
|
+
prepare(): Promise<void>;
|
|
42
|
+
/** Not cookies. This one authenticates with a header. */
|
|
43
|
+
cookies(): string | null;
|
|
44
|
+
/** No TLS material: this credential lives in a header, not in the transport. */
|
|
45
|
+
transportMaterial(): ICertificateMaterial;
|
|
36
46
|
/**
|
|
37
47
|
* A token, or something that can produce one.
|
|
38
48
|
*
|
|
@@ -50,10 +60,21 @@ export declare class TokenAuthProvider implements IAuthProvider {
|
|
|
50
60
|
* stale one and hide exactly the renewal the provider exists to do — which
|
|
51
61
|
* is what the first version of this class did.
|
|
52
62
|
*/
|
|
53
|
-
authorizationHeader(): Promise<string>;
|
|
63
|
+
authorizationHeader(): Promise<string | null>;
|
|
54
64
|
/**
|
|
55
65
|
* The token was refused, so force a new one.
|
|
56
66
|
*
|
|
67
|
+
* Declared through `IRenewableCredential` rather than as an optional member
|
|
68
|
+
* of every credential, so a consumer narrows to it: a password has nothing
|
|
69
|
+
* behind it to ask again, and a SAML session was negotiated elsewhere.
|
|
70
|
+
*
|
|
71
|
+
* **Nothing in this package calls it.** A token that EXPIRED is replaced
|
|
72
|
+
* inside `authorizationHeader()` above, which is asked per request — nobody
|
|
73
|
+
* decides anything. This is the other case, a token the source still believes
|
|
74
|
+
* in and the server refuses, and whether a refusal meant that is a judgement
|
|
75
|
+
* made with what the caller knows. So the refusal surfaces, and this is the
|
|
76
|
+
* seam the caller decides with.
|
|
77
|
+
*
|
|
57
78
|
* `getToken()` is documented to return the cached token while it believes it
|
|
58
79
|
* is still valid — which is exactly the situation after a 401 on a token the
|
|
59
80
|
* provider has not yet noticed is dead. `refreshToken()` is the contract's
|
|
@@ -70,8 +91,13 @@ export declare class TokenAuthProvider implements IAuthProvider {
|
|
|
70
91
|
export declare class SamlAuthProvider implements IAuthProvider {
|
|
71
92
|
private readonly sessionCookies;
|
|
72
93
|
readonly kind = "saml";
|
|
94
|
+
/** Nothing to get ready: this credential is complete as constructed. */
|
|
95
|
+
prepare(): Promise<void>;
|
|
96
|
+
/** No TLS material: this credential lives in a header, not in the transport. */
|
|
97
|
+
transportMaterial(): ICertificateMaterial;
|
|
73
98
|
constructor(sessionCookies: string);
|
|
74
|
-
|
|
99
|
+
/** Not a header: this credential authenticates with the cookies below. */
|
|
100
|
+
authorizationHeader(): Promise<string | null>;
|
|
75
101
|
/** The cookies to present. */
|
|
76
102
|
cookies(): string;
|
|
77
103
|
}
|
|
@@ -86,10 +112,13 @@ export declare class CertificateAuthProvider implements IAuthProvider {
|
|
|
86
112
|
private readonly loader;
|
|
87
113
|
private readonly config;
|
|
88
114
|
readonly kind = "certificate";
|
|
115
|
+
/** Not cookies. This one authenticates with a header. */
|
|
116
|
+
cookies(): string | null;
|
|
89
117
|
private material;
|
|
90
118
|
constructor(loader: ICertificateMaterialLoader, config: ISapConfig);
|
|
91
119
|
prepare(): Promise<void>;
|
|
92
|
-
|
|
93
|
-
|
|
120
|
+
/** Not a header: this credential authenticates through TLS. */
|
|
121
|
+
authorizationHeader(): Promise<string | null>;
|
|
122
|
+
transportMaterial(): ICertificateMaterial;
|
|
94
123
|
}
|
|
95
124
|
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/auth/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/auth/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,UAAU,EACV,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC,2DAA2D;AAC3D,qBAAa,iBAAkB,YAAW,aAAa;IAiBnD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAjB3B,QAAQ,CAAC,IAAI,WAAW;IAExB,wEAAwE;IAClE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,yDAAyD;IACzD,OAAO,IAAI,MAAM,GAAG,IAAI;IAIxB,gFAAgF;IAChF,iBAAiB,IAAI,oBAAoB;gBAKtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM;IAG7B,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAGpD;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,YAAW,oBAAoB;IAyB1D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAxBzB,QAAQ,CAAC,IAAI,WAAW;IAExB,wEAAwE;IAClE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,yDAAyD;IACzD,OAAO,IAAI,MAAM,GAAG,IAAI;IAIxB,gFAAgF;IAChF,iBAAiB,IAAI,oBAAoB;IAIzC;;;;;;;OAOG;gBAEgB,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAG7E;;;;;;;OAOG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUnD;;;;;;;;;;;;;;;;;;OAkBG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAWxC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAV3C,QAAQ,CAAC,IAAI,UAAU;IAEvB,wEAAwE;IAClE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,gFAAgF;IAChF,iBAAiB,IAAI,oBAAoB;gBAIZ,cAAc,EAAE,MAAM;IAEnD,0EAA0E;IACpE,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInD,8BAA8B;IAC9B,OAAO,IAAI,MAAM;CAGlB;AAED;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,aAAa;IAWzD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXzB,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,yDAAyD;IACzD,OAAO,IAAI,MAAM,GAAG,IAAI;IAIxB,OAAO,CAAC,QAAQ,CAAqC;gBAGlC,MAAM,EAAE,0BAA0B,EAClC,MAAM,EAAE,UAAU;IAG/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,+DAA+D;IACzD,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInD,iBAAiB,IAAI,oBAAoB;CAS1C"}
|
package/dist/auth/providers.js
CHANGED
|
@@ -15,6 +15,16 @@ class BasicAuthProvider {
|
|
|
15
15
|
username;
|
|
16
16
|
password;
|
|
17
17
|
kind = 'basic';
|
|
18
|
+
/** Nothing to get ready: this credential is complete as constructed. */
|
|
19
|
+
async prepare() { }
|
|
20
|
+
/** Not cookies. This one authenticates with a header. */
|
|
21
|
+
cookies() {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/** No TLS material: this credential lives in a header, not in the transport. */
|
|
25
|
+
transportMaterial() {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
18
28
|
constructor(username, password) {
|
|
19
29
|
this.username = username;
|
|
20
30
|
this.password = password;
|
|
@@ -39,6 +49,16 @@ exports.BasicAuthProvider = BasicAuthProvider;
|
|
|
39
49
|
class TokenAuthProvider {
|
|
40
50
|
source;
|
|
41
51
|
kind = 'token';
|
|
52
|
+
/** Nothing to get ready: this credential is complete as constructed. */
|
|
53
|
+
async prepare() { }
|
|
54
|
+
/** Not cookies. This one authenticates with a header. */
|
|
55
|
+
cookies() {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/** No TLS material: this credential lives in a header, not in the transport. */
|
|
59
|
+
transportMaterial() {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
42
62
|
/**
|
|
43
63
|
* A token, or something that can produce one.
|
|
44
64
|
*
|
|
@@ -69,6 +89,17 @@ class TokenAuthProvider {
|
|
|
69
89
|
/**
|
|
70
90
|
* The token was refused, so force a new one.
|
|
71
91
|
*
|
|
92
|
+
* Declared through `IRenewableCredential` rather than as an optional member
|
|
93
|
+
* of every credential, so a consumer narrows to it: a password has nothing
|
|
94
|
+
* behind it to ask again, and a SAML session was negotiated elsewhere.
|
|
95
|
+
*
|
|
96
|
+
* **Nothing in this package calls it.** A token that EXPIRED is replaced
|
|
97
|
+
* inside `authorizationHeader()` above, which is asked per request — nobody
|
|
98
|
+
* decides anything. This is the other case, a token the source still believes
|
|
99
|
+
* in and the server refuses, and whether a refusal meant that is a judgement
|
|
100
|
+
* made with what the caller knows. So the refusal surfaces, and this is the
|
|
101
|
+
* seam the caller decides with.
|
|
102
|
+
*
|
|
72
103
|
* `getToken()` is documented to return the cached token while it believes it
|
|
73
104
|
* is still valid — which is exactly the situation after a 401 on a token the
|
|
74
105
|
* provider has not yet noticed is dead. `refreshToken()` is the contract's
|
|
@@ -93,11 +124,18 @@ exports.TokenAuthProvider = TokenAuthProvider;
|
|
|
93
124
|
class SamlAuthProvider {
|
|
94
125
|
sessionCookies;
|
|
95
126
|
kind = 'saml';
|
|
127
|
+
/** Nothing to get ready: this credential is complete as constructed. */
|
|
128
|
+
async prepare() { }
|
|
129
|
+
/** No TLS material: this credential lives in a header, not in the transport. */
|
|
130
|
+
transportMaterial() {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
96
133
|
constructor(sessionCookies) {
|
|
97
134
|
this.sessionCookies = sessionCookies;
|
|
98
135
|
}
|
|
136
|
+
/** Not a header: this credential authenticates with the cookies below. */
|
|
99
137
|
async authorizationHeader() {
|
|
100
|
-
return
|
|
138
|
+
return null;
|
|
101
139
|
}
|
|
102
140
|
/** The cookies to present. */
|
|
103
141
|
cookies() {
|
|
@@ -116,6 +154,10 @@ class CertificateAuthProvider {
|
|
|
116
154
|
loader;
|
|
117
155
|
config;
|
|
118
156
|
kind = 'certificate';
|
|
157
|
+
/** Not cookies. This one authenticates with a header. */
|
|
158
|
+
cookies() {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
119
161
|
material = null;
|
|
120
162
|
constructor(loader, config) {
|
|
121
163
|
this.loader = loader;
|
|
@@ -126,10 +168,11 @@ class CertificateAuthProvider {
|
|
|
126
168
|
this.material = await this.loader.load(this.config);
|
|
127
169
|
}
|
|
128
170
|
}
|
|
171
|
+
/** Not a header: this credential authenticates through TLS. */
|
|
129
172
|
async authorizationHeader() {
|
|
130
|
-
return
|
|
173
|
+
return null;
|
|
131
174
|
}
|
|
132
|
-
|
|
175
|
+
transportMaterial() {
|
|
133
176
|
if (!this.material) {
|
|
134
177
|
throw new Error('CertificateAuthProvider: certificate material not loaded. connect() prepares it; a request before that has nothing to present.');
|
|
135
178
|
}
|