@truenas/api-client 3.0.5 → 3.0.7
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/index.cjs +167 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -2
- package/dist/index.d.ts +88 -2
- package/dist/index.js +168 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2401,6 +2401,7 @@ var AuthErrorCode = /* @__PURE__ */ ((AuthErrorCode2) => {
|
|
|
2401
2401
|
AuthErrorCode2["OtpAuthFailed"] = "OTP_AUTH_FAILED";
|
|
2402
2402
|
AuthErrorCode2["ApiKeyAuthFailed"] = "API_KEY_AUTH_FAILED";
|
|
2403
2403
|
AuthErrorCode2["TokenAuthFailed"] = "TOKEN_AUTH_FAILED";
|
|
2404
|
+
AuthErrorCode2["LoginSuperseded"] = "LOGIN_SUPERSEDED";
|
|
2404
2405
|
AuthErrorCode2["FullAdminRequired"] = "FULL_ADMIN_REQUIRED";
|
|
2405
2406
|
return AuthErrorCode2;
|
|
2406
2407
|
})(AuthErrorCode || {});
|
|
@@ -2439,24 +2440,70 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2439
2440
|
this.authenticating$ = new rxjs.BehaviorSubject(false);
|
|
2440
2441
|
this.credentials = { username: "", password: "", key: "" };
|
|
2441
2442
|
this.sessionLifetime = _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2443
|
+
/**
|
|
2444
|
+
* Claimed by each login when it sends and checked when its answer lands: a
|
|
2445
|
+
* difference means another login or a logout was issued in between, so this
|
|
2446
|
+
* answer is stale and must not write session state. Responses on one socket
|
|
2447
|
+
* are not ordered, which is why arrival is not enough to make an answer
|
|
2448
|
+
* current.
|
|
2449
|
+
*
|
|
2450
|
+
* `logout()` bumps it without claiming one. It has no answer to guard —
|
|
2451
|
+
* it settles its own state at the call — and bumping is what invalidates the
|
|
2452
|
+
* logins already on the wire that a logout is meant to override.
|
|
2453
|
+
*/
|
|
2454
|
+
this.authEpoch = 0;
|
|
2455
|
+
/**
|
|
2456
|
+
* Caller-issued logins still awaiting an answer, keyed by the epoch each
|
|
2457
|
+
* claimed. The value is whether its frame has been written to a socket yet.
|
|
2458
|
+
*
|
|
2459
|
+
* The auto-relogin below defers while any entry exists. It is this class
|
|
2460
|
+
* retrying a cached credential, not a request anyone made, so it must never
|
|
2461
|
+
* outrank an explicit login — and it would: `TrueNasConnection.send` holds a
|
|
2462
|
+
* frame through an outage rather than dropping it, so a login submitted while
|
|
2463
|
+
* the socket is down is still pending when `opened` fires, and a relogin
|
|
2464
|
+
* claiming the newer epoch has that login answered `LoginSuperseded` while the
|
|
2465
|
+
* client authenticates as the previously cached account.
|
|
2466
|
+
*
|
|
2467
|
+
* Keyed rather than counted, because a count cannot say *which* login a
|
|
2468
|
+
* removal belongs to: a login torn down by its caller would retire a slot
|
|
2469
|
+
* belonging to a different login that is still waiting, and the retry would
|
|
2470
|
+
* overtake it again. Identity also makes a double-subscribed login harmless.
|
|
2471
|
+
*/
|
|
2472
|
+
this.liveCallerLogins = /* @__PURE__ */ new Map();
|
|
2473
|
+
/** True only while the constructor's relogin is being constructed. */
|
|
2474
|
+
this.reloginInProgress = false;
|
|
2475
|
+
this.connection.opened.subscribe((isOpen) => {
|
|
2476
|
+
if (!isOpen) return;
|
|
2477
|
+
for (const epoch of this.liveCallerLogins.keys()) {
|
|
2478
|
+
this.liveCallerLogins.set(epoch, true);
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2442
2481
|
this.connection.opened.pipe(
|
|
2443
2482
|
rxjs.filter(
|
|
2444
|
-
(isOpen) => !!(isOpen && this.credentials?.username && (this.credentials.password || this.credentials.key)
|
|
2483
|
+
(isOpen) => !!(isOpen && this.credentials?.username && (this.credentials.password || this.credentials.key) && // An explicit login already on the wire outranks this retry.
|
|
2484
|
+
this.liveCallerLogins.size === 0)
|
|
2445
2485
|
),
|
|
2446
2486
|
rxjs.switchMap(() => {
|
|
2447
|
-
|
|
2448
|
-
|
|
2487
|
+
this.reloginInProgress = true;
|
|
2488
|
+
let relogin;
|
|
2489
|
+
try {
|
|
2490
|
+
relogin = this.credentials.password ? this.loginWithUserPass(
|
|
2449
2491
|
this.credentials.username,
|
|
2450
2492
|
this.credentials.password
|
|
2451
|
-
)
|
|
2493
|
+
) : this.loginWithApiKey({
|
|
2494
|
+
username: this.credentials.username,
|
|
2495
|
+
key: this.credentials.key
|
|
2496
|
+
});
|
|
2497
|
+
} finally {
|
|
2498
|
+
this.reloginInProgress = false;
|
|
2452
2499
|
}
|
|
2453
|
-
return
|
|
2454
|
-
username: this.credentials.username,
|
|
2455
|
-
key: this.credentials.key
|
|
2456
|
-
});
|
|
2500
|
+
return relogin.pipe(rxjs.catchError(() => rxjs.EMPTY));
|
|
2457
2501
|
})
|
|
2458
2502
|
).subscribe();
|
|
2459
2503
|
connection.closed.subscribe(() => {
|
|
2504
|
+
for (const [epoch, flushed] of this.liveCallerLogins) {
|
|
2505
|
+
if (flushed) this.liveCallerLogins.delete(epoch);
|
|
2506
|
+
}
|
|
2460
2507
|
this.sessionLifetime = _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2461
2508
|
this.authenticated$.next(false);
|
|
2462
2509
|
});
|
|
@@ -2487,7 +2534,36 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2487
2534
|
if (!this.version || this.version.year <= legacyCutoffYear) return void 0;
|
|
2488
2535
|
return { login_options: { reconnect_token: true } };
|
|
2489
2536
|
}
|
|
2537
|
+
/**
|
|
2538
|
+
* Throws when another login or a logout was issued after this one was sent,
|
|
2539
|
+
* so a stale answer cannot be reported to its caller as a successful login.
|
|
2540
|
+
*/
|
|
2541
|
+
assertNotSuperseded(sentDuring) {
|
|
2542
|
+
if (this.authEpoch === sentDuring) return;
|
|
2543
|
+
throw new AuthError(
|
|
2544
|
+
"LOGIN_SUPERSEDED" /* LoginSuperseded */,
|
|
2545
|
+
"Login was superseded by a later logout or login and was discarded."
|
|
2546
|
+
);
|
|
2547
|
+
}
|
|
2548
|
+
/** Claim the next epoch for a login, and record it if a caller asked for it. */
|
|
2549
|
+
beginLogin() {
|
|
2550
|
+
const callerInitiated = !this.reloginInProgress;
|
|
2551
|
+
const sentDuring = ++this.authEpoch;
|
|
2552
|
+
if (callerInitiated) {
|
|
2553
|
+
this.liveCallerLogins.set(sentDuring, this.connection.opened.value);
|
|
2554
|
+
}
|
|
2555
|
+
return { sentDuring, callerInitiated };
|
|
2556
|
+
}
|
|
2557
|
+
endLogin(sentDuring, callerInitiated, answered) {
|
|
2558
|
+
const flushed = this.liveCallerLogins.get(sentDuring);
|
|
2559
|
+
if (callerInitiated && (answered || flushed)) {
|
|
2560
|
+
this.liveCallerLogins.delete(sentDuring);
|
|
2561
|
+
}
|
|
2562
|
+
this.authenticating$.next(false);
|
|
2563
|
+
}
|
|
2490
2564
|
loginWithUserPass(username, password) {
|
|
2565
|
+
const { sentDuring, callerInitiated } = this.beginLogin();
|
|
2566
|
+
let answered = false;
|
|
2491
2567
|
const message = createJsonRpcMessage("auth.login_ex", [
|
|
2492
2568
|
{
|
|
2493
2569
|
mechanism: "PASSWORD_PLAIN" /* Password */,
|
|
@@ -2501,6 +2577,9 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2501
2577
|
const messageId = message.id ?? "";
|
|
2502
2578
|
return this.connection.messages().pipe(
|
|
2503
2579
|
withId(messageId),
|
|
2580
|
+
rxjs.tap(() => {
|
|
2581
|
+
answered = true;
|
|
2582
|
+
}),
|
|
2504
2583
|
rxjs.map((msg) => {
|
|
2505
2584
|
if (msg.error) {
|
|
2506
2585
|
const errorMessage = getApiErrorMessage(
|
|
@@ -2517,28 +2596,21 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2517
2596
|
),
|
|
2518
2597
|
rxjs.tap((res) => {
|
|
2519
2598
|
if (res.response_type === "SUCCESS" /* Success */) {
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
this.authenticated$.next(true);
|
|
2525
|
-
} else {
|
|
2526
|
-
this.logout();
|
|
2527
|
-
this.authenticated$.next(false);
|
|
2528
|
-
throw new AuthError(
|
|
2529
|
-
"FULL_ADMIN_REQUIRED" /* FullAdminRequired */,
|
|
2530
|
-
"User account must have full admin privileges"
|
|
2531
|
-
);
|
|
2532
|
-
}
|
|
2599
|
+
this.assertNotSuperseded(sentDuring);
|
|
2600
|
+
this.credentials = { username, password, key: "" };
|
|
2601
|
+
this.sessionLifetime = res.user_info?.attributes?.preferences?.lifetime ?? _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2602
|
+
this.authenticated$.next(true);
|
|
2533
2603
|
}
|
|
2534
2604
|
}),
|
|
2535
2605
|
rxjs.finalize(() => {
|
|
2536
|
-
this.
|
|
2606
|
+
this.endLogin(sentDuring, callerInitiated, answered);
|
|
2537
2607
|
}),
|
|
2538
2608
|
rxjs.take(1)
|
|
2539
2609
|
);
|
|
2540
2610
|
}
|
|
2541
2611
|
loginWithOtp(code) {
|
|
2612
|
+
const { sentDuring, callerInitiated } = this.beginLogin();
|
|
2613
|
+
let answered = false;
|
|
2542
2614
|
const message = createJsonRpcMessage("auth.login_ex", [
|
|
2543
2615
|
{
|
|
2544
2616
|
mechanism: "OTP_TOKEN" /* Otp */,
|
|
@@ -2550,6 +2622,9 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2550
2622
|
const messageId = message.id ?? "";
|
|
2551
2623
|
return this.connection.messages().pipe(
|
|
2552
2624
|
withId(messageId),
|
|
2625
|
+
rxjs.tap(() => {
|
|
2626
|
+
answered = true;
|
|
2627
|
+
}),
|
|
2553
2628
|
rxjs.map((msg) => {
|
|
2554
2629
|
if (msg.error) {
|
|
2555
2630
|
const errorMessage = getApiErrorMessage(
|
|
@@ -2562,6 +2637,7 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2562
2637
|
}),
|
|
2563
2638
|
rxjs.tap((res) => {
|
|
2564
2639
|
if (res?.response_type === "SUCCESS" /* Success */) {
|
|
2640
|
+
this.assertNotSuperseded(sentDuring);
|
|
2565
2641
|
this.sessionLifetime = res.user_info?.attributes?.preferences?.lifetime ?? _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2566
2642
|
this.authenticated$.next(true);
|
|
2567
2643
|
}
|
|
@@ -2571,7 +2647,7 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2571
2647
|
"TrueNAS authentication failed. Please verify your one-time passcode and try again."
|
|
2572
2648
|
),
|
|
2573
2649
|
rxjs.finalize(() => {
|
|
2574
|
-
this.
|
|
2650
|
+
this.endLogin(sentDuring, callerInitiated, answered);
|
|
2575
2651
|
}),
|
|
2576
2652
|
rxjs.take(1)
|
|
2577
2653
|
);
|
|
@@ -2596,6 +2672,8 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2596
2672
|
* reason the socket dropped in the first place.
|
|
2597
2673
|
*/
|
|
2598
2674
|
loginWithToken(token) {
|
|
2675
|
+
const { sentDuring, callerInitiated } = this.beginLogin();
|
|
2676
|
+
let answered = false;
|
|
2599
2677
|
const message = createJsonRpcMessage("auth.login_ex", [
|
|
2600
2678
|
{
|
|
2601
2679
|
mechanism: "TOKEN_PLAIN" /* Token */,
|
|
@@ -2608,6 +2686,9 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2608
2686
|
const messageId = message.id ?? "";
|
|
2609
2687
|
return this.connection.messages().pipe(
|
|
2610
2688
|
withId(messageId),
|
|
2689
|
+
rxjs.tap(() => {
|
|
2690
|
+
answered = true;
|
|
2691
|
+
}),
|
|
2611
2692
|
rxjs.map((msg) => {
|
|
2612
2693
|
if (msg.error) {
|
|
2613
2694
|
const errorMessage = getApiErrorMessage(
|
|
@@ -2634,21 +2715,13 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2634
2715
|
}),
|
|
2635
2716
|
rxjs.tap((res) => {
|
|
2636
2717
|
if (res.response_type === "SUCCESS" /* Success */) {
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
} else {
|
|
2641
|
-
this.logout();
|
|
2642
|
-
this.authenticated$.next(false);
|
|
2643
|
-
throw new AuthError(
|
|
2644
|
-
"FULL_ADMIN_REQUIRED" /* FullAdminRequired */,
|
|
2645
|
-
"User account must have full admin privileges"
|
|
2646
|
-
);
|
|
2647
|
-
}
|
|
2718
|
+
this.assertNotSuperseded(sentDuring);
|
|
2719
|
+
this.sessionLifetime = res.user_info?.attributes?.preferences?.lifetime ?? _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2720
|
+
this.authenticated$.next(true);
|
|
2648
2721
|
}
|
|
2649
2722
|
}),
|
|
2650
2723
|
rxjs.finalize(() => {
|
|
2651
|
-
this.
|
|
2724
|
+
this.endLogin(sentDuring, callerInitiated, answered);
|
|
2652
2725
|
}),
|
|
2653
2726
|
rxjs.take(1)
|
|
2654
2727
|
);
|
|
@@ -2659,6 +2732,8 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2659
2732
|
* and replayed. The token exists for the credential that cannot be.
|
|
2660
2733
|
*/
|
|
2661
2734
|
loginWithApiKey(credentials) {
|
|
2735
|
+
const { sentDuring, callerInitiated } = this.beginLogin();
|
|
2736
|
+
let answered = false;
|
|
2662
2737
|
const { username, key } = credentials;
|
|
2663
2738
|
const message = createJsonRpcMessage("auth.login_ex", [
|
|
2664
2739
|
{
|
|
@@ -2672,6 +2747,9 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2672
2747
|
const messageId = message.id ?? "";
|
|
2673
2748
|
return this.connection.messages().pipe(
|
|
2674
2749
|
withId(messageId),
|
|
2750
|
+
rxjs.tap(() => {
|
|
2751
|
+
answered = true;
|
|
2752
|
+
}),
|
|
2675
2753
|
rxjs.map((msg) => {
|
|
2676
2754
|
if (msg.error) {
|
|
2677
2755
|
const errorMessage = getApiErrorMessage(
|
|
@@ -2687,13 +2765,13 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2687
2765
|
"TrueNAS authentication failed. Has the TrueNAS Connect API key been removed from your TrueNAS server?"
|
|
2688
2766
|
),
|
|
2689
2767
|
rxjs.tap((res) => {
|
|
2690
|
-
this.
|
|
2691
|
-
this.credentials
|
|
2768
|
+
this.assertNotSuperseded(sentDuring);
|
|
2769
|
+
this.credentials = { username, password: "", key };
|
|
2692
2770
|
this.sessionLifetime = res.user_info?.attributes?.preferences?.lifetime ?? _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2693
2771
|
this.authenticated$.next(true);
|
|
2694
2772
|
}),
|
|
2695
2773
|
rxjs.finalize(() => {
|
|
2696
|
-
this.
|
|
2774
|
+
this.endLogin(sentDuring, callerInitiated, answered);
|
|
2697
2775
|
}),
|
|
2698
2776
|
rxjs.take(1)
|
|
2699
2777
|
);
|
|
@@ -2720,6 +2798,10 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2720
2798
|
);
|
|
2721
2799
|
}
|
|
2722
2800
|
logout() {
|
|
2801
|
+
this.credentials = { username: "", password: "", key: "" };
|
|
2802
|
+
this.sessionLifetime = _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2803
|
+
this.authEpoch += 1;
|
|
2804
|
+
this.authenticated$.next(false);
|
|
2723
2805
|
const message = createJsonRpcMessage("auth.logout");
|
|
2724
2806
|
this.connection.send(message);
|
|
2725
2807
|
const messageId = message.id ?? "";
|
|
@@ -2731,10 +2813,6 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2731
2813
|
}
|
|
2732
2814
|
return msg.result;
|
|
2733
2815
|
}),
|
|
2734
|
-
rxjs.tap((success) => {
|
|
2735
|
-
this.sessionLifetime = _TrueNasAuthenticator.DefaultSessionLifetime;
|
|
2736
|
-
this.authenticated$.next(!success);
|
|
2737
|
-
}),
|
|
2738
2816
|
rxjs.take(1)
|
|
2739
2817
|
);
|
|
2740
2818
|
}
|
|
@@ -2758,6 +2836,7 @@ var noopLogger = {
|
|
|
2758
2836
|
};
|
|
2759
2837
|
|
|
2760
2838
|
// src/utils/truenas-connection.utils.ts
|
|
2839
|
+
var policyViolationCloseCode = 1008;
|
|
2761
2840
|
function isHttpStatusError(reason) {
|
|
2762
2841
|
return ["404", "502", "503"].some((code) => reason.includes(code));
|
|
2763
2842
|
}
|
|
@@ -2866,7 +2945,25 @@ var TrueNasConnection = class {
|
|
|
2866
2945
|
rxjs.switchMap((enabled) => {
|
|
2867
2946
|
if (enabled) {
|
|
2868
2947
|
return this.connect().pipe(
|
|
2869
|
-
rxjs.map((conn) => makeActiveConnection(conn.ws, conn.hostname))
|
|
2948
|
+
rxjs.map((conn) => makeActiveConnection(conn.ws, conn.hostname)),
|
|
2949
|
+
// A refusal becomes a value here rather than an error, so it never
|
|
2950
|
+
// reaches the `retry` below and nothing reconnects on its own.
|
|
2951
|
+
//
|
|
2952
|
+
// Handled at this depth on purpose: letting it out completes the
|
|
2953
|
+
// pipeline and unsubscribes `enabledChange$`, and `setEnabled` is the
|
|
2954
|
+
// documented way an app asks for another attempt once the network
|
|
2955
|
+
// changes. Not retrying is a statement about what this client does on
|
|
2956
|
+
// its own; it is not a reason to refuse the caller asking again.
|
|
2957
|
+
rxjs.catchError(
|
|
2958
|
+
(err) => isTerminalClose(err) ? rxjs.of(
|
|
2959
|
+
makeConnectionError(
|
|
2960
|
+
err.message,
|
|
2961
|
+
err.hostname,
|
|
2962
|
+
err.closeCode,
|
|
2963
|
+
err.closeReason
|
|
2964
|
+
)
|
|
2965
|
+
) : rxjs.throwError(() => err)
|
|
2966
|
+
)
|
|
2870
2967
|
);
|
|
2871
2968
|
}
|
|
2872
2969
|
return rxjs.of(closedConnection);
|
|
@@ -2892,7 +2989,14 @@ var TrueNasConnection = class {
|
|
|
2892
2989
|
rxjs.catchError((err) => {
|
|
2893
2990
|
this.logger.error("All connections failed - retrying", { message: err?.message, hostname: err?.hostname });
|
|
2894
2991
|
return rxjs.concat(
|
|
2895
|
-
rxjs.of(
|
|
2992
|
+
rxjs.of(
|
|
2993
|
+
makeConnectionError(
|
|
2994
|
+
err.message,
|
|
2995
|
+
err.hostname,
|
|
2996
|
+
err.closeCode,
|
|
2997
|
+
err.closeReason
|
|
2998
|
+
)
|
|
2999
|
+
),
|
|
2896
3000
|
// since this error will immediately get caught by `retry` there's no reason to build a real error.
|
|
2897
3001
|
rxjs.throwError(() => null)
|
|
2898
3002
|
);
|
|
@@ -3001,6 +3105,11 @@ var TrueNasConnection = class {
|
|
|
3001
3105
|
/**
|
|
3002
3106
|
* enables or disables the connection gate. the app calls this when its `SystemState`
|
|
3003
3107
|
* changes (mapping `SystemState.Active -> true`, everything else -> `false`).
|
|
3108
|
+
*
|
|
3109
|
+
* This is also how a caller asks for another attempt after the appliance has
|
|
3110
|
+
* refused the client — nothing reconnects on its own from there. The gate is
|
|
3111
|
+
* `distinctUntilChanged`, so re-asserting `true` while it is already `true`
|
|
3112
|
+
* does nothing: the round trip through `false` is what asks again.
|
|
3004
3113
|
*/
|
|
3005
3114
|
setEnabled(enabled) {
|
|
3006
3115
|
this.enabled$.next(enabled);
|
|
@@ -3058,7 +3167,9 @@ var TrueNasConnection = class {
|
|
|
3058
3167
|
errorMessage = getWebSocketError(event.code);
|
|
3059
3168
|
}
|
|
3060
3169
|
this.connectionAttempts.next(this.connectionAttempts.value + 1);
|
|
3061
|
-
subscriber.error(
|
|
3170
|
+
subscriber.error(
|
|
3171
|
+
makeConnectionError(errorMessage, hostname, event.code, reason)
|
|
3172
|
+
);
|
|
3062
3173
|
}
|
|
3063
3174
|
}
|
|
3064
3175
|
});
|
|
@@ -3108,12 +3219,15 @@ var makeActiveConnection = (ws, hostname) => ({
|
|
|
3108
3219
|
hostname,
|
|
3109
3220
|
state: "active"
|
|
3110
3221
|
});
|
|
3111
|
-
var makeConnectionError = (message, hostname) => ({
|
|
3222
|
+
var makeConnectionError = (message, hostname, closeCode, closeReason) => ({
|
|
3112
3223
|
name: "ConnectionError",
|
|
3113
3224
|
message,
|
|
3114
3225
|
hostname,
|
|
3226
|
+
closeCode,
|
|
3227
|
+
closeReason,
|
|
3115
3228
|
state: "error"
|
|
3116
3229
|
});
|
|
3230
|
+
var isTerminalClose = (err) => err?.closeCode === policyViolationCloseCode;
|
|
3117
3231
|
var closedConnection = { state: "closed" };
|
|
3118
3232
|
|
|
3119
3233
|
// src/client/truenas-api-client.ts
|
|
@@ -3925,6 +4039,12 @@ function errorMessageOrDefault(error, fallback) {
|
|
|
3925
4039
|
return fallback;
|
|
3926
4040
|
}
|
|
3927
4041
|
|
|
4042
|
+
// src/enums/user-role.enum.ts
|
|
4043
|
+
var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
4044
|
+
UserRole2["FullAdmin"] = "FULL_ADMIN";
|
|
4045
|
+
return UserRole2;
|
|
4046
|
+
})(UserRole || {});
|
|
4047
|
+
|
|
3928
4048
|
exports.AppState = AppState;
|
|
3929
4049
|
exports.AuthError = AuthError;
|
|
3930
4050
|
exports.AuthErrorCode = AuthErrorCode;
|
|
@@ -3937,6 +4057,7 @@ exports.TrueNasApiClientV2510 = TrueNasApiClientV2510;
|
|
|
3937
4057
|
exports.TrueNasApiClientV26 = TrueNasApiClientV26;
|
|
3938
4058
|
exports.TrueNasApiClientV27 = TrueNasApiClientV27;
|
|
3939
4059
|
exports.TrueNasAuthMechanism = TrueNasAuthMechanism;
|
|
4060
|
+
exports.UserRole = UserRole;
|
|
3940
4061
|
exports.VersionCompatibility = VersionCompatibility;
|
|
3941
4062
|
exports.VersionDiscovery = VersionDiscovery;
|
|
3942
4063
|
exports.VersionDiscoveryError = VersionDiscoveryError;
|