@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 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: toAppState(container.status.state),
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-UOTSHE2J.cjs.map
4827
- //# sourceMappingURL=chunk-UOTSHE2J.cjs.map
4882
+ //# sourceMappingURL=chunk-MQAS7GKB.cjs.map
4883
+ //# sourceMappingURL=chunk-MQAS7GKB.cjs.map