@calimero-network/mero-react 3.0.1 → 3.0.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/dist/index.cjs +67 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +69 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,28 @@ var ConnectionType = /* @__PURE__ */ ((ConnectionType2) => {
|
|
|
45
45
|
return ConnectionType2;
|
|
46
46
|
})(ConnectionType || {});
|
|
47
47
|
|
|
48
|
+
// src/auth/node-trust.ts
|
|
49
|
+
function sameOrigin(a, b) {
|
|
50
|
+
try {
|
|
51
|
+
return new URL(a).origin === new URL(b).origin;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function resolveTrustedNodeUrl(params) {
|
|
57
|
+
const { candidate, initiated, allowedNodeUrls } = params;
|
|
58
|
+
if (!candidate) {
|
|
59
|
+
return { url: initiated ?? null, rejected: false };
|
|
60
|
+
}
|
|
61
|
+
if (initiated) {
|
|
62
|
+
return sameOrigin(candidate, initiated) ? { url: candidate, rejected: false } : { url: null, rejected: true };
|
|
63
|
+
}
|
|
64
|
+
if (allowedNodeUrls && allowedNodeUrls.length > 0) {
|
|
65
|
+
return allowedNodeUrls.some((u) => sameOrigin(candidate, u)) ? { url: candidate, rejected: false } : { url: null, rejected: true };
|
|
66
|
+
}
|
|
67
|
+
return { url: null, rejected: true };
|
|
68
|
+
}
|
|
69
|
+
|
|
48
70
|
// src/storage/index.ts
|
|
49
71
|
var STORAGE_KEYS = {
|
|
50
72
|
ACCESS_TOKEN: "mero:access_token",
|
|
@@ -175,13 +197,6 @@ function clearAllStorage() {
|
|
|
175
197
|
}
|
|
176
198
|
var MeroContext = react.createContext(null);
|
|
177
199
|
var isBrowser = typeof window !== "undefined";
|
|
178
|
-
var _tokenStore = null;
|
|
179
|
-
function getTokenStore() {
|
|
180
|
-
if (!_tokenStore) {
|
|
181
|
-
_tokenStore = new meroJs.LocalStorageTokenStore();
|
|
182
|
-
}
|
|
183
|
-
return _tokenStore;
|
|
184
|
-
}
|
|
185
200
|
function getPermissionsForMode(mode) {
|
|
186
201
|
switch (mode) {
|
|
187
202
|
case "single-context" /* SingleContext */:
|
|
@@ -215,8 +230,14 @@ function MeroProvider({
|
|
|
215
230
|
packageName,
|
|
216
231
|
packageVersion,
|
|
217
232
|
registryUrl,
|
|
218
|
-
timeoutMs = 3e4
|
|
233
|
+
timeoutMs = 3e4,
|
|
234
|
+
allowedNodeUrls,
|
|
235
|
+
tokenStore: tokenStoreProp
|
|
219
236
|
}) {
|
|
237
|
+
const tokenStore = react.useMemo(
|
|
238
|
+
() => tokenStoreProp ?? new meroJs.LocalStorageTokenStore(),
|
|
239
|
+
[tokenStoreProp]
|
|
240
|
+
);
|
|
220
241
|
const [mero, setMero] = react.useState(null);
|
|
221
242
|
const [isAuthenticated, setIsAuthenticated] = react.useState(false);
|
|
222
243
|
const [isOnline, setIsOnline] = react.useState(true);
|
|
@@ -239,13 +260,13 @@ function MeroProvider({
|
|
|
239
260
|
}
|
|
240
261
|
const instance = new meroJs.MeroJs({
|
|
241
262
|
baseUrl: url,
|
|
242
|
-
tokenStore
|
|
263
|
+
tokenStore,
|
|
243
264
|
timeoutMs
|
|
244
265
|
});
|
|
245
266
|
meroRef.current = instance;
|
|
246
267
|
return instance;
|
|
247
268
|
},
|
|
248
|
-
[timeoutMs]
|
|
269
|
+
[timeoutMs, tokenStore]
|
|
249
270
|
);
|
|
250
271
|
const checkAuth = react.useCallback(async (instance) => {
|
|
251
272
|
try {
|
|
@@ -279,6 +300,7 @@ function MeroProvider({
|
|
|
279
300
|
meroRef.current.clearToken();
|
|
280
301
|
meroRef.current.close();
|
|
281
302
|
}
|
|
303
|
+
tokenStore.clear();
|
|
282
304
|
clearAllStorage();
|
|
283
305
|
setMero(null);
|
|
284
306
|
setIsAuthenticated(false);
|
|
@@ -287,39 +309,50 @@ function MeroProvider({
|
|
|
287
309
|
setContextIdState(null);
|
|
288
310
|
setContextIdentityState(null);
|
|
289
311
|
meroRef.current = null;
|
|
290
|
-
}, []);
|
|
312
|
+
}, [tokenStore]);
|
|
291
313
|
react.useEffect(() => {
|
|
292
314
|
let active = true;
|
|
293
315
|
const init = async () => {
|
|
294
316
|
const callback = callbackRef.current;
|
|
317
|
+
let nodeFromCallback = null;
|
|
295
318
|
if (callback) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
319
|
+
const { url, rejected } = resolveTrustedNodeUrl({
|
|
320
|
+
candidate: callback.nodeUrl,
|
|
321
|
+
initiated: getNodeUrl(),
|
|
322
|
+
allowedNodeUrls
|
|
300
323
|
});
|
|
301
|
-
if (callback.applicationId) {
|
|
302
|
-
setApplicationId(callback.applicationId);
|
|
303
|
-
if (active) setApplicationIdState(callback.applicationId);
|
|
304
|
-
}
|
|
305
|
-
if (callback.contextId) {
|
|
306
|
-
setContextId(callback.contextId);
|
|
307
|
-
if (active) setContextIdState(callback.contextId);
|
|
308
|
-
}
|
|
309
|
-
if (callback.contextIdentity) {
|
|
310
|
-
setContextIdentity(callback.contextIdentity);
|
|
311
|
-
if (active) setContextIdentityState(callback.contextIdentity);
|
|
312
|
-
}
|
|
313
|
-
if (callback.nodeUrl) {
|
|
314
|
-
setNodeUrl(callback.nodeUrl);
|
|
315
|
-
if (active) setNodeUrlState(callback.nodeUrl);
|
|
316
|
-
}
|
|
317
324
|
if (isBrowser) {
|
|
318
325
|
window.history.replaceState({}, "", window.location.pathname + window.location.search);
|
|
319
326
|
}
|
|
320
327
|
callbackRef.current = null;
|
|
328
|
+
if (rejected) {
|
|
329
|
+
console.error(
|
|
330
|
+
"[MeroProvider] OAuth callback node_url is not trusted (it does not match the node login was initiated with, nor `allowedNodeUrls`). Ignoring the callback; no tokens stored."
|
|
331
|
+
);
|
|
332
|
+
} else if (url) {
|
|
333
|
+
tokenStore.setTokens({
|
|
334
|
+
access_token: callback.accessToken,
|
|
335
|
+
refresh_token: callback.refreshToken,
|
|
336
|
+
expires_at: parseJwtExpiry(callback.accessToken)
|
|
337
|
+
});
|
|
338
|
+
if (callback.applicationId) {
|
|
339
|
+
setApplicationId(callback.applicationId);
|
|
340
|
+
if (active) setApplicationIdState(callback.applicationId);
|
|
341
|
+
}
|
|
342
|
+
if (callback.contextId) {
|
|
343
|
+
setContextId(callback.contextId);
|
|
344
|
+
if (active) setContextIdState(callback.contextId);
|
|
345
|
+
}
|
|
346
|
+
if (callback.contextIdentity) {
|
|
347
|
+
setContextIdentity(callback.contextIdentity);
|
|
348
|
+
if (active) setContextIdentityState(callback.contextIdentity);
|
|
349
|
+
}
|
|
350
|
+
setNodeUrl(url);
|
|
351
|
+
if (active) setNodeUrlState(url);
|
|
352
|
+
nodeFromCallback = url;
|
|
353
|
+
}
|
|
321
354
|
}
|
|
322
|
-
const savedUrl =
|
|
355
|
+
const savedUrl = nodeFromCallback || getNodeUrl();
|
|
323
356
|
if (!savedUrl) {
|
|
324
357
|
if (active) setIsLoading(false);
|
|
325
358
|
return;
|
|
@@ -331,7 +364,7 @@ function MeroProvider({
|
|
|
331
364
|
setMero(instance);
|
|
332
365
|
setIsAuthenticated(true);
|
|
333
366
|
setIsOnline(true);
|
|
334
|
-
} else if (
|
|
367
|
+
} else if (nodeFromCallback) {
|
|
335
368
|
setMero(instance);
|
|
336
369
|
}
|
|
337
370
|
setIsLoading(false);
|
|
@@ -343,7 +376,7 @@ function MeroProvider({
|
|
|
343
376
|
return () => {
|
|
344
377
|
active = false;
|
|
345
378
|
};
|
|
346
|
-
}, [createMeroInstance, checkAuth]);
|
|
379
|
+
}, [createMeroInstance, checkAuth, allowedNodeUrls, tokenStore]);
|
|
347
380
|
react.useEffect(() => {
|
|
348
381
|
if (!isAuthenticated || !meroRef.current) return;
|
|
349
382
|
let active = true;
|