@calimero-network/mero-js 29.4.0 → 29.6.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/index.mjs CHANGED
@@ -1418,6 +1418,31 @@ var OriginTaken = class extends CalimeroError {
1418
1418
  this.name = "OriginTaken";
1419
1419
  }
1420
1420
  };
1421
+ var NotServing = class extends CalimeroError {
1422
+ constructor(message, details = {}) {
1423
+ super(400, "NOT_SERVING", message, details);
1424
+ this.name = "NotServing";
1425
+ }
1426
+ };
1427
+ var ClusterNotUpgraded = class extends CalimeroError {
1428
+ constructor(message, details = {}) {
1429
+ super(409, "CLUSTER_NOT_UPGRADED", message, details);
1430
+ this.name = "ClusterNotUpgraded";
1431
+ }
1432
+ };
1433
+ var RecoveryNotReady = class extends CalimeroError {
1434
+ constructor(message, details = {}) {
1435
+ super(409, "RECOVERY_NOT_READY", message, details);
1436
+ this.name = "RecoveryNotReady";
1437
+ this.readyAt = typeof details.readyAt === "number" ? details.readyAt : void 0;
1438
+ }
1439
+ };
1440
+ var WrongRecoveryCode = class extends CalimeroError {
1441
+ constructor(message, details = {}) {
1442
+ super(401, "UNAUTHENTICATED", message || "unknown or used recovery code", details);
1443
+ this.name = "WrongRecoveryCode";
1444
+ }
1445
+ };
1421
1446
  var SignUpRefused = class extends CalimeroError {
1422
1447
  constructor(message, details = {}) {
1423
1448
  super(403, "SIGN_UP_REFUSED", message, details);
@@ -1505,8 +1530,14 @@ function errorFrom(status, body, retryAfterHeader) {
1505
1530
  return new BadOrigin(code, message, details);
1506
1531
  case "409 ORIGIN_TAKEN":
1507
1532
  return new OriginTaken(message, details);
1533
+ case "400 NOT_SERVING":
1534
+ return new NotServing(message, details);
1535
+ case "409 CLUSTER_NOT_UPGRADED":
1536
+ return new ClusterNotUpgraded(message, details);
1508
1537
  case "429 QUOTA_EXCEEDED":
1509
1538
  return new QuotaExceeded(message, details);
1539
+ case "409 RECOVERY_NOT_READY":
1540
+ return new RecoveryNotReady(message, details);
1510
1541
  case "403 SIGN_UP_REFUSED":
1511
1542
  return new SignUpRefused(message, details);
1512
1543
  case "412 CONFIRM_REQUIRED":
@@ -1853,8 +1884,9 @@ function retryDelayMs(retry, options) {
1853
1884
  return Math.min(options.baseDelayMs * 2 ** retry, options.maxDelayMs);
1854
1885
  }
1855
1886
  function ceremony(path) {
1856
- return path === "auth/refresh" || path.startsWith("auth/passkey/");
1887
+ return path === "auth/refresh" || path.startsWith("auth/passkey/") || RECOVERY_CEREMONIES.has(path);
1857
1888
  }
1889
+ var RECOVERY_CEREMONIES = /* @__PURE__ */ new Set(["auth/recovery/begin", "auth/recovery/start", "auth/recovery/finish"]);
1858
1890
  var CalimeroClient = class _CalimeroClient {
1859
1891
  constructor(options) {
1860
1892
  /** The one in use: an index into {@link nodeUrls}. */
@@ -1877,7 +1909,13 @@ var CalimeroClient = class _CalimeroClient {
1877
1909
  add: (pkg, origin, passkey, options = {}) => this.confirmed(
1878
1910
  "POST",
1879
1911
  `package-origins/${seg(pkg)}`,
1880
- options.rpId === void 0 ? { origin } : { origin, rpId: options.rpId },
1912
+ // Only the fields set: the node refuses unknown ones, and one that
1913
+ // predates served origins takes a plain add unchanged.
1914
+ {
1915
+ origin,
1916
+ ...options.rpId === void 0 ? {} : { rpId: options.rpId },
1917
+ ...options.served ? { served: true } : {}
1918
+ },
1881
1919
  passkey
1882
1920
  ),
1883
1921
  remove: (pkg, origin, passkey) => this.confirmed("DELETE", `package-origins/${seg(pkg)}`, { origin }, passkey)
@@ -2289,6 +2327,71 @@ var CalimeroClient = class _CalimeroClient {
2289
2327
  async labelPasskey(credentialId, label) {
2290
2328
  await this.post(`auth/passkeys/${seg(credentialId)}`, { label });
2291
2329
  }
2330
+ // ---------------------------------------------------------------- account recovery
2331
+ //
2332
+ // core #4844 (`docs/specs/account-recovery.md`): a recovery code, made with
2333
+ // a passkey and shown once, lets someone who lost every passkey register a
2334
+ // new one; it is added, and the account signed in, 72 hours later unless a
2335
+ // passkey the account still has cancels it first.
2336
+ /**
2337
+ * Make the account's recovery code (replacing any it had), approved with
2338
+ * `passkey` (`412 CONFIRM_REQUIRED`). Answers the code, once: show it to
2339
+ * the person to keep offline; the node keeps only its public key. A passkey
2340
+ * session on the cluster's own origin only (never an API key or a
2341
+ * package-bound session).
2342
+ */
2343
+ async createRecoveryCode(passkey) {
2344
+ const { code } = await this.postConfirmed("auth/recovery", {}, passkey);
2345
+ return code;
2346
+ }
2347
+ /** Remove the account's recovery code, approved with `passkey`. */
2348
+ async removeRecoveryCode(passkey) {
2349
+ await this.deleteConfirmed("auth/recovery", passkey);
2350
+ }
2351
+ /**
2352
+ * Signed out: start recovering the account `code` names. `passkey` makes a
2353
+ * new passkey for it (the browser's create prompt, user verified); the
2354
+ * node spends the code and keeps the passkey as pending. Nothing is added
2355
+ * and no session opens: finish with {@link finishAccountRecovery} at
2356
+ * `readyAt`. A code the cluster does not hold (mistyped, replaced or
2357
+ * spent) is {@link WrongRecoveryCode}; an account with a recovery already
2358
+ * under way `409 RECOVERY_PENDING`.
2359
+ */
2360
+ async startAccountRecovery(code, passkey) {
2361
+ try {
2362
+ const begin = await this.post("auth/recovery/begin", { code });
2363
+ const registration = await passkey.create(begin.options);
2364
+ return await this.post("auth/recovery/start", { challengeId: begin.challengeId, code, registration });
2365
+ } catch (error) {
2366
+ if (error instanceof LoginRequired) throw new WrongRecoveryCode(error.message.replace(/^401 UNAUTHENTICATED: /, ""), error.details);
2367
+ throw error;
2368
+ }
2369
+ }
2370
+ /**
2371
+ * Cancel the recovery of the signed-in account under way, approved with
2372
+ * `passkey` (one the account already has). The code stays spent: make a
2373
+ * new one.
2374
+ */
2375
+ async cancelAccountRecovery(passkey) {
2376
+ await this.postConfirmed("auth/recovery/cancel", {}, passkey);
2377
+ }
2378
+ /**
2379
+ * Signed out, once the delay passed: finish the recovery with the passkey
2380
+ * it registered (`passkey` signs the node's sign-in challenge). The passkey
2381
+ * joins the account, every other session of the account ends, and this
2382
+ * client is signed in. `accountId` (from the start) lets the node refuse
2383
+ * early and offer only that passkey; before `readyAt` it is
2384
+ * {@link RecoveryNotReady}, with no recovery under way {@link NotFound}.
2385
+ */
2386
+ async finishAccountRecovery(passkey, accountId) {
2387
+ const session = await this.postConfirmed(
2388
+ "auth/recovery/finish",
2389
+ accountId ? { accountId } : {},
2390
+ passkey
2391
+ );
2392
+ this.useSession(session);
2393
+ return session;
2394
+ }
2292
2395
  /** What this account uses (apps, bundle bytes, API keys, owned orgs), with the cluster's quotas. */
2293
2396
  usage() {
2294
2397
  return this.get("auth/usage");
@@ -2848,6 +2951,14 @@ var CalimeroClient = class _CalimeroClient {
2848
2951
  opsOrgs(page = {}) {
2849
2952
  return this.get(`ops/orgs${pageQuery(page)}`);
2850
2953
  }
2954
+ /**
2955
+ * `GET /ops/served-origins`: every served origin (custom domain) the
2956
+ * cluster's log holds, with its package's label and no package name or
2957
+ * account. Operator token.
2958
+ */
2959
+ opsServedOrigins() {
2960
+ return this.get("ops/served-origins");
2961
+ }
2851
2962
  /**
2852
2963
  * Announce when work on images older than `version` ends: from `after` on,
2853
2964
  * a scope that has not approved it (or newer) starts no new work. Operator
@@ -3480,6 +3591,7 @@ export {
3480
3591
  BadOrigin,
3481
3592
  CalimeroClient,
3482
3593
  CalimeroError,
3594
+ ClusterNotUpgraded,
3483
3595
  ConfirmCancelled,
3484
3596
  ConfirmRequired,
3485
3597
  ConsentStale,
@@ -3498,6 +3610,7 @@ export {
3498
3610
  MOCK_QUOTE_HEADER,
3499
3611
  NODE_RELEASE_SIGNER,
3500
3612
  NotFound,
3613
+ NotServing,
3501
3614
  ORG_CAPABILITIES,
3502
3615
  OriginNotRegistered,
3503
3616
  OriginTaken,
@@ -3505,6 +3618,7 @@ export {
3505
3618
  QuotaExceeded,
3506
3619
  RECOVERY_DOMAIN,
3507
3620
  RELEASE_VERIFIER,
3621
+ RecoveryNotReady,
3508
3622
  ReleaseDeadlineError,
3509
3623
  SEALED_CONTENT_TYPE,
3510
3624
  SEALED_PATH,
@@ -3514,6 +3628,7 @@ export {
3514
3628
  TrapError,
3515
3629
  UnavailableError,
3516
3630
  WrongNode,
3631
+ WrongRecoveryCode,
3517
3632
  agentKeyBinding,
3518
3633
  agentQuoteVerifier,
3519
3634
  attestAgent,