@openfort/react 1.0.6 → 1.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.
Files changed (40) hide show
  1. package/build/components/Common/WalletRecoveryIcon/index.d.ts +1 -0
  2. package/build/components/Common/WalletRecoveryIcon/index.js +6 -1
  3. package/build/components/Common/WalletRecoveryIcon/index.js.map +1 -1
  4. package/build/components/ConnectModal/ConnectWithInjector/index.js +4 -4
  5. package/build/components/ConnectModal/ConnectWithMobile.js +10 -8
  6. package/build/components/ConnectModal/ConnectWithMobile.js.map +1 -1
  7. package/build/components/ConnectModal/ConnectWithOAuth.js +5 -1
  8. package/build/components/ConnectModal/ConnectWithOAuth.js.map +1 -1
  9. package/build/components/Openfort/OpenfortProvider.js +4 -0
  10. package/build/components/Openfort/OpenfortProvider.js.map +1 -1
  11. package/build/components/Pages/Connectors/index.js +1 -55
  12. package/build/components/Pages/Connectors/index.js.map +1 -1
  13. package/build/components/Pages/LinkedProvider/index.js +7 -2
  14. package/build/components/Pages/LinkedProvider/index.js.map +1 -1
  15. package/build/components/Pages/LoadWallets/index.js +35 -28
  16. package/build/components/Pages/LoadWallets/index.js.map +1 -1
  17. package/build/components/Pages/RemoveLinkedProvider/index.js +5 -1
  18. package/build/components/Pages/RemoveLinkedProvider/index.js.map +1 -1
  19. package/build/components/Pages/SelectWalletToRecover/index.js +35 -3
  20. package/build/components/Pages/SelectWalletToRecover/index.js.map +1 -1
  21. package/build/hooks/openfort/auth/useAuthCallback.d.ts +1 -1
  22. package/build/hooks/openfort/auth/useAuthCallback.js +24 -8
  23. package/build/hooks/openfort/auth/useAuthCallback.js.map +1 -1
  24. package/build/hooks/useResolvedIdentity.js +4 -1
  25. package/build/hooks/useResolvedIdentity.js.map +1 -1
  26. package/build/utils/rpc.d.ts +0 -4
  27. package/build/utils/rpc.js +5 -1
  28. package/build/utils/rpc.js.map +1 -1
  29. package/build/utils/urlSecurity.d.ts +28 -0
  30. package/build/utils/urlSecurity.js +56 -0
  31. package/build/utils/urlSecurity.js.map +1 -0
  32. package/build/version.d.ts +1 -1
  33. package/build/version.js +1 -1
  34. package/build/wagmi/useConnectWithSiwe.js +35 -29
  35. package/build/wagmi/useConnectWithSiwe.js.map +1 -1
  36. package/build/wagmi/useEmbeddedWalletWagmiSync.js +21 -1
  37. package/build/wagmi/useEmbeddedWalletWagmiSync.js.map +1 -1
  38. package/build/wagmi/useWalletAuth.js +7 -0
  39. package/build/wagmi/useWalletAuth.js.map +1 -1
  40. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { RecoveryMethod } from '@openfort/openfort-js';
2
+ export declare const RECOVERY_METHOD_LABEL: Record<RecoveryMethod, string>;
2
3
  export declare const WalletRecoveryIcon: ({ recovery }: {
3
4
  recovery: RecoveryMethod | undefined;
4
5
  }) => import("react/jsx-runtime").JSX.Element | null;
@@ -2,6 +2,11 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { RecoveryMethod } from '@openfort/openfort-js';
3
3
  import { LockIcon, FingerPrintIcon, KeyIcon } from '../../../assets/icons.js';
4
4
 
