@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.mjs
CHANGED
|
@@ -1592,11 +1592,18 @@ function cancelled(message) {
|
|
|
1592
1592
|
error.name = "NotAllowedError";
|
|
1593
1593
|
return error;
|
|
1594
1594
|
}
|
|
1595
|
-
async function ask(method, options) {
|
|
1595
|
+
async function ask(method, options, signal, what) {
|
|
1596
1596
|
const container = navigator.credentials;
|
|
1597
1597
|
const own = globalThis.CredentialsContainer?.prototype?.[method];
|
|
1598
1598
|
const call = own ?? container[method];
|
|
1599
|
-
|
|
1599
|
+
try {
|
|
1600
|
+
return await call.call(container, signal ? { ...options, signal } : options);
|
|
1601
|
+
} catch (error) {
|
|
1602
|
+
if (signal?.aborted || error?.name === "AbortError") {
|
|
1603
|
+
throw Object.assign(cancelled(`${what} was cancelled`), { cause: error });
|
|
1604
|
+
}
|
|
1605
|
+
throw error;
|
|
1606
|
+
}
|
|
1600
1607
|
}
|
|
1601
1608
|
function es256First(params) {
|
|
1602
1609
|
const es256 = params.filter((p) => p.alg === -7);
|
|
@@ -1604,7 +1611,7 @@ function es256First(params) {
|
|
|
1604
1611
|
}
|
|
1605
1612
|
function browserPasskey() {
|
|
1606
1613
|
return {
|
|
1607
|
-
async create(options) {
|
|
1614
|
+
async create(options, createOptions) {
|
|
1608
1615
|
const o = options;
|
|
1609
1616
|
const cred = await ask("create", {
|
|
1610
1617
|
publicKey: {
|
|
@@ -1620,7 +1627,7 @@ function browserPasskey() {
|
|
|
1620
1627
|
attestation: "none",
|
|
1621
1628
|
timeout: o.timeout
|
|
1622
1629
|
}
|
|
1623
|
-
});
|
|
1630
|
+
}, createOptions?.signal, "passkey creation");
|
|
1624
1631
|
if (!cred) throw cancelled("passkey creation was cancelled");
|
|
1625
1632
|
const r = cred.response;
|
|
1626
1633
|
return {
|
|
@@ -1639,7 +1646,7 @@ function browserPasskey() {
|
|
|
1639
1646
|
id: buf(fromB64url(id))
|
|
1640
1647
|
}))
|
|
1641
1648
|
}
|
|
1642
|
-
});
|
|
1649
|
+
}, options?.signal, "passkey sign-in");
|
|
1643
1650
|
if (!cred) throw cancelled("passkey sign-in was cancelled");
|
|
1644
1651
|
const r = cred.response;
|
|
1645
1652
|
return {
|
|
@@ -2244,14 +2251,16 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2244
2251
|
origin === void 0 ? { name, ...invite } : { name, origin, ...invite },
|
|
2245
2252
|
origin
|
|
2246
2253
|
);
|
|
2247
|
-
const
|
|
2254
|
+
const signal = options.signal;
|
|
2255
|
+
const registration = await (signal ? passkey.create(begin.options, { signal }) : passkey.create(begin.options));
|
|
2248
2256
|
const session = await this.confirmed(
|
|
2249
2257
|
"POST",
|
|
2250
2258
|
"auth/passkey/register/finish",
|
|
2251
2259
|
{ challengeId: begin.challengeId, registration, ...invite },
|
|
2252
2260
|
passkey,
|
|
2253
2261
|
void 0,
|
|
2254
|
-
"preferred"
|
|
2262
|
+
"preferred",
|
|
2263
|
+
signal
|
|
2255
2264
|
);
|
|
2256
2265
|
this.useSession(session);
|
|
2257
2266
|
return session;
|
|
@@ -2272,7 +2281,8 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2272
2281
|
const origin = this.pageOrigin(options);
|
|
2273
2282
|
const begin = await this.begin("auth/passkey/login/begin", origin === void 0 ? void 0 : { origin }, origin);
|
|
2274
2283
|
const rpId = begin.options.rpId ?? begin.options.rp?.id ?? "";
|
|
2275
|
-
const
|
|
2284
|
+
const challenge = fromB64url(begin.options.challenge);
|
|
2285
|
+
const assertion = await (options.signal ? passkey.get(challenge, rpId, void 0, { signal: options.signal }) : passkey.get(challenge, rpId));
|
|
2276
2286
|
const session = await this.post("auth/passkey/login/finish", {
|
|
2277
2287
|
challengeId: begin.challengeId,
|
|
2278
2288
|
assertion
|
|
@@ -2341,16 +2351,31 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2341
2351
|
if (this.current === current) this.useSession(session);
|
|
2342
2352
|
return session;
|
|
2343
2353
|
}
|
|
2354
|
+
/**
|
|
2355
|
+
* End this session. The client is signed out whether or not the node
|
|
2356
|
+
* answers: the revoke (`POST /auth/logout`) is attempted, and its failure
|
|
2357
|
+
* (the node unreachable, say) is thrown after the session is dropped, so a
|
|
2358
|
+
* caller can say the server may still hold it, but no request after this
|
|
2359
|
+
* one carries its token.
|
|
2360
|
+
*/
|
|
2344
2361
|
async signOut() {
|
|
2345
|
-
await this.
|
|
2346
|
-
this.auth = void 0;
|
|
2347
|
-
this.current = void 0;
|
|
2362
|
+
await this.signingOut("auth/logout");
|
|
2348
2363
|
}
|
|
2349
|
-
/**
|
|
2364
|
+
/**
|
|
2365
|
+
* End every session of the signed-in account, on every device, this one
|
|
2366
|
+
* too. Like {@link signOut}, this client is signed out even when the
|
|
2367
|
+
* request fails, and the failure is thrown.
|
|
2368
|
+
*/
|
|
2350
2369
|
async signOutEverywhere() {
|
|
2351
|
-
await this.
|
|
2352
|
-
|
|
2353
|
-
|
|
2370
|
+
await this.signingOut("auth/logout-all");
|
|
2371
|
+
}
|
|
2372
|
+
async signingOut(path) {
|
|
2373
|
+
try {
|
|
2374
|
+
await this.post(path);
|
|
2375
|
+
} finally {
|
|
2376
|
+
this.auth = void 0;
|
|
2377
|
+
this.current = void 0;
|
|
2378
|
+
}
|
|
2354
2379
|
}
|
|
2355
2380
|
/** Who the credential is: the account, how it signed in, and the package (`app`) and `origin` a session is bound to. */
|
|
2356
2381
|
me() {
|
|
@@ -2642,7 +2667,7 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2642
2667
|
deleteConfirmed(path, passkey, body = {}) {
|
|
2643
2668
|
return this.confirmed("DELETE", path, body, passkey);
|
|
2644
2669
|
}
|
|
2645
|
-
async confirmed(method, path, body, passkey, send = (b) => this.json(method, path, b), userVerification = "required") {
|
|
2670
|
+
async confirmed(method, path, body, passkey, send = (b) => this.json(method, path, b), userVerification = "required", signal) {
|
|
2646
2671
|
try {
|
|
2647
2672
|
return await send(body);
|
|
2648
2673
|
} catch (error) {
|
|
@@ -2651,7 +2676,8 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2651
2676
|
let assertion;
|
|
2652
2677
|
try {
|
|
2653
2678
|
assertion = await passkey.get(fromB64url(d.challenge), d.rpId, d.allowCredentials, {
|
|
2654
|
-
userVerification: userVerificationOf(d.userVerification, userVerification)
|
|
2679
|
+
userVerification: userVerificationOf(d.userVerification, userVerification),
|
|
2680
|
+
...signal ? { signal } : {}
|
|
2655
2681
|
});
|
|
2656
2682
|
} catch (declined) {
|
|
2657
2683
|
throw promptFailure(declined);
|
|
@@ -3038,16 +3064,33 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
3038
3064
|
}
|
|
3039
3065
|
/**
|
|
3040
3066
|
* Set capability bits ({@link ORG_CAPABILITIES}): for a member (`account`),
|
|
3041
|
-
* for a member of one team (`account` and `team`),
|
|
3042
|
-
*
|
|
3067
|
+
* for a member of one team (`account` and `team`), a team's default
|
|
3068
|
+
* (`team` alone, {@link setTeamDefaultCapabilities}), or the
|
|
3069
|
+
* organization's default (neither). Approved with the caller's `passkey`.
|
|
3043
3070
|
*/
|
|
3044
3071
|
async setCapabilities(org, capabilities, passkey, at = {}) {
|
|
3045
3072
|
await this.postConfirmed(`orgs/${seg(org)}/capabilities`, { capabilities, ...at }, passkey);
|
|
3046
3073
|
}
|
|
3074
|
+
/**
|
|
3075
|
+
* Set the capability bits everyone in `team` holds there on top of their
|
|
3076
|
+
* own, unless their row sets its own (`POST /orgs/{org}/capabilities` with
|
|
3077
|
+
* `team` and no `account`): `ORG_CAPABILITIES.INVITE_MEMBERS` is "members
|
|
3078
|
+
* may invite others to this app". The team's managers, or whoever holds
|
|
3079
|
+
* `MANAGE_MEMBERS` on it; approved with the caller's `passkey`
|
|
3080
|
+
* (`__set_default_capabilities { team, capabilities }`).
|
|
3081
|
+
*/
|
|
3082
|
+
async setTeamDefaultCapabilities(org, team, capabilities, passkey) {
|
|
3083
|
+
await this.postConfirmed(`orgs/${seg(org)}/capabilities`, { team, capabilities }, passkey);
|
|
3084
|
+
}
|
|
3047
3085
|
async createTeam(org, name, join, parent) {
|
|
3048
3086
|
const { teamId } = await this.post(`orgs/${seg(org)}/teams`, { name, join, parent });
|
|
3049
3087
|
return teamId;
|
|
3050
3088
|
}
|
|
3089
|
+
/**
|
|
3090
|
+
* A team the caller sees: its rows (each with its effective capabilities),
|
|
3091
|
+
* children, apps, the package it is the app team of and its default
|
|
3092
|
+
* capabilities.
|
|
3093
|
+
*/
|
|
3051
3094
|
getTeam(org, team) {
|
|
3052
3095
|
return this.get(`orgs/${seg(org)}/teams/${seg(team)}`);
|
|
3053
3096
|
}
|
|
@@ -3089,6 +3132,48 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
3089
3132
|
redeemInvite(token) {
|
|
3090
3133
|
return this.post(`invites/${seg(token)}/redeem`);
|
|
3091
3134
|
}
|
|
3135
|
+
/**
|
|
3136
|
+
* The organization's pending invites the caller may see (never a token):
|
|
3137
|
+
* every one for an owner or admin, their own, and those naming only teams
|
|
3138
|
+
* they manage. Expired ones are listed (`expired: true`) until revoked. A
|
|
3139
|
+
* caller outside the organization: {@link NotFound}.
|
|
3140
|
+
*/
|
|
3141
|
+
async listInvites(org) {
|
|
3142
|
+
const { invites } = await this.get(`orgs/${seg(org)}/invites`);
|
|
3143
|
+
return invites;
|
|
3144
|
+
}
|
|
3145
|
+
/**
|
|
3146
|
+
* Withdraw an invite by its key ({@link listInvites}), approved with the
|
|
3147
|
+
* caller's `passkey` (`__revoke_invite { inviteKey }`). One the caller may
|
|
3148
|
+
* not see: {@link NotFound}.
|
|
3149
|
+
*/
|
|
3150
|
+
async revokeInvite(org, inviteKey, passkey) {
|
|
3151
|
+
await this.deleteConfirmed(`orgs/${seg(org)}/invites/${seg(inviteKey)}`, passkey);
|
|
3152
|
+
}
|
|
3153
|
+
// ---------------------------------------------------------------- app teams
|
|
3154
|
+
/**
|
|
3155
|
+
* The organization's mode and its app teams (one per package), for any
|
|
3156
|
+
* member; a guest sees only those they are in. A caller outside the
|
|
3157
|
+
* organization: {@link NotFound}.
|
|
3158
|
+
*/
|
|
3159
|
+
listAppTeams(org) {
|
|
3160
|
+
return this.get(`orgs/${seg(org)}/app-teams`);
|
|
3161
|
+
}
|
|
3162
|
+
/**
|
|
3163
|
+
* Give apps their own access lists in one step (owner or admin): find or
|
|
3164
|
+
* make each package's app team, add everyone who reaches its instances now,
|
|
3165
|
+
* and move those instances onto it; with `shared`, close every app team.
|
|
3166
|
+
* Idempotent per package. Approved with the caller's `passkey`
|
|
3167
|
+
* (`__scope_apps { apps, shared }`); a refusal is `400 REJECTED` with the
|
|
3168
|
+
* node's reason. For a fresh standalone install pass
|
|
3169
|
+
* `{ apps: [{ package, name, instances: [] }] }`.
|
|
3170
|
+
*/
|
|
3171
|
+
scopeApps(org, passkey, options = {}) {
|
|
3172
|
+
const body = {};
|
|
3173
|
+
if (options.apps !== void 0) body.apps = options.apps;
|
|
3174
|
+
if (options.shared !== void 0) body.shared = options.shared;
|
|
3175
|
+
return this.postConfirmed(`orgs/${seg(org)}/app-teams`, body, passkey);
|
|
3176
|
+
}
|
|
3092
3177
|
// ---------------------------------------------------------------- deployers
|
|
3093
3178
|
/**
|
|
3094
3179
|
* Let an account or organization install apps where the cluster's
|