@calimero-network/mero-js 29.0.0 → 29.2.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 +2 -1
- package/dist/cloud-v2/client.d.ts +110 -7
- package/dist/cloud-v2/client.js +78 -10
- package/dist/cloud-v2/errors.d.ts +30 -0
- package/dist/cloud-v2/errors.js +53 -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 +124 -11
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +124 -11
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1394,6 +1394,36 @@ var ConsentStale = class extends CalimeroError {
|
|
|
1394
1394
|
this.name = "ConsentStale";
|
|
1395
1395
|
}
|
|
1396
1396
|
};
|
|
1397
|
+
var OriginNotRegistered = class extends CalimeroError {
|
|
1398
|
+
constructor(message, details = {}) {
|
|
1399
|
+
const origin = typeof details.origin === "string" ? details.origin : "";
|
|
1400
|
+
const pkg = typeof details.package === "string" ? details.package : "";
|
|
1401
|
+
const site = origin ? `this site (${origin})` : "this site";
|
|
1402
|
+
super(403, "ORIGIN_NOT_REGISTERED", `${site} is not registered for ${pkg || "any package"}${message ? ` (${message})` : ""}`, details);
|
|
1403
|
+
this.name = "OriginNotRegistered";
|
|
1404
|
+
this.origin = origin;
|
|
1405
|
+
this.package = pkg;
|
|
1406
|
+
this.nodeMessage = message;
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
var BadOrigin = class extends CalimeroError {
|
|
1410
|
+
constructor(code, message, details = {}) {
|
|
1411
|
+
super(400, code, message, details);
|
|
1412
|
+
this.name = "BadOrigin";
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
var OriginTaken = class extends CalimeroError {
|
|
1416
|
+
constructor(message, details = {}) {
|
|
1417
|
+
super(409, "ORIGIN_TAKEN", message, details);
|
|
1418
|
+
this.name = "OriginTaken";
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
var QuotaExceeded = class extends CalimeroError {
|
|
1422
|
+
constructor(message, details = {}) {
|
|
1423
|
+
super(429, "QUOTA_EXCEEDED", message, details);
|
|
1424
|
+
this.name = "QuotaExceeded";
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1397
1427
|
var AppError = class extends CalimeroError {
|
|
1398
1428
|
constructor(message, details = {}) {
|
|
1399
1429
|
super(422, "APP_ERROR", message, details);
|
|
@@ -1453,6 +1483,15 @@ function errorFrom(status, body, retryAfterHeader) {
|
|
|
1453
1483
|
return new ReleaseDeadlineError(message, details);
|
|
1454
1484
|
case "409 CONSENT_STALE":
|
|
1455
1485
|
return new ConsentStale(message, details);
|
|
1486
|
+
case "403 ORIGIN_NOT_REGISTERED":
|
|
1487
|
+
return new OriginNotRegistered(message, details);
|
|
1488
|
+
case "400 BAD_ORIGIN":
|
|
1489
|
+
case "400 BAD_RP_ID":
|
|
1490
|
+
return new BadOrigin(code, message, details);
|
|
1491
|
+
case "409 ORIGIN_TAKEN":
|
|
1492
|
+
return new OriginTaken(message, details);
|
|
1493
|
+
case "429 QUOTA_EXCEEDED":
|
|
1494
|
+
return new QuotaExceeded(message, details);
|
|
1456
1495
|
case "412 CONFIRM_REQUIRED":
|
|
1457
1496
|
return new ConfirmRequired(message, details);
|
|
1458
1497
|
case "413 ARGS_TOO_LARGE":
|
|
@@ -1741,6 +1780,25 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
1741
1780
|
this.channels = /* @__PURE__ */ new Map();
|
|
1742
1781
|
/** Rejections of the underlying `fetch` itself: the node could not be reached or dropped the connection. */
|
|
1743
1782
|
this.networkFailures = /* @__PURE__ */ new WeakSet();
|
|
1783
|
+
// ---------------------------------------------------------------- package origins
|
|
1784
|
+
/**
|
|
1785
|
+
* The web origins `{package}`'s managers registered so a frontend they host
|
|
1786
|
+
* themselves can sign users in with passkeys ({@link PackageOrigins}).
|
|
1787
|
+
* Adding and removing one is approved with a passkey.
|
|
1788
|
+
*/
|
|
1789
|
+
this.packageOrigins = {
|
|
1790
|
+
list: async (pkg) => {
|
|
1791
|
+
const { origins } = await this.get(`package-origins/${seg(pkg)}`);
|
|
1792
|
+
return origins ?? [];
|
|
1793
|
+
},
|
|
1794
|
+
add: (pkg, origin, passkey, options = {}) => this.confirmed(
|
|
1795
|
+
"POST",
|
|
1796
|
+
`package-origins/${seg(pkg)}`,
|
|
1797
|
+
options.rpId === void 0 ? { origin } : { origin, rpId: options.rpId },
|
|
1798
|
+
passkey
|
|
1799
|
+
),
|
|
1800
|
+
remove: (pkg, origin, passkey) => this.confirmed("DELETE", `package-origins/${seg(pkg)}`, { origin }, passkey)
|
|
1801
|
+
};
|
|
1744
1802
|
const trim = (url2) => url2.replace(/\/+$/, "");
|
|
1745
1803
|
this.nodeUrls = [...new Set([options.baseUrl, ...options.nodes ?? []].map(trim))];
|
|
1746
1804
|
this.policy = options.policy;
|
|
@@ -1996,13 +2054,19 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
1996
2054
|
// ---------------------------------------------------------------- identity
|
|
1997
2055
|
/**
|
|
1998
2056
|
* Create an account with a new passkey, and sign in. The node then asks the
|
|
1999
|
-
* new passkey to sign the account it creates (`412 CONFIRM_REQUIRED
|
|
2000
|
-
*
|
|
2057
|
+
* new passkey to sign the account it creates (`412 CONFIRM_REQUIRED`), so a
|
|
2058
|
+
* sign-up prompts twice: create, then sign. On a page whose origin is not
|
|
2059
|
+
* the cluster's ({@link SignInOptions}), the node makes the passkey for that
|
|
2060
|
+
* origin's relying party (the confirmation's `rpId` is that origin's too)
|
|
2061
|
+
* and binds the session to the package the origin is registered for; an
|
|
2062
|
+
* unregistered origin is refused with {@link OriginNotRegistered}.
|
|
2001
2063
|
*/
|
|
2002
|
-
async signUp(passkey, name) {
|
|
2003
|
-
const
|
|
2064
|
+
async signUp(passkey, name, options = {}) {
|
|
2065
|
+
const origin = this.pageOrigin(options);
|
|
2066
|
+
const begin = await this.begin(
|
|
2004
2067
|
"auth/passkey/register/begin",
|
|
2005
|
-
{ name }
|
|
2068
|
+
origin === void 0 ? { name } : { name, origin },
|
|
2069
|
+
origin
|
|
2006
2070
|
);
|
|
2007
2071
|
const registration = await passkey.create(begin.options);
|
|
2008
2072
|
const session = await this.postConfirmed(
|
|
@@ -2013,12 +2077,18 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2013
2077
|
this.useSession(session);
|
|
2014
2078
|
return session;
|
|
2015
2079
|
}
|
|
2016
|
-
/**
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2080
|
+
/**
|
|
2081
|
+
* Sign in with an existing passkey. On a page whose origin is not the
|
|
2082
|
+
* cluster's ({@link SignInOptions}), the assertion is made for that
|
|
2083
|
+
* origin's relying-party id, as the node answers it, and the session is
|
|
2084
|
+
* bound to the origin's package; an unregistered origin is refused with
|
|
2085
|
+
* {@link OriginNotRegistered}.
|
|
2086
|
+
*/
|
|
2087
|
+
async signIn(passkey, options = {}) {
|
|
2088
|
+
const origin = this.pageOrigin(options);
|
|
2089
|
+
const begin = await this.begin("auth/passkey/login/begin", origin === void 0 ? void 0 : { origin }, origin);
|
|
2090
|
+
const rpId = begin.options.rpId ?? begin.options.rp?.id ?? "";
|
|
2091
|
+
const assertion = await passkey.get(fromB64url(begin.options.challenge), rpId);
|
|
2022
2092
|
const session = await this.post("auth/passkey/login/finish", {
|
|
2023
2093
|
challengeId: begin.challengeId,
|
|
2024
2094
|
assertion
|
|
@@ -2026,6 +2096,36 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2026
2096
|
this.useSession(session);
|
|
2027
2097
|
return session;
|
|
2028
2098
|
}
|
|
2099
|
+
/**
|
|
2100
|
+
* The origin a sign-up or sign-in sends: the one given, or the page's own
|
|
2101
|
+
* when it is not a node's origin; `undefined` for none.
|
|
2102
|
+
*/
|
|
2103
|
+
pageOrigin(options) {
|
|
2104
|
+
if (options.origin !== void 0) return options.origin ?? void 0;
|
|
2105
|
+
const page = globalThis.location?.origin;
|
|
2106
|
+
if (!page || page === "null") return void 0;
|
|
2107
|
+
const nodes = new Set(
|
|
2108
|
+
this.nodeUrls.map((url2) => {
|
|
2109
|
+
try {
|
|
2110
|
+
return new URL(url2).origin;
|
|
2111
|
+
} catch {
|
|
2112
|
+
return url2;
|
|
2113
|
+
}
|
|
2114
|
+
})
|
|
2115
|
+
);
|
|
2116
|
+
return nodes.has(page) ? void 0 : page;
|
|
2117
|
+
}
|
|
2118
|
+
/** POST a ceremony's `begin`, naming the page's `origin` in an {@link OriginNotRegistered} the node leaves it out of. */
|
|
2119
|
+
async begin(path, body, origin) {
|
|
2120
|
+
try {
|
|
2121
|
+
return await this.post(path, body);
|
|
2122
|
+
} catch (error) {
|
|
2123
|
+
if (error instanceof OriginNotRegistered && !error.origin && origin !== void 0) {
|
|
2124
|
+
throw new OriginNotRegistered(error.nodeMessage, { ...error.details, origin });
|
|
2125
|
+
}
|
|
2126
|
+
throw error;
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2029
2129
|
/**
|
|
2030
2130
|
* Swap the refresh token for a new session, on whichever node the client
|
|
2031
2131
|
* uses: any node of the cluster takes it. A refresh token is used once, so
|
|
@@ -2068,6 +2168,7 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2068
2168
|
this.auth = void 0;
|
|
2069
2169
|
this.current = void 0;
|
|
2070
2170
|
}
|
|
2171
|
+
/** Who the credential is: the account, how it signed in, and the package (`app`) and `origin` a session is bound to. */
|
|
2071
2172
|
me() {
|
|
2072
2173
|
return this.get("auth/me");
|
|
2073
2174
|
}
|
|
@@ -2122,6 +2223,12 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2122
2223
|
* Create an API key for an agent or server, approved with the account's
|
|
2123
2224
|
* `passkey` (`412 CONFIRM_REQUIRED`); needs a passkey session (an API key
|
|
2124
2225
|
* is refused `403`). The key is returned once.
|
|
2226
|
+
*
|
|
2227
|
+
* `upgrades: { app, package? }` makes an upgrade key, for CI: it upgrades
|
|
2228
|
+
* that one app to signed releases of its package (default: the one the app
|
|
2229
|
+
* runs, by that package's pinned signer) with {@link upgradeApp} and no
|
|
2230
|
+
* passkey, and every other request with it is refused
|
|
2231
|
+
* `403 UPGRADE_KEY_ONLY`. It takes no other scope field.
|
|
2125
2232
|
*/
|
|
2126
2233
|
createApiKey(options, passkey) {
|
|
2127
2234
|
return this.postConfirmed("auth/apikeys", { ...options }, passkey);
|
|
@@ -2261,6 +2368,8 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2261
2368
|
* `passkey` gives. Refused (`403`) to a session opened on an app's
|
|
2262
2369
|
* frontend: an app asks its user with {@link requestConsent} instead. Past
|
|
2263
2370
|
* a release deadline its approver has not met: {@link ReleaseDeadlineError}.
|
|
2371
|
+
* With an upgrade key ({@link createApiKey} `upgrades`) pass no passkey and
|
|
2372
|
+
* a `version` of the key's package: the key's own proof stands in for it.
|
|
2264
2373
|
*/
|
|
2265
2374
|
upgradeApp(app, target, passkey) {
|
|
2266
2375
|
const path = `apps/${seg(app)}/upgrade`;
|
|
@@ -3234,6 +3343,7 @@ export {
|
|
|
3234
3343
|
AgentGateError,
|
|
3235
3344
|
AppError,
|
|
3236
3345
|
ArgsTooLarge,
|
|
3346
|
+
BadOrigin,
|
|
3237
3347
|
CalimeroClient,
|
|
3238
3348
|
CalimeroError,
|
|
3239
3349
|
ConfirmCancelled,
|
|
@@ -3254,7 +3364,10 @@ export {
|
|
|
3254
3364
|
NODE_RELEASE_SIGNER,
|
|
3255
3365
|
NotFound,
|
|
3256
3366
|
ORG_CAPABILITIES,
|
|
3367
|
+
OriginNotRegistered,
|
|
3368
|
+
OriginTaken,
|
|
3257
3369
|
PRODUCTION_PROFILE,
|
|
3370
|
+
QuotaExceeded,
|
|
3258
3371
|
RELEASE_VERIFIER,
|
|
3259
3372
|
ReleaseDeadlineError,
|
|
3260
3373
|
SEALED_CONTENT_TYPE,
|