5
+ const RECOVERY_METHOD_LABEL = {
6
+ [RecoveryMethod.AUTOMATIC]: 'Automatic',
7
+ [RecoveryMethod.PASSWORD]: 'Password',
8
+ [RecoveryMethod.PASSKEY]: 'Passkey',
9
+ };
5
10
  const WalletRecoveryIcon = ({ recovery }) => {
6
11
  switch (recovery) {
7
12
  case RecoveryMethod.PASSWORD:
@@ -15,5 +20,5 @@ const WalletRecoveryIcon = ({ recovery }) => {
15
20
  }
16
21
  };
17
22
 
18
- export { WalletRecoveryIcon };
23
+ export { RECOVERY_METHOD_LABEL, WalletRecoveryIcon };
19
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -118,7 +118,7 @@ const ConnectWithInjector = ({ forceState }) => {
118
118
  connectorType: (_b = walletItem.connector) === null || _b === void 0 ? void 0 : _b.type,
119
119
  walletClientType: (_c = walletItem.connector) === null || _c === void 0 ? void 0 : _c.id,
120
120
  onError: (error, _errorType) => {
121
- logger.error(error);
121
+ logger.error('[ConnectWithInjector] SIWE failed:', error);
122
122
  disconnect();
123
123
  setStatus(states.FAILED);
124
124
  },
@@ -211,14 +211,14 @@ const ConnectWithInjector = ({ forceState }) => {
211
211
  }
212
212
  if (!wallet) {
213
213
  setStatus(states.FAILED);
214
- logger.error('No wallet found');
214
+ logger.error('[ConnectWithInjector] No wallet found after connect');
215
215
  return;
216
216
  }
217
- logger.log('Connect type is:', props.connectType);
217
+ logger.log('[ConnectWithInjector] Connect type is:', props.connectType);
218
218
  await handleConnectSettled(wallet, connectResult);
219
219
  }
220
220
  catch (err) {
221
- logger.error(err);
221
+ logger.error('[ConnectWithInjector] Connection error', err instanceof Error ? err.message : err);
222
222
  handleConnectError(err && typeof err === 'object' && 'code' in err
223
223
  ? err
224
224
  : {
@@ -1,5 +1,6 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useState, useEffect } from 'react';
3
+ import { embeddedWalletId } from '../../constants/openfort.js';
3
4
  import { useEthereumBridge } from '../../ethereum/OpenfortEthereumBridgeContext.js';
4
5
  import styled from '../../styles/styled/index.js';
5
6
  import { isAndroid } from '../../utils/index.js';
@@ -25,7 +26,7 @@ const DownloadFooter = styled.div `
25
26
  color: var(--ck-body-color-muted);
26
27
  `;
27
28
  const ConnectWithMobile = () => {
28
- var _a, _b, _c, _d, _e;
29
+ var _a, _b, _c, _d, _e, _f, _g;
29
30
  const { connector, setRoute } = useOpenfort();
30
31
  const walletId = Object.keys(walletConfigs).find(
31
32
  // where id is comma separated list
@@ -35,8 +36,9 @@ const ConnectWithMobile = () => {
35
36
  .indexOf(connector.id) !== -1);
36
37
  const wallet = useExternalConnector(connector.id) || (walletId && walletConfigs[walletId]) || {};
37
38
  const bridge = useEthereumBridge();
38
- const isConnected = (_b = (_a = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _a === void 0 ? void 0 : _a.isConnected) !== null && _b !== void 0 ? _b : false;
39
- const [status, setStatus] = useState(isConnected ? states.INIT : states.CONNECTING);
39
+ // Only consider external wallets as "connected" ignore the embedded wallet connector
40
+ const isExternalConnected = (_d = (((_a = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _a === void 0 ? void 0 : _a.isConnected) && ((_c = (_b = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _b === void 0 ? void 0 : _b.connector) === null || _c === void 0 ? void 0 : _c.id) !== embeddedWalletId)) !== null && _d !== void 0 ? _d : false;
41
+ const [status, setStatus] = useState(isExternalConnected ? states.CONNECTING : states.INIT);
40
42
  const [description, setDescription] = useState(undefined);
41
43
  const [hasReturned, setHasReturned] = useState(false);
42
44
  const { connectWithSiwe } = useConnectWithSiwe();
@@ -59,7 +61,7 @@ const ConnectWithMobile = () => {
59
61
  useEffect(() => {
60
62
  if (hasReturned) {
61
63
  setHasReturned(false);
62
- if (isConnected) {
64
+ if (isExternalConnected) {
63
65
  setStatus(states.CONNECTING);
64
66
  }
65
67
  else {
@@ -67,7 +69,7 @@ const ConnectWithMobile = () => {
67
69
  setDescription('Connection failed or cancelled');
68
70
  }
69
71
  }
70
- }, [hasReturned, isConnected]);
72
+ }, [hasReturned, isExternalConnected]);
71
73
  useEffect(() => {
72
74
  switch (status) {
73
75
  case states.INIT:
@@ -86,13 +88,13 @@ const ConnectWithMobile = () => {
86
88
  }
87
89
  }, [status]);
88
90
  return (jsxs(PageContent, { children: [jsx(Loader, { header: `Connecting with ${connector.id.split(',')[0]}`, icon: wallet === null || wallet === void 0 ? void 0 : wallet.icon, isError: status === states.ERROR, description: description, onRetry: () => {
89
- setStatus(isConnected ? states.CONNECTING : states.INIT);
91
+ setStatus(isExternalConnected ? states.CONNECTING : states.INIT);
90
92
  setDescription('');
91
- } }), isConnected ? (jsx(Button, { onClick: () => {
93
+ } }), isExternalConnected ? (jsx(Button, { onClick: () => {
92
94
  openApp();
93
95
  }, children: "Sign in App" })) : (jsx(Button, { onClick: () => {
94
96
  openApp();
95
- }, children: "Sign in App" })), jsx(DownloadFooter, { children: jsxs(FitText, { children: ["Don't have ", (_c = wallet.name) !== null && _c !== void 0 ? _c : connector.id.split(',')[0], " installed?", ' ', jsx("a", { style: { marginLeft: 5 }, href: isAndroid() ? (_d = wallet === null || wallet === void 0 ? void 0 : wallet.downloadUrls) === null || _d === void 0 ? void 0 : _d.android : (_e = wallet === null || wallet === void 0 ? void 0 : wallet.downloadUrls) === null || _e === void 0 ? void 0 : _e.ios, target: "_blank", rel: "noreferrer", children: "GET" })] }) })] }));
97
+ }, children: "Sign in App" })), jsx(DownloadFooter, { children: jsxs(FitText, { children: ["Don't have ", (_e = wallet.name) !== null && _e !== void 0 ? _e : connector.id.split(',')[0], " installed?", ' ', jsx("a", { style: { marginLeft: 5 }, href: isAndroid() ? (_f = wallet === null || wallet === void 0 ? void 0 : wallet.downloadUrls) === null || _f === void 0 ? void 0 : _f.android : (_g = wallet === null || wallet === void 0 ? void 0 : wallet.downloadUrls) === null || _g === void 0 ? void 0 : _g.ios, target: "_blank", rel: "noreferrer", children: "GET" })] }) })] }));
96
98
  };
97
99
 
98
100
  export { ConnectWithMobile as default };
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectWithMobile.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ConnectWithMobile.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -3,6 +3,7 @@ import { useState, useEffect } from 'react';
3
3
  import { providersLogos } from '../../assets/logos.js';
4
4
  import { useOpenfortCore } from '../../openfort/useOpenfort.js';
5
5
  import { logger } from '../../utils/logger.js';
6
+ import { parseCallbackUrl, suppressReferrer } from '../../utils/urlSecurity.js';
6
7
  import Loader from '../Common/Loading/index.js';
7
8
  import { routes } from '../Openfort/types.js';
8
9
  import { useOpenfort } from '../Openfort/useOpenfort.js';
@@ -27,7 +28,7 @@ const ConnectWithOAuth = () => {
27
28
  return;
28
29
  if (connector.type !== 'oauth')
29
30
  throw new Error('Invalid connector type');
30
- const url = new URL(win.location.href.replace('?access_token=', '&access_token=')); // handle both ? and & cases
31
+ const url = parseCallbackUrl(win.location.href);
31
32
  const hasProvider = !!url.searchParams.get('openfortAuthProviderUI');
32
33
  const provider = connector.id;
33
34
  switch (status) {
@@ -38,6 +39,8 @@ const ConnectWithOAuth = () => {
38
39
  setTimeout(() => setStatus(states.REDIRECT), 150); // UX: wait a bit before redirecting
39
40
  break;
40
41
  case states.CONNECTING: {
42
+ // Suppress Referer before any async work to prevent token leakage
43
+ const restoreReferrer = suppressReferrer();
41
44
  const userId = url.searchParams.get('user_id');
42
45
  const token = url.searchParams.get('access_token');
43
46
  const error = url.searchParams.get('error');
@@ -45,6 +48,7 @@ const ConnectWithOAuth = () => {
45
48
  url.searchParams.delete(key);
46
49
  });
47
50
  win.history.replaceState({}, doc.title, url.toString());
51
+ restoreReferrer();
48
52
  if (!userId || !token || error) {
49
53
  logger.error(`Missing user id or access token: userId=${userId}, accessToken=${token ? `${token.substring(0, 10)}...` : token}`);
50
54
  setStatus(states.ERROR);
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectWithOAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ConnectWithOAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -142,6 +142,10 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
142
142
  const setOpen = useCallback((value) => {
143
143
  if (value) {
144
144
  setRouteHistory([]);
145
+ // Reset route and connector to avoid stale state from a previous modal session
146
+ // (e.g. a failed SIWE attempt leaving route on CONNECT with a stale connector)
147
+ setRoute({ route: routes.LOADING });
148
+ setConnector(initialConnector);
145
149
  }
146
150
  setOpenWithoutHistory(value);
147
151
  }, []);
@@ -1 +1 @@
1
- {"version":3,"file":"OpenfortProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"OpenfortProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,64 +1,10 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useState, useEffect } from 'react';
3
- import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
4
- import useIsMobile from '../../../hooks/useIsMobile.js';
5
- import { useWalletConnectModal } from '../../../hooks/useWalletConnectModal.js';
6
2
  import { logger } from '../../../utils/logger.js';
7
3
  import ConnectorList from '../../Common/ConnectorList/index.js';
8
- import Loader from '../../Common/Loading/index.js';
9
- import { routes } from '../../Openfort/types.js';
10
- import { useOpenfort } from '../../Openfort/useOpenfort.js';
11
4
  import { PageContent } from '../../PageContent/index.js';
12
5
 
13
6
  let hasWarnedConnectors = false;
14
- const ConnectWithMobile = () => {
15
- var _a, _b;
16
- const { open: openWalletConnectModal } = useWalletConnectModal();
17
- const [error, setError] = useState(undefined);
18
- const bridge = useEthereumBridge();
19
- const connector = (_a = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _a === void 0 ? void 0 : _a.connector;
20
- const address = (_b = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _b === void 0 ? void 0 : _b.address;
21
- const { setRoute, setConnector } = useOpenfort();
22
- const openWCModal = async () => {
23
- setError(undefined);
24
- const { error } = await openWalletConnectModal();
25
- if (error) {
26
- setError(error);
27
- }
28
- };
29
- useEffect(() => {
30
- openWCModal();
31
- }, []);
32
- useEffect(() => {
33
- if (connector && address) {
34
- const walletConnectDeeplinkChoice = localStorage.getItem('WALLETCONNECT_DEEPLINK_CHOICE');
35
- if (walletConnectDeeplinkChoice) {
36
- try {
37
- const parsedChoice = JSON.parse(walletConnectDeeplinkChoice);
38
- if (parsedChoice &&
39
- typeof parsedChoice === 'object' &&
40
- 'name' in parsedChoice &&
41
- typeof parsedChoice.name === 'string') {
42
- setConnector({ id: parsedChoice.name });
43
- }
44
- else {
45
- setConnector({ id: connector.id });
46
- }
47
- }
48
- catch {
49
- setConnector({ id: connector.id });
50
- }
51
- }
52
- else {
53
- setConnector({ id: connector.id });
54
- }
55
- setRoute(routes.CONNECT_WITH_MOBILE);
56
- }
57
- }, [address, connector]);
58
- return (jsx(Loader, { header: error ? 'Error connecting wallet.' : `Connecting...`, isError: !!error, description: error, onRetry: () => openWCModal() }));
59
- };
60
7
  const Connectors = ({ logoutOnBack }) => {
61
- const isMobile = useIsMobile();
62
8
  // Runtime deprecation warning
63
9
  if (process.env.NODE_ENV === 'development' && !hasWarnedConnectors) {
64
10
  logger.warn('[@openfort/react] <Connectors /> is deprecated and will be moved to @openfort/react/wagmi in v3.0.\n' +
@@ -66,7 +12,7 @@ const Connectors = ({ logoutOnBack }) => {
66
12
  'See: https://openfort.io/docs/migration/external-wallets');
67
13
  hasWarnedConnectors = true;
68
14
  }
69
- return (jsx(PageContent, { logoutOnBack: logoutOnBack, width: 312, children: isMobile ? jsx(ConnectWithMobile, {}) : jsx(ConnectorList, {}) }));
15
+ return (jsx(PageContent, { logoutOnBack: logoutOnBack, width: 312, children: jsx(ConnectorList, {}) }));
70
16
  };
71
17
 
72
18
  export { Connectors as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { useMemo } from 'react';
2
+ import { useRef, useMemo } from 'react';
3
3
  import { useUser } from '../../../hooks/openfort/useUser.js';
4
4
  import { useResolvedIdentity } from '../../../hooks/useResolvedIdentity.js';
5
5
  import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
@@ -65,11 +65,14 @@ const OAuthContent = ({ account }) => {
65
65
  };
66
66
  const LinkedProvider = () => {
67
67
  const { route } = useOpenfort();
68
+ const lastAccountRef = useRef(null);
68
69
  const account = useMemo(() => {
69
70
  if (route.route === 'linkedProvider') {
71
+ lastAccountRef.current = route.account;
70
72
  return route.account;
71
73
  }
72
- throw new Error('No account found in route');
74
+ // During exit animations or route transitions, return the last known account
75
+ return lastAccountRef.current;
73
76
  }, [route]);
74
77
  const getProviderDetails = (account) => {
75
78
  switch (account.provider) {
@@ -83,6 +86,8 @@ const LinkedProvider = () => {
83
86
  return (jsxs("div", { style: { marginTop: '16px', display: 'flex', alignItems: 'center', gap: '8px', flexDirection: 'column' }, children: [jsxs("div", { children: ["Authentication method: ", jsx("b", { children: getProviderName(account.provider) })] }), jsx(FitText, { children: jsx(ProviderHeader, { account: account }) })] }));
84
87
  }
85
88
  };
89
+ if (!account)
90
+ return null;
86
91
  return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: getProviderName(account.provider) }), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ProviderIconContainer, { children: jsx(ProviderIconWrapper, { children: jsx(ProviderIconInner, { children: jsx(ProviderIcon, { account: account }) }) }) }), jsx(ModalBody, { children: getProviderDetails(account) })] })] }));
87
92
  };
88
93
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { ChainTypeEnum } from '@openfort/openfort-js';
2
+ import { ChainTypeEnum, RecoveryMethod } from '@openfort/openfort-js';
3
3
  import { useState, useEffect } from 'react';
4
4
  import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
5
5
  import { toSolanaUserWallet } from '../../../hooks/openfort/walletTypes.js';
@@ -7,20 +7,24 @@ import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
7
7
  import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
8
8
  import { logger } from '../../../utils/logger.js';
9
9
  import Loader from '../../Common/Loading/index.js';
10
- import { recoverRoute, createRoute } from '../../Openfort/routeHelpers.js';
10
+ import { createRoute, recoverRoute } from '../../Openfort/routeHelpers.js';
11
11
  import { routes } from '../../Openfort/types.js';
12
12
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
13
13
  import { PageContent } from '../../PageContent/index.js';
14
14
 
15
- const handleSingleWalletRegistry = {
16
- [ChainTypeEnum.SVM]: (w, chainType, setRoute) => {
17
- const walletForRoute = toSolanaUserWallet(w);
18
- setRoute(recoverRoute(chainType, walletForRoute));
19
- },
20
- [ChainTypeEnum.EVM]: (w, chainType, setRoute) => {
21
- setRoute(recoverRoute(chainType, w));
22
- },
23
- };
15
+ /** Pick the best wallet to auto-recover: automatic > passkey > first available */
16
+ function pickBestWallet(wallets) {
17
+ var _a, _b;
18
+ return ((_b = (_a = wallets.find((w) => w.recoveryMethod === RecoveryMethod.AUTOMATIC)) !== null && _a !== void 0 ? _a : wallets.find((w) => w.recoveryMethod === RecoveryMethod.PASSKEY)) !== null && _b !== void 0 ? _b : wallets[0]);
19
+ }
20
+ function routeToRecover(wallet, chainType, setRoute) {
21
+ if (chainType === ChainTypeEnum.SVM) {
22
+ setRoute(recoverRoute(chainType, toSolanaUserWallet(wallet)));
23
+ }
24
+ else {
25
+ setRoute(recoverRoute(chainType, wallet));
26
+ }
27
+ }
24
28
  const errorForChainRegistry = {
25
29
  [ChainTypeEnum.SVM]: () => ({ isError: false, message: undefined }),
26
30
  [ChainTypeEnum.EVM]: (errorWallets) => ({
@@ -29,11 +33,13 @@ const errorForChainRegistry = {
29
33
  }),
30
34
  };
31
35
  const LoadWallets = () => {
36
+ var _a;
32
37
  const { chainType, user, isLoadingAccounts } = useOpenfortCore();
33
38
  const { triggerResize, setRoute, setConnector, walletConfig } = useOpenfort();
34
39
  const ethereumWallet = useEthereumEmbeddedWallet();
35
40
  const solanaWallet = useSolanaEmbeddedWallet();
36
41
  const embeddedWallet = chainType === ChainTypeEnum.EVM ? ethereumWallet : solanaWallet;
42
+ const connectOnLogin = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) !== null && _a !== void 0 ? _a : true;
37
43
  const [loadingUX, setLoadingUX] = useState(true);
38
44
  const wallets = embeddedWallet.wallets;
39
45
  const isLoadingWallets = embeddedWallet.status === 'fetching-wallets' ||
@@ -63,31 +69,32 @@ const LoadWallets = () => {
63
69
  return;
64
70
  }
65
71
  logger.log('User wallets loaded:', wallets.length);
72
+ // No wallets → create one
66
73
  if (wallets.length === 0) {
67
- // Always show the create wallet page when no wallets exist.
68
- // connectOnLogin only controls whether creation starts automatically
69
- // (handled inside CreateWalletAutomaticRecovery), not whether the
70
- // page is shown — routing to CONNECTED with 0 wallets would show a
71
- // broken "Connect wallet" button aimed at external wagmi wallets.
72
74
  setRoute(createRoute(chainType));
73
75
  return;
74
76
  }
75
- if (wallets.length === 1) {
76
- const single = wallets[0];
77
- const alreadyActive = embeddedWallet.status === 'connected' &&
78
- embeddedWallet.address &&
79
- (chainType === ChainTypeEnum.SVM
80
- ? embeddedWallet.address === single.address
81
- : embeddedWallet.address.toLowerCase() === single.address.toLowerCase());
82
- if (alreadyActive) {
77
+ // If a wallet is already active and connected, go to connected (triggers auto-close)
78
+ if (embeddedWallet.status === 'connected' && embeddedWallet.address) {
79
+ const activeAddr = embeddedWallet.address;
80
+ const isActiveInList = wallets.some((w) => chainType === ChainTypeEnum.SVM
81
+ ? w.address === activeAddr
82
+ : w.address.toLowerCase() === activeAddr.toLowerCase());
83
+ if (isActiveInList) {
83
84
  setRoute(chainType === ChainTypeEnum.SVM ? routes.SOL_CONNECTED : routes.ETH_CONNECTED);
84
85
  return;
85
86
  }
86
- handleSingleWalletRegistry[chainType](single, chainType, setRoute, setConnector);
87
- return;
88
87
  }
89
- setRoute(routes.SELECT_WALLET_TO_RECOVER);
90
- }, [loadingUX, isLoadingWallets, wallets, user, chainType, setRoute, setConnector, walletConfig]);
88
+ if (connectOnLogin) {
89
+ // Auto-connect: pick the best wallet (automatic > passkey > password) and recover it
90
+ const best = pickBestWallet(wallets);
91
+ routeToRecover(best, chainType, setRoute);
92
+ }
93
+ else {
94
+ // Not auto-connecting: close modal (go to connected page which triggers auto-close)
95
+ setRoute(chainType === ChainTypeEnum.SVM ? routes.SOL_CONNECTED : routes.ETH_CONNECTED);
96
+ }
97
+ }, [loadingUX, isLoadingWallets, wallets, user, chainType, setRoute, setConnector, walletConfig, connectOnLogin]);
91
98
  const { isError: isErrorFromChain, message: errorMessageFromChain } = errorForChainRegistry[chainType](errorWallets);
