@calimero-network/mero-js 28.1.1 → 29.1.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 +103 -7
- package/dist/cloud-v2/client.js +77 -15
- 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 +127 -16
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +127 -16
- package/dist/index.mjs.map +2 -2
- package/package.json +20 -2
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ Pinned measurements go through `policy.verifyQuote` (`createQuoteVerifier`).
|
|
|
98
98
|
## The API
|
|
99
99
|
|
|
100
100
|
- **Credentials**: `signUp`, `signIn`, `refresh`, `signOut`, `signOutEverywhere`, `useSession`, `useApiKey`, `me`, `usage`, `addPasskey`, `labelPasskey`, `removePasskey`, `createApiKey`, `listApiKeys`, `revokeApiKey`. Adding or removing a passkey and creating an API key are approved with a passkey the account already has.
|
|
101
|
+
- **Package origins**: `packageOrigins.list`, `packageOrigins.add`, `packageOrigins.remove`. A package's managers register the web origins of a frontend they host themselves (approved with a passkey); `signUp` and `signIn` on such a page send its origin, sign for that origin's relying-party id, and open a session bound to the package (`me()` answers its `app` and `origin`). An unregistered origin is refused with `OriginNotRegistered`.
|
|
101
102
|
- **Packages**: `installPackage`, `uploadPackage`, `packages`, `package`, `uninstallPackage`; `uploadBundle` (raw WASM, development clusters only).
|
|
102
103
|
- **Apps**: `createApp`, `listApps`, `getApp`, `deleteApp`, `setAccess`, `setAppMetadata`, `appStorage`, `appAbi`, `upgradeApp`, `transferApp`.
|
|
103
104
|
- **Calls**: `call`, `callConfirmed`, `view`, `events`. A call always carries an idempotency key, and is sent again with it while the node answers `503`, then to the next node.
|
|
@@ -110,7 +111,7 @@ Pinned measurements go through `policy.verifyQuote` (`createQuoteVerifier`).
|
|
|
110
111
|
|
|
111
112
|
Refusals are typed (`LoginRequired`, `WrongNode`, `NotFound`, `ConfirmRequired`, `ConfirmCancelled`,
|
|
112
113
|
`ArgsTooLarge`, `IdempotencyMismatch`, `ReleaseDeadlineError`, `ConsentStale`, `AppError`, `TrapError`,
|
|
113
|
-
`UnavailableError`),
|
|
114
|
+
`UnavailableError`, `OriginNotRegistered`, `BadOrigin`, `OriginTaken`, `QuotaExceeded`),
|
|
114
115
|
all extending `CalimeroError` with the node's `status` and `code`. A `401` once
|
|
115
116
|
the node that issued the session is replaced or out of reach is answered by one
|
|
116
117
|
refresh and a repeat; a `421 WRONG_NODE` by moving to the next of the `nodes` the client was
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { type AttestationDoc, type CloudPolicy } from './attestation.js';
|
|
13
13
|
import { type PasskeyProvider } from './passkey.js';
|
|
14
14
|
import { type AppsReport, type ConsentRequest, type ConsentResult, type ConsentStarted, type OpenConsentOptions, type OpsAppsReport, type OpsOrgsReport, type PageOptions, type PendingApprovals, type PublisherBindingInfo, type PublisherProof, type ReleaseRules } from './approvals.js';
|
|
15
|
-
export { AppError, ArgsTooLarge, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
15
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, QuotaExceeded, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
16
16
|
export type { Committed } from './errors.js';
|
|
17
17
|
export interface CalimeroSession {
|
|
18
18
|
accountId: string;
|
|
@@ -271,6 +271,73 @@ export declare function frontendManifest(origin?: string, fetcher?: typeof fetch
|
|
|
271
271
|
* not opened through a deployment. `href` defaults to `window.location.href`.
|
|
272
272
|
*/
|
|
273
273
|
export declare function pageDeployment(href?: string): string | null;
|
|
274
|
+
/** `GET /auth/me`: who the credential is. */
|
|
275
|
+
export interface MeInfo extends Record<string, unknown> {
|
|
276
|
+
accountId?: string;
|
|
277
|
+
/** `session` or `apikey`. */
|
|
278
|
+
via?: string;
|
|
279
|
+
/**
|
|
280
|
+
* The package the session is bound to: opened on an app's frontend or on
|
|
281
|
+
* an origin its manager registered ({@link CalimeroClient.packageOrigins}).
|
|
282
|
+
* `null` (or absent, on an older node) for an unbound session.
|
|
283
|
+
*/
|
|
284
|
+
app?: string | null;
|
|
285
|
+
/** The web origin the session was opened on, when the node recorded one. */
|
|
286
|
+
origin?: string | null;
|
|
287
|
+
}
|
|
288
|
+
/** One web origin registered for a package (`GET /package-origins/{package}`). */
|
|
289
|
+
export interface PackageOrigin {
|
|
290
|
+
/** `scheme://host[:port]`. */
|
|
291
|
+
origin: string;
|
|
292
|
+
/** The WebAuthn relying-party id passkeys made there are bound to. */
|
|
293
|
+
rpId: string;
|
|
294
|
+
/** The account that registered it. */
|
|
295
|
+
addedBy: string;
|
|
296
|
+
addedAt: string | number;
|
|
297
|
+
}
|
|
298
|
+
/** What registering an origin answers. */
|
|
299
|
+
export interface PackageOriginAdded extends PackageOrigin {
|
|
300
|
+
package: string;
|
|
301
|
+
}
|
|
302
|
+
/** What removing an origin answers. */
|
|
303
|
+
export interface PackageOriginRemoved {
|
|
304
|
+
package: string;
|
|
305
|
+
origin: string;
|
|
306
|
+
removed: true;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* The web origins a package's frontend may sign users in from besides the
|
|
310
|
+
* cluster's own, so a developer can host it themselves. A session opened on
|
|
311
|
+
* one is bound to the package. For the package's managers.
|
|
312
|
+
*/
|
|
313
|
+
export interface PackageOrigins {
|
|
314
|
+
/** The origins registered for `pkg`. `NotFound` for an unknown package; `403` to anyone not managing it. */
|
|
315
|
+
list(pkg: string): Promise<PackageOrigin[]>;
|
|
316
|
+
/**
|
|
317
|
+
* Register `origin` for `pkg`, approved with `passkey` (`412
|
|
318
|
+
* CONFIRM_REQUIRED` over `__add_origin`; without a passkey it reaches the
|
|
319
|
+
* caller as {@link ConfirmRequired}). `rpId` defaults to the node's choice
|
|
320
|
+
* for the origin (its host). Refusals: {@link BadOrigin} (`BAD_ORIGIN`,
|
|
321
|
+
* `BAD_RP_ID`), {@link OriginTaken}, {@link QuotaExceeded}.
|
|
322
|
+
*/
|
|
323
|
+
add(pkg: string, origin: string, passkey?: PasskeyProvider, options?: {
|
|
324
|
+
rpId?: string;
|
|
325
|
+
}): Promise<PackageOriginAdded>;
|
|
326
|
+
/**
|
|
327
|
+
* Remove `origin` from `pkg`, approved with `passkey` (`__remove_origin`).
|
|
328
|
+
* Sessions opened there stop working (`401`). `NotFound` if it was not registered.
|
|
329
|
+
*/
|
|
330
|
+
remove(pkg: string, origin: string, passkey?: PasskeyProvider): Promise<PackageOriginRemoved>;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Where a sign-up or sign-in says it runs. By default the page's origin
|
|
334
|
+
* (`window.location.origin`) when it is not the origin of a node the client
|
|
335
|
+
* talks to; nothing outside a browser. A string sends that origin; `null`
|
|
336
|
+
* sends none (the cluster's own origins).
|
|
337
|
+
*/
|
|
338
|
+
export interface SignInOptions {
|
|
339
|
+
origin?: string | null;
|
|
340
|
+
}
|
|
274
341
|
/**
|
|
275
342
|
* How a call or a view is sent again while the node is unavailable (D70): with
|
|
276
343
|
* the same key, after a backoff that starts at `baseDelayMs` and doubles up to
|
|
@@ -445,10 +512,31 @@ export declare class CalimeroClient {
|
|
|
445
512
|
get<T = Record<string, unknown>>(path: string): Promise<T>;
|
|
446
513
|
put<T = Record<string, unknown>>(path: string, body?: unknown): Promise<T>;
|
|
447
514
|
delete<T = Record<string, unknown>>(path: string, body?: unknown): Promise<T>;
|
|
448
|
-
/**
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
515
|
+
/**
|
|
516
|
+
* Create an account with a new passkey, and sign in. The node then asks the
|
|
517
|
+
* new passkey to sign the account it creates (`412 CONFIRM_REQUIRED`), so a
|
|
518
|
+
* sign-up prompts twice: create, then sign. On a page whose origin is not
|
|
519
|
+
* the cluster's ({@link SignInOptions}), the node makes the passkey for that
|
|
520
|
+
* origin's relying party (the confirmation's `rpId` is that origin's too)
|
|
521
|
+
* and binds the session to the package the origin is registered for; an
|
|
522
|
+
* unregistered origin is refused with {@link OriginNotRegistered}.
|
|
523
|
+
*/
|
|
524
|
+
signUp(passkey: PasskeyProvider, name: string, options?: SignInOptions): Promise<CalimeroSession>;
|
|
525
|
+
/**
|
|
526
|
+
* Sign in with an existing passkey. On a page whose origin is not the
|
|
527
|
+
* cluster's ({@link SignInOptions}), the assertion is made for that
|
|
528
|
+
* origin's relying-party id, as the node answers it, and the session is
|
|
529
|
+
* bound to the origin's package; an unregistered origin is refused with
|
|
530
|
+
* {@link OriginNotRegistered}.
|
|
531
|
+
*/
|
|
532
|
+
signIn(passkey: PasskeyProvider, options?: SignInOptions): Promise<CalimeroSession>;
|
|
533
|
+
/**
|
|
534
|
+
* The origin a sign-up or sign-in sends: the one given, or the page's own
|
|
535
|
+
* when it is not a node's origin; `undefined` for none.
|
|
536
|
+
*/
|
|
537
|
+
private pageOrigin;
|
|
538
|
+
/** POST a ceremony's `begin`, naming the page's `origin` in an {@link OriginNotRegistered} the node leaves it out of. */
|
|
539
|
+
private begin;
|
|
452
540
|
/**
|
|
453
541
|
* Swap the refresh token for a new session, on whichever node the client
|
|
454
542
|
* uses: any node of the cluster takes it. A refresh token is used once, so
|
|
@@ -460,7 +548,8 @@ export declare class CalimeroClient {
|
|
|
460
548
|
signOut(): Promise<void>;
|
|
461
549
|
/** End every session of the signed-in account, on every device, this one too. */
|
|
462
550
|
signOutEverywhere(): Promise<void>;
|
|
463
|
-
|
|
551
|
+
/** Who the credential is: the account, how it signed in, and the package (`app`) and `origin` a session is bound to. */
|
|
552
|
+
me(): Promise<MeInfo>;
|
|
464
553
|
/**
|
|
465
554
|
* Add another passkey (another device, `passkey`) to the signed-in account;
|
|
466
555
|
* answers its credential id. The node asks for the approval of a passkey
|
|
@@ -481,7 +570,8 @@ export declare class CalimeroClient {
|
|
|
481
570
|
attestation(): Promise<AttestationDoc>;
|
|
482
571
|
/** The account's API keys (never the keys themselves). */
|
|
483
572
|
listApiKeys(): Promise<Array<Record<string, unknown>>>;
|
|
484
|
-
|
|
573
|
+
/** Revoke one of the account's API keys, approved with its `passkey` (`412 CONFIRM_REQUIRED`). */
|
|
574
|
+
revokeApiKey(keyId: string, passkey: PasskeyProvider): Promise<void>;
|
|
485
575
|
/**
|
|
486
576
|
* Create an API key for an agent or server, approved with the account's
|
|
487
577
|
* `passkey` (`412 CONFIRM_REQUIRED`); needs a passkey session (an API key
|
|
@@ -856,6 +946,12 @@ export declare class CalimeroClient {
|
|
|
856
946
|
uses?: number;
|
|
857
947
|
}): Promise<string>;
|
|
858
948
|
redeemInvite(token: string): Promise<Record<string, unknown>>;
|
|
949
|
+
/**
|
|
950
|
+
* The web origins `{package}`'s managers registered so a frontend they host
|
|
951
|
+
* themselves can sign users in with passkeys ({@link PackageOrigins}).
|
|
952
|
+
* Adding and removing one is approved with a passkey.
|
|
953
|
+
*/
|
|
954
|
+
readonly packageOrigins: PackageOrigins;
|
|
859
955
|
/**
|
|
860
956
|
* Let an account or organization install apps where the cluster's
|
|
861
957
|
* deployments are `granted`, until `until` (RFC 3339 or a `Date`; absent,
|
package/dist/cloud-v2/client.js
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import { SealedTransportError, createSealedFetch } from '../sealed/sealed.js';
|
|
13
13
|
import { fetchAttestedKey } from './attestation.js';
|
|
14
14
|
import { DEFAULT_DIRECTORY, orderNodes, readDirectory } from './directory.js';
|
|
15
|
-
import { CalimeroError, ConfirmCancelled, ConfirmRequired, LoginRequired, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
15
|
+
import { CalimeroError, ConfirmCancelled, ConfirmRequired, LoginRequired, OriginNotRegistered, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
16
16
|
import { b64url, fromB64url } from './passkey.js';
|
|
17
17
|
import { confirmationCode, pageQuery, pendingApprovalsFrom, } from './approvals.js';
|
|
18
|
-
export { AppError, ArgsTooLarge, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
18
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, QuotaExceeded, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
19
19
|
/** A deployer's key, as `GET /deployers` lists it and `DELETE /deployers/{key}` takes it. */
|
|
20
20
|
export function deployerKey(deployer) {
|
|
21
21
|
return 'account' in deployer ? `account:${deployer.account}` : `org:${deployer.org}`;
|
|
@@ -186,6 +186,20 @@ export class CalimeroClient {
|
|
|
186
186
|
this.channels = new Map();
|
|
187
187
|
/** Rejections of the underlying `fetch` itself: the node could not be reached or dropped the connection. */
|
|
188
188
|
this.networkFailures = new WeakSet();
|
|
189
|
+
// ---------------------------------------------------------------- package origins
|
|
190
|
+
/**
|
|
191
|
+
* The web origins `{package}`'s managers registered so a frontend they host
|
|
192
|
+
* themselves can sign users in with passkeys ({@link PackageOrigins}).
|
|
193
|
+
* Adding and removing one is approved with a passkey.
|
|
194
|
+
*/
|
|
195
|
+
this.packageOrigins = {
|
|
196
|
+
list: async (pkg) => {
|
|
197
|
+
const { origins } = await this.get(`package-origins/${seg(pkg)}`);
|
|
198
|
+
return origins ?? [];
|
|
199
|
+
},
|
|
200
|
+
add: (pkg, origin, passkey, options = {}) => this.confirmed('POST', `package-origins/${seg(pkg)}`, options.rpId === undefined ? { origin } : { origin, rpId: options.rpId }, passkey),
|
|
201
|
+
remove: (pkg, origin, passkey) => this.confirmed('DELETE', `package-origins/${seg(pkg)}`, { origin }, passkey),
|
|
202
|
+
};
|
|
189
203
|
const trim = (url) => url.replace(/\/+$/, '');
|
|
190
204
|
this.nodeUrls = [...new Set([options.baseUrl, ...(options.nodes ?? [])].map(trim))];
|
|
191
205
|
this.policy = options.policy;
|
|
@@ -440,21 +454,35 @@ export class CalimeroClient {
|
|
|
440
454
|
return this.json('DELETE', path, body);
|
|
441
455
|
}
|
|
442
456
|
// ---------------------------------------------------------------- identity
|
|
443
|
-
/**
|
|
444
|
-
|
|
445
|
-
|
|
457
|
+
/**
|
|
458
|
+
* Create an account with a new passkey, and sign in. The node then asks the
|
|
459
|
+
* new passkey to sign the account it creates (`412 CONFIRM_REQUIRED`), so a
|
|
460
|
+
* sign-up prompts twice: create, then sign. On a page whose origin is not
|
|
461
|
+
* the cluster's ({@link SignInOptions}), the node makes the passkey for that
|
|
462
|
+
* origin's relying party (the confirmation's `rpId` is that origin's too)
|
|
463
|
+
* and binds the session to the package the origin is registered for; an
|
|
464
|
+
* unregistered origin is refused with {@link OriginNotRegistered}.
|
|
465
|
+
*/
|
|
466
|
+
async signUp(passkey, name, options = {}) {
|
|
467
|
+
const origin = this.pageOrigin(options);
|
|
468
|
+
const begin = await this.begin('auth/passkey/register/begin', origin === undefined ? { name } : { name, origin }, origin);
|
|
446
469
|
const registration = await passkey.create(begin.options);
|
|
447
|
-
const session = await this.
|
|
448
|
-
challengeId: begin.challengeId,
|
|
449
|
-
registration,
|
|
450
|
-
});
|
|
470
|
+
const session = await this.postConfirmed('auth/passkey/register/finish', { challengeId: begin.challengeId, registration }, passkey);
|
|
451
471
|
this.useSession(session);
|
|
452
472
|
return session;
|
|
453
473
|
}
|
|
454
|
-
/**
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
474
|
+
/**
|
|
475
|
+
* Sign in with an existing passkey. On a page whose origin is not the
|
|
476
|
+
* cluster's ({@link SignInOptions}), the assertion is made for that
|
|
477
|
+
* origin's relying-party id, as the node answers it, and the session is
|
|
478
|
+
* bound to the origin's package; an unregistered origin is refused with
|
|
479
|
+
* {@link OriginNotRegistered}.
|
|
480
|
+
*/
|
|
481
|
+
async signIn(passkey, options = {}) {
|
|
482
|
+
const origin = this.pageOrigin(options);
|
|
483
|
+
const begin = await this.begin('auth/passkey/login/begin', origin === undefined ? undefined : { origin }, origin);
|
|
484
|
+
const rpId = begin.options.rpId ?? begin.options.rp?.id ?? '';
|
|
485
|
+
const assertion = await passkey.get(fromB64url(begin.options.challenge), rpId);
|
|
458
486
|
const session = await this.post('auth/passkey/login/finish', {
|
|
459
487
|
challengeId: begin.challengeId,
|
|
460
488
|
assertion,
|
|
@@ -462,6 +490,38 @@ export class CalimeroClient {
|
|
|
462
490
|
this.useSession(session);
|
|
463
491
|
return session;
|
|
464
492
|
}
|
|
493
|
+
/**
|
|
494
|
+
* The origin a sign-up or sign-in sends: the one given, or the page's own
|
|
495
|
+
* when it is not a node's origin; `undefined` for none.
|
|
496
|
+
*/
|
|
497
|
+
pageOrigin(options) {
|
|
498
|
+
if (options.origin !== undefined)
|
|
499
|
+
return options.origin ?? undefined;
|
|
500
|
+
const page = globalThis.location?.origin;
|
|
501
|
+
if (!page || page === 'null')
|
|
502
|
+
return undefined;
|
|
503
|
+
const nodes = new Set(this.nodeUrls.map((url) => {
|
|
504
|
+
try {
|
|
505
|
+
return new URL(url).origin;
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
return url;
|
|
509
|
+
}
|
|
510
|
+
}));
|
|
511
|
+
return nodes.has(page) ? undefined : page;
|
|
512
|
+
}
|
|
513
|
+
/** POST a ceremony's `begin`, naming the page's `origin` in an {@link OriginNotRegistered} the node leaves it out of. */
|
|
514
|
+
async begin(path, body, origin) {
|
|
515
|
+
try {
|
|
516
|
+
return await this.post(path, body);
|
|
517
|
+
}
|
|
518
|
+
catch (error) {
|
|
519
|
+
if (error instanceof OriginNotRegistered && !error.origin && origin !== undefined) {
|
|
520
|
+
throw new OriginNotRegistered(error.nodeMessage, { ...error.details, origin });
|
|
521
|
+
}
|
|
522
|
+
throw error;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
465
525
|
/**
|
|
466
526
|
* Swap the refresh token for a new session, on whichever node the client
|
|
467
527
|
* uses: any node of the cluster takes it. A refresh token is used once, so
|
|
@@ -513,6 +573,7 @@ export class CalimeroClient {
|
|
|
513
573
|
this.auth = undefined;
|
|
514
574
|
this.current = undefined;
|
|
515
575
|
}
|
|
576
|
+
/** Who the credential is: the account, how it signed in, and the package (`app`) and `origin` a session is bound to. */
|
|
516
577
|
me() {
|
|
517
578
|
return this.get('auth/me');
|
|
518
579
|
}
|
|
@@ -556,8 +617,9 @@ export class CalimeroClient {
|
|
|
556
617
|
const { keys } = await this.get('auth/apikeys');
|
|
557
618
|
return keys;
|
|
558
619
|
}
|
|
559
|
-
|
|
560
|
-
|
|
620
|
+
/** Revoke one of the account's API keys, approved with its `passkey` (`412 CONFIRM_REQUIRED`). */
|
|
621
|
+
async revokeApiKey(keyId, passkey) {
|
|
622
|
+
await this.deleteConfirmed(`auth/apikeys/${seg(keyId)}`, passkey);
|
|
561
623
|
}
|
|
562
624
|
/**
|
|
563
625
|
* Create an API key for an agent or server, approved with the account's
|
|
@@ -100,6 +100,36 @@ export declare class ReleaseDeadlineError extends CalimeroError {
|
|
|
100
100
|
export declare class ConsentStale extends CalimeroError {
|
|
101
101
|
constructor(message: string, details?: Record<string, unknown>);
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* `403 ORIGIN_NOT_REGISTERED`: a sign-up or sign-in started on a web origin
|
|
105
|
+
* the cluster does not know: neither the cluster's own nor one a package's
|
|
106
|
+
* manager registered (`packageOrigins.add`). `origin` is the page's origin
|
|
107
|
+
* and `package` the package it was expected to be registered for, when known.
|
|
108
|
+
*/
|
|
109
|
+
export declare class OriginNotRegistered extends CalimeroError {
|
|
110
|
+
readonly origin: string;
|
|
111
|
+
readonly package: string;
|
|
112
|
+
/** What the node said, if anything. */
|
|
113
|
+
readonly nodeMessage: string;
|
|
114
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* `400 BAD_ORIGIN` or `400 BAD_RP_ID`: the node does not accept the origin a
|
|
118
|
+
* package's manager tried to register (it must be a bare web origin,
|
|
119
|
+
* `scheme://host[:port]`), or the relying-party id given for it (which must
|
|
120
|
+
* fit the origin's host). `code` says which.
|
|
121
|
+
*/
|
|
122
|
+
export declare class BadOrigin extends CalimeroError {
|
|
123
|
+
constructor(code: 'BAD_ORIGIN' | 'BAD_RP_ID', message: string, details?: Record<string, unknown>);
|
|
124
|
+
}
|
|
125
|
+
/** `409 ORIGIN_TAKEN`: the origin is registered already (for this package or another). */
|
|
126
|
+
export declare class OriginTaken extends CalimeroError {
|
|
127
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
128
|
+
}
|
|
129
|
+
/** `429 QUOTA_EXCEEDED`: the caller holds as many of something (origins, blobs, ...) as it may. */
|
|
130
|
+
export declare class QuotaExceeded extends CalimeroError {
|
|
131
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
132
|
+
}
|
|
103
133
|
/**
|
|
104
134
|
* `422 APP_ERROR`: the app refused the call. `appCode` is the app's declared
|
|
105
135
|
* error (`Taken`, `Forbidden`, ...) and `fields` its named fields. The call was
|
package/dist/cloud-v2/errors.js
CHANGED
|
@@ -128,6 +128,50 @@ export class ConsentStale extends CalimeroError {
|
|
|
128
128
|
this.name = 'ConsentStale';
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* `403 ORIGIN_NOT_REGISTERED`: a sign-up or sign-in started on a web origin
|
|
133
|
+
* the cluster does not know: neither the cluster's own nor one a package's
|
|
134
|
+
* manager registered (`packageOrigins.add`). `origin` is the page's origin
|
|
135
|
+
* and `package` the package it was expected to be registered for, when known.
|
|
136
|
+
*/
|
|
137
|
+
export class OriginNotRegistered extends CalimeroError {
|
|
138
|
+
constructor(message, details = {}) {
|
|
139
|
+
const origin = typeof details.origin === 'string' ? details.origin : '';
|
|
140
|
+
const pkg = typeof details.package === 'string' ? details.package : '';
|
|
141
|
+
const site = origin ? `this site (${origin})` : 'this site';
|
|
142
|
+
super(403, 'ORIGIN_NOT_REGISTERED', `${site} is not registered for ${pkg || 'any package'}${message ? ` (${message})` : ''}`, details);
|
|
143
|
+
this.name = 'OriginNotRegistered';
|
|
144
|
+
this.origin = origin;
|
|
145
|
+
this.package = pkg;
|
|
146
|
+
this.nodeMessage = message;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* `400 BAD_ORIGIN` or `400 BAD_RP_ID`: the node does not accept the origin a
|
|
151
|
+
* package's manager tried to register (it must be a bare web origin,
|
|
152
|
+
* `scheme://host[:port]`), or the relying-party id given for it (which must
|
|
153
|
+
* fit the origin's host). `code` says which.
|
|
154
|
+
*/
|
|
155
|
+
export class BadOrigin extends CalimeroError {
|
|
156
|
+
constructor(code, message, details = {}) {
|
|
157
|
+
super(400, code, message, details);
|
|
158
|
+
this.name = 'BadOrigin';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** `409 ORIGIN_TAKEN`: the origin is registered already (for this package or another). */
|
|
162
|
+
export class OriginTaken extends CalimeroError {
|
|
163
|
+
constructor(message, details = {}) {
|
|
164
|
+
super(409, 'ORIGIN_TAKEN', message, details);
|
|
165
|
+
this.name = 'OriginTaken';
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** `429 QUOTA_EXCEEDED`: the caller holds as many of something (origins, blobs, ...) as it may. */
|
|
169
|
+
export class QuotaExceeded extends CalimeroError {
|
|
170
|
+
constructor(message, details = {}) {
|
|
171
|
+
super(429, 'QUOTA_EXCEEDED', message, details);
|
|
172
|
+
this.name = 'QuotaExceeded';
|
|
173
|
+
}
|
|
174
|
+
}
|
|
131
175
|
/**
|
|
132
176
|
* `422 APP_ERROR`: the app refused the call. `appCode` is the app's declared
|
|
133
177
|
* error (`Taken`, `Forbidden`, ...) and `fields` its named fields. The call was
|
|
@@ -212,6 +256,15 @@ export function errorFrom(status, body, retryAfterHeader) {
|
|
|
212
256
|
return new ReleaseDeadlineError(message, details);
|
|
213
257
|
case '409 CONSENT_STALE':
|
|
214
258
|
return new ConsentStale(message, details);
|
|
259
|
+
case '403 ORIGIN_NOT_REGISTERED':
|
|
260
|
+
return new OriginNotRegistered(message, details);
|
|
261
|
+
case '400 BAD_ORIGIN':
|
|
262
|
+
case '400 BAD_RP_ID':
|
|
263
|
+
return new BadOrigin(code, message, details);
|
|
264
|
+
case '409 ORIGIN_TAKEN':
|
|
265
|
+
return new OriginTaken(message, details);
|
|
266
|
+
case '429 QUOTA_EXCEEDED':
|
|
267
|
+
return new QuotaExceeded(message, details);
|
|
215
268
|
case '412 CONFIRM_REQUIRED':
|
|
216
269
|
return new ConfirmRequired(message, details);
|
|
217
270
|
case '413 ARGS_TOO_LARGE':
|
package/dist/cloud-v2/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { CalimeroClient, deployerKey, frontendManifest, pageDeployment } from './client.js';
|
|
2
2
|
export { DEFAULT_DIRECTORY, DirectoryError } from './directory.js';
|
|
3
3
|
export type { DirectoryFailure } from './directory.js';
|
|
4
|
-
export { AppError, ArgsTooLarge, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
4
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, QuotaExceeded, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
5
5
|
export type { Committed } from './errors.js';
|
|
6
|
-
export type { AppInfo, AppXcalls, BlobContent, BlobInfo, DeadLetter, Deployer, DeployerGrant, DeployersInfo, DeploymentInfo, DeploymentOffer, DeploymentOrgs, FrontendManifest, PublicDeployment, CallResult, CalimeroClientOptions, CalimeroConnectOptions, CloudEvent, CalimeroSession, PackageInfo, PackageInstalled, CloudRetryOptions, OrgInfo, OrgUpgradeTarget, PresenceEntry, UpgradeRun, ViewResult, } from './client.js';
|
|
6
|
+
export type { AppInfo, AppXcalls, BlobContent, BlobInfo, DeadLetter, Deployer, DeployerGrant, DeployersInfo, DeploymentInfo, DeploymentOffer, DeploymentOrgs, FrontendManifest, MeInfo, PackageOrigin, PackageOriginAdded, PackageOriginRemoved, PackageOrigins, SignInOptions, PublicDeployment, CallResult, CalimeroClientOptions, CalimeroConnectOptions, CloudEvent, CalimeroSession, PackageInfo, PackageInstalled, CloudRetryOptions, OrgInfo, OrgUpgradeTarget, PresenceEntry, UpgradeRun, ViewResult, } from './client.js';
|
|
7
7
|
export { claimedRelease, fetchAttestedKey, freshCollateral, MOCK_QUOTE_HEADER } from './attestation.js';
|
|
8
8
|
export type { AttestationDoc, CloudPolicy, CloudReleasePolicy } from './attestation.js';
|
|
9
9
|
export { browserPasskey, b64url, fromB64url } from './passkey.js';
|
package/dist/cloud-v2/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { CalimeroClient, deployerKey, frontendManifest, pageDeployment } from './client.js';
|
|
2
2
|
export { DEFAULT_DIRECTORY, DirectoryError } from './directory.js';
|
|
3
|
-
export { AppError, ArgsTooLarge, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
3
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, QuotaExceeded, ReleaseDeadlineError, TrapError, UnavailableError, WrongNode, errorFrom, } from './errors.js';
|
|
4
4
|
export { claimedRelease, fetchAttestedKey, freshCollateral, MOCK_QUOTE_HEADER } from './attestation.js';
|
|
5
5
|
export { browserPasskey, b64url, fromB64url } from './passkey.js';
|
|
6
6
|
export { MAX_REPORT_PAGE, RELEASE_VERIFIER, compareVersions, confirmationCode, consentReturn, pageQuery, pendingApprovalsFrom, publisherBindingBytes, publisherBindingMessage, releaseConsent, releaseNotesUrl, stalledBy, upgradeConsent, verifyReleaseUrl, withdrawConsent, } from './approvals.js';
|