@calimero-network/mero-js 25.0.6 → 25.0.7
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/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +30 -10
- package/dist/index.cjs.map +3 -3
- package/dist/index.mjs +30 -10
- package/dist/index.mjs.map +3 -3
- package/dist/mero-js.d.ts +5 -0
- package/dist/mero-js.js +31 -9
- package/dist/token-store/index.js +1 -0
- package/package.json +1 -1
package/dist/mero-js.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export interface TokenData {
|
|
|
86
86
|
access_token: string;
|
|
87
87
|
refresh_token: string;
|
|
88
88
|
expires_at: number;
|
|
89
|
+
/** Origin and path prefix of the issuing node; a store entry for another node is ignored. */
|
|
90
|
+
node_origin?: string;
|
|
89
91
|
}
|
|
90
92
|
/**
|
|
91
93
|
* Main MeroJs SDK class that manages all API clients and authentication
|
|
@@ -101,6 +103,7 @@ export declare class MeroJs {
|
|
|
101
103
|
private storeHoldsTokens;
|
|
102
104
|
private tokenGeneration;
|
|
103
105
|
private readonly onStorage;
|
|
106
|
+
private readonly nodeKey;
|
|
104
107
|
private rpcClient;
|
|
105
108
|
private sseClient;
|
|
106
109
|
private wsClient;
|
|
@@ -156,6 +159,8 @@ export declare class MeroJs {
|
|
|
156
159
|
password: string;
|
|
157
160
|
}): Promise<TokenData>;
|
|
158
161
|
private persistTokens;
|
|
162
|
+
/** The stored bundle, only if this node issued it; a legacy or foreign entry reads as empty. */
|
|
163
|
+
private readStoredTokens;
|
|
159
164
|
private signedOutElsewhere;
|
|
160
165
|
private dropLocalTokens;
|
|
161
166
|
/**
|
package/dist/mero-js.js
CHANGED
|
@@ -28,6 +28,16 @@ function getLockManager() {
|
|
|
28
28
|
const locks = nav?.locks;
|
|
29
29
|
return locks && typeof locks.request === 'function' ? locks : null;
|
|
30
30
|
}
|
|
31
|
+
/** Key a token bundle to its node: origin plus path prefix, so nodes behind one host stay apart. */
|
|
32
|
+
function nodeKeyOf(baseUrl) {
|
|
33
|
+
try {
|
|
34
|
+
const { origin, pathname } = new URL(baseUrl);
|
|
35
|
+
return origin === 'null' ? baseUrl : origin + pathname.replace(/\/+$/, '');
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return baseUrl;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
31
41
|
/** Try to extract `exp` (seconds) from a JWT, return ms timestamp or fallback. */
|
|
32
42
|
function expiresAtFromJwt(token, fallbackMs) {
|
|
33
43
|
try {
|
|
@@ -72,9 +82,10 @@ export class MeroJs {
|
|
|
72
82
|
...config,
|
|
73
83
|
};
|
|
74
84
|
this.tokenStore = config.tokenStore ?? null;
|
|
85
|
+
this.nodeKey = nodeKeyOf(config.baseUrl);
|
|
75
86
|
// Restore tokens from store if available
|
|
87
|
+
this.tokenData = this.readStoredTokens();
|
|
76
88
|
if (this.tokenStore) {
|
|
77
|
-
this.tokenData = this.tokenStore.getTokens();
|
|
78
89
|
this.storeHoldsTokens = this.tokenData !== null;
|
|
79
90
|
if (typeof window !== 'undefined')
|
|
80
91
|
window.addEventListener('storage', this.onStorage);
|
|
@@ -101,7 +112,7 @@ export class MeroJs {
|
|
|
101
112
|
onTokenRefresh: async (newToken) => {
|
|
102
113
|
if (this.tokenData) {
|
|
103
114
|
this.tokenData.access_token = newToken;
|
|
104
|
-
this.persistTokens(
|
|
115
|
+
this.persistTokens();
|
|
105
116
|
}
|
|
106
117
|
},
|
|
107
118
|
onAuthRevoked: async () => {
|
|
@@ -253,19 +264,30 @@ export class MeroJs {
|
|
|
253
264
|
refresh_token: response.data.refresh_token,
|
|
254
265
|
expires_at: expiresAtFromJwt(accessToken, Date.now() + 3600000),
|
|
255
266
|
};
|
|
256
|
-
this.persistTokens(
|
|
267
|
+
this.persistTokens();
|
|
257
268
|
return this.tokenData;
|
|
258
269
|
}
|
|
259
270
|
catch (error) {
|
|
260
271
|
throw new Error(`Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
261
272
|
}
|
|
262
273
|
}
|
|
263
|
-
persistTokens(
|
|
264
|
-
if (!this.tokenStore)
|
|
274
|
+
persistTokens() {
|
|
275
|
+
if (!this.tokenStore || !this.tokenData)
|
|
265
276
|
return;
|
|
266
|
-
this.tokenStore.setTokens(
|
|
277
|
+
this.tokenStore.setTokens({ ...this.tokenData, node_origin: this.nodeKey });
|
|
267
278
|
this.storeHoldsTokens = this.tokenStore.getTokens() !== null;
|
|
268
279
|
}
|
|
280
|
+
/** The stored bundle, only if this node issued it; a legacy or foreign entry reads as empty. */
|
|
281
|
+
readStoredTokens() {
|
|
282
|
+
const stored = this.tokenStore?.getTokens();
|
|
283
|
+
if (!stored || stored.node_origin !== this.nodeKey)
|
|
284
|
+
return null;
|
|
285
|
+
return {
|
|
286
|
+
access_token: stored.access_token,
|
|
287
|
+
refresh_token: stored.refresh_token,
|
|
288
|
+
expires_at: stored.expires_at,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
269
291
|
// Raw store read: an empty store is a logout, another node's bundle is not.
|
|
270
292
|
signedOutElsewhere() {
|
|
271
293
|
return this.storeHoldsTokens && !this.tokenStore?.getTokens();
|
|
@@ -338,7 +360,7 @@ export class MeroJs {
|
|
|
338
360
|
this.dropLocalTokens();
|
|
339
361
|
throw new Error('Signed out in another tab');
|
|
340
362
|
}
|
|
341
|
-
const stored = this.
|
|
363
|
+
const stored = this.readStoredTokens();
|
|
342
364
|
if (stored?.refresh_token) {
|
|
343
365
|
this.storeHoldsTokens = true;
|
|
344
366
|
this.tokenData = stored;
|
|
@@ -377,7 +399,7 @@ export class MeroJs {
|
|
|
377
399
|
refresh_token: response.data.refresh_token,
|
|
378
400
|
expires_at: expiresAtFromJwt(accessToken, Date.now() + 3600000),
|
|
379
401
|
};
|
|
380
|
-
this.persistTokens(
|
|
402
|
+
this.persistTokens();
|
|
381
403
|
return this.tokenData;
|
|
382
404
|
}
|
|
383
405
|
catch (error) {
|
|
@@ -409,7 +431,7 @@ export class MeroJs {
|
|
|
409
431
|
setTokenData(data) {
|
|
410
432
|
const expiresAt = data.expires_at || expiresAtFromJwt(data.access_token, Date.now() + 3600000);
|
|
411
433
|
this.tokenData = { ...data, expires_at: expiresAt };
|
|
412
|
-
this.persistTokens(
|
|
434
|
+
this.persistTokens();
|
|
413
435
|
}
|
|
414
436
|
/**
|
|
415
437
|
* Get the current token data (for debugging)
|
|
@@ -30,6 +30,7 @@ export class LocalStorageTokenStore {
|
|
|
30
30
|
access_token: parsed.access_token,
|
|
31
31
|
refresh_token: parsed.refresh_token,
|
|
32
32
|
expires_at: typeof parsed.expires_at === 'number' ? parsed.expires_at : Date.now() + 3600000,
|
|
33
|
+
...(typeof parsed.node_origin === 'string' && { node_origin: parsed.node_origin }),
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
return null;
|