92
99
  const isError = !user || isErrorFromChain;
93
100
  const errorMessage = !user ? undefined : errorMessageFromChain;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -32,7 +32,7 @@ const RemoveLinkedProvider = () => {
32
32
  if (route.route === 'removeLinkedProvider') {
33
33
  return route.account;
34
34
  }
35
- throw new Error('No provider found in route');
35
+ return null;
36
36
  }, [route]);
37
37
  useEffect(() => {
38
38
  if (error)
@@ -60,6 +60,8 @@ const RemoveLinkedProvider = () => {
60
60
  }, [isSuccess]);
61
61
  const handleRemove = async () => {
62
62
  var _a;
63
+ if (!provider)
64
+ return;
63
65
  const errorMsg = 'Failed to remove linked provider. Please try again.';
64
66
  if (provider.provider === 'siwe' || provider.provider === 'wallet') {
65
67
  try {
@@ -97,6 +99,8 @@ const RemoveLinkedProvider = () => {
97
99
  }
98
100
  }
99
101
  };
102
+ if (!provider)
103
+ return null;
100
104
  return (jsxs(PageContent, { children: [jsxs(ModalHeading, { children: ["Remove ", getProviderName(provider.provider)] }), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ProviderIconContainer, { style: { marginBottom: '16px' }, children: jsx(ProviderIconWrapper, { children: jsx(ProviderIconInner, { children: jsx(ProviderIcon, { account: provider }) }) }) }), isSuccess ? (jsxs(Fragment, { children: [jsx(ModalH1, { "$valid": true, children: "Success" }), jsxs(ModalBody, { children: ["Successfully removed", ' ', provider.provider === 'siwe' ? (jsxs("span", { children: [jsx("b", { children: jsx(WalletDisplay, { walletAddress: provider.accountId }) }), "."] })) : (jsxs(Fragment, { children: [jsx("b", { children: getProviderName(provider.provider) }), " as an authentication method."] }))] }), jsx(ButtonWrapper, { style: { marginTop: 0 }, children: jsx(Button, { onClick: () => onBack === null || onBack === void 0 ? void 0 : onBack(), children: "Back" }) })] })) : (jsxs(Fragment, { children: [jsxs("p", { children: ["Are you sure you want to remove", ' ', provider.provider === 'siwe' ? (jsxs(CopyText, { value: provider.accountId, children: [jsx("b", { children: jsx(WalletDisplay, { walletAddress: provider.accountId }) }), "?"] })) : (jsxs(Fragment, { children: [jsx("b", { children: getProviderName(provider.provider) }), "as an authentication method?"] }))] }), error && jsx(ErrorMessage, { children: error }), jsxs(ButtonWrapper, { style: { marginTop: 0 }, children: [jsx(Button, { onClick: () => onBack === null || onBack === void 0 ? void 0 : onBack(), children: "Cancel" }), jsx(Button, { onClick: handleRemove, children: "Remove" })] })] }))] })] }));
