@truenas/api-client 9.0.6 → 11.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/README.md +16 -0
- package/dist/{chunk-UOTSHE2J.cjs → chunk-MQAS7GKB.cjs} +64 -8
- package/dist/chunk-MQAS7GKB.cjs.map +1 -0
- package/dist/{chunk-R4VP3HBB.js → chunk-ZH75OPDH.js} +64 -8
- package/dist/chunk-ZH75OPDH.js.map +1 -0
- package/dist/index.cjs +37 -37
- package/dist/index.d.cts +30 -7
- package/dist/index.d.ts +30 -7
- package/dist/index.js +1 -1
- package/dist/testing/index.cjs +13 -13
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/{truenas-auth-mechanism.enum-CtU2b15s.d.cts → truenas-auth-mechanism.enum-B0j9EN8G.d.cts} +1429 -425
- package/dist/{truenas-auth-mechanism.enum-CtU2b15s.d.ts → truenas-auth-mechanism.enum-B0j9EN8G.d.ts} +1429 -425
- package/package.json +1 -1
- package/dist/chunk-R4VP3HBB.js.map +0 -1
- package/dist/chunk-UOTSHE2J.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -84,6 +84,22 @@ errors with an `AuthError` carrying an `AuthErrorCode`, plus the refusing
|
|
|
84
84
|
`response` when middleware answered with one (`response.response_type` tells
|
|
85
85
|
`EXPIRED`, `DENIED` and `REDIRECT` apart from `AUTH_ERR`).
|
|
86
86
|
|
|
87
|
+
A wrong one-time code errors from `loginWithOtp(code)`; it never emits
|
|
88
|
+
`OTP_REQUIRED`. Releases differ on whether the login survives a wrong code
|
|
89
|
+
(25.10 keeps it for up to three tries, 27 and later drop it), and the API
|
|
90
|
+
version does not tell them apart, so read `loginPending` off the error instead:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
client.authenticator.loginWithOtp(code).subscribe({
|
|
94
|
+
next: () => { /* signed in */ },
|
|
95
|
+
error: (err: unknown) => {
|
|
96
|
+
if (!(err instanceof AuthError)) throw err;
|
|
97
|
+
if (err.loginPending) askForAnotherCode(); // OtpAuthFailed, login still open
|
|
98
|
+
else startOverWithPassword(); // OtpAuthFailed or OtpLoginNotPending
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
87
103
|
## Calls
|
|
88
104
|
|
|
89
105
|
```typescript
|
|
@@ -1733,6 +1733,7 @@ __export(v27_0_0_exports, {
|
|
|
1733
1733
|
IscsiTargetCreateModeInput: () => IscsiTargetCreateModeInput,
|
|
1734
1734
|
KeychainCredentialEntryType: () => KeychainCredentialEntryType,
|
|
1735
1735
|
KeychainCredentialEntryTypeInput: () => KeychainCredentialEntryTypeInput,
|
|
1736
|
+
Layout: () => Layout,
|
|
1736
1737
|
Level: () => Level,
|
|
1737
1738
|
NFS4ACEType: () => NFS4ACEType,
|
|
1738
1739
|
NFS4ACETypeInput: () => NFS4ACETypeInput,
|
|
@@ -1847,6 +1848,10 @@ var Interval = {
|
|
|
1847
1848
|
"30": 30,
|
|
1848
1849
|
"60": 60
|
|
1849
1850
|
};
|
|
1851
|
+
var Layout = {
|
|
1852
|
+
Bucket: "BUCKET",
|
|
1853
|
+
Dataset: "DATASET"
|
|
1854
|
+
};
|
|
1850
1855
|
var Name2 = {
|
|
1851
1856
|
Cpu: "cpu",
|
|
1852
1857
|
Cputemp: "cputemp",
|
|
@@ -1990,6 +1995,7 @@ __export(v28_0_0_exports, {
|
|
|
1990
1995
|
IscsiTargetCreateModeInput: () => IscsiTargetCreateModeInput,
|
|
1991
1996
|
KeychainCredentialEntryType: () => KeychainCredentialEntryType,
|
|
1992
1997
|
KeychainCredentialEntryTypeInput: () => KeychainCredentialEntryTypeInput,
|
|
1998
|
+
Layout: () => Layout,
|
|
1993
1999
|
Level: () => Level,
|
|
1994
2000
|
NFS4ACEType: () => NFS4ACEType,
|
|
1995
2001
|
NFS4ACETypeInput: () => NFS4ACETypeInput,
|
|
@@ -2065,6 +2071,8 @@ __export(v28_0_0_exports, {
|
|
|
2065
2071
|
Versioning: () => Versioning,
|
|
2066
2072
|
Volblocksize: () => Volblocksize,
|
|
2067
2073
|
When: () => When,
|
|
2074
|
+
ZFSResourceUserspaceEntryType: () => ZFSResourceUserspaceEntryType,
|
|
2075
|
+
ZFSResourceUserspaceEntryTypeInput: () => ZFSResourceUserspaceEntryTypeInput,
|
|
2068
2076
|
ZfsTierRewriteJobEntryStatus: () => ZfsTierRewriteJobEntryStatus,
|
|
2069
2077
|
ZfsTierRewriteJobEntryStatusInput: () => ZfsTierRewriteJobEntryStatusInput,
|
|
2070
2078
|
ZpoolScrubRunAction: () => ZpoolScrubRunAction
|
|
@@ -2150,6 +2158,14 @@ var VMWareMatchDatastoresWithDatasetsResultFilesystemTypeInput = {
|
|
|
2150
2158
|
Filesystem: "FILESYSTEM",
|
|
2151
2159
|
Volume: "VOLUME"
|
|
2152
2160
|
};
|
|
2161
|
+
var ZFSResourceUserspaceEntryType = {
|
|
2162
|
+
User: "user",
|
|
2163
|
+
Group: "group"
|
|
2164
|
+
};
|
|
2165
|
+
var ZFSResourceUserspaceEntryTypeInput = {
|
|
2166
|
+
User: "user",
|
|
2167
|
+
Group: "group"
|
|
2168
|
+
};
|
|
2153
2169
|
|
|
2154
2170
|
// src/generated/index.ts
|
|
2155
2171
|
var SUPPORTED_API_VERSIONS = [
|
|
@@ -2186,6 +2202,7 @@ var TrueNasAuthMechanism = /* @__PURE__ */ ((TrueNasAuthMechanism2) => {
|
|
|
2186
2202
|
var AuthErrorCode = /* @__PURE__ */ ((AuthErrorCode2) => {
|
|
2187
2203
|
AuthErrorCode2["PasswordAuthFailed"] = "PASSWORD_AUTH_FAILED";
|
|
2188
2204
|
AuthErrorCode2["OtpAuthFailed"] = "OTP_AUTH_FAILED";
|
|
2205
|
+
AuthErrorCode2["OtpLoginNotPending"] = "OTP_LOGIN_NOT_PENDING";
|
|
2189
2206
|
AuthErrorCode2["ApiKeyAuthFailed"] = "API_KEY_AUTH_FAILED";
|
|
2190
2207
|
AuthErrorCode2["TokenAuthFailed"] = "TOKEN_AUTH_FAILED";
|
|
2191
2208
|
AuthErrorCode2["LoginSuperseded"] = "LOGIN_SUPERSEDED";
|
|
@@ -2199,11 +2216,12 @@ var AuthError = class _AuthError extends Error {
|
|
|
2199
2216
|
* `AUTH_ERR`; the code alone says only which mechanism failed. Absent when the login
|
|
2200
2217
|
* never got an answer of that kind (an error frame, or a superseded login).
|
|
2201
2218
|
*/
|
|
2202
|
-
constructor(code, message, response) {
|
|
2219
|
+
constructor(code, message, response, options = {}) {
|
|
2203
2220
|
super(message);
|
|
2204
2221
|
this.code = code;
|
|
2205
2222
|
this.response = response;
|
|
2206
2223
|
this.name = "AuthError";
|
|
2224
|
+
this.loginPending = options.loginPending ?? false;
|
|
2207
2225
|
Object.setPrototypeOf(this, _AuthError.prototype);
|
|
2208
2226
|
}
|
|
2209
2227
|
};
|
|
@@ -2744,6 +2762,7 @@ var throwOnAuthenticationFailure = (code, message) => rxjs.switchMap((response)
|
|
|
2744
2762
|
}
|
|
2745
2763
|
return rxjs.of(response);
|
|
2746
2764
|
});
|
|
2765
|
+
var isOtpLoginNotPending = (error) => error.data?.errname === "EINVAL" && typeof error.data.reason === "string" && error.data.reason.includes("OTP_TOKEN: no authentication in progress");
|
|
2747
2766
|
var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
2748
2767
|
constructor(connection, version) {
|
|
2749
2768
|
this.connection = connection;
|
|
@@ -2927,6 +2946,19 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2927
2946
|
rxjs.take(1)
|
|
2928
2947
|
);
|
|
2929
2948
|
}
|
|
2949
|
+
/**
|
|
2950
|
+
* The second step of a two-factor login, after `loginWithUserPass` answered
|
|
2951
|
+
* `OTP_REQUIRED`.
|
|
2952
|
+
*
|
|
2953
|
+
* Emits the answer when the code is accepted (`SUCCESS`), or when middleware
|
|
2954
|
+
* refuses the account outright (`EXPIRED`, `DENIED`, `REDIRECT`); never
|
|
2955
|
+
* `OTP_REQUIRED`. A refused code errors with `AuthError`, the same way on
|
|
2956
|
+
* every release:
|
|
2957
|
+
*
|
|
2958
|
+
* - `OtpAuthFailed` with `loginPending: true`: ask for another code.
|
|
2959
|
+
* - `OtpAuthFailed` with `loginPending: false`: start over with the password.
|
|
2960
|
+
* - `OtpLoginNotPending`: no login was waiting for a code; start over.
|
|
2961
|
+
*/
|
|
2930
2962
|
loginWithOtp(code) {
|
|
2931
2963
|
const { sentDuring, callerInitiated } = this.beginLogin();
|
|
2932
2964
|
let answered = false;
|
|
@@ -2946,6 +2978,12 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2946
2978
|
}),
|
|
2947
2979
|
rxjs.map((msg) => {
|
|
2948
2980
|
if (msg.error) {
|
|
2981
|
+
if (isOtpLoginNotPending(msg.error)) {
|
|
2982
|
+
throw new AuthError(
|
|
2983
|
+
"OTP_LOGIN_NOT_PENDING" /* OtpLoginNotPending */,
|
|
2984
|
+
"TrueNAS is no longer waiting for a one-time passcode for this login. Please sign in with your password again."
|
|
2985
|
+
);
|
|
2986
|
+
}
|
|
2949
2987
|
const errorMessage = getApiErrorMessage(
|
|
2950
2988
|
msg.error,
|
|
2951
2989
|
"Authentication failed"
|
|
@@ -2954,6 +2992,23 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2954
2992
|
}
|
|
2955
2993
|
return msg.result;
|
|
2956
2994
|
}),
|
|
2995
|
+
// A wrong code is answered differently by release, and the API version
|
|
2996
|
+
// does not say which: 25.10 answers `OTP_REQUIRED` and keeps the login
|
|
2997
|
+
// for another code, 27+ answers `AUTH_ERR` and drops it. Both are the
|
|
2998
|
+
// same failure to the caller, told apart only by `loginPending`, so no
|
|
2999
|
+
// caller has to read `OTP_REQUIRED` as "wrong code".
|
|
3000
|
+
rxjs.map((res) => {
|
|
3001
|
+
const loginPending = res?.response_type === "OTP_REQUIRED" /* OtpRequired */;
|
|
3002
|
+
if (loginPending || res?.response_type === "AUTH_ERR" /* AuthErr */) {
|
|
3003
|
+
throw new AuthError(
|
|
3004
|
+
"OTP_AUTH_FAILED" /* OtpAuthFailed */,
|
|
3005
|
+
loginPending ? "TrueNAS rejected the one-time passcode. Please verify it and try again." : "TrueNAS rejected the one-time passcode. Please sign in with your password again.",
|
|
3006
|
+
res,
|
|
3007
|
+
{ loginPending }
|
|
3008
|
+
);
|
|
3009
|
+
}
|
|
3010
|
+
return res;
|
|
3011
|
+
}),
|
|
2957
3012
|
rxjs.tap((res) => {
|
|
2958
3013
|
if (res?.response_type === "SUCCESS" /* Success */) {
|
|
2959
3014
|
this.assertNotSuperseded(sentDuring);
|
|
@@ -2961,10 +3016,6 @@ var TrueNasAuthenticator = class _TrueNasAuthenticator {
|
|
|
2961
3016
|
this.authenticated$.next(true);
|
|
2962
3017
|
}
|
|
2963
3018
|
}),
|
|
2964
|
-
throwOnAuthenticationFailure(
|
|
2965
|
-
"OTP_AUTH_FAILED" /* OtpAuthFailed */,
|
|
2966
|
-
"TrueNAS authentication failed. Please verify your one-time passcode and try again."
|
|
2967
|
-
),
|
|
2968
3019
|
rxjs.finalize(() => {
|
|
2969
3020
|
this.endLogin(sentDuring, callerInitiated, answered);
|
|
2970
3021
|
}),
|
|
@@ -4207,7 +4258,12 @@ function toContainer3(container) {
|
|
|
4207
4258
|
return {
|
|
4208
4259
|
id: container.id.toString(),
|
|
4209
4260
|
name: container.name,
|
|
4210
|
-
status:
|
|
4261
|
+
// `status` is nullable from v28. Middleware's own word on when: "`null` if
|
|
4262
|
+
// `query-options.extra.retrieve_status` is `false`" — so a null is status
|
|
4263
|
+
// that was not fetched, not a container in an unreportable state. That is
|
|
4264
|
+
// what `Unknown` is for ("no usable state"), and it keeps `Container.status`
|
|
4265
|
+
// non-optional for every caller.
|
|
4266
|
+
status: container.status ? toAppState(container.status.state) : "UNKNOWN" /* Unknown */,
|
|
4211
4267
|
// Optional in the generated entry, required by `Container`.
|
|
4212
4268
|
autostart: container.autostart ?? false,
|
|
4213
4269
|
description
|
|
@@ -4823,5 +4879,5 @@ exports.v25_10_4_exports = v25_10_4_exports;
|
|
|
4823
4879
|
exports.v25_10_5_exports = v25_10_5_exports;
|
|
4824
4880
|
exports.v27_0_0_exports = v27_0_0_exports;
|
|
4825
4881
|
exports.v28_0_0_exports = v28_0_0_exports;
|
|
4826
|
-
//# sourceMappingURL=chunk-
|
|
4827
|
-
//# sourceMappingURL=chunk-
|
|
4882
|
+
//# sourceMappingURL=chunk-MQAS7GKB.cjs.map
|
|
4883
|
+
//# sourceMappingURL=chunk-MQAS7GKB.cjs.map
|