@calimero-network/mero-js 29.7.3 → 29.7.4
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 +1 -1
- package/dist/cloud-v2/client.js +36 -9
- package/dist/cloud-v2/errors.d.ts +12 -0
- package/dist/cloud-v2/errors.js +15 -0
- package/dist/cloud-v2/index.d.ts +2 -2
- package/dist/cloud-v2/index.js +1 -1
- package/dist/cloud-v2/passkey.d.ts +18 -2
- package/dist/cloud-v2/passkey.js +2 -2
- package/dist/index.browser.mjs +5 -5
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +27 -6
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +27 -6
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,7 +110,7 @@ Pinned measurements go through `policy.verifyQuote` (`createQuoteVerifier`).
|
|
|
110
110
|
- **Operator** (ops token): `opsApps`, `opsOrgs`, `opsServedOrigins` (every custom domain the log holds, by package label), `setReleaseDeadline`, `liftReleaseDeadline`.
|
|
111
111
|
- **Any route**: `get`, `post`, `put`, `delete`; `postConfirmed` and `deleteConfirmed` answer a `412 CONFIRM_REQUIRED` with a passkey.
|
|
112
112
|
|
|
113
|
-
Refusals are typed (`LoginRequired`, `PasskeyUnknownHere`, `WrongNode`, `NotFound`, `ConfirmRequired`, `ConfirmCancelled`,
|
|
113
|
+
Refusals are typed (`LoginRequired`, `PasskeyUnknownHere`, `WrongNode`, `NotFound`, `ConfirmRequired`, `ConfirmCancelled`, `ConfirmPromptBlocked`,
|
|
114
114
|
`ArgsTooLarge`, `IdempotencyMismatch`, `ReleaseDeadlineError`, `ConsentStale`, `AppError`, `TrapError`,
|
|
115
115
|
`UnavailableError`, `OriginNotRegistered`, `BadOrigin`, `OriginTaken`, `QuotaExceeded`),
|
|
116
116
|
all extending `CalimeroError` with the node's `status` and `code`. A `401` once
|
|
@@ -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, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
15
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmPromptBlocked, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
16
16
|
export type { Committed, SignUpRefusal } from './errors.js';
|
|
17
17
|
export interface CalimeroSession {
|
|
18
18
|
accountId: string;
|
package/dist/cloud-v2/client.js
CHANGED
|
@@ -12,11 +12,11 @@
|
|
|
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, OriginNotRegistered, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
15
|
+
import { CalimeroError, ConfirmCancelled, ConfirmPromptBlocked, ConfirmRequired, LoginRequired, OriginNotRegistered, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
16
16
|
import { b64url, fromB64url } from './passkey.js';
|
|
17
17
|
import { signRecovery } from './recovery.js';
|
|
18
18
|
import { confirmationCode, pageQuery, pendingApprovalsFrom, } from './approvals.js';
|
|
19
|
-
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
19
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ConfirmCancelled, ConfirmPromptBlocked, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
20
20
|
/** A deployer's key, as `GET /deployers` lists it and `DELETE /deployers/{key}` takes it. */
|
|
21
21
|
export function deployerKey(deployer) {
|
|
22
22
|
return 'account' in deployer ? `account:${deployer.account}` : `org:${deployer.org}`;
|
|
@@ -55,6 +55,33 @@ export function pageDeployment(href) {
|
|
|
55
55
|
return null;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* The user verification a confirmation asks the passkey for: what the node's
|
|
60
|
+
* `412` details name, if it names one WebAuthn knows, else `required` (the
|
|
61
|
+
* node takes a confirmation only with the user verified).
|
|
62
|
+
*/
|
|
63
|
+
function userVerificationOf(named) {
|
|
64
|
+
return named === 'required' || named === 'preferred' || named === 'discouraged' ? named : 'required';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* What a failed confirmation prompt means to the caller. The browser or a
|
|
68
|
+
* password manager refusing to show the prompt (the page not focused because
|
|
69
|
+
* an extension's popup still holds focus, or another prompt still open) is
|
|
70
|
+
* {@link ConfirmPromptBlocked}; the user dismissing it (`NotAllowedError`, or
|
|
71
|
+
* `AbortError` when it was aborted) is {@link ConfirmCancelled}; anything
|
|
72
|
+
* else is a real failure, passed through.
|
|
73
|
+
*/
|
|
74
|
+
function promptFailure(error) {
|
|
75
|
+
const e = error;
|
|
76
|
+
const name = e?.name;
|
|
77
|
+
const message = typeof e?.message === 'string' ? e.message : '';
|
|
78
|
+
if (name === 'InvalidStateError' || /not focused|already pending/i.test(message)) {
|
|
79
|
+
return new ConfirmPromptBlocked(error);
|
|
80
|
+
}
|
|
81
|
+
if (name === 'NotAllowedError' || name === 'AbortError')
|
|
82
|
+
return new ConfirmCancelled(error);
|
|
83
|
+
return error;
|
|
84
|
+
}
|
|
58
85
|
/** One URL path segment, so an id cannot reach another route. */
|
|
59
86
|
function seg(value) {
|
|
60
87
|
return encodeURIComponent(value);
|
|
@@ -891,15 +918,15 @@ export class CalimeroClient {
|
|
|
891
918
|
const d = error.details;
|
|
892
919
|
let assertion;
|
|
893
920
|
try {
|
|
894
|
-
|
|
921
|
+
// The node takes a confirmation only with the user verified (PIN or
|
|
922
|
+
// biometric); `preferred` lets a password manager skip it, and the
|
|
923
|
+
// node then refuses. A requirement the node names itself wins.
|
|
924
|
+
assertion = await passkey.get(fromB64url(d.challenge), d.rpId, d.allowCredentials, {
|
|
925
|
+
userVerification: userVerificationOf(d.userVerification),
|
|
926
|
+
});
|
|
895
927
|
}
|
|
896
928
|
catch (declined) {
|
|
897
|
-
|
|
898
|
-
// (`AbortError` when it was aborted); anything else is a real failure.
|
|
899
|
-
const name = declined?.name;
|
|
900
|
-
if (name === 'NotAllowedError' || name === 'AbortError')
|
|
901
|
-
throw new ConfirmCancelled(declined);
|
|
902
|
-
throw declined;
|
|
929
|
+
throw promptFailure(declined);
|
|
903
930
|
}
|
|
904
931
|
return send({ ...body, confirm: { challengeId: d.challengeId, assertion } });
|
|
905
932
|
}
|
|
@@ -86,6 +86,18 @@ export declare class ConfirmCancelled extends Error {
|
|
|
86
86
|
readonly cause?: unknown;
|
|
87
87
|
constructor(cause?: unknown);
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* The browser or a password manager refused to show the passkey prompt a
|
|
91
|
+
* confirmation asked for: the page was not focused (an extension's popup
|
|
92
|
+
* still held focus), or another prompt was still open. The user did not
|
|
93
|
+
* decline; nothing was sent. Ask them to try again from a click, e.g. "Your
|
|
94
|
+
* password manager or browser blocked the second prompt. Click to try again."
|
|
95
|
+
* `cause` is the browser's error.
|
|
96
|
+
*/
|
|
97
|
+
export declare class ConfirmPromptBlocked extends Error {
|
|
98
|
+
readonly cause?: unknown;
|
|
99
|
+
constructor(cause?: unknown);
|
|
100
|
+
}
|
|
89
101
|
/** `413 ARGS_TOO_LARGE`: the call's arguments are over the node's limit; it did not run. */
|
|
90
102
|
export declare class ArgsTooLarge extends CalimeroError {
|
|
91
103
|
constructor(message: string, details?: Record<string, unknown>);
|
package/dist/cloud-v2/errors.js
CHANGED
|
@@ -107,6 +107,21 @@ export class ConfirmCancelled extends Error {
|
|
|
107
107
|
this.name = 'ConfirmCancelled';
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* The browser or a password manager refused to show the passkey prompt a
|
|
112
|
+
* confirmation asked for: the page was not focused (an extension's popup
|
|
113
|
+
* still held focus), or another prompt was still open. The user did not
|
|
114
|
+
* decline; nothing was sent. Ask them to try again from a click, e.g. "Your
|
|
115
|
+
* password manager or browser blocked the second prompt. Click to try again."
|
|
116
|
+
* `cause` is the browser's error.
|
|
117
|
+
*/
|
|
118
|
+
export class ConfirmPromptBlocked extends Error {
|
|
119
|
+
constructor(cause) {
|
|
120
|
+
super('the passkey prompt was blocked by the browser or a password manager');
|
|
121
|
+
this.cause = cause;
|
|
122
|
+
this.name = 'ConfirmPromptBlocked';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
110
125
|
/** `413 ARGS_TOO_LARGE`: the call's arguments are over the node's limit; it did not run. */
|
|
111
126
|
export class ArgsTooLarge extends CalimeroError {
|
|
112
127
|
constructor(message, details = {}) {
|
package/dist/cloud-v2/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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, BadOrigin, CalimeroError, ClusterNotUpgraded, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, NotServing, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
4
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ClusterNotUpgraded, ConfirmCancelled, ConfirmPromptBlocked, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, NotServing, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
5
5
|
export type { Committed, SignUpRefusal } from './errors.js';
|
|
6
6
|
export type { AppInfo, AppXcalls, BlobContent, BlobInfo, DeadLetter, Deployer, DeployerGrant, DeployersInfo, DeploymentInfo, DeploymentOffer, DeploymentOrgs, FrontendManifest, MeInfo, PackageOrigin, PackageOriginAdded, PackageOriginRemoved, PackageOrigins, ServedOrigin, ServedOrigins, SignInOptions, AccountRecovery, SignUpOptions, SignUpPolicy, PublicDeployment, CallResult, CalimeroClientOptions, CalimeroConnectOptions, CloudEvent, CalimeroSession, PackageInfo, PackageInstalled, CloudRetryOptions, OrgInfo, OrgRecovery, RecoveryTimes, 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';
|
|
10
10
|
export { MAX_RECOVERY_NONCE_BYTES, RECOVERY_DOMAIN, newRecoverySeed, parseRecoverySeed, recoveryMessage, recoveryPublicKey, recoverySeedText, signRecovery, } from './recovery.js';
|
|
11
|
-
export type { AssertionJSON, PasskeyProvider, RegistrationJSON } from './passkey.js';
|
|
11
|
+
export type { AssertionJSON, PasskeyGetOptions, PasskeyProvider, PasskeyUserVerification, RegistrationJSON, } from './passkey.js';
|
|
12
12
|
export { MAX_REPORT_PAGE, RELEASE_VERIFIER, compareVersions, confirmationCode, consentReturn, pageQuery, pendingApprovalsFrom, publisherBindingBytes, publisherBindingMessage, releaseConsent, releaseNotesUrl, stalledBy, upgradeConsent, verifyReleaseUrl, withdrawConsent, } from './approvals.js';
|
|
13
13
|
export type { ActorKind, AppsReport, Authority, ClusterRelease, ConsentReleaseModel, ConsentRequest, ConsentResult, ConsentScope, ConsentStarted, ConsentStatus, OpenConsentOptions, Governance, LastUpgrade, OpsAppsReport, OpsOrgsReport, PageOptions, PendingApprovals, PendingRelease, PendingUpgrade, PublisherBindingInfo, PublisherProof, ReleaseDeadline, ReleaseRules, ReportScope, ReportedApp, ReportedBundle, ReportedRelease, ReportedReplica, UpgradeAuthority, } from './approvals.js';
|
|
14
14
|
export { DEFAULT_ORG_CAPABILITIES, ORG_CAPABILITIES, orgCapabilities } from './capabilities.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, BadOrigin, CalimeroError, ClusterNotUpgraded, ConfirmCancelled, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, NotServing, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
|
|
3
|
+
export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ClusterNotUpgraded, ConfirmCancelled, ConfirmPromptBlocked, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, NotServing, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, 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_RECOVERY_NONCE_BYTES, RECOVERY_DOMAIN, newRecoverySeed, parseRecoverySeed, recoveryMessage, recoveryPublicKey, recoverySeedText, signRecovery, } from './recovery.js';
|
|
@@ -14,12 +14,28 @@ export interface AssertionJSON {
|
|
|
14
14
|
clientDataJson: string;
|
|
15
15
|
signature: string;
|
|
16
16
|
}
|
|
17
|
+
/** How strongly an assertion must verify the user (WebAuthn's `UserVerificationRequirement`). */
|
|
18
|
+
export type PasskeyUserVerification = "required" | "preferred" | "discouraged";
|
|
19
|
+
/** What a confirmation asks of the passkey beyond the challenge. */
|
|
20
|
+
export interface PasskeyGetOptions {
|
|
21
|
+
/**
|
|
22
|
+
* `"required"` for a confirmation (`412 CONFIRM_REQUIRED`): the node
|
|
23
|
+
* accepts only an assertion with the user-verified flag (PIN or
|
|
24
|
+
* biometric). Absent for a plain sign-in, where `"preferred"` is enough.
|
|
25
|
+
*/
|
|
26
|
+
userVerification?: PasskeyUserVerification;
|
|
27
|
+
}
|
|
17
28
|
/** Something that holds a passkey. */
|
|
18
29
|
export interface PasskeyProvider {
|
|
19
30
|
/** Answer `navigator.credentials.create` for the node's options. */
|
|
20
31
|
create(options: Record<string, unknown>): Promise<RegistrationJSON>;
|
|
21
|
-
/**
|
|
22
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Sign `challenge` (an assertion), optionally limited to
|
|
34
|
+
* `allowCredentials`. `options.userVerification` is `"required"` when the
|
|
35
|
+
* client answers a confirmation; a provider that always verifies the user
|
|
36
|
+
* may ignore it.
|
|
37
|
+
*/
|
|
38
|
+
get(challenge: Uint8Array, rpId: string, allowCredentials?: string[], options?: PasskeyGetOptions): Promise<AssertionJSON>;
|
|
23
39
|
}
|
|
24
40
|
export declare function b64url(bytes: Uint8Array): string;
|
|
25
41
|
export declare function fromB64url(s: string): Uint8Array;
|
package/dist/cloud-v2/passkey.js
CHANGED
|
@@ -70,12 +70,12 @@ export function browserPasskey() {
|
|
|
70
70
|
clientDataJson: b64url(new Uint8Array(r.clientDataJSON)),
|
|
71
71
|
};
|
|
72
72
|
},
|
|
73
|
-
async get(challenge, rpId, allowCredentials) {
|
|
73
|
+
async get(challenge, rpId, allowCredentials, options) {
|
|
74
74
|
const cred = (await ask("get", {
|
|
75
75
|
publicKey: {
|
|
76
76
|
challenge: buf(challenge),
|
|
77
77
|
rpId,
|
|
78
|
-
userVerification: "preferred",
|
|
78
|
+
userVerification: options?.userVerification ?? "preferred",
|
|
79
79
|
allowCredentials: (allowCredentials ?? []).map((id) => ({
|
|
80
80
|
type: "public-key",
|
|
81
81
|
id: buf(fromB64url(id)),
|