101
105
  };
102
106
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -6,19 +6,50 @@ import { toSolanaUserWallet } from '../../../hooks/openfort/walletTypes.js';
6
6
  import { useResolvedIdentity } from '../../../hooks/useResolvedIdentity.js';
7
7
  import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
8
8
  import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
9
+ import styled from '../../../styles/styled/index.js';
9
10
  import 'detect-browser';
10
11
  import 'react';
11
12
  import { truncateEthAddress } from '../../../utils/format.js';
12
13
  import { walletConfigs } from '../../../wallets/walletConfigs.js';
13
14
  import Button from '../../Common/Button/index.js';
14
15
  import { ModalHeading } from '../../Common/Modal/styles.js';
15
- import { WalletRecoveryIcon } from '../../Common/WalletRecoveryIcon/index.js';
16
+ import { RECOVERY_METHOD_LABEL, WalletRecoveryIcon } from '../../Common/WalletRecoveryIcon/index.js';
16
17
  import { recoverRoute } from '../../Openfort/routeHelpers.js';
17
18
  import { routes } from '../../Openfort/types.js';
18
19
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
19
20
  import { PageContent } from '../../PageContent/index.js';
20
21
  import { ProvidersButton, ProviderLabel, ProviderIcon } from '../Providers/styles.js';
21
22
 
