@calimero-network/mero-js 29.7.6 → 29.8.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 -1
- package/dist/cloud-v2/client.d.ts +180 -4
- package/dist/cloud-v2/client.js +97 -13
- package/dist/cloud-v2/index.d.ts +2 -2
- package/dist/cloud-v2/passkey.d.ts +18 -2
- package/dist/cloud-v2/passkey.js +16 -5
- package/dist/index.browser.mjs +3 -3
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +104 -19
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +104 -19
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1725,11 +1725,18 @@ function cancelled(message) {
|
|
|
1725
1725
|
error.name = "NotAllowedError";
|
|
1726
1726
|
return error;
|
|
1727
1727
|
}
|
|
1728
|
-
async function ask(method, options) {
|
|
1728
|
+
async function ask(method, options, signal, what) {
|
|
1729
1729
|
const container = navigator.credentials;
|
|
1730
1730
|
const own = globalThis.CredentialsContainer?.prototype?.[method];
|
|
1731
1731
|
const call = own ?? container[method];
|
|
1732
|
-
|
|
1732
|
+
try {
|
|
1733
|
+
return await call.call(container, signal ? { ...options, signal } : options);
|
|
1734
|
+
} catch (error) {
|
|
1735
|
+
if (signal?.aborted || error?.name === "AbortError") {
|
|
1736
|
+
throw Object.assign(cancelled(`${what} was cancelled`), { cause: error });
|
|
1737
|
+
}
|
|
1738
|
+
throw error;
|
|
1739
|
+
}
|
|
1733
1740
|
}
|
|
1734
1741
|
function es256First(params) {
|
|
1735
1742
|
const es256 = params.filter((p) => p.alg === -7);
|
|
@@ -1737,7 +1744,7 @@ function es256First(params) {
|
|
|
1737
1744
|
}
|
|
1738
1745
|
function browserPasskey() {
|
|
1739
1746
|
return {
|
|
1740
|
-
async create(options) {
|
|
1747
|
+
async create(options, createOptions) {
|
|
1741
1748
|
const o = options;
|
|
1742
1749
|
const cred = await ask("create", {
|
|
1743
1750
|
publicKey: {
|
|
@@ -1753,7 +1760,7 @@ function browserPasskey() {
|
|
|
1753
1760
|
attestation: "none",
|
|
1754
1761
|
timeout: o.timeout
|
|
1755
1762
|
}
|
|
1756
|
-
});
|
|
1763
|
+
}, createOptions?.signal, "passkey creation");
|
|
1757
1764
|
if (!cred) throw cancelled("passkey creation was cancelled");
|
|
1758
1765
|
const r = cred.response;
|
|
1759
1766
|
return {
|
|
@@ -1772,7 +1779,7 @@ function browserPasskey() {
|
|
|
1772
1779
|
id: buf(fromB64url(id))
|
|
1773
1780
|
}))
|
|
1774
1781
|
}
|
|
1775
|
-
});
|
|
1782
|
+
}, options?.signal, "passkey sign-in");
|
|
1776
1783
|
if (!cred) throw cancelled("passkey sign-in was cancelled");
|
|
1777
1784
|
const r = cred.response;
|
|
1778
1785
|
return {
|
|
@@ -2377,14 +2384,16 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2377
2384
|
origin === void 0 ? { name, ...invite } : { name, origin, ...invite },
|
|
2378
2385
|
origin
|
|
2379
2386
|
);
|
|
2380
|
-
const
|
|
2387
|
+
const signal = options.signal;
|
|
2388
|
+
const registration = await (signal ? passkey.create(begin.options, { signal }) : passkey.create(begin.options));
|
|
2381
2389
|
const session = await this.confirmed(
|
|
2382
2390
|
"POST",
|
|
2383
2391
|
"auth/passkey/register/finish",
|
|
2384
2392
|
{ challengeId: begin.challengeId, registration, ...invite },
|
|
2385
2393
|
passkey,
|
|
2386
2394
|
void 0,
|
|
2387
|
-
"preferred"
|
|
2395
|
+
"preferred",
|
|
2396
|
+
signal
|
|
2388
2397
|
);
|
|
2389
2398
|
this.useSession(session);
|
|
2390
2399
|
return session;
|
|
@@ -2405,7 +2414,8 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2405
2414
|
const origin = this.pageOrigin(options);
|
|
2406
2415
|
const begin = await this.begin("auth/passkey/login/begin", origin === void 0 ? void 0 : { origin }, origin);
|
|
2407
2416
|
const rpId = begin.options.rpId ?? begin.options.rp?.id ?? "";
|
|
2408
|
-
const
|
|
2417
|
+
const challenge = fromB64url(begin.options.challenge);
|
|
2418
|
+
const assertion = await (options.signal ? passkey.get(challenge, rpId, void 0, { signal: options.signal }) : passkey.get(challenge, rpId));
|
|
2409
2419
|
const session = await this.post("auth/passkey/login/finish", {
|
|
2410
2420
|
challengeId: begin.challengeId,
|
|
2411
2421
|
assertion
|
|
@@ -2474,16 +2484,31 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2474
2484
|
if (this.current === current) this.useSession(session);
|
|
2475
2485
|
return session;
|
|
2476
2486
|
}
|
|
2487
|
+
/**
|
|
2488
|
+
* End this session. The client is signed out whether or not the node
|
|
2489
|
+
* answers: the revoke (`POST /auth/logout`) is attempted, and its failure
|
|
2490
|
+
* (the node unreachable, say) is thrown after the session is dropped, so a
|
|
2491
|
+
* caller can say the server may still hold it, but no request after this
|
|
2492
|
+
* one carries its token.
|
|
2493
|
+
*/
|
|
2477
2494
|
async signOut() {
|
|
2478
|
-
await this.
|
|
2479
|
-
this.auth = void 0;
|
|
2480
|
-
this.current = void 0;
|
|
2495
|
+
await this.signingOut("auth/logout");
|
|
2481
2496
|
}
|
|
2482
|
-
/**
|
|
2497
|
+
/**
|
|
2498
|
+
* End every session of the signed-in account, on every device, this one
|
|
2499
|
+
* too. Like {@link signOut}, this client is signed out even when the
|
|
2500
|
+
* request fails, and the failure is thrown.
|
|
2501
|
+
*/
|
|
2483
2502
|
async signOutEverywhere() {
|
|
2484
|
-
await this.
|
|
2485
|
-
|
|
2486
|
-
|
|
2503
|
+
await this.signingOut("auth/logout-all");
|
|
2504
|
+
}
|
|
2505
|
+
async signingOut(path) {
|
|
2506
|
+
try {
|
|
2507
|
+
await this.post(path);
|
|
2508
|
+
} finally {
|
|
2509
|
+
this.auth = void 0;
|
|
2510
|
+
this.current = void 0;
|
|
2511
|
+
}
|
|
2487
2512
|
}
|
|
2488
2513
|
/** Who the credential is: the account, how it signed in, and the package (`app`) and `origin` a session is bound to. */
|
|
2489
2514
|
me() {
|
|
@@ -2775,7 +2800,7 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2775
2800
|
deleteConfirmed(path, passkey, body = {}) {
|
|
2776
2801
|
return this.confirmed("DELETE", path, body, passkey);
|
|
2777
2802
|
}
|
|
2778
|
-
async confirmed(method, path, body, passkey, send = (b) => this.json(method, path, b), userVerification = "required") {
|
|
2803
|
+
async confirmed(method, path, body, passkey, send = (b) => this.json(method, path, b), userVerification = "required", signal) {
|
|
2779
2804
|
try {
|
|
2780
2805
|
return await send(body);
|
|
2781
2806
|
} catch (error) {
|
|
@@ -2784,7 +2809,8 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2784
2809
|
let assertion;
|
|
2785
2810
|
try {
|
|
2786
2811
|
assertion = await passkey.get(fromB64url(d.challenge), d.rpId, d.allowCredentials, {
|
|
2787
|
-
userVerification: userVerificationOf(d.userVerification, userVerification)
|
|
2812
|
+
userVerification: userVerificationOf(d.userVerification, userVerification),
|
|
2813
|
+
...signal ? { signal } : {}
|
|
2788
2814
|
});
|
|
2789
2815
|
} catch (declined) {
|
|
2790
2816
|
throw promptFailure(declined);
|
|
@@ -3171,16 +3197,33 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
3171
3197
|
}
|
|
3172
3198
|
/**
|
|
3173
3199
|
* Set capability bits ({@link ORG_CAPABILITIES}): for a member (`account`),
|
|
3174
|
-
* for a member of one team (`account` and `team`),
|
|
3175
|
-
*
|
|
3200
|
+
* for a member of one team (`account` and `team`), a team's default
|
|
3201
|
+
* (`team` alone, {@link setTeamDefaultCapabilities}), or the
|
|
3202
|
+
* organization's default (neither). Approved with the caller's `passkey`.
|
|
3176
3203
|
*/
|
|
3177
3204
|
async setCapabilities(org, capabilities, passkey, at = {}) {
|
|
3178
3205
|
await this.postConfirmed(`orgs/${seg(org)}/capabilities`, { capabilities, ...at }, passkey);
|
|
3179
3206
|
}
|
|
3207
|
+
/**
|
|
3208
|
+
* Set the capability bits everyone in `team` holds there on top of their
|
|
3209
|
+
* own, unless their row sets its own (`POST /orgs/{org}/capabilities` with
|
|
3210
|
+
* `team` and no `account`): `ORG_CAPABILITIES.INVITE_MEMBERS` is "members
|
|
3211
|
+
* may invite others to this app". The team's managers, or whoever holds
|
|
3212
|
+
* `MANAGE_MEMBERS` on it; approved with the caller's `passkey`
|
|
3213
|
+
* (`__set_default_capabilities { team, capabilities }`).
|
|
3214
|
+
*/
|
|
3215
|
+
async setTeamDefaultCapabilities(org, team, capabilities, passkey) {
|
|
3216
|
+
await this.postConfirmed(`orgs/${seg(org)}/capabilities`, { team, capabilities }, passkey);
|
|
3217
|
+
}
|
|
3180
3218
|
async createTeam(org, name, join, parent) {
|
|
3181
3219
|
const { teamId } = await this.post(`orgs/${seg(org)}/teams`, { name, join, parent });
|
|
3182
3220
|
return teamId;
|
|
3183
3221
|
}
|
|
3222
|
+
/**
|
|
3223
|
+
* A team the caller sees: its rows (each with its effective capabilities),
|
|
3224
|
+
* children, apps, the package it is the app team of and its default
|
|
3225
|
+
* capabilities.
|
|
3226
|
+
*/
|
|
3184
3227
|
getTeam(org, team) {
|
|
3185
3228
|
return this.get(`orgs/${seg(org)}/teams/${seg(team)}`);
|
|
3186
3229
|
}
|
|
@@ -3222,6 +3265,48 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
3222
3265
|
redeemInvite(token) {
|
|
3223
3266
|
return this.post(`invites/${seg(token)}/redeem`);
|
|
3224
3267
|
}
|
|
3268
|
+
/**
|
|
3269
|
+
* The organization's pending invites the caller may see (never a token):
|
|
3270
|
+
* every one for an owner or admin, their own, and those naming only teams
|
|
3271
|
+
* they manage. Expired ones are listed (`expired: true`) until revoked. A
|
|
3272
|
+
* caller outside the organization: {@link NotFound}.
|
|
3273
|
+
*/
|
|
3274
|
+
async listInvites(org) {
|
|
3275
|
+
const { invites } = await this.get(`orgs/${seg(org)}/invites`);
|
|
3276
|
+
return invites;
|
|
3277
|
+
}
|
|
3278
|
+
/**
|
|
3279
|
+
* Withdraw an invite by its key ({@link listInvites}), approved with the
|
|
3280
|
+
* caller's `passkey` (`__revoke_invite { inviteKey }`). One the caller may
|
|
3281
|
+
* not see: {@link NotFound}.
|
|
3282
|
+
*/
|
|
3283
|
+
async revokeInvite(org, inviteKey, passkey) {
|
|
3284
|
+
await this.deleteConfirmed(`orgs/${seg(org)}/invites/${seg(inviteKey)}`, passkey);
|
|
3285
|
+
}
|
|
3286
|
+
// ---------------------------------------------------------------- app teams
|
|
3287
|
+
/**
|
|
3288
|
+
* The organization's mode and its app teams (one per package), for any
|
|
3289
|
+
* member; a guest sees only those they are in. A caller outside the
|
|
3290
|
+
* organization: {@link NotFound}.
|
|
3291
|
+
*/
|
|
3292
|
+
listAppTeams(org) {
|
|
3293
|
+
return this.get(`orgs/${seg(org)}/app-teams`);
|
|
3294
|
+
}
|
|
3295
|
+
/**
|
|
3296
|
+
* Give apps their own access lists in one step (owner or admin): find or
|
|
3297
|
+
* make each package's app team, add everyone who reaches its instances now,
|
|
3298
|
+
* and move those instances onto it; with `shared`, close every app team.
|
|
3299
|
+
* Idempotent per package. Approved with the caller's `passkey`
|
|
3300
|
+
* (`__scope_apps { apps, shared }`); a refusal is `400 REJECTED` with the
|
|
3301
|
+
* node's reason. For a fresh standalone install pass
|
|
3302
|
+
* `{ apps: [{ package, name, instances: [] }] }`.
|
|
3303
|
+
*/
|
|
3304
|
+
scopeApps(org, passkey, options = {}) {
|
|
3305
|
+
const body = {};
|
|
3306
|
+
if (options.apps !== void 0) body.apps = options.apps;
|
|
3307
|
+
if (options.shared !== void 0) body.shared = options.shared;
|
|
3308
|
+
return this.postConfirmed(`orgs/${seg(org)}/app-teams`, body, passkey);
|
|
3309
|
+
}
|
|
3225
3310
|
// ---------------------------------------------------------------- deployers
|
|
3226
3311
|
/**
|
|
3227
3312
|
* Let an account or organization install apps where the cluster's
|