@calimero-network/mero-js 29.4.0 → 29.5.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 +1 -0
- package/dist/cloud-v2/client.d.ts +55 -1
- package/dist/cloud-v2/client.js +68 -3
- package/dist/cloud-v2/errors.d.ts +18 -0
- package/dist/cloud-v2/errors.js +26 -0
- package/dist/cloud-v2/index.d.ts +2 -2
- package/dist/cloud-v2/index.js +1 -1
- package/dist/index.browser.mjs +3 -3
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +84 -1
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +84 -1
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1418,6 +1418,19 @@ var OriginTaken = class extends CalimeroError {
|
|
|
1418
1418
|
this.name = "OriginTaken";
|
|
1419
1419
|
}
|
|
1420
1420
|
};
|
|
1421
|
+
var RecoveryNotReady = class extends CalimeroError {
|
|
1422
|
+
constructor(message, details = {}) {
|
|
1423
|
+
super(409, "RECOVERY_NOT_READY", message, details);
|
|
1424
|
+
this.name = "RecoveryNotReady";
|
|
1425
|
+
this.readyAt = typeof details.readyAt === "number" ? details.readyAt : void 0;
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
var WrongRecoveryCode = class extends CalimeroError {
|
|
1429
|
+
constructor(message, details = {}) {
|
|
1430
|
+
super(401, "UNAUTHENTICATED", message || "unknown or used recovery code", details);
|
|
1431
|
+
this.name = "WrongRecoveryCode";
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1421
1434
|
var SignUpRefused = class extends CalimeroError {
|
|
1422
1435
|
constructor(message, details = {}) {
|
|
1423
1436
|
super(403, "SIGN_UP_REFUSED", message, details);
|
|
@@ -1507,6 +1520,8 @@ function errorFrom(status, body, retryAfterHeader) {
|
|
|
1507
1520
|
return new OriginTaken(message, details);
|
|
1508
1521
|
case "429 QUOTA_EXCEEDED":
|
|
1509
1522
|
return new QuotaExceeded(message, details);
|
|
1523
|
+
case "409 RECOVERY_NOT_READY":
|
|
1524
|
+
return new RecoveryNotReady(message, details);
|
|
1510
1525
|
case "403 SIGN_UP_REFUSED":
|
|
1511
1526
|
return new SignUpRefused(message, details);
|
|
1512
1527
|
case "412 CONFIRM_REQUIRED":
|
|
@@ -1853,8 +1868,9 @@ function retryDelayMs(retry, options) {
|
|
|
1853
1868
|
return Math.min(options.baseDelayMs * 2 ** retry, options.maxDelayMs);
|
|
1854
1869
|
}
|
|
1855
1870
|
function ceremony(path) {
|
|
1856
|
-
return path === "auth/refresh" || path.startsWith("auth/passkey/");
|
|
1871
|
+
return path === "auth/refresh" || path.startsWith("auth/passkey/") || RECOVERY_CEREMONIES.has(path);
|
|
1857
1872
|
}
|
|
1873
|
+
var RECOVERY_CEREMONIES = /* @__PURE__ */ new Set(["auth/recovery/begin", "auth/recovery/start", "auth/recovery/finish"]);
|
|
1858
1874
|
var CalimeroClient = class _CalimeroClient {
|
|
1859
1875
|
constructor(options) {
|
|
1860
1876
|
/** The one in use: an index into {@link nodeUrls}. */
|
|
@@ -2289,6 +2305,71 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2289
2305
|
async labelPasskey(credentialId, label) {
|
|
2290
2306
|
await this.post(`auth/passkeys/${seg(credentialId)}`, { label });
|
|
2291
2307
|
}
|
|
2308
|
+
// ---------------------------------------------------------------- account recovery
|
|
2309
|
+
//
|
|
2310
|
+
// core #4844 (`docs/specs/account-recovery.md`): a recovery code, made with
|
|
2311
|
+
// a passkey and shown once, lets someone who lost every passkey register a
|
|
2312
|
+
// new one; it is added, and the account signed in, 72 hours later unless a
|
|
2313
|
+
// passkey the account still has cancels it first.
|
|
2314
|
+
/**
|
|
2315
|
+
* Make the account's recovery code (replacing any it had), approved with
|
|
2316
|
+
* `passkey` (`412 CONFIRM_REQUIRED`). Answers the code, once: show it to
|
|
2317
|
+
* the person to keep offline; the node keeps only its public key. A passkey
|
|
2318
|
+
* session on the cluster's own origin only (never an API key or a
|
|
2319
|
+
* package-bound session).
|
|
2320
|
+
*/
|
|
2321
|
+
async createRecoveryCode(passkey) {
|
|
2322
|
+
const { code } = await this.postConfirmed("auth/recovery", {}, passkey);
|
|
2323
|
+
return code;
|
|
2324
|
+
}
|
|
2325
|
+
/** Remove the account's recovery code, approved with `passkey`. */
|
|
2326
|
+
async removeRecoveryCode(passkey) {
|
|
2327
|
+
await this.deleteConfirmed("auth/recovery", passkey);
|
|
2328
|
+
}
|
|
2329
|
+
/**
|
|
2330
|
+
* Signed out: start recovering the account `code` names. `passkey` makes a
|
|
2331
|
+
* new passkey for it (the browser's create prompt, user verified); the
|
|
2332
|
+
* node spends the code and keeps the passkey as pending. Nothing is added
|
|
2333
|
+
* and no session opens: finish with {@link finishAccountRecovery} at
|
|
2334
|
+
* `readyAt`. A code the cluster does not hold (mistyped, replaced or
|
|
2335
|
+
* spent) is {@link WrongRecoveryCode}; an account with a recovery already
|
|
2336
|
+
* under way `409 RECOVERY_PENDING`.
|
|
2337
|
+
*/
|
|
2338
|
+
async startAccountRecovery(code, passkey) {
|
|
2339
|
+
try {
|
|
2340
|
+
const begin = await this.post("auth/recovery/begin", { code });
|
|
2341
|
+
const registration = await passkey.create(begin.options);
|
|
2342
|
+
return await this.post("auth/recovery/start", { challengeId: begin.challengeId, code, registration });
|
|
2343
|
+
} catch (error) {
|
|
2344
|
+
if (error instanceof LoginRequired) throw new WrongRecoveryCode(error.message.replace(/^401 UNAUTHENTICATED: /, ""), error.details);
|
|
2345
|
+
throw error;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
/**
|
|
2349
|
+
* Cancel the recovery of the signed-in account under way, approved with
|
|
2350
|
+
* `passkey` (one the account already has). The code stays spent: make a
|
|
2351
|
+
* new one.
|
|
2352
|
+
*/
|
|
2353
|
+
async cancelAccountRecovery(passkey) {
|
|
2354
|
+
await this.postConfirmed("auth/recovery/cancel", {}, passkey);
|
|
2355
|
+
}
|
|
2356
|
+
/**
|
|
2357
|
+
* Signed out, once the delay passed: finish the recovery with the passkey
|
|
2358
|
+
* it registered (`passkey` signs the node's sign-in challenge). The passkey
|
|
2359
|
+
* joins the account, every other session of the account ends, and this
|
|
2360
|
+
* client is signed in. `accountId` (from the start) lets the node refuse
|
|
2361
|
+
* early and offer only that passkey; before `readyAt` it is
|
|
2362
|
+
* {@link RecoveryNotReady}, with no recovery under way {@link NotFound}.
|
|
2363
|
+
*/
|
|
2364
|
+
async finishAccountRecovery(passkey, accountId) {
|
|
2365
|
+
const session = await this.postConfirmed(
|
|
2366
|
+
"auth/recovery/finish",
|
|
2367
|
+
accountId ? { accountId } : {},
|
|
2368
|
+
passkey
|
|
2369
|
+
);
|
|
2370
|
+
this.useSession(session);
|
|
2371
|
+
return session;
|
|
2372
|
+
}
|
|
2292
2373
|
/** What this account uses (apps, bundle bytes, API keys, owned orgs), with the cluster's quotas. */
|
|
2293
2374
|
usage() {
|
|
2294
2375
|
return this.get("auth/usage");
|
|
@@ -3505,6 +3586,7 @@ export {
|
|
|
3505
3586
|
QuotaExceeded,
|
|
3506
3587
|
RECOVERY_DOMAIN,
|
|
3507
3588
|
RELEASE_VERIFIER,
|
|
3589
|
+
RecoveryNotReady,
|
|
3508
3590
|
ReleaseDeadlineError,
|
|
3509
3591
|
SEALED_CONTENT_TYPE,
|
|
3510
3592
|
SEALED_PATH,
|
|
@@ -3514,6 +3596,7 @@ export {
|
|
|
3514
3596
|
TrapError,
|
|
3515
3597
|
UnavailableError,
|
|
3516
3598
|
WrongNode,
|
|
3599
|
+
WrongRecoveryCode,
|
|
3517
3600
|
agentKeyBinding,
|
|
3518
3601
|
agentQuoteVerifier,
|
|
3519
3602
|
attestAgent,
|