23
+ const RecoveryTag = styled.span `
24
+ display: inline-flex;
25
+ align-items: center;
26
+ padding: 2px 8px;
27
+ border-radius: 6px;
28
+ font-size: 11px;
29
+ font-weight: 600;
30
+ line-height: 16px;
31
+ white-space: nowrap;
32
+ background: var(--ck-body-background-secondary, #f0f0f0);
33
+ color: var(--ck-body-color-muted, #999);
34
+ `;
35
+ const WalletListScroll = styled.div `
36
+ max-height: min(400px, 50vh);
37
+ overflow-x: hidden;
38
+ overflow-y: auto;
39
+
40
+ &::-webkit-scrollbar {
41
+ width: 4px;
42
+ }
43
+ &::-webkit-scrollbar-track {
44
+ background: transparent;
45
+ }
46
+ &::-webkit-scrollbar-thumb {
47
+ background: var(--ck-body-color-muted, #c47a2a);
48
+ border-radius: 4px;
49
+ }
50
+ scrollbar-width: thin;
51
+ scrollbar-color: var(--ck-body-color-muted, #c47a2a) transparent;
52
+ `;
22
53
  function WalletRow({ chainType, wallet, }) {
23
54
  var _a;
24
55
  const { setRoute } = useOpenfort();
@@ -54,7 +85,8 @@ function WalletRow({ chainType, wallet, }) {
54
85
  }
55
86
  setRoute(recoverRoute(chainType, wallet));
56
87
  };
57
- return (jsx(ProvidersButton, { children: jsxs(Button, { onClick: handleClick, children: [jsx(ProviderLabel, { children: display }), jsx(ProviderIcon, { children: walletIcon() })] }) }));
88
+ const tag = wallet.recoveryMethod != null ? RECOVERY_METHOD_LABEL[wallet.recoveryMethod] : undefined;
89
+ return (jsx(ProvidersButton, { children: jsxs(Button, { onClick: handleClick, children: [jsxs(ProviderLabel, { children: [display, tag && jsx(RecoveryTag, { children: tag })] }), jsx(ProviderIcon, { children: walletIcon() })] }) }));
58
90
  }
