@calimero-network/mero-js 25.3.1 → 25.3.2
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 +3 -3
- package/dist/auth/index.d.ts +11 -2
- package/dist/auth/index.js +20 -3
- package/dist/cloud/enrol-redirect.d.ts +10 -24
- package/dist/cloud/enrol-redirect.js +16 -8
- package/dist/cloud/link-state.d.ts +5 -1
- package/dist/cloud/link-state.js +28 -21
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +92 -70
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +92 -70
- package/dist/index.mjs.map +4 -4
- package/dist/mero-js.d.ts +2 -2
- package/dist/mero-js.js +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2984,8 +2984,73 @@ function createAdminApiClientFromHttpClient(httpClient, _config) {
|
|
|
2984
2984
|
return new AdminApiClient(httpClient);
|
|
2985
2985
|
}
|
|
2986
2986
|
|
|
2987
|
+
// src/cloud/link-state.ts
|
|
2988
|
+
var KEY = "calimero.cloud.link.pending";
|
|
2989
|
+
var STATE_PARAM = "link_state";
|
|
2990
|
+
var LIFETIME_MS = 10 * 60 * 1e3;
|
|
2991
|
+
var ACCOUNT_HEX = /^[0-9a-f]{64}$/;
|
|
2992
|
+
var MAX_PENDING = 20;
|
|
2993
|
+
function readPending(key, now) {
|
|
2994
|
+
try {
|
|
2995
|
+
const raw = localStorage.getItem(key);
|
|
2996
|
+
const pending = raw ? JSON.parse(raw) : {};
|
|
2997
|
+
return Object.fromEntries(
|
|
2998
|
+
Object.entries(pending).filter(
|
|
2999
|
+
([, p]) => p && typeof p.expiresAt === "number" && p.expiresAt > now
|
|
3000
|
+
)
|
|
3001
|
+
);
|
|
3002
|
+
} catch {
|
|
3003
|
+
return {};
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
function writePending(key, pending) {
|
|
3007
|
+
try {
|
|
3008
|
+
localStorage.setItem(key, JSON.stringify(pending));
|
|
3009
|
+
} catch {
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
function beginState(key, payload) {
|
|
3013
|
+
const now = Date.now();
|
|
3014
|
+
const pending = readPending(key, now);
|
|
3015
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
3016
|
+
const state = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
|
|
3017
|
+
""
|
|
3018
|
+
);
|
|
3019
|
+
pending[state] = { ...payload, expiresAt: now + LIFETIME_MS };
|
|
3020
|
+
writePending(key, Object.fromEntries(Object.entries(pending).slice(-MAX_PENDING)));
|
|
3021
|
+
return state;
|
|
3022
|
+
}
|
|
3023
|
+
function takeState(key, state) {
|
|
3024
|
+
const pending = readPending(key, Date.now());
|
|
3025
|
+
if (!state || !Object.prototype.hasOwnProperty.call(pending, state))
|
|
3026
|
+
return null;
|
|
3027
|
+
const entry = pending[state];
|
|
3028
|
+
delete pending[state];
|
|
3029
|
+
writePending(key, pending);
|
|
3030
|
+
return entry;
|
|
3031
|
+
}
|
|
3032
|
+
function beginLinkState(account, returnTo) {
|
|
3033
|
+
if (!ACCOUNT_HEX.test(account)) {
|
|
3034
|
+
throw new Error("accountId must be 64 lowercase hex characters");
|
|
3035
|
+
}
|
|
3036
|
+
const url2 = new URL(returnTo);
|
|
3037
|
+
url2.searchParams.set(STATE_PARAM, beginState(KEY, { account }));
|
|
3038
|
+
return url2.toString();
|
|
3039
|
+
}
|
|
3040
|
+
function takeLinkState(search) {
|
|
3041
|
+
return takeState(KEY, new URLSearchParams(search).get(STATE_PARAM));
|
|
3042
|
+
}
|
|
3043
|
+
function withoutLinkState(search) {
|
|
3044
|
+
const params = new URLSearchParams(search);
|
|
3045
|
+
params.delete(STATE_PARAM);
|
|
3046
|
+
const rest = params.toString();
|
|
3047
|
+
return rest ? `?${rest}` : "";
|
|
3048
|
+
}
|
|
3049
|
+
|
|
2987
3050
|
// src/auth/index.ts
|
|
2988
|
-
|
|
3051
|
+
var PENDING_KEY = "calimero.auth.login.pending";
|
|
3052
|
+
var STATE_PARAM2 = "auth_state";
|
|
3053
|
+
function parseAuthCallback(url2, options = {}) {
|
|
2989
3054
|
try {
|
|
2990
3055
|
const hashIndex = url2.indexOf("#");
|
|
2991
3056
|
if (hashIndex === -1) return null;
|
|
@@ -2993,6 +3058,12 @@ function parseAuthCallback(url2) {
|
|
|
2993
3058
|
const params = new URLSearchParams(hash);
|
|
2994
3059
|
const accessToken = params.get("access_token");
|
|
2995
3060
|
if (!accessToken) return null;
|
|
3061
|
+
if (!options.allowUnsolicited && !takeState(PENDING_KEY, stateOf(url2, hashIndex))) {
|
|
3062
|
+
console.warn(
|
|
3063
|
+
"[mero-js] ignoring auth callback tokens: they answer no login begun in this browser"
|
|
3064
|
+
);
|
|
3065
|
+
return null;
|
|
3066
|
+
}
|
|
2996
3067
|
return {
|
|
2997
3068
|
accessToken,
|
|
2998
3069
|
refreshToken: params.get("refresh_token") ?? "",
|
|
@@ -3005,9 +3076,16 @@ function parseAuthCallback(url2) {
|
|
|
3005
3076
|
return null;
|
|
3006
3077
|
}
|
|
3007
3078
|
}
|
|
3079
|
+
function stateOf(url2, hashIndex) {
|
|
3080
|
+
const queryIndex = url2.indexOf("?");
|
|
3081
|
+
if (queryIndex === -1 || queryIndex > hashIndex) return null;
|
|
3082
|
+
return new URLSearchParams(url2.substring(queryIndex + 1, hashIndex)).get(STATE_PARAM2);
|
|
3083
|
+
}
|
|
3008
3084
|
function buildAuthLoginUrl(nodeUrl, opts) {
|
|
3085
|
+
const callback = new URL(opts.callbackUrl);
|
|
3086
|
+
callback.searchParams.set(STATE_PARAM2, beginState(PENDING_KEY, {}));
|
|
3009
3087
|
const params = new URLSearchParams();
|
|
3010
|
-
params.set("callback-url",
|
|
3088
|
+
params.set("callback-url", callback.toString());
|
|
3011
3089
|
if (opts.permissions && opts.permissions.length > 0) {
|
|
3012
3090
|
params.set("permissions", opts.permissions.join(","));
|
|
3013
3091
|
}
|
|
@@ -9423,12 +9501,12 @@ function createMeroClient(config) {
|
|
|
9423
9501
|
}
|
|
9424
9502
|
|
|
9425
9503
|
// src/account/session.ts
|
|
9426
|
-
var
|
|
9504
|
+
var KEY2 = "calimero.delegated.connection";
|
|
9427
9505
|
var CREDENTIAL_KEY = "calimero.delegated.credential";
|
|
9428
9506
|
function readDelegatedSession() {
|
|
9429
9507
|
if (typeof sessionStorage === "undefined") return null;
|
|
9430
9508
|
try {
|
|
9431
|
-
const raw = sessionStorage.getItem(
|
|
9509
|
+
const raw = sessionStorage.getItem(KEY2);
|
|
9432
9510
|
return raw ? JSON.parse(raw) : null;
|
|
9433
9511
|
} catch {
|
|
9434
9512
|
return null;
|
|
@@ -9436,13 +9514,13 @@ function readDelegatedSession() {
|
|
|
9436
9514
|
}
|
|
9437
9515
|
function saveDelegatedSession(s) {
|
|
9438
9516
|
try {
|
|
9439
|
-
sessionStorage.setItem(
|
|
9517
|
+
sessionStorage.setItem(KEY2, JSON.stringify(s));
|
|
9440
9518
|
} catch {
|
|
9441
9519
|
}
|
|
9442
9520
|
}
|
|
9443
9521
|
function clearDelegatedSession() {
|
|
9444
9522
|
try {
|
|
9445
|
-
sessionStorage.removeItem(
|
|
9523
|
+
sessionStorage.removeItem(KEY2);
|
|
9446
9524
|
} catch {
|
|
9447
9525
|
}
|
|
9448
9526
|
}
|
|
@@ -10240,64 +10318,6 @@ function base643(bytes) {
|
|
|
10240
10318
|
return btoa(binary);
|
|
10241
10319
|
}
|
|
10242
10320
|
|
|
10243
|
-
// src/cloud/link-state.ts
|
|
10244
|
-
var KEY2 = "calimero.cloud.link.pending";
|
|
10245
|
-
var STATE_PARAM = "link_state";
|
|
10246
|
-
var LIFETIME_MS = 10 * 60 * 1e3;
|
|
10247
|
-
var ACCOUNT_HEX = /^[0-9a-f]{64}$/;
|
|
10248
|
-
var MAX_PENDING = 20;
|
|
10249
|
-
function readPending(now) {
|
|
10250
|
-
try {
|
|
10251
|
-
const raw = localStorage.getItem(KEY2);
|
|
10252
|
-
const pending = raw ? JSON.parse(raw) : {};
|
|
10253
|
-
return Object.fromEntries(
|
|
10254
|
-
Object.entries(pending).filter(
|
|
10255
|
-
([, p]) => p && typeof p.expiresAt === "number" && p.expiresAt > now
|
|
10256
|
-
)
|
|
10257
|
-
);
|
|
10258
|
-
} catch {
|
|
10259
|
-
return {};
|
|
10260
|
-
}
|
|
10261
|
-
}
|
|
10262
|
-
function writePending(pending) {
|
|
10263
|
-
try {
|
|
10264
|
-
localStorage.setItem(KEY2, JSON.stringify(pending));
|
|
10265
|
-
} catch {
|
|
10266
|
-
}
|
|
10267
|
-
}
|
|
10268
|
-
function beginLinkState(account, returnTo) {
|
|
10269
|
-
if (!ACCOUNT_HEX.test(account)) {
|
|
10270
|
-
throw new Error("accountId must be 64 lowercase hex characters");
|
|
10271
|
-
}
|
|
10272
|
-
const url2 = new URL(returnTo);
|
|
10273
|
-
const now = Date.now();
|
|
10274
|
-
const pending = readPending(now);
|
|
10275
|
-
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
10276
|
-
const state = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
|
|
10277
|
-
""
|
|
10278
|
-
);
|
|
10279
|
-
pending[state] = { account, expiresAt: now + LIFETIME_MS };
|
|
10280
|
-
writePending(Object.fromEntries(Object.entries(pending).slice(-MAX_PENDING)));
|
|
10281
|
-
url2.searchParams.set(STATE_PARAM, state);
|
|
10282
|
-
return url2.toString();
|
|
10283
|
-
}
|
|
10284
|
-
function takeLinkState(search) {
|
|
10285
|
-
const state = new URLSearchParams(search).get(STATE_PARAM);
|
|
10286
|
-
const pending = readPending(Date.now());
|
|
10287
|
-
if (!state || !Object.prototype.hasOwnProperty.call(pending, state))
|
|
10288
|
-
return null;
|
|
10289
|
-
const entry = pending[state];
|
|
10290
|
-
delete pending[state];
|
|
10291
|
-
writePending(pending);
|
|
10292
|
-
return entry;
|
|
10293
|
-
}
|
|
10294
|
-
function withoutLinkState(search) {
|
|
10295
|
-
const params = new URLSearchParams(search);
|
|
10296
|
-
params.delete(STATE_PARAM);
|
|
10297
|
-
const rest = params.toString();
|
|
10298
|
-
return rest ? `?${rest}` : "";
|
|
10299
|
-
}
|
|
10300
|
-
|
|
10301
10321
|
// src/cloud/link-redirect.ts
|
|
10302
10322
|
var DEFAULT_CLOUD_WEB_URL = "https://cloud.calimero.network";
|
|
10303
10323
|
function cloudLinkUrl(options) {
|
|
@@ -10354,7 +10374,8 @@ async function completeCloudLink(options) {
|
|
|
10354
10374
|
var DEVICE_PARAM = "enrol-device";
|
|
10355
10375
|
var KEM_PARAM = "enrol-kem";
|
|
10356
10376
|
var CALLBACK_PARAM = "callback-url";
|
|
10357
|
-
var
|
|
10377
|
+
var STATE_PARAM3 = "state";
|
|
10378
|
+
var PENDING_KEY2 = "calimero.device.enrol.pending";
|
|
10358
10379
|
function deviceEnrolmentUrl(options) {
|
|
10359
10380
|
assertHex(options.devicePublicKey, "devicePublicKey");
|
|
10360
10381
|
assertHex(options.kemPublicKey, "kemPublicKey");
|
|
@@ -10364,7 +10385,7 @@ function deviceEnrolmentUrl(options) {
|
|
|
10364
10385
|
url2.searchParams.set(DEVICE_PARAM, options.devicePublicKey);
|
|
10365
10386
|
url2.searchParams.set(KEM_PARAM, options.kemPublicKey);
|
|
10366
10387
|
url2.searchParams.set(CALLBACK_PARAM, options.returnTo);
|
|
10367
|
-
|
|
10388
|
+
url2.searchParams.set(STATE_PARAM3, beginState(PENDING_KEY2, {}));
|
|
10368
10389
|
return url2.toString();
|
|
10369
10390
|
}
|
|
10370
10391
|
function beginDeviceEnrolment(options) {
|
|
@@ -10375,6 +10396,7 @@ function readEnrolmentCallback(location2 = window.location) {
|
|
|
10375
10396
|
const params = new URLSearchParams(location2.hash.replace(/^#/, ""));
|
|
10376
10397
|
const error = params.get("error");
|
|
10377
10398
|
if (error) {
|
|
10399
|
+
takeState(PENDING_KEY2, params.get(STATE_PARAM3));
|
|
10378
10400
|
stripFragment2();
|
|
10379
10401
|
throw new Error(
|
|
10380
10402
|
error === "denied" || error === "cancelled" ? "the device was not approved at the wallet" : `the wallet refused this enrolment: ${error}`
|
|
@@ -10393,9 +10415,9 @@ function stripFragment2() {
|
|
|
10393
10415
|
history.replaceState(null, "", location.pathname + location.search);
|
|
10394
10416
|
}
|
|
10395
10417
|
async function completeDeviceEnrolment(options) {
|
|
10396
|
-
if (
|
|
10418
|
+
if (!takeState(PENDING_KEY2, options.state)) {
|
|
10397
10419
|
throw new Error(
|
|
10398
|
-
"this enrolment answers a request this app did not make
|
|
10420
|
+
"this enrolment answers a request this app did not make - start the enrolment again from here"
|
|
10399
10421
|
);
|
|
10400
10422
|
}
|
|
10401
10423
|
const certificate = await verifyDeviceCredential(options.credential);
|
|
@@ -12788,8 +12810,8 @@ var MeroJs = class {
|
|
|
12788
12810
|
/**
|
|
12789
12811
|
* Parse an auth callback URL hash fragment (static utility)
|
|
12790
12812
|
*/
|
|
12791
|
-
static parseAuthCallback(url2) {
|
|
12792
|
-
return parseAuthCallback(url2);
|
|
12813
|
+
static parseAuthCallback(url2, options) {
|
|
12814
|
+
return parseAuthCallback(url2, options);
|
|
12793
12815
|
}
|
|
12794
12816
|
/**
|
|
12795
12817
|
* Build an auth login URL (static utility)
|