59
91
  function SelectWalletToRecover() {
60
92
  const { chainType } = useOpenfortCore();
@@ -63,7 +95,7 @@ function SelectWalletToRecover() {
63
95
  const embeddedWallet = chainType === ChainTypeEnum.EVM ? ethereumWallet : solanaWallet;
64
96
  const wallets = embeddedWallet.wallets;
65
97
  const list = wallets.map((wallet) => jsx(WalletRow, { chainType: chainType, wallet: wallet }, wallet.id));
66
- return (jsxs(PageContent, { onBack: routes.PROVIDERS, logoutOnBack: true, children: [jsx(ModalHeading, { children: "Select a wallet to recover" }), list] }));
98
+ return (jsxs(PageContent, { onBack: routes.PROVIDERS, logoutOnBack: true, children: [jsx(ModalHeading, { children: "Select a wallet to recover" }), jsx(WalletListScroll, { children: list })] }));
67
99
  }
68
100
 
69
101
  export { SelectWalletToRecover as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import type { UIAuthProvider } from '../../../components/Openfort/types';
1
+ import { UIAuthProvider } from '../../../components/Openfort/types';
2
2
  import { OpenfortError } from '../../../core/errors';
3
3
  import type { OpenfortHookOptions } from '../../../types';
4
4
  import type { CreateWalletPostAuthOptions } from './useConnectToWalletPostAuth';
@@ -1,6 +1,8 @@
1
1
  import { useState, useRef, useEffect } from 'react';
2
+ import { UIAuthProvider } from '../../../components/Openfort/types.js';
2
3
  import { OpenfortError, OpenfortReactErrorType } from '../../../types.js';
3
4
  import { logger } from '../../../utils/logger.js';
5
+ import { parseCallbackUrl, suppressReferrer } from '../../../utils/urlSecurity.js';
4
6
  import { useEmailAuth } from './useEmailAuth.js';
5
7
  import { useOAuth } from './useOAuth.js';
6
8
 
@@ -79,17 +81,27 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
79
81
  if (callbackProcessedRef.current)
80
82
  return;
81
83
  callbackProcessedRef.current = true;
84
+ // Parse callback URL (fixes OF-1013 duplicate `?` issue)
85
+ const url = parseCallbackUrl(window.location.href);
86
+ const rawProvider = url.searchParams.get('openfortAuthProvider');
87
+ // Allowlist: UIAuthProvider values + callback-only providers set by buildCallbackUrl
88
+ const validProviders = new Set([
89
+ ...Object.values(UIAuthProvider),
90
+ 'email', // set by buildCallbackUrl for email verification
91
+ 'password', // set by buildCallbackUrl for password reset
92
+ ]);
93
+ if (!rawProvider || !validProviders.has(rawProvider)) {
94
+ return;
95
+ }
96
+ // Validated against the allowlist above
97
+ const openfortAuthProvider = rawProvider;
98
+ // Suppress Referer SYNCHRONOUSLY — before any async work — so that
99
+ // subresource requests cannot leak access_token to third parties.
100
+ const restoreReferrer = suppressReferrer();
82
101
  (async () => {
83
102
  var _a, _b, _c;
84
- // redirectUrl is not working with query params OF-1013
85
- const fixedUrl = window.location.href.replace('?state=', '&state=');
86
- const url = new URL(fixedUrl);
87
- const openfortAuthProvider = url.searchParams.get('openfortAuthProvider');
88
- if (!openfortAuthProvider) {
89
- return;
90
- }
91
103
  setProvider(openfortAuthProvider);
92
- if (openfortAuthProvider === 'email') {
104
+ if (openfortAuthProvider === 'email' || openfortAuthProvider === 'password') {
93
105
  // Email verification flow
94
106
  // The backend verifies the email server-side via /auth/verify-email?token=...
95
107
  // and then redirects here. If a `state` token is present we verify client-side
@@ -101,6 +113,7 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
101
113
  url.searchParams.delete(key);
102
114
  });
103
115
  window.history.replaceState({}, document.title, url.toString());
116
+ restoreReferrer();
104
117
  };
105
118
  if (state && email) {
106
119
  // State present — verify client-side as well
@@ -130,6 +143,7 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
130
143
  removeParams();
131
144
  }
132
145
  else {
146
+ restoreReferrer();
133
147
  const err = new OpenfortError('No email found in URL', OpenfortReactErrorType.AUTHENTICATION_ERROR);
134
148
  logger.error('No email found in URL');
135
149
  (_b = hookOptions.onError) === null || _b === void 0 ? void 0 : _b.call(hookOptions, err);
@@ -142,6 +156,7 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
142
156
  const userId = url.searchParams.get('user_id');
143
157
  const token = url.searchParams.get('access_token');
144
158
  if (!userId || !token) {
159
+ restoreReferrer();
145
160
  logger.error(`Missing user id or access token`, {
146
161
  hasUserId: !!userId,
147
162
  hasToken: !!token,
@@ -157,6 +172,7 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
157
172
  url.searchParams.delete(key);
158
173
  });
159
174
  window.history.replaceState({}, document.title, url.toString());
175
+ restoreReferrer();
160
176
  };
161
177
  logger.log('callback', { userId });
162
178
  const options = {
@@ -1 +1 @@
1
- {"version":3,"file":"useAuthCallback.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useAuthCallback.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -61,7 +61,10 @@ function useResolvedIdentity(options) {
61
61
  var _a, _b, _c, _d, _e;
62
62
  const { address, chainType = ChainTypeEnum.EVM, ensChainId = 0, enabled = true } = options;
63
63
  const { walletConfig } = useOpenfort();
64
- const rpcUrl = (_c = (_b = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.rpcUrls) === null || _b === void 0 ? void 0 : _b[ensChainId]) !== null && _c !== void 0 ? _c : getDefaultEthereumRpcUrl(ensChainId);
64
+ // Only resolve RPC URL for mainnet (ensChainId === 1) chainId 0 means "do not resolve"
65
+ const rpcUrl = ensChainId === 1
66
+ ? ((_c = (_b = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.rpcUrls) === null || _b === void 0 ? void 0 : _b[ensChainId]) !== null && _c !== void 0 ? _c : getDefaultEthereumRpcUrl(ensChainId))
67
+ : undefined;
65
68
  const isEnabled = enabled && !!address && address.length > 0 && ensChainId === 1 && !!rpcUrl;
66
69
  const { data, error, isLoading } = useAsyncData({
67
70
  queryKey: ['identity', chainType, address, ensChainId],
@@ -1 +1 @@
1
- {"version":3,"file":"useResolvedIdentity.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useResolvedIdentity.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -6,10 +6,6 @@
6
6
  */
7
7
  import type { Chain } from 'viem';
8
8
  import type { SolanaCluster } from '../solana/types';
9
- /**
10
- * Get default Ethereum RPC URL for a chain ID.
11
- * Returns the viem/chains default RPC when known, falls back to Sepolia.
12
- */
13
9
  export declare function getDefaultEthereumRpcUrl(chainId: number): string;
14
10
  /**
15
11
  * Get default Solana RPC URL for a cluster.
@@ -30,11 +30,15 @@ const DEFAULT_SOLANA_RPC_URLS = {
30
30
  * Get default Ethereum RPC URL for a chain ID.
31
31
  * Returns the viem/chains default RPC when known, falls back to Sepolia.
32
32
  */
33
+ const warnedChainIds = new Set();
33
34
  function getDefaultEthereumRpcUrl(chainId) {
34
35
  const chain = KNOWN_CHAINS[chainId];
35
36
  const rpcUrl = chain === null || chain === void 0 ? void 0 : chain.rpcUrls.default.http[0];
36
37
  if (!rpcUrl) {
37
- logger.warn(`No default Ethereum RPC URL found for chain ${chainId}. Configure rpcUrls in OpenfortProvider for better reliability and rate limits.`);
38
+ if (!warnedChainIds.has(chainId)) {
39
+ warnedChainIds.add(chainId);
40
+ logger.warn(`No default Ethereum RPC URL found for chain ${chainId}. Configure rpcUrls in OpenfortProvider for better reliability and rate limits.`);
41
+ }
38
42
  return sepolia.rpcUrls.default.http[0];
39
43
  }
40
44
  return rpcUrl;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"rpc.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Utilities for secure handling of OAuth callback URLs containing tokens.
3
+ *
4
+ * Prevents Referer-header leakage of access tokens and provides robust
5
+ * URL parsing for the OF-1013 workaround (duplicate `?` in redirect URLs).
6
+ */
7
+ /**
8
+ * Injects a `<meta name="referrer" content="no-referrer">` tag so that
9
+ * any subresource request fired before `history.replaceState` strips the
10
+ * tokens will NOT leak the full URL (including access_token) via the
11
+ * Referer header.
12
+ *
13
+ * Call this **synchronously** — before any `await` — when the URL
14
+ * contains sensitive query parameters.
15
+ *
16
+ * @returns A cleanup function that removes the meta tag.
17
+ */
18
+ export declare function suppressReferrer(): () => void;
19
+ /**
20
+ * Parses the current `window.location.href`, fixing the OF-1013 issue
21
+ * where the server redirect produces a URL with a duplicate `?`, e.g.
22
+ * `https://example.com/callback?existing=1?access_token=xxx&user_id=yyy`.
23
+ *
24
+ * Instead of a fragile `.replace('?access_token=', '&access_token=')`
25
+ * that can mangle values containing the same substring, this finds the
26
+ * *second* `?` (if any) and replaces it with `&`.
27
+ */
28
+ export declare function parseCallbackUrl(href: string): URL;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Utilities for secure handling of OAuth callback URLs containing tokens.
3
+ *
4
+ * Prevents Referer-header leakage of access tokens and provides robust
5
+ * URL parsing for the OF-1013 workaround (duplicate `?` in redirect URLs).
6
+ */
7
+ const REFERRER_META_ID = '__openfort_no_referrer';
8
+ /**
9
+ * Injects a `<meta name="referrer" content="no-referrer">` tag so that
10
+ * any subresource request fired before `history.replaceState` strips the
11
+ * tokens will NOT leak the full URL (including access_token) via the
12
+ * Referer header.
13
+ *
14
+ * Call this **synchronously** — before any `await` — when the URL
15
+ * contains sensitive query parameters.
16
+ *
17
+ * @returns A cleanup function that removes the meta tag.
18
+ */
19
+ function suppressReferrer() {
20
+ if (typeof document === 'undefined')
21
+ return () => { };
22
+ // Avoid duplicates if called more than once
23
+ if (document.getElementById(REFERRER_META_ID))
24
+ return () => { };
25
+ const meta = document.createElement('meta');
26
+ meta.id = REFERRER_META_ID;
27
+ meta.name = 'referrer';
28
+ meta.content = 'no-referrer';
29
+ document.head.appendChild(meta);
30
+ return () => {
31
+ meta.remove();
32
+ };
33
+ }
34
+ /**
35
+ * Parses the current `window.location.href`, fixing the OF-1013 issue
36
+ * where the server redirect produces a URL with a duplicate `?`, e.g.
37
+ * `https://example.com/callback?existing=1?access_token=xxx&user_id=yyy`.
38
+ *
39
+ * Instead of a fragile `.replace('?access_token=', '&access_token=')`
40
+ * that can mangle values containing the same substring, this finds the
41
+ * *second* `?` (if any) and replaces it with `&`.
42
+ */
43
+ function parseCallbackUrl(href) {
44
+ const firstQ = href.indexOf('?');
45
+ if (firstQ === -1)
46
+ return new URL(href);
47
+ const secondQ = href.indexOf('?', firstQ + 1);
48
+ if (secondQ === -1)
49
+ return new URL(href);
50
+ // Replace only the second `?` with `&`
51
+ const fixed = `${href.slice(0, secondQ)}&${href.slice(secondQ + 1)}`;
52
+ return new URL(fixed);
53
+ }
54
+
55
+ export { parseCallbackUrl, suppressReferrer };
56
+ //# sourceMappingURL=urlSecurity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urlSecurity.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- export declare const OPENFORT_VERSION = "1.0.6";
1
+ export declare const OPENFORT_VERSION = "1.0.7";
package/build/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const OPENFORT_VERSION = '1.0.6';
1
+ const OPENFORT_VERSION = '1.0.7';
2
2
 
3
3
  export { OPENFORT_VERSION };
4
4
  //# sourceMappingURL=version.js.map
@@ -1,5 +1,5 @@
1
1
  import { OpenfortError } from '@openfort/openfort-js';
2
- import { useCallback } from 'react';
2
+ import { useRef, useCallback } from 'react';
3
3
  import { useEthereumBridge } from '../ethereum/OpenfortEthereumBridgeContext.js';
4
4
  import { useOpenfortCore } from '../openfort/useOpenfort.js';
5
5
  import { createSIWEMessage } from '../siwe/create-siwe-message.js';
@@ -17,27 +17,35 @@ import { logger } from '../utils/logger.js';
17
17
  * ```
18
18
  */
19
19
  function useConnectWithSiwe() {
20
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
21
20
  const { client, user, updateUser } = useOpenfortCore();
22
21
  const bridge = useEthereumBridge();
23
- const address = (_a = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _a === void 0 ? void 0 : _a.address;
24
- const connector = (_b = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _b === void 0 ? void 0 : _b.connector;
25
- const chainId = (_c = bridge === null || bridge === void 0 ? void 0 : bridge.chainId) !== null && _c !== void 0 ? _c : 0;
26
- const accountChainId = (_f = (_e = (_d = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _d === void 0 ? void 0 : _d.chain) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : bridge === null || bridge === void 0 ? void 0 : bridge.chainId;
27
- const chainName = (_h = (_g = bridge === null || bridge === void 0 ? void 0 : bridge.account) === null || _g === void 0 ? void 0 : _g.chain) === null || _h === void 0 ? void 0 : _h.name;
28
- const switchChainAsync = (_j = bridge === null || bridge === void 0 ? void 0 : bridge.switchChain) === null || _j === void 0 ? void 0 : _j.switchChainAsync;
29
- const signMessage = bridge === null || bridge === void 0 ? void 0 : bridge.signMessage;
30
- const connectWithSiwe = useCallback(async ({ onError, onConnect, address: propsAddress, connectorType: propsConnectorType, walletClientType: propsWalletClientType, link = !!user, } = {}) => {
31
- var _a, _b;
32
- const addressToUse = propsAddress !== null && propsAddress !== void 0 ? propsAddress : address;
33
- const connectorType = propsConnectorType !== null && propsConnectorType !== void 0 ? propsConnectorType : connector === null || connector === void 0 ? void 0 : connector.type;
34
- const walletClientType = propsWalletClientType !== null && propsWalletClientType !== void 0 ? propsWalletClientType : connector === null || connector === void 0 ? void 0 : connector.id;
35
- if (!addressToUse || !connectorType || !walletClientType) {
36
- logger.log('No address found', { address: addressToUse, connectorType, walletClientType });
22
+ // Use a ref so the callback always reads the latest bridge state,
23
+ // not a stale closure from the last render (critical after connectAsync changes the active connector).
24
+ const bridgeRef = useRef(bridge);
25
+ bridgeRef.current = bridge;
26
+ const userRef = useRef(user);
27
+ userRef.current = user;
28
+ const connectWithSiwe = useCallback(async ({ onError, onConnect, address: propsAddress, connectorType: propsConnectorType, walletClientType: propsWalletClientType, link, } = {}) => {
29
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
30
+ // Read fresh values from the bridge ref — NOT from the stale render closure
31
+ const b = bridgeRef.current;
32
+ const currentUser = userRef.current;
33
+ const shouldLink = link !== null && link !== void 0 ? link : !!currentUser;
34
+ const address = propsAddress !== null && propsAddress !== void 0 ? propsAddress : (_a = b === null || b === void 0 ? void 0 : b.account) === null || _a === void 0 ? void 0 : _a.address;
35
+ const connectorType = propsConnectorType !== null && propsConnectorType !== void 0 ? propsConnectorType : (_c = (_b = b === null || b === void 0 ? void 0 : b.account) === null || _b === void 0 ? void 0 : _b.connector) === null || _c === void 0 ? void 0 : _c.type;
36
+ const walletClientType = propsWalletClientType !== null && propsWalletClientType !== void 0 ? propsWalletClientType : (_e = (_d = b === null || b === void 0 ? void 0 : b.account) === null || _d === void 0 ? void 0 : _d.connector) === null || _e === void 0 ? void 0 : _e.id;
37
+ const chainId = (_f = b === null || b === void 0 ? void 0 : b.chainId) !== null && _f !== void 0 ? _f : 0;
38
+ const accountChainId = (_j = (_h = (_g = b === null || b === void 0 ? void 0 : b.account) === null || _g === void 0 ? void 0 : _g.chain) === null || _h === void 0 ? void 0 : _h.id) !== null && _j !== void 0 ? _j : b === null || b === void 0 ? void 0 : b.chainId;
39
+ const chainName = (_l = (_k = b === null || b === void 0 ? void 0 : b.account) === null || _k === void 0 ? void 0 : _k.chain) === null || _l === void 0 ? void 0 : _l.name;
40
+ const switchChainAsync = (_m = b === null || b === void 0 ? void 0 : b.switchChain) === null || _m === void 0 ? void 0 : _m.switchChainAsync;
41
+ const signMessage = b === null || b === void 0 ? void 0 : b.signMessage;
42
+ if (!address || !connectorType || !walletClientType) {
43
+ logger.warn('[useConnectWithSiwe] Missing params', { address, connectorType, walletClientType });
37
44
  onError === null || onError === void 0 ? void 0 : onError('No address found');
38
45
  return;
39
46
  }
40
47
  if (!signMessage) {
48
+ logger.warn('[useConnectWithSiwe] No signMessage on bridge');
41
49
  onError === null || onError === void 0 ? void 0 : onError('EVM bridge not available (signMessage)');
42
50
  return;
43
51
  }
@@ -46,46 +54,44 @@ function useConnectWithSiwe() {
46
54
  await switchChainAsync({ chainId });
47
55
  }
48
56
  let nonce;
49
- if (link) {
50
- const resp = await client.auth.initLinkSiwe({ address: addressToUse });
57
+ if (shouldLink) {
58
+ const resp = await client.auth.initLinkSiwe({ address });
51
59
  nonce = resp.nonce;
52
60
  }
53
61
  else {
54
- const resp = await client.auth.initSiwe({ address: addressToUse });
62
+ const resp = await client.auth.initSiwe({ address });
55
63
  nonce = resp.nonce;
56
64
  }
57
- const SIWEMessage = createSIWEMessage(addressToUse, nonce, chainId);
65
+ const SIWEMessage = createSIWEMessage(address, nonce, chainId);
58
66
  if (!SIWEMessage)
59
67
  throw new Error('SIWE message creation failed (window not available)');
60
68
  const signature = await signMessage({ message: SIWEMessage });
61
- if (link) {
62
- logger.log('Linking wallet to user');
69
+ if (shouldLink) {
63
70
  await client.auth.linkWithSiwe({
64
71
  signature,
65
72
  message: SIWEMessage,
66
73
  connectorType,
67
74
  walletClientType,
68
- address: addressToUse,
75
+ address,
69
76
  chainId,
70
77
  });
71
78
  }
72
79
  else {
73
- logger.log('Authenticating with SIWE');
74
80
  await client.auth.loginWithSiwe({
75
81
  signature,
76
82
  message: SIWEMessage,
77
83
  connectorType,
78
84
  walletClientType,
79
- address: addressToUse,
85
+ address,
80
86
  });
81
87
  }
82
88
  await updateUser();
83
89
  await Promise.resolve(onConnect === null || onConnect === void 0 ? void 0 : onConnect());
84
90
  }
85
91
  catch (err) {
86
- logger.log('Failed to connect with SIWE', {
87
- error: err,
88
- status: (_b = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : 'unknown',
92
+ logger.error('[useConnectWithSiwe] SIWE failed', {
93
+ message: err instanceof Error ? err.message : String(err),
94
+ status: (_o = err === null || err === void 0 ? void 0 : err.response) === null || _o === void 0 ? void 0 : _o.status,
89
95
  });
90
96
  if (!onError)
91
97
  return;
@@ -107,7 +113,7 @@ function useConnectWithSiwe() {
107
113
  }
108
114
  onError(message, err instanceof OpenfortError ? err : undefined);
109
115
  }
110
- }, [client, user, updateUser, address, chainId, connector, accountChainId, chainName, switchChainAsync, signMessage]);
116
+ }, [client, updateUser]);
111
117
  return { connectWithSiwe };
112
118
  }
113
119
 
@@ -1 +1 @@
1
- {"version":3,"file":"useConnectWithSiwe.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useConnectWithSiwe.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,7 +1,8 @@
1
- import { useEffect } from 'react';
1
+ import { useRef, useEffect } from 'react';
2
2
  import { useAccount, useConnect, useDisconnect } from 'wagmi';
3
3
  import { embeddedWalletId } from '../constants/openfort.js';
4
4
  import { useEthereumEmbeddedWallet } from '../ethereum/hooks/useEthereumEmbeddedWallet.js';
5
+ import { logger } from '../utils/logger.js';
5
6
  import { setEmbeddedWalletProvider } from './embeddedConnector.js';
6
7
 
7
8
  /** Null component — rendered inside CoreOpenfortProvider + WagmiProvider to sync embedded wallet into wagmi. */
@@ -16,6 +17,16 @@ function useEmbeddedWalletWagmiSync() {
16
17
  const { disconnectAsync } = useDisconnect();
17
18
  const status = wallet.status;
18
19
  const provider = status === 'connected' ? wallet.provider : null;
20
+ // Track whether an external wallet was explicitly connected — don't override it
21
+ const externalConnectorActiveRef = useRef(false);
22
+ useEffect(() => {
23
+ if (activeConnector && activeConnector.id !== embeddedWalletId) {
24
+ externalConnectorActiveRef.current = true;
25
+ }
26
+ else if (!activeConnector || activeConnector.id === embeddedWalletId) {
27
+ externalConnectorActiveRef.current = false;
28
+ }
29
+ }, [activeConnector]);
19
30
  // Keep the module-level provider slot in sync — clear on disconnect
20
31
  useEffect(() => {
21
32
  if (status === 'connected' && provider) {
@@ -26,6 +37,7 @@ function useEmbeddedWalletWagmiSync() {
26
37
  }
27
38
  }, [status, provider]);
28
39
  // Connect wagmi once the embedded wallet is ready AND wagmi has settled (not mid-reconnect)
40
+ // BUT do NOT override an explicitly connected external wallet
29
41
  useEffect(() => {
30
42
  if (status !== 'connected' || !provider)
31
43
  return;
@@ -33,9 +45,17 @@ function useEmbeddedWalletWagmiSync() {
33
45
  return;
34
46
  if ((activeConnector === null || activeConnector === void 0 ? void 0 : activeConnector.id) === embeddedWalletId)
35
47
  return;
48
+ // An external wallet is actively connected — don't override it
49
+ if (externalConnectorActiveRef.current) {
50
+ logger.log('[EmbeddedWalletWagmiSync] Skipping auto-connect — external wallet is active', {
51
+ activeConnector: activeConnector === null || activeConnector === void 0 ? void 0 : activeConnector.id,
52
+ });
53
+ return;
54
+ }
36
55
  const embeddedConnector = connectors.find((c) => c.id === embeddedWalletId);
37
56
  if (!embeddedConnector)
38
57
  return;
58
+ logger.log('[EmbeddedWalletWagmiSync] Auto-connecting embedded wallet to wagmi');
39
59
  connectAsync({ connector: embeddedConnector }).catch(() => { });
40
60
  }, [status, provider, wagmiStatus, activeConnector, connectors, connectAsync]);
41
61
  // Disconnect embedded connector from wagmi when the embedded wallet logs out
@@ -1 +1 @@
1
- {"version":3,"file":"useEmbeddedWalletWagmiSync.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useEmbeddedWalletWagmiSync.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -6,6 +6,7 @@ import { mapStatus } from '../hooks/openfort/auth/status.js';
6
6
  import { onError, onSuccess } from '../hooks/openfort/hookConsistency.js';
7
7
  import { useOpenfortCore } from '../openfort/useOpenfort.js';
8
8
  import { createSIWEMessage } from '../siwe/create-siwe-message.js';
9
+ import { logger } from '../utils/logger.js';
9
10
 
10
11
  function runConnectWithSiwe(bridge, openfort, params) {
11
12
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
@@ -19,10 +20,12 @@ function runConnectWithSiwe(bridge, openfort, params) {
19
20
  const switchChainAsync = (_q = bridge.switchChain) === null || _q === void 0 ? void 0 : _q.switchChainAsync;
20
21
  const signMessage = bridge.signMessage;
21
22
  if (!address || !connectorType || !walletClientType) {
23
+ logger.warn('[runConnectWithSiwe] Missing params', { address, connectorType, walletClientType });
22
24
  (_r = params.onError) === null || _r === void 0 ? void 0 : _r.call(params, 'No address found');
23
25
  return Promise.resolve();
24
26
  }
25
27
  if (!signMessage) {
28
+ logger.warn('[runConnectWithSiwe] No signMessage on bridge');
26
29
  (_s = params.onError) === null || _s === void 0 ? void 0 : _s.call(params, 'EVM bridge not available (signMessage)');
27
30
  return Promise.resolve();
28
31
  }
@@ -67,6 +70,7 @@ function runConnectWithSiwe(bridge, openfort, params) {
67
70
  (_a = params.onConnect) === null || _a === void 0 ? void 0 : _a.call(params);
68
71
  }
69
72
  catch (err) {
73
+ logger.error('[runConnectWithSiwe] SIWE failed', err instanceof Error ? err.message : err);
70
74
  if (!params.onError)
71
75
  return;
72
76
  let message = err instanceof Error ? err.message : String(err);
@@ -105,6 +109,7 @@ function useWalletAuth(hookOptions = {}) {
105
109
  const connector = (_a = bridge === null || bridge === void 0 ? void 0 : bridge.connectors) === null || _a === void 0 ? void 0 : _a.find((c) => c.id === connectorId);
106
110
  if (!connector || !(bridge === null || bridge === void 0 ? void 0 : bridge.connectAsync)) {
107
111
  const msg = 'Connector not available';
112
+ logger.warn('[useWalletAuth] Connector not found', { connectorId });
108
113
  const err = new OpenfortError(msg, OpenfortReactErrorType.AUTHENTICATION_ERROR);
109
114
  setStatus({ status: 'error', error: err });
110
115
  onError({ hookOptions, error: err });
@@ -118,6 +123,7 @@ function useWalletAuth(hookOptions = {}) {
118
123
  await bridge.disconnect();
119
124
  }
120
125
  catch (e) {
126
+ logger.error('[useWalletAuth] Failed to disconnect', e);
121
127
  setWalletConnectingTo(null);
122
128
  const err = new OpenfortError('Failed to disconnect', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
123
129
  error: e,
@@ -157,6 +163,7 @@ function useWalletAuth(hookOptions = {}) {
157
163
  });
158
164
  }
159
165
  catch (err) {
166
+ logger.error('[useWalletAuth] connectAsync failed', err instanceof Error ? err.message : err);
160
167
  setWalletConnectingTo(null);
161
168
  const message = err instanceof Error ? err.message : 'Connection failed';
162
169
  const openfortErr = new OpenfortError(message, OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: err });
@@ -1 +1 @@
1
- {"version":3,"file":"useWalletAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useWalletAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/react",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "author": "Openfort (https://www.openfort.io)",
5
5
  "license": "BSD-2-Clause license",
6
6
  "description": "The easiest way to integrate Openfort to your project.",