@openfort/react 0.2.4 → 0.2.6
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/build/components/Common/OTPInput/index.d.ts +2 -1
- package/build/components/Common/OTPInput/styles.d.ts +1 -0
- package/build/components/Openfort/types.d.ts +28 -2
- package/build/components/PageContent/index.d.ts +2 -1
- package/build/components/PageLayout/index.d.ts +6 -0
- package/build/components/Pages/BuyProviderSelect/styles.d.ts +2 -1
- package/build/components/Pages/SelectToken/styles.d.ts +2 -1
- package/build/hooks/openfort/useWallets.d.ts +10 -0
- package/build/index.d.ts +2 -1
- package/build/index.es.js +2151 -1869
- package/build/index.es.js.map +1 -1
- package/build/types.d.ts +1 -1
- package/build/version.d.ts +1 -1
- package/package.json +2 -2
package/build/index.es.js
CHANGED
|
@@ -15,7 +15,7 @@ import { safe, injected, coinbaseWallet, walletConnect } from '@wagmi/connectors
|
|
|
15
15
|
import { useTransition } from 'react-transition-state';
|
|
16
16
|
import ResizeObserver from 'resize-observer-polyfill';
|
|
17
17
|
import { createPortal } from 'react-dom';
|
|
18
|
-
import { numberToHex, formatUnits, parseUnits, isAddress, parseAbi, encodeFunctionData, parseSignature } from 'viem';
|
|
18
|
+
import { custom, createWalletClient, numberToHex, formatUnits, parseUnits, isAddress, parseAbi, encodeFunctionData, parseSignature } from 'viem';
|
|
19
19
|
import { erc7811Actions, erc7715Actions } from 'viem/experimental';
|
|
20
20
|
import calculateEntropy from 'fast-password-entropy';
|
|
21
21
|
import QRCodeUtil from 'qrcode';
|
|
@@ -5643,7 +5643,7 @@ const FitText = ({ children, maxFontSize = 100, minFontSize = 70, justifyContent
|
|
|
5643
5643
|
};
|
|
5644
5644
|
FitText.displayName = 'FitText';
|
|
5645
5645
|
|
|
5646
|
-
const OPENFORT_VERSION = '0.2.
|
|
5646
|
+
const OPENFORT_VERSION = '0.2.6';
|
|
5647
5647
|
|
|
5648
5648
|
const Portal = (props) => {
|
|
5649
5649
|
props = {
|
|
@@ -6492,8 +6492,6 @@ onInfo, }) => {
|
|
|
6492
6492
|
return locales.downloadAppScreen_heading;
|
|
6493
6493
|
case routes.ONBOARDING:
|
|
6494
6494
|
return locales.onboardingScreen_heading;
|
|
6495
|
-
case routes.CONNECTED:
|
|
6496
|
-
return locales.profileScreen_heading;
|
|
6497
6495
|
case routes.SWITCHNETWORKS:
|
|
6498
6496
|
return locales.switchNetworkScreen_heading;
|
|
6499
6497
|
default:
|
|
@@ -6550,7 +6548,8 @@ onInfo, }) => {
|
|
|
6550
6548
|
duration: mobile ? 0 : 0.17,
|
|
6551
6549
|
delay: mobile ? 0.01 : 0,
|
|
6552
6550
|
}, children: jsx(FitText, { children: getHeading() }) }, `${route}-${'signedIn'}`) }) }), jsx(InnerContainer$1, { children: Object.keys(pages).map((key) => {
|
|
6553
|
-
|
|
6551
|
+
var _a, _b;
|
|
6552
|
+
const page = (_b = (_a = context.uiConfig.customPageComponents) === null || _a === void 0 ? void 0 : _a[key]) !== null && _b !== void 0 ? _b : pages[key];
|
|
6554
6553
|
return (
|
|
6555
6554
|
// OLD_TODO: We may need to use the follow check avoid unnecessary computations, but this causes a bug where the content flashes
|
|
6556
6555
|
// (key === pageId || key === prevPage) && (
|
|
@@ -7096,7 +7095,7 @@ function useSignOut(hookOptions = {}) {
|
|
|
7096
7095
|
};
|
|
7097
7096
|
}
|
|
7098
7097
|
|
|
7099
|
-
const PageContent = ({ children, width, onBack = 'back', logoutOnBack }) => {
|
|
7098
|
+
const PageContent = ({ children, width, onBack = 'back', logoutOnBack, header }) => {
|
|
7100
7099
|
const { setOnBack, setRoute, setPreviousRoute, setRouteHistory } = useOpenfort();
|
|
7101
7100
|
const { signOut } = useSignOut();
|
|
7102
7101
|
useEffect(() => {
|
|
@@ -7139,7 +7138,7 @@ const PageContent = ({ children, width, onBack = 'back', logoutOnBack }) => {
|
|
|
7139
7138
|
else
|
|
7140
7139
|
setOnBack(null);
|
|
7141
7140
|
}, [!!onBack, !!logoutOnBack]);
|
|
7142
|
-
return
|
|
7141
|
+
return (jsxs(PageContentStyle, { style: { width }, children: [header && jsx(ModalHeading, { children: header }), children] }));
|
|
7143
7142
|
};
|
|
7144
7143
|
|
|
7145
7144
|
const pulseAnim = { scale: [0.9, 1.25, 1.6], opacity: [0, 0.11, 0] };
|
|
@@ -7589,11 +7588,130 @@ const About = () => {
|
|
|
7589
7588
|
} }, s.key))) }) }), jsx(Button, { href: ctaUrl, arrow: true, children: locales.aboutScreen_ctaText })] }));
|
|
7590
7589
|
};
|
|
7591
7590
|
|
|
7591
|
+
/**
|
|
7592
|
+
* Hook for accessing current user information and authentication state
|
|
7593
|
+
*
|
|
7594
|
+
* This hook provides access to the current authenticated user's information and
|
|
7595
|
+
* authentication status. It also offers methods to manage access tokens and validate
|
|
7596
|
+
* user sessions. The hook automatically updates when authentication state changes.
|
|
7597
|
+
*
|
|
7598
|
+
* @returns Current user state and authentication utilities
|
|
7599
|
+
*
|
|
7600
|
+
* @example
|
|
7601
|
+
* ```tsx
|
|
7602
|
+
* const userHook = useUser();
|
|
7603
|
+
*
|
|
7604
|
+
* // Check if user is authenticated
|
|
7605
|
+
* if (userHook.isAuthenticated && userHook.user) {
|
|
7606
|
+
* console.log('User is authenticated:', userHook.user);
|
|
7607
|
+
* console.log('User ID:', userHook.user.id);
|
|
7608
|
+
* console.log('User email:', userHook.user.email);
|
|
7609
|
+
* console.log('Linked accounts:', userHook.linkedAccounts);
|
|
7610
|
+
* } else {
|
|
7611
|
+
* console.log('User is not authenticated');
|
|
7612
|
+
* }
|
|
7613
|
+
*
|
|
7614
|
+
* // Get fresh access token
|
|
7615
|
+
* const getToken = async () => {
|
|
7616
|
+
* try {
|
|
7617
|
+
* const token = await userHook.getAccessToken();
|
|
7618
|
+
* console.log('Access token:', token);
|
|
7619
|
+
* } catch (error) {
|
|
7620
|
+
* console.error('Failed to get access token:', error);
|
|
7621
|
+
* }
|
|
7622
|
+
* };
|
|
7623
|
+
*
|
|
7624
|
+
* // Validate and refresh token if needed
|
|
7625
|
+
* const refreshToken = async () => {
|
|
7626
|
+
* try {
|
|
7627
|
+
* await userHook.validateAndRefreshToken();
|
|
7628
|
+
* console.log('Token validated and refreshed');
|
|
7629
|
+
* } catch (error) {
|
|
7630
|
+
* console.error('Token validation failed:', error);
|
|
7631
|
+
* }
|
|
7632
|
+
* };
|
|
7633
|
+
* ```
|
|
7634
|
+
*/
|
|
7635
|
+
function useUser() {
|
|
7636
|
+
const { user, client, embeddedState, linkedAccounts } = useOpenfortCore();
|
|
7637
|
+
const getAccessTokenAndUpdate = useCallback(async () => {
|
|
7638
|
+
try {
|
|
7639
|
+
await client.validateAndRefreshToken();
|
|
7640
|
+
const token = await client.getAccessToken();
|
|
7641
|
+
return token;
|
|
7642
|
+
}
|
|
7643
|
+
catch (error) {
|
|
7644
|
+
handleOAuthConfigError(error);
|
|
7645
|
+
throw error;
|
|
7646
|
+
}
|
|
7647
|
+
}, [client]);
|
|
7648
|
+
const validateAndRefresh = useCallback(async () => {
|
|
7649
|
+
try {
|
|
7650
|
+
await client.validateAndRefreshToken();
|
|
7651
|
+
}
|
|
7652
|
+
catch (error) {
|
|
7653
|
+
handleOAuthConfigError(error);
|
|
7654
|
+
throw error;
|
|
7655
|
+
}
|
|
7656
|
+
}, [client]);
|
|
7657
|
+
return {
|
|
7658
|
+
user,
|
|
7659
|
+
linkedAccounts,
|
|
7660
|
+
isAuthenticated: embeddedState !== EmbeddedState.NONE && embeddedState !== EmbeddedState.UNAUTHENTICATED,
|
|
7661
|
+
getAccessToken: getAccessTokenAndUpdate,
|
|
7662
|
+
validateAndRefreshToken: validateAndRefresh,
|
|
7663
|
+
};
|
|
7664
|
+
}
|
|
7665
|
+
|
|
7592
7666
|
const useWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000 } = {}) => {
|
|
7593
7667
|
const chainId = useChainId();
|
|
7594
7668
|
const { data: walletClient } = useWalletClient();
|
|
7595
|
-
const { walletConfig } = useOpenfort();
|
|
7669
|
+
const { walletConfig, publishableKey, overrides, thirdPartyAuth } = useOpenfort();
|
|
7596
7670
|
const { address } = useAccount();
|
|
7671
|
+
const { getAccessToken } = useUser();
|
|
7672
|
+
const buildHeaders = useCallback(async () => {
|
|
7673
|
+
if (thirdPartyAuth) {
|
|
7674
|
+
const accessToken = await thirdPartyAuth.getAccessToken();
|
|
7675
|
+
if (!accessToken) {
|
|
7676
|
+
throw new OpenfortError('Failed to get access token from third party auth provider', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
7677
|
+
}
|
|
7678
|
+
const headers = {
|
|
7679
|
+
'Content-Type': 'application/json',
|
|
7680
|
+
'x-auth-provider': thirdPartyAuth.provider,
|
|
7681
|
+
'x-player-token': accessToken,
|
|
7682
|
+
'x-token-type': 'idToken',
|
|
7683
|
+
Authorization: `Bearer ${publishableKey}`,
|
|
7684
|
+
};
|
|
7685
|
+
return headers;
|
|
7686
|
+
}
|
|
7687
|
+
const headers = {
|
|
7688
|
+
'Content-Type': 'application/json',
|
|
7689
|
+
'x-project-key': publishableKey,
|
|
7690
|
+
Authorization: `Bearer ${await getAccessToken()}`,
|
|
7691
|
+
};
|
|
7692
|
+
return headers;
|
|
7693
|
+
}, [publishableKey, getAccessToken, thirdPartyAuth]);
|
|
7694
|
+
const customTransport = useMemo(() => () => {
|
|
7695
|
+
return custom({
|
|
7696
|
+
async request({ method, params }) {
|
|
7697
|
+
const res = await fetch(`${(overrides === null || overrides === void 0 ? void 0 : overrides.backendUrl) || 'https://api.openfort.io'}/rpc`, {
|
|
7698
|
+
method: 'POST',
|
|
7699
|
+
headers: await buildHeaders(),
|
|
7700
|
+
body: JSON.stringify({
|
|
7701
|
+
method,
|
|
7702
|
+
params: params[0],
|
|
7703
|
+
id: 1,
|
|
7704
|
+
jsonrpc: '2.0',
|
|
7705
|
+
}),
|
|
7706
|
+
});
|
|
7707
|
+
const data = await res.json();
|
|
7708
|
+
if (data.error) {
|
|
7709
|
+
throw new Error(data.error.message);
|
|
7710
|
+
}
|
|
7711
|
+
return data.result;
|
|
7712
|
+
},
|
|
7713
|
+
});
|
|
7714
|
+
}, [publishableKey, getAccessToken]);
|
|
7597
7715
|
const customAssetsToFetch = useMemo(() => {
|
|
7598
7716
|
const assetsFromConfig = (walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.assets) ? walletConfig.assets[chainId] || [] : [];
|
|
7599
7717
|
const assetsFromHook = hookCustomAssets ? hookCustomAssets[chainId] || [] : [];
|
|
@@ -7608,7 +7726,12 @@ const useWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000 } = {}) =
|
|
|
7608
7726
|
error: new Error('Wallet client not initialized'),
|
|
7609
7727
|
});
|
|
7610
7728
|
}
|
|
7611
|
-
const
|
|
7729
|
+
const customClient = createWalletClient({
|
|
7730
|
+
account: walletClient.account,
|
|
7731
|
+
chain: walletClient.chain,
|
|
7732
|
+
transport: customTransport(),
|
|
7733
|
+
});
|
|
7734
|
+
const extendedClient = customClient.extend(erc7811Actions());
|
|
7612
7735
|
// Fetch default assets
|
|
7613
7736
|
const defaultAssetsPromise = extendedClient.getAssets({
|
|
7614
7737
|
chainIds: [chainId],
|
|
@@ -10343,7 +10466,8 @@ const Connected = () => {
|
|
|
10343
10466
|
const separator = ['web95', 'rounded', 'minimal'].includes((_c = (_b = themeContext.theme) !== null && _b !== void 0 ? _b : context.uiConfig.theme) !== null && _c !== void 0 ? _c : '')
|
|
10344
10467
|
? '....'
|
|
10345
10468
|
: undefined;
|
|
10346
|
-
|
|
10469
|
+
const locales = useLocales();
|
|
10470
|
+
return (jsxs(PageContent, { onBack: null, header: locales.profileScreen_heading, children: [jsx(ModalContent, { style: { paddingBottom: 6, gap: 6 }, children: address ? (jsxs(Fragment, { children: [jsx(AvatarContainer, { children: jsxs(AvatarInner, { children: [jsx(ChainSelectorContainer, { children: jsx(ChainSelector, {}) }), jsx(Avatar, { address: address })] }) }), jsx(ModalH1, { children: jsx(CopyText, { value: address, children: ensName !== null && ensName !== void 0 ? ensName : truncateEthAddress(address, separator) }) }), (context === null || context === void 0 ? void 0 : context.uiConfig.hideBalance) ? null : (jsxs(ModalBody, { children: [jsxs(BalanceContainer, { children: [!!assets && !isLoading && (jsx(TextLinkButton, { type: "button", onClick: () => {
|
|
10347
10471
|
const firstBalanceAsset = assets === null || assets === void 0 ? void 0 : assets.find((a) => a.balance && a.balance > BigInt(0));
|
|
10348
10472
|
if (!firstBalanceAsset) {
|
|
10349
10473
|
setRoute(routes.NO_ASSETS_AVAILABLE);
|
|
@@ -11272,81 +11396,6 @@ const Connectors = ({ logoutOnBack }) => {
|
|
|
11272
11396
|
return (jsx(PageContent, { logoutOnBack: logoutOnBack, width: 312, children: isMobile ? jsx(ConnectWithMobile$1, {}) : jsx(ConnectorList, {}) }));
|
|
11273
11397
|
};
|
|
11274
11398
|
|
|
11275
|
-
/**
|
|
11276
|
-
* Hook for accessing current user information and authentication state
|
|
11277
|
-
*
|
|
11278
|
-
* This hook provides access to the current authenticated user's information and
|
|
11279
|
-
* authentication status. It also offers methods to manage access tokens and validate
|
|
11280
|
-
* user sessions. The hook automatically updates when authentication state changes.
|
|
11281
|
-
*
|
|
11282
|
-
* @returns Current user state and authentication utilities
|
|
11283
|
-
*
|
|
11284
|
-
* @example
|
|
11285
|
-
* ```tsx
|
|
11286
|
-
* const userHook = useUser();
|
|
11287
|
-
*
|
|
11288
|
-
* // Check if user is authenticated
|
|
11289
|
-
* if (userHook.isAuthenticated && userHook.user) {
|
|
11290
|
-
* console.log('User is authenticated:', userHook.user);
|
|
11291
|
-
* console.log('User ID:', userHook.user.id);
|
|
11292
|
-
* console.log('User email:', userHook.user.email);
|
|
11293
|
-
* console.log('Linked accounts:', userHook.linkedAccounts);
|
|
11294
|
-
* } else {
|
|
11295
|
-
* console.log('User is not authenticated');
|
|
11296
|
-
* }
|
|
11297
|
-
*
|
|
11298
|
-
* // Get fresh access token
|
|
11299
|
-
* const getToken = async () => {
|
|
11300
|
-
* try {
|
|
11301
|
-
* const token = await userHook.getAccessToken();
|
|
11302
|
-
* console.log('Access token:', token);
|
|
11303
|
-
* } catch (error) {
|
|
11304
|
-
* console.error('Failed to get access token:', error);
|
|
11305
|
-
* }
|
|
11306
|
-
* };
|
|
11307
|
-
*
|
|
11308
|
-
* // Validate and refresh token if needed
|
|
11309
|
-
* const refreshToken = async () => {
|
|
11310
|
-
* try {
|
|
11311
|
-
* await userHook.validateAndRefreshToken();
|
|
11312
|
-
* console.log('Token validated and refreshed');
|
|
11313
|
-
* } catch (error) {
|
|
11314
|
-
* console.error('Token validation failed:', error);
|
|
11315
|
-
* }
|
|
11316
|
-
* };
|
|
11317
|
-
* ```
|
|
11318
|
-
*/
|
|
11319
|
-
function useUser() {
|
|
11320
|
-
const { user, client, embeddedState, linkedAccounts } = useOpenfortCore();
|
|
11321
|
-
const getAccessTokenAndUpdate = useCallback(async () => {
|
|
11322
|
-
try {
|
|
11323
|
-
await client.validateAndRefreshToken();
|
|
11324
|
-
const token = await client.getAccessToken();
|
|
11325
|
-
return token;
|
|
11326
|
-
}
|
|
11327
|
-
catch (error) {
|
|
11328
|
-
handleOAuthConfigError(error);
|
|
11329
|
-
throw error;
|
|
11330
|
-
}
|
|
11331
|
-
}, [client]);
|
|
11332
|
-
const validateAndRefresh = useCallback(async () => {
|
|
11333
|
-
try {
|
|
11334
|
-
await client.validateAndRefreshToken();
|
|
11335
|
-
}
|
|
11336
|
-
catch (error) {
|
|
11337
|
-
handleOAuthConfigError(error);
|
|
11338
|
-
throw error;
|
|
11339
|
-
}
|
|
11340
|
-
}, [client]);
|
|
11341
|
-
return {
|
|
11342
|
-
user,
|
|
11343
|
-
linkedAccounts,
|
|
11344
|
-
isAuthenticated: embeddedState !== EmbeddedState.NONE && embeddedState !== EmbeddedState.UNAUTHENTICATED,
|
|
11345
|
-
getAccessToken: getAccessTokenAndUpdate,
|
|
11346
|
-
validateAndRefreshToken: validateAndRefresh,
|
|
11347
|
-
};
|
|
11348
|
-
}
|
|
11349
|
-
|
|
11350
11399
|
// get accounts from the same address and chain type
|
|
11351
11400
|
const getSimpleAccounts = ({ address, embeddedAccounts, }) => {
|
|
11352
11401
|
return embeddedAccounts
|
|
@@ -11436,7 +11485,7 @@ const mapWalletStatus = (status) => {
|
|
|
11436
11485
|
*/
|
|
11437
11486
|
function useWallets(hookOptions = {}) {
|
|
11438
11487
|
const { client, embeddedAccounts, isLoadingAccounts: isLoadingWallets, updateEmbeddedAccounts } = useOpenfortCore();
|
|
11439
|
-
const { linkedAccounts } = useUser();
|
|
11488
|
+
const { linkedAccounts, user } = useUser();
|
|
11440
11489
|
const { walletConfig, setOpen, setRoute, setConnector, uiConfig } = useOpenfort();
|
|
11441
11490
|
const { connector, isConnected, address } = useAccount();
|
|
11442
11491
|
const chainId = useChainId();
|
|
@@ -11477,24 +11526,88 @@ function useWallets(hookOptions = {}) {
|
|
|
11477
11526
|
},
|
|
11478
11527
|
});
|
|
11479
11528
|
const openfortConnector = useMemo(() => { var _a; return (_a = availableWallets.find((c) => c.connector.id === embeddedWalletId)) === null || _a === void 0 ? void 0 : _a.connector; }, [availableWallets]);
|
|
11480
|
-
const getEncryptionSession = useCallback(async () => {
|
|
11481
|
-
if (!walletConfig
|
|
11482
|
-
throw new Error('No
|
|
11529
|
+
const getEncryptionSession = useCallback(async ({ accessToken, userId, otpCode }) => {
|
|
11530
|
+
if (!walletConfig) {
|
|
11531
|
+
throw new Error('No walletConfig found');
|
|
11532
|
+
}
|
|
11533
|
+
if (walletConfig.getEncryptionSession) {
|
|
11534
|
+
return await walletConfig.getEncryptionSession({ userId, otpCode: otpCode, accessToken });
|
|
11535
|
+
}
|
|
11536
|
+
if (!walletConfig.createEncryptedSessionEndpoint) {
|
|
11537
|
+
throw new Error('No requestWalletRecoverOTPEndpoint set in walletConfig');
|
|
11483
11538
|
}
|
|
11484
11539
|
const resp = await fetch(walletConfig.createEncryptedSessionEndpoint, {
|
|
11485
11540
|
method: 'POST',
|
|
11486
11541
|
headers: {
|
|
11487
11542
|
'Content-Type': 'application/json',
|
|
11488
11543
|
},
|
|
11544
|
+
body: JSON.stringify({ user_id: userId, otp_code: otpCode }),
|
|
11489
11545
|
});
|
|
11546
|
+
const respJSON = await resp.json();
|
|
11490
11547
|
if (!resp.ok) {
|
|
11548
|
+
if (respJSON.error === 'OTP_REQUIRED')
|
|
11549
|
+
throw new Error('OTP_REQUIRED');
|
|
11491
11550
|
throw new Error('Failed to create encryption session');
|
|
11492
11551
|
}
|
|
11493
|
-
const respJSON = await resp.json();
|
|
11494
11552
|
return respJSON.session;
|
|
11495
11553
|
}, [walletConfig]);
|
|
11554
|
+
const isWalletRecoveryOTPEnabled = useMemo(() => {
|
|
11555
|
+
return !!walletConfig && (!!walletConfig.requestWalletRecoverOTP || !!walletConfig.requestWalletRecoverOTPEndpoint);
|
|
11556
|
+
}, [walletConfig]);
|
|
11557
|
+
const requestWalletRecoverOTP = useCallback(async () => {
|
|
11558
|
+
try {
|
|
11559
|
+
logger.log('Requesting wallet recover OTP for user', { userId: user === null || user === void 0 ? void 0 : user.id });
|
|
11560
|
+
if (!walletConfig) {
|
|
11561
|
+
throw new Error('No walletConfig found');
|
|
11562
|
+
}
|
|
11563
|
+
const accessToken = await client.getAccessToken();
|
|
11564
|
+
if (!accessToken) {
|
|
11565
|
+
throw new OpenfortError('Openfort access token not found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
11566
|
+
}
|
|
11567
|
+
if (!(user === null || user === void 0 ? void 0 : user.id)) {
|
|
11568
|
+
throw new OpenfortError('User not found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
11569
|
+
}
|
|
11570
|
+
const userId = user.id;
|
|
11571
|
+
const email = user.email;
|
|
11572
|
+
const phone = user.email ? undefined : user.phoneNumber;
|
|
11573
|
+
if (!email && !phone) {
|
|
11574
|
+
throw new OpenfortError('No email or phone number found for user', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
11575
|
+
}
|
|
11576
|
+
logger.log('Requesting wallet recover OTP for user', { userId, email, phone });
|
|
11577
|
+
if (walletConfig.requestWalletRecoverOTP) {
|
|
11578
|
+
await walletConfig.requestWalletRecoverOTP({ userId, accessToken, email, phone });
|
|
11579
|
+
return { sentTo: email ? 'email' : 'phone', email, phone };
|
|
11580
|
+
}
|
|
11581
|
+
if (!walletConfig.requestWalletRecoverOTPEndpoint) {
|
|
11582
|
+
throw new Error('No requestWalletRecoverOTPEndpoint set in walletConfig');
|
|
11583
|
+
}
|
|
11584
|
+
const resp = await fetch(walletConfig.requestWalletRecoverOTPEndpoint, {
|
|
11585
|
+
method: 'POST',
|
|
11586
|
+
headers: {
|
|
11587
|
+
'Content-Type': 'application/json',
|
|
11588
|
+
},
|
|
11589
|
+
body: JSON.stringify({ user_id: userId, email, phone }),
|
|
11590
|
+
});
|
|
11591
|
+
if (!resp.ok) {
|
|
11592
|
+
throw new Error('Failed to request wallet recover OTP');
|
|
11593
|
+
}
|
|
11594
|
+
return { sentTo: email ? 'email' : 'phone', email, phone };
|
|
11595
|
+
}
|
|
11596
|
+
catch (err) {
|
|
11597
|
+
logger.log('Error requesting wallet recover OTP:', err);
|
|
11598
|
+
const error = new OpenfortError('Failed to request wallet recover OTP', OpenfortReactErrorType.WALLET_ERROR);
|
|
11599
|
+
return onError({
|
|
11600
|
+
error,
|
|
11601
|
+
hookOptions,
|
|
11602
|
+
});
|
|
11603
|
+
}
|
|
11604
|
+
}, [walletConfig]);
|
|
11496
11605
|
const parseWalletRecovery = useMemo(() => async function parseWalletRecovery(recovery, embeddedAccounts, walletAddress) {
|
|
11497
11606
|
var _a, _b;
|
|
11607
|
+
const user = await client.user.get();
|
|
11608
|
+
if (!(user === null || user === void 0 ? void 0 : user.id)) {
|
|
11609
|
+
throw new OpenfortError('User not found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
11610
|
+
}
|
|
11498
11611
|
switch (recovery === null || recovery === void 0 ? void 0 : recovery.recoveryMethod) {
|
|
11499
11612
|
case undefined:
|
|
11500
11613
|
case RecoveryMethod.AUTOMATIC: {
|
|
@@ -11504,9 +11617,11 @@ function useWallets(hookOptions = {}) {
|
|
|
11504
11617
|
}
|
|
11505
11618
|
return {
|
|
11506
11619
|
recoveryMethod: RecoveryMethod.AUTOMATIC,
|
|
11507
|
-
encryptionSession:
|
|
11508
|
-
|
|
11509
|
-
:
|
|
11620
|
+
encryptionSession: await getEncryptionSession({
|
|
11621
|
+
accessToken,
|
|
11622
|
+
otpCode: recovery === null || recovery === void 0 ? void 0 : recovery.otpCode,
|
|
11623
|
+
userId: user.id,
|
|
11624
|
+
}),
|
|
11510
11625
|
};
|
|
11511
11626
|
}
|
|
11512
11627
|
case RecoveryMethod.PASSWORD:
|
|
@@ -11544,7 +11659,7 @@ function useWallets(hookOptions = {}) {
|
|
|
11544
11659
|
default:
|
|
11545
11660
|
throw new OpenfortError('Invalid recovery method', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
11546
11661
|
}
|
|
11547
|
-
}, [walletConfig, getEncryptionSession]);
|
|
11662
|
+
}, [walletConfig, getEncryptionSession, user === null || user === void 0 ? void 0 : user.id]);
|
|
11548
11663
|
const userLinkedWalletConnectors = useMemo(() => {
|
|
11549
11664
|
const userWallets = linkedAccounts
|
|
11550
11665
|
? linkedAccounts
|
|
@@ -11604,7 +11719,7 @@ function useWallets(hookOptions = {}) {
|
|
|
11604
11719
|
connect({ connector: connectToConnector.connector });
|
|
11605
11720
|
}, [connectToConnector]);
|
|
11606
11721
|
const setActiveWallet = useCallback(async (options) => {
|
|
11607
|
-
var _a, _b, _c, _d, _e, _f;
|
|
11722
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
11608
11723
|
const optionsObject = typeof options === 'string' ? { walletId: options } : options;
|
|
11609
11724
|
const { showUI } = optionsObject;
|
|
11610
11725
|
let connector = null;
|
|
@@ -11715,6 +11830,7 @@ function useWallets(hookOptions = {}) {
|
|
|
11715
11830
|
const recovery = {
|
|
11716
11831
|
recoveryMethod: (_c = accountToRecover.recoveryMethod) !== null && _c !== void 0 ? _c : RecoveryMethod.AUTOMATIC,
|
|
11717
11832
|
password: (_d = optionsObject.recovery) === null || _d === void 0 ? void 0 : _d.password,
|
|
11833
|
+
otpCode: (_e = optionsObject.recovery) === null || _e === void 0 ? void 0 : _e.otpCode,
|
|
11718
11834
|
};
|
|
11719
11835
|
const recoveryParams = await parseWalletRecovery(recovery, embeddedAccounts, walletAddress);
|
|
11720
11836
|
embeddedAccount = await client.embeddedWallet.recover({
|
|
@@ -11741,8 +11857,9 @@ function useWallets(hookOptions = {}) {
|
|
|
11741
11857
|
}
|
|
11742
11858
|
logger.log('Found embedded wallet to recover (without walletAddress)', accountToRecover);
|
|
11743
11859
|
const recovery = {
|
|
11744
|
-
recoveryMethod: (
|
|
11745
|
-
password: (
|
|
11860
|
+
recoveryMethod: (_f = accountToRecover.recoveryMethod) !== null && _f !== void 0 ? _f : RecoveryMethod.AUTOMATIC,
|
|
11861
|
+
password: (_g = optionsObject.recovery) === null || _g === void 0 ? void 0 : _g.password,
|
|
11862
|
+
otpCode: (_h = optionsObject.recovery) === null || _h === void 0 ? void 0 : _h.otpCode,
|
|
11746
11863
|
};
|
|
11747
11864
|
const recoveryParams = await parseWalletRecovery(recovery, embeddedAccounts, walletAddress);
|
|
11748
11865
|
embeddedAccount = await client.embeddedWallet.recover({
|
|
@@ -11793,15 +11910,29 @@ function useWallets(hookOptions = {}) {
|
|
|
11793
11910
|
}
|
|
11794
11911
|
}
|
|
11795
11912
|
logger.log('Error handling recovery with Openfort:', error, err);
|
|
11913
|
+
let isOTPRequired = false;
|
|
11914
|
+
if (error.message === 'OTP_REQUIRED') {
|
|
11915
|
+
if (!isWalletRecoveryOTPEnabled) {
|
|
11916
|
+
error = new OpenfortError('OTP code is required to recover the wallet.\nPlease set requestWalletRecoverOTP or requestWalletRecoverOTPEndpoint in OpenfortProvider.', OpenfortReactErrorType.WALLET_ERROR);
|
|
11917
|
+
}
|
|
11918
|
+
else {
|
|
11919
|
+
error = new OpenfortError('OTP code is required to recover the wallet.', OpenfortReactErrorType.WALLET_ERROR);
|
|
11920
|
+
}
|
|
11921
|
+
isOTPRequired = true;
|
|
11922
|
+
}
|
|
11796
11923
|
setStatus({
|
|
11797
11924
|
status: 'error',
|
|
11798
11925
|
error,
|
|
11799
11926
|
});
|
|
11800
|
-
|
|
11927
|
+
onError({
|
|
11801
11928
|
error,
|
|
11802
11929
|
options: optionsObject,
|
|
11803
11930
|
hookOptions,
|
|
11804
11931
|
});
|
|
11932
|
+
return {
|
|
11933
|
+
error,
|
|
11934
|
+
isOTPRequired,
|
|
11935
|
+
};
|
|
11805
11936
|
}
|
|
11806
11937
|
finally {
|
|
11807
11938
|
if (hasToSwitchChain) {
|
|
@@ -11878,18 +12009,29 @@ function useWallets(hookOptions = {}) {
|
|
|
11878
12009
|
}
|
|
11879
12010
|
catch (e) {
|
|
11880
12011
|
const errorObj = e instanceof Error ? e : new Error('Failed to create wallet');
|
|
11881
|
-
|
|
12012
|
+
let error = e instanceof OpenfortError
|
|
11882
12013
|
? e
|
|
11883
12014
|
: new OpenfortError('Failed to create wallet', OpenfortReactErrorType.WALLET_ERROR, { error: errorObj });
|
|
12015
|
+
let isOTPRequired = false;
|
|
12016
|
+
if (error.message === 'OTP_REQUIRED') {
|
|
12017
|
+
if (!isWalletRecoveryOTPEnabled) {
|
|
12018
|
+
error = new OpenfortError('OTP code is required to recover the wallet.\nPlease set requestWalletRecoverOTP or requestWalletRecoverOTPEndpoint in OpenfortProvider.', OpenfortReactErrorType.WALLET_ERROR);
|
|
12019
|
+
}
|
|
12020
|
+
else {
|
|
12021
|
+
error = new OpenfortError('OTP code is required to recover the wallet.', OpenfortReactErrorType.WALLET_ERROR);
|
|
12022
|
+
}
|
|
12023
|
+
isOTPRequired = true;
|
|
12024
|
+
}
|
|
11884
12025
|
setStatus({
|
|
11885
12026
|
status: 'error',
|
|
11886
12027
|
error,
|
|
11887
12028
|
});
|
|
11888
|
-
|
|
12029
|
+
onError({
|
|
11889
12030
|
error,
|
|
11890
12031
|
hookOptions,
|
|
11891
12032
|
options,
|
|
11892
12033
|
});
|
|
12034
|
+
return { error, isOTPRequired };
|
|
11893
12035
|
}
|
|
11894
12036
|
}, [client, uiConfig, chainId]);
|
|
11895
12037
|
const setRecovery = useCallback(async (params) => {
|
|
@@ -11938,6 +12080,8 @@ function useWallets(hookOptions = {}) {
|
|
|
11938
12080
|
reset: () => setStatus({ status: 'idle' }),
|
|
11939
12081
|
createWallet,
|
|
11940
12082
|
setActiveWallet,
|
|
12083
|
+
requestWalletRecoverOTP,
|
|
12084
|
+
isWalletRecoveryOTPEnabled,
|
|
11941
12085
|
...mapWalletStatus(status),
|
|
11942
12086
|
exportPrivateKey: () => client.embeddedWallet.exportPrivateKey(),
|
|
11943
12087
|
};
|
|
@@ -12192,1381 +12336,1462 @@ const Input = ({ ...props }) => {
|
|
|
12192
12336
|
return (jsx(InputContainer, { children: jsx(Input$1, { ...props }) }));
|
|
12193
12337
|
};
|
|
12194
12338
|
|
|
12195
|
-
const
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
gap: 8px;
|
|
12199
|
-
padding-top: 8px;
|
|
12200
|
-
padding-bottom: 8px;
|
|
12201
|
-
`;
|
|
12202
|
-
const TickItem = styled.li `
|
|
12203
|
-
display: flex;
|
|
12204
|
-
align-items: center;
|
|
12205
|
-
text-align: left;
|
|
12206
|
-
gap: 8px;
|
|
12207
|
-
font-size: 16px;
|
|
12208
|
-
line-height: 24px;
|
|
12339
|
+
const caretBlink = keyframes `
|
|
12340
|
+
0%, 70%, 100% { opacity: 1; }
|
|
12341
|
+
20%, 50% { opacity: 0; }
|
|
12209
12342
|
`;
|
|
12210
|
-
const
|
|
12343
|
+
const OtpContainer = styled.div `
|
|
12211
12344
|
display: flex;
|
|
12212
12345
|
align-items: center;
|
|
12213
12346
|
justify-content: center;
|
|
12214
|
-
|
|
12215
|
-
height: 16px;
|
|
12216
|
-
flex-shrink: 0;
|
|
12217
|
-
`;
|
|
12347
|
+
scale: ${({ scale }) => scale || '1'};
|
|
12218
12348
|
|
|
12219
|
-
|
|
12220
|
-
return (jsx(TickListContainer, { children: items.map((item) => (jsxs(TickItem, { children: [jsx(TickIconWrapper, { children: jsx(TickIcon, {}) }), jsx("span", { children: item })] }, item))) }));
|
|
12221
|
-
};
|
|
12222
|
-
TickList.displayName = 'TickList';
|
|
12223
|
-
|
|
12224
|
-
var wave = (jsxs("svg", { "aria-hidden": "true", width: "298", height: "188", viewBox: "0 0 298 188", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("path", { d: "M1 55.2757L21.6438 46.0285C55.5896 30.8228 94.4104 30.8228 128.356 46.0286L169.644 64.5229C203.59 79.7287 242.41 79.7286 276.356 64.5229L297 55.2757M1 44.2118L21.6438 34.9646C55.5896 19.7589 94.4104 19.7589 128.356 34.9646L169.644 53.459C203.59 68.6647 242.41 68.6647 276.356 53.459L297 44.2118M1 33.1477L21.6438 23.9005C55.5896 8.69479 94.4104 8.69479 128.356 23.9005L169.644 42.3949C203.59 57.6006 242.41 57.6006 276.356 42.3949L297 33.1477M1 22.1477L21.6438 12.9005C55.5896 -2.30521 94.4104 -2.30521 128.356 12.9005L169.644 31.3949C203.59 46.6006 242.41 46.6006 276.356 31.3949L297 22.1477M1 66.3398L21.6438 57.0926C55.5896 41.8869 94.4104 41.8869 128.356 57.0926L169.644 75.587C203.59 90.7927 242.41 90.7927 276.356 75.587L297 66.3398M1 77.404L21.6438 68.1568C55.5896 52.9511 94.4104 52.9511 128.356 68.1569L169.644 86.6512C203.59 101.857 242.41 101.857 276.356 86.6512L297 77.404M1 88.4681L21.6438 79.2209C55.5896 64.0152 94.4104 64.0152 128.356 79.2209L169.644 97.7153C203.59 112.921 242.41 112.921 276.356 97.7153L297 88.4681M1 121.66L21.6438 112.413C55.5896 97.2075 94.4104 97.2075 128.356 112.413L169.644 130.908C203.59 146.113 242.41 146.113 276.356 130.908L297 121.66M1 110.596L21.6438 101.349C55.5896 86.1433 94.4104 86.1433 128.356 101.349L169.644 119.843C203.59 135.049 242.41 135.049 276.356 119.843L297 110.596M1 99.5321L21.6438 90.2849C55.5896 75.0792 94.4104 75.0792 128.356 90.2849L169.644 108.779C203.59 123.985 242.41 123.985 276.356 108.779L297 99.5321M1 132.724L21.6438 123.477C55.5896 108.271 94.4104 108.271 128.356 123.477L169.644 141.971C203.59 157.177 242.41 157.177 276.356 141.971L297 132.724M1 143.788L21.6438 134.541C55.5896 119.336 94.4104 119.336 128.356 134.541L169.644 153.036C203.59 168.241 242.41 168.241 276.356 153.036L297 143.788M1 154.853L21.6438 145.605C55.5896 130.4 94.4104 130.4 128.356 145.605L169.644 164.1C203.59 179.305 242.41 179.305 276.356 164.1L297 154.853M1 165.853L21.6438 156.605C55.5896 141.4 94.4104 141.4 128.356 156.605L169.644 175.1C203.59 190.305 242.41 190.305 276.356 175.1L297 165.853", stroke: "url(#paint0_linear_1094_2077)", strokeOpacity: "0.9", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("defs", { children: jsxs("linearGradient", { id: "paint0_linear_1094_2077", x1: "1", y1: "112.587", x2: "297.034", y2: "79.6111", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-01)" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-02)", offset: "0.239583" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-03)", offset: "0.515625" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-04)", offset: "0.739583" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-05)", offset: "1" })] }) })] }));
|
|
12225
|
-
|
|
12226
|
-
const Graphic = styled(motion.div) `
|
|
12227
|
-
position: relative;
|
|
12228
|
-
margin-top: ${({ $marginTop }) => $marginTop !== null && $marginTop !== void 0 ? $marginTop : '16px'};
|
|
12229
|
-
margin-bottom: ${({ $marginBottom }) => $marginBottom !== null && $marginBottom !== void 0 ? $marginBottom : '20px'};
|
|
12230
|
-
margin-left: auto;
|
|
12231
|
-
margin-right: auto;
|
|
12232
|
-
height: ${({ $height }) => $height !== null && $height !== void 0 ? $height : '190px'};
|
|
12233
|
-
max-width: 295px;
|
|
12234
|
-
pointer-events: none;
|
|
12235
|
-
user-select: none;
|
|
12236
|
-
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
|
|
12237
|
-
height: 200px;
|
|
12238
|
-
max-width: 100%;
|
|
12239
|
-
margin-bottom: 32px;
|
|
12240
|
-
}
|
|
12349
|
+
--border: ${({ showBorder }) => (showBorder ? 'var(--ck-body-color-muted)' : 'transparent')};
|
|
12241
12350
|
`;
|
|
12242
|
-
const
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
z-index: 2;
|
|
12246
|
-
`;
|
|
12247
|
-
const graphicIn = keyframes `
|
|
12248
|
-
0%{
|
|
12249
|
-
opacity:0;
|
|
12250
|
-
transform:scale(0.9);
|
|
12251
|
-
}
|
|
12252
|
-
100%{
|
|
12253
|
-
opacity:1;
|
|
12254
|
-
transform:none;
|
|
12255
|
-
}
|
|
12256
|
-
`;
|
|
12257
|
-
const GraphicBackground = styled(motion.div) `
|
|
12258
|
-
z-index: 1;
|
|
12259
|
-
position: absolute;
|
|
12260
|
-
inset: 0;
|
|
12261
|
-
top: -2px;
|
|
12262
|
-
overflow: hidden;
|
|
12263
|
-
&:before {
|
|
12264
|
-
content: '';
|
|
12265
|
-
position: absolute;
|
|
12266
|
-
inset: 0;
|
|
12267
|
-
background: var(--ck-body-background);
|
|
12268
|
-
background: radial-gradient(
|
|
12269
|
-
closest-side,
|
|
12270
|
-
var(--ck-body-background-transparent, transparent) 18.75%,
|
|
12271
|
-
var(--ck-body-background) 100%
|
|
12272
|
-
);
|
|
12273
|
-
background-size: 100%;
|
|
12274
|
-
}
|
|
12275
|
-
svg {
|
|
12276
|
-
display: block;
|
|
12277
|
-
width: 100%;
|
|
12278
|
-
height: auto;
|
|
12279
|
-
}
|
|
12280
|
-
animation: ${graphicIn} 1000ms 100ms ease both;
|
|
12281
|
-
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
|
|
12282
|
-
animation: none;
|
|
12351
|
+
const pulse = keyframes `
|
|
12352
|
+
0% {
|
|
12353
|
+
opacity: 100%;
|
|
12283
12354
|
}
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
0%{
|
|
12287
|
-
opacity:0;
|
|
12288
|
-
transform:scale(0) translateY(40%);
|
|
12355
|
+
50% {
|
|
12356
|
+
opacity: 40%;
|
|
12289
12357
|
}
|
|
12290
|
-
100%{
|
|
12291
|
-
opacity:
|
|
12292
|
-
transform:none;
|
|
12358
|
+
100% {
|
|
12359
|
+
opacity: 100%;
|
|
12293
12360
|
}
|
|
12294
12361
|
`;
|
|
12295
|
-
const
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12362
|
+
const dist = 2;
|
|
12363
|
+
const shakeKeyframes = keyframes `
|
|
12364
|
+
0%{ transform:none; }
|
|
12365
|
+
25%{ transform:translateX(${dist}px); }
|
|
12366
|
+
50%{ transform:translateX(-${dist}px); }
|
|
12367
|
+
75%{ transform:translateX(${dist}px); }
|
|
12368
|
+
100%{ transform:none; }
|
|
12300
12369
|
`;
|
|
12301
|
-
const
|
|
12302
|
-
|
|
12370
|
+
const keyframeSuccess = keyframes `
|
|
12371
|
+
0% { transform: scale(1); }
|
|
12372
|
+
50% { transform: scale(1.1); }
|
|
12373
|
+
100% { transform: scale(1); }
|
|
12303
12374
|
`;
|
|
12304
|
-
const
|
|
12305
|
-
|
|
12306
|
-
overflow: hidden;
|
|
12307
|
-
height: 58px;
|
|
12308
|
-
width: 58px;
|
|
12309
|
-
border-radius: 13.84px;
|
|
12310
|
-
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 20px 0 rgba(0, 0, 0, 0.03);
|
|
12375
|
+
const OTPGroup = styled.div `
|
|
12376
|
+
display: flex;
|
|
12311
12377
|
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12378
|
+
outline-width: 3px;
|
|
12379
|
+
outline-style: solid;
|
|
12380
|
+
border-radius: 0.375rem;
|
|
12381
|
+
transition: outline-color 0.3s, border-radius .5s;
|
|
12382
|
+
|
|
12383
|
+
outline-color: ${({ isError, isSuccess }) => {
|
|
12384
|
+
if (isError)
|
|
12385
|
+
return 'var(--ck-body-color-danger)';
|
|
12386
|
+
if (isSuccess)
|
|
12387
|
+
return 'var(--ck-body-color-valid)';
|
|
12388
|
+
return 'transparent';
|
|
12389
|
+
}};
|
|
12390
|
+
|
|
12391
|
+
${({ isLoading }) => isLoading &&
|
|
12392
|
+
css `
|
|
12393
|
+
animation: ${pulse} 1s ease-in-out infinite;
|
|
12394
|
+
`}
|
|
12395
|
+
|
|
12396
|
+
${({ isError }) => isError &&
|
|
12397
|
+
css `
|
|
12398
|
+
animation: ${shakeKeyframes} 220ms ease-out both;
|
|
12399
|
+
`}
|
|
12400
|
+
|
|
12401
|
+
${({ isSuccess }) => isSuccess &&
|
|
12402
|
+
css `
|
|
12403
|
+
border-radius: 3rem;
|
|
12404
|
+
min-width: 3.5rem;
|
|
12405
|
+
${OTPSlotWrapper} {
|
|
12406
|
+
width: 0;
|
|
12407
|
+
border: 0;
|
|
12408
|
+
transition: width .5s, border .5s;
|
|
12409
|
+
}
|
|
12410
|
+
animation: ${keyframeSuccess} 220ms ease-out both;
|
|
12411
|
+
animation-delay: 250ms;
|
|
12412
|
+
`}
|
|
12331
12413
|
`;
|
|
12332
|
-
const
|
|
12414
|
+
const OTPSlotWrapper = styled.div `
|
|
12333
12415
|
position: relative;
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
`;
|
|
12338
|
-
const Logo$1 = styled(motion.div) `
|
|
12339
|
-
position: absolute;
|
|
12340
|
-
inset: 0;
|
|
12416
|
+
width: 2.5rem;
|
|
12417
|
+
height: 3.5rem;
|
|
12418
|
+
font-size: 2rem;
|
|
12341
12419
|
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
&:nth-child(3){ z-index:1; animation-delay:30ms; }
|
|
12346
|
-
&:nth-child(4){ z-index:1; animation-delay:90ms; }
|
|
12347
|
-
&:nth-child(5){ z-index:1; animation-delay:120ms;}
|
|
12420
|
+
display: flex;
|
|
12421
|
+
align-items: center;
|
|
12422
|
+
justify-content: center;
|
|
12348
12423
|
|
|
12349
|
-
|
|
12350
|
-
&:nth-child(2){ ${RotateWrapper}{ animation-delay:-600ms; } }
|
|
12351
|
-
&:nth-child(3){ ${RotateWrapper}{ animation-delay:-1200ms; } }
|
|
12352
|
-
&:nth-child(4){ ${RotateWrapper}{ animation-delay:-1800ms; } }
|
|
12353
|
-
&:nth-child(5){ ${RotateWrapper}{ animation-delay:-2400ms; } }
|
|
12424
|
+
transition: all 0.3s;
|
|
12354
12425
|
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
&:nth-child(5){ ${FloatWrapper}{ animation-delay:-3200ms; } }
|
|
12426
|
+
border-top: 1px solid var(--border);
|
|
12427
|
+
border-bottom: 1px solid var(--border);
|
|
12428
|
+
border-right: 0.5px solid var(--border);
|
|
12429
|
+
border-left: 0.5px solid var(--border);
|
|
12360
12430
|
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
animation: none !important;
|
|
12365
|
-
}
|
|
12431
|
+
&:first-child {
|
|
12432
|
+
border-left: 1px solid var(--border);
|
|
12433
|
+
border-radius: 0.375rem 0 0 0.375rem;
|
|
12366
12434
|
}
|
|
12367
12435
|
|
|
12368
|
-
|
|
12369
|
-
|
|
12436
|
+
&:last-child {
|
|
12437
|
+
border-radius: 0 0.375rem 0.375rem 0;
|
|
12370
12438
|
}
|
|
12371
12439
|
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
&:nth-child(5) ${LogoPosition} {
|
|
12390
|
-
transform: translate(76%, 80%);
|
|
12391
|
-
}
|
|
12440
|
+
outline: ${({ isActive }) => (isActive ? '2px solid var(--ck-connectbutton-color)' : '0')};
|
|
12441
|
+
z-index: ${({ isActive }) => (isActive ? 1 : 0)};
|
|
12442
|
+
outline-offset: 0;
|
|
12443
|
+
|
|
12444
|
+
cursor: text;
|
|
12445
|
+
color: var(--ck-body-color);
|
|
12446
|
+
`;
|
|
12447
|
+
const OTPNumberValue = styled.div `
|
|
12448
|
+
opacity: ${({ $hide }) => ($hide ? 0 : 1)};
|
|
12449
|
+
transition: opacity 0.3s;
|
|
12450
|
+
`;
|
|
12451
|
+
const OTPHiddenInput = styled.input `
|
|
12452
|
+
position: absolute;
|
|
12453
|
+
inset: 0;
|
|
12454
|
+
opacity: 0;
|
|
12455
|
+
cursor: text;
|
|
12456
|
+
caret-color: transparent; /* Hide native caret */
|
|
12392
12457
|
`;
|
|
12458
|
+
const FakeCaretWrapper = styled.div `
|
|
12459
|
+
position: absolute;
|
|
12460
|
+
inset: 0;
|
|
12461
|
+
pointer-events: none;
|
|
12393
12462
|
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
const FloatingGraphic = ({ height = '130px', marginBottom, marginTop, logoCenter, logoTopRight, logoTopLeft, logoBottomRight, logoBottomLeft, }) => {
|
|
12398
|
-
return (jsxs(Graphic, { "$height": height, "$marginBottom": marginBottom, "$marginTop": marginTop, children: [jsxs(LogoGroup, { children: [jsx(LogoGraphic, { ...logoCenter }), logoTopLeft ? jsx(LogoGraphic, { ...logoTopLeft }) : jsx("div", {}), logoTopRight ? jsx(LogoGraphic, { ...logoTopRight }) : jsx("div", {}), logoBottomLeft ? jsx(LogoGraphic, { ...logoBottomLeft }) : jsx("div", {}), logoBottomRight ? jsx(LogoGraphic, { ...logoBottomRight }) : jsx("div", {})] }), jsx(GraphicBackground, { children: wave })] }));
|
|
12399
|
-
};
|
|
12463
|
+
display: flex;
|
|
12464
|
+
align-items: center;
|
|
12465
|
+
justify-content: center;
|
|
12400
12466
|
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
const
|
|
12413
|
-
|
|
12414
|
-
|
|
12415
|
-
|
|
12416
|
-
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12421
|
-
|
|
12422
|
-
|
|
12423
|
-
*/
|
|
12424
|
-
const SPECIAL_CHARACTERS = '!@#$%^&()\\-*+.';
|
|
12425
|
-
/**
|
|
12426
|
-
* Escape regex metacharacters for safe use inside a character class.
|
|
12427
|
-
*/
|
|
12428
|
-
function escapeForCharClass(str) {
|
|
12429
|
-
return str.replace(/[-\\^]/g, '\\$&');
|
|
12430
|
-
// escapes -, \, and ^ (the only risky chars in [])
|
|
12431
|
-
}
|
|
12432
|
-
/**
|
|
12433
|
-
* Regular expression to match special characters.
|
|
12434
|
-
*/
|
|
12435
|
-
const SPECIAL_CHARACTER_REGEX = new RegExp(`[${escapeForCharClass(SPECIAL_CHARACTERS)}]`);
|
|
12436
|
-
/**
|
|
12437
|
-
* Maximum entropy score for normalization.
|
|
12438
|
-
*/
|
|
12439
|
-
const MAX_ENTROPY_SCORE = 95;
|
|
12440
|
-
/**
|
|
12441
|
-
* Minimum password length for security.
|
|
12442
|
-
*/
|
|
12443
|
-
const MIN_PASSWORD_LENGTH = 8;
|
|
12444
|
-
/**
|
|
12445
|
-
* Weight for diversity score in overall strength calculation.
|
|
12446
|
-
*/
|
|
12447
|
-
const DIVERSITY_WEIGHT = 0.3;
|
|
12448
|
-
const ENTROPY_WEIGHT = 0.7;
|
|
12449
|
-
const MEDIUM_SCORE_THRESHOLD = 0.5;
|
|
12450
|
-
const STRONG_SCORE_THRESHOLD = 0.75;
|
|
12451
|
-
const VERY_STRONG_SCORE_THRESHOLD = 0.9;
|
|
12452
|
-
/**
|
|
12453
|
-
* Converts a numeric password strength score to a human-readable label.
|
|
12454
|
-
*
|
|
12455
|
-
* @param score - The strength score (0-1).
|
|
12456
|
-
* @returns The corresponding strength label.
|
|
12457
|
-
*
|
|
12458
|
-
* @example
|
|
12459
|
-
* ```ts
|
|
12460
|
-
* const label = getPasswordStrengthLabel(0.8);
|
|
12461
|
-
* // label === 'Strong'
|
|
12462
|
-
* ```
|
|
12463
|
-
*/
|
|
12464
|
-
function getPasswordStrengthLabel(score) {
|
|
12465
|
-
if (score > VERY_STRONG_SCORE_THRESHOLD) {
|
|
12466
|
-
return 'Very Strong';
|
|
12467
|
-
}
|
|
12468
|
-
else if (score > STRONG_SCORE_THRESHOLD) {
|
|
12469
|
-
return 'Strong';
|
|
12470
|
-
}
|
|
12471
|
-
else if (score > MEDIUM_SCORE_THRESHOLD) {
|
|
12472
|
-
return 'Medium';
|
|
12473
|
-
}
|
|
12474
|
-
else {
|
|
12475
|
-
return 'Weak';
|
|
12476
|
-
}
|
|
12477
|
-
}
|
|
12478
|
-
/**
|
|
12479
|
-
* Calculates the diversity score of a password based on character types used.
|
|
12480
|
-
*
|
|
12481
|
-
* Considers lowercase, uppercase, digits, and special characters.
|
|
12482
|
-
*
|
|
12483
|
-
* @param password - The password to analyse.
|
|
12484
|
-
* @returns A score between 0 and 1 representing character diversity.
|
|
12485
|
-
*
|
|
12486
|
-
* @example
|
|
12487
|
-
* ```ts
|
|
12488
|
-
* const diversity = calculatePasswordDiversityScore('Password123!');
|
|
12489
|
-
* ```
|
|
12490
|
-
*/
|
|
12491
|
-
function calculatePasswordDiversityScore(password) {
|
|
12492
|
-
// Passwords shorter than minimum length get a score of 0
|
|
12493
|
-
if (password.length < MIN_PASSWORD_LENGTH) {
|
|
12494
|
-
return 0;
|
|
12495
|
-
}
|
|
12496
|
-
let characterTypesUsed = 0;
|
|
12497
|
-
if (LOWERCASE_REGEX.test(password)) {
|
|
12498
|
-
characterTypesUsed += 1;
|
|
12499
|
-
}
|
|
12500
|
-
if (UPPERCASE_REGEX.test(password)) {
|
|
12501
|
-
characterTypesUsed += 1;
|
|
12502
|
-
}
|
|
12503
|
-
if (DIGIT_REGEX.test(password)) {
|
|
12504
|
-
characterTypesUsed += 1;
|
|
12505
|
-
}
|
|
12506
|
-
if (SPECIAL_CHARACTER_REGEX.test(password)) {
|
|
12507
|
-
characterTypesUsed += 1;
|
|
12508
|
-
}
|
|
12509
|
-
return Math.max(0, Math.min(1, characterTypesUsed / 4));
|
|
12467
|
+
animation: ${caretBlink} 1.2s ease-out infinite;
|
|
12468
|
+
`;
|
|
12469
|
+
const CaretBar = styled.div `
|
|
12470
|
+
width: 1px;
|
|
12471
|
+
height: 2rem;
|
|
12472
|
+
background: var(--ck-body-color);
|
|
12473
|
+
`;
|
|
12474
|
+
const keyframeWrapper = keyframes `
|
|
12475
|
+
0% { transform: scale(0); }
|
|
12476
|
+
100% { transform: scale(1); }
|
|
12477
|
+
`;
|
|
12478
|
+
const SuccessTickWrapper = styled.div `
|
|
12479
|
+
position: absolute;
|
|
12480
|
+
inset: 5px;
|
|
12481
|
+
display: flex;
|
|
12482
|
+
animation: ${keyframeWrapper} 200ms ease-out both;
|
|
12483
|
+
animation-delay: 200ms;
|
|
12484
|
+
color: var(--ck-body-color-valid);
|
|
12485
|
+
`;
|
|
12486
|
+
|
|
12487
|
+
function FakeCaret() {
|
|
12488
|
+
return (jsx(FakeCaretWrapper, { children: jsx(CaretBar, {}) }));
|
|
12510
12489
|
}
|
|
12511
|
-
|
|
12512
|
-
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12490
|
+
function OtpInputStandalone({ length = 6, onChange, onComplete, isLoading, isError, isSuccess, scale, }) {
|
|
12491
|
+
const [values, setValues] = useState(Array(length).fill(''));
|
|
12492
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
12493
|
+
const canEdit = !isLoading && !isError && !isSuccess;
|
|
12494
|
+
const inputsRef = useRef([]);
|
|
12495
|
+
const handleInput = (index, char) => {
|
|
12496
|
+
var _a;
|
|
12497
|
+
if (!char.match(/^[0-9]$/))
|
|
12498
|
+
return;
|
|
12499
|
+
if (!canEdit)
|
|
12500
|
+
return;
|
|
12501
|
+
const newValues = [...values];
|
|
12502
|
+
newValues[index] = char;
|
|
12503
|
+
setValues(newValues);
|
|
12504
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
|
|
12505
|
+
// Move cursor to next box
|
|
12506
|
+
if (index < length - 1) {
|
|
12507
|
+
setActiveIndex(index + 1);
|
|
12508
|
+
(_a = inputsRef.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12509
|
+
}
|
|
12510
|
+
};
|
|
12511
|
+
useEffect(() => {
|
|
12512
|
+
if (values.every((v) => v !== '')) {
|
|
12513
|
+
onComplete === null || onComplete === void 0 ? void 0 : onComplete(values.join(''));
|
|
12514
|
+
}
|
|
12515
|
+
}, [values]);
|
|
12516
|
+
const handleBackspace = (index) => {
|
|
12517
|
+
var _a;
|
|
12518
|
+
const newValues = [...values];
|
|
12519
|
+
if (newValues[index] === '') {
|
|
12520
|
+
if (index > 0) {
|
|
12521
|
+
// Move back
|
|
12522
|
+
setActiveIndex(index - 1);
|
|
12523
|
+
(_a = inputsRef.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12524
|
+
}
|
|
12525
|
+
newValues[index - 1] = '';
|
|
12526
|
+
}
|
|
12527
|
+
else {
|
|
12528
|
+
newValues[index] = '';
|
|
12529
|
+
}
|
|
12530
|
+
setValues(newValues);
|
|
12531
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
|
|
12532
|
+
};
|
|
12533
|
+
const handlePaste = (e) => {
|
|
12534
|
+
var _a;
|
|
12535
|
+
const pasted = e.clipboardData.getData('text').replace(/\D/g, '');
|
|
12536
|
+
if (!pasted)
|
|
12537
|
+
return;
|
|
12538
|
+
const arr = pasted.substring(0, length).split('');
|
|
12539
|
+
const newValues = [...values];
|
|
12540
|
+
arr.forEach((char, i) => {
|
|
12541
|
+
newValues[i] = char;
|
|
12542
|
+
});
|
|
12543
|
+
setValues(newValues);
|
|
12544
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
|
|
12545
|
+
const finalIndex = Math.min(arr.length - 1, length - 1);
|
|
12546
|
+
setActiveIndex(finalIndex);
|
|
12547
|
+
(_a = inputsRef.current[finalIndex]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12548
|
+
};
|
|
12549
|
+
const handleFocus = (i) => {
|
|
12550
|
+
var _a, _b;
|
|
12551
|
+
if (activeIndex !== -1) {
|
|
12552
|
+
setActiveIndex(i);
|
|
12553
|
+
return;
|
|
12554
|
+
}
|
|
12555
|
+
const firstEmptyIndex = values.indexOf('');
|
|
12556
|
+
if (firstEmptyIndex !== -1) {
|
|
12557
|
+
setActiveIndex(firstEmptyIndex);
|
|
12558
|
+
(_a = inputsRef.current[firstEmptyIndex]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12559
|
+
}
|
|
12560
|
+
else {
|
|
12561
|
+
setActiveIndex(length - 1);
|
|
12562
|
+
(_b = inputsRef.current[length - 1]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
12563
|
+
}
|
|
12564
|
+
};
|
|
12565
|
+
useEffect(() => {
|
|
12566
|
+
var _a;
|
|
12567
|
+
if (!isError) {
|
|
12568
|
+
setValues(Array(length).fill(''));
|
|
12569
|
+
setActiveIndex(0);
|
|
12570
|
+
(_a = inputsRef.current[0]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12571
|
+
}
|
|
12572
|
+
}, [isError]);
|
|
12573
|
+
return (jsx(OtpContainer, { showBorder: !isSuccess, scale: scale, children: jsxs(OTPGroup, { isError: isError, isSuccess: isSuccess, isLoading: isLoading, children: [values.slice(0, length).map((value, idx) => {
|
|
12574
|
+
const index = idx;
|
|
12575
|
+
return (jsxs(OTPSlotWrapper, { isActive: canEdit && activeIndex === index, children: [jsx(OTPHiddenInput, { ref: (el) => {
|
|
12576
|
+
inputsRef.current[index] = el;
|
|
12577
|
+
}, value: "", inputMode: "numeric", onBlur: () => setActiveIndex(-1), autoComplete: "one-time-code", autoFocus: index === 0, onFocus: () => handleFocus(index), onPaste: handlePaste, onKeyDown: (e) => {
|
|
12578
|
+
if (!canEdit)
|
|
12579
|
+
return;
|
|
12580
|
+
if (e.key === 'Backspace') {
|
|
12581
|
+
e.preventDefault();
|
|
12582
|
+
handleBackspace(index);
|
|
12583
|
+
}
|
|
12584
|
+
}, onChange: (e) => handleInput(index, e.target.value) }), value && jsx(OTPNumberValue, { "$hide": isSuccess, children: value }), !value && activeIndex === index && jsx(FakeCaret, {})] }, index));
|
|
12585
|
+
}), isSuccess && (jsx(SuccessTickWrapper, { children: jsx(TickIcon, { width: '100%', height: '100%' }) }))] }) }));
|
|
12526
12586
|
}
|
|
12527
12587
|
|
|
12528
|
-
const
|
|
12588
|
+
const TickListContainer = styled.ul `
|
|
12529
12589
|
display: flex;
|
|
12530
12590
|
flex-direction: column;
|
|
12531
|
-
gap:
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
text-align: left;
|
|
12535
|
-
`;
|
|
12536
|
-
const BarWrapper = styled.div `
|
|
12537
|
-
width: 100%;
|
|
12538
|
-
height: 4px;
|
|
12539
|
-
background: var(--ck-secondary-button-background);
|
|
12540
|
-
border-radius: 4px;
|
|
12541
|
-
overflow: hidden;
|
|
12591
|
+
gap: 8px;
|
|
12592
|
+
padding-top: 8px;
|
|
12593
|
+
padding-bottom: 8px;
|
|
12542
12594
|
`;
|
|
12543
|
-
const
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12595
|
+
const TickItem = styled.li `
|
|
12596
|
+
display: flex;
|
|
12597
|
+
align-items: center;
|
|
12598
|
+
text-align: left;
|
|
12599
|
+
gap: 8px;
|
|
12600
|
+
font-size: 16px;
|
|
12601
|
+
line-height: 24px;
|
|
12547
12602
|
`;
|
|
12548
|
-
const
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12603
|
+
const TickIconWrapper = styled.span `
|
|
12604
|
+
display: flex;
|
|
12605
|
+
align-items: center;
|
|
12606
|
+
justify-content: center;
|
|
12607
|
+
width: 16px;
|
|
12608
|
+
height: 16px;
|
|
12609
|
+
flex-shrink: 0;
|
|
12552
12610
|
`;
|
|
12553
|
-
const LabelColor = styled.span `
|
|
12554
|
-
color: ${({ color }) => color};
|
|
12555
|
-
`;
|
|
12556
|
-
const PasswordStrengthIndicator = ({ password, showPasswordIsTooWeakError, }) => {
|
|
12557
|
-
const passwordStrength = getPasswordStrength(password); // should return a number between 0 and 1
|
|
12558
|
-
const label = getPasswordStrengthLabel(passwordStrength);
|
|
12559
|
-
const color = useMemo(() => {
|
|
12560
|
-
switch (label) {
|
|
12561
|
-
case 'Weak':
|
|
12562
|
-
return '#ef4444'; // red-500
|
|
12563
|
-
case 'Medium':
|
|
12564
|
-
return '#f59e0b'; // amber-500
|
|
12565
|
-
case 'Strong':
|
|
12566
|
-
return '#10b981'; // emerald-500
|
|
12567
|
-
case 'Very Strong':
|
|
12568
|
-
return '#3b82f6'; // blue-500
|
|
12569
|
-
default:
|
|
12570
|
-
return '#d1d5db'; // gray-300
|
|
12571
|
-
}
|
|
12572
|
-
}, [label]);
|
|
12573
|
-
return (jsxs(Container$1, { children: [jsx(BarWrapper, { children: jsx(Progress, { color: color, initial: { width: 0 }, animate: { width: `${passwordStrength * 100}%` }, transition: { ease: 'easeOut', duration: 0.5 } }) }), jsxs("div", { style: { position: 'relative' }, children: [jsx(motion.div, { initial: { opacity: 1 }, animate: {
|
|
12574
|
-
opacity: showPasswordIsTooWeakError ? 0 : 1,
|
|
12575
|
-
y: showPasswordIsTooWeakError ? 5 : 0,
|
|
12576
|
-
}, transition: { duration: 0.3 }, children: jsxs(Label$1, { children: ["Password strength: ", jsx(LabelColor, { color: color, children: label })] }) }), jsx(motion.div, { initial: { opacity: 0 }, animate: {
|
|
12577
|
-
opacity: showPasswordIsTooWeakError ? 1 : 0,
|
|
12578
|
-
y: showPasswordIsTooWeakError ? 0 : -5,
|
|
12579
|
-
}, transition: { duration: 0.3 }, style: { color: '#ef4444', fontSize: '0.875rem', fontWeight: 500, position: 'absolute', top: '0' }, children: "Password is too weak" })] })] }));
|
|
12580
|
-
};
|
|
12581
|
-
|
|
12582
|
-
const ProviderInputInner = styled.div `
|
|
12583
|
-
// Styles from react-international-phone (imported here to avoid importing the whole CSS file for nextjs compatibility)
|
|
12584
|
-
.react-international-phone-country-selector{position:relative}.react-international-phone-country-selector-button{display:flex;height:var(--react-international-phone-height, 36px);box-sizing:border-box;align-items:center;justify-content:center;padding:0;border:1px solid var(--react-international-phone-country-selector-border-color, var(--react-international-phone-border-color, gainsboro));margin:0;appearance:button;-webkit-appearance:button;background-color:var(--react-international-phone-country-selector-background-color, var(--react-international-phone-background-color, white));cursor:pointer;text-transform:none;user-select:none}.react-international-phone-country-selector-button:hover{background-color:var(--react-international-phone-country-selector-background-color-hover, whitesmoke)}.react-international-phone-country-selector-button--hide-dropdown{cursor:auto}.react-international-phone-country-selector-button--hide-dropdown:hover{background-color:transparent}.react-international-phone-country-selector-button__button-content{display:flex;align-items:center;justify-content:center}.react-international-phone-country-selector-button__flag-emoji{margin:0 4px}.react-international-phone-country-selector-button__flag-emoji--disabled{opacity:.75}.react-international-phone-country-selector-button__dropdown-arrow{border-top:var(--react-international-phone-country-selector-arrow-size, 4px) solid var(--react-international-phone-country-selector-arrow-color, #777);border-right:var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;border-left:var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;margin-right:4px;transition:all .1s ease-out}.react-international-phone-country-selector-button__dropdown-arrow--active{transform:rotateX(180deg)}.react-international-phone-country-selector-button__dropdown-arrow--disabled{border-top-color:var(--react-international-phone-disabled-country-selector-arrow-color, #999)}.react-international-phone-country-selector-button--disabled,.react-international-phone-country-selector-button--disabled:hover{background-color:var(--react-international-phone-disabled-country-selector-background-color, var(--react-international-phone-disabled-background-color, whitesmoke))}.react-international-phone-country-selector-button--disabled{cursor:auto}.react-international-phone-flag-emoji{width:var(--react-international-phone-flag-width, 24px);height:var(--react-international-phone-flag-height, 24px);box-sizing:border-box}.react-international-phone-country-selector-dropdown{position:absolute;z-index:1;top:var(--react-international-phone-dropdown-top, 44px);left:var(--react-international-phone-dropdown-left, 0);display:flex;width:300px;max-height:200px;flex-direction:column;padding:4px 0;margin:0;background-color:var(--react-international-phone-dropdown-item-background-color, var(--react-international-phone-background-color, white));box-shadow:var(--react-international-phone-dropdown-shadow, 2px 2px 16px rgba(0, 0, 0, .25));color:var(--react-international-phone-dropdown-item-text-color, var(--react-international-phone-text-color, #222));list-style:none;overflow-y:scroll}.react-international-phone-country-selector-dropdown__preferred-list-divider{height:1px;border:none;margin:var(--react-international-phone-dropdown-preferred-list-divider-margin, 0);background:var(--react-international-phone-dropdown-preferred-list-divider-color, var(--react-international-phone-border-color, gainsboro))}.react-international-phone-country-selector-dropdown__list-item{display:flex;min-height:var(--react-international-phone-dropdown-item-height, 28px);box-sizing:border-box;align-items:center;padding:2px 8px}.react-international-phone-country-selector-dropdown__list-item-flag-emoji{margin-right:8px}.react-international-phone-country-selector-dropdown__list-item-country-name{overflow:hidden;margin-right:8px;font-size:var(--react-international-phone-dropdown-item-font-size, 14px);text-overflow:ellipsis;white-space:nowrap}.react-international-phone-country-selector-dropdown__list-item-dial-code{color:var(--react-international-phone-dropdown-item-dial-code-color, gray);font-size:var(--react-international-phone-dropdown-item-font-size, 14px)}.react-international-phone-country-selector-dropdown__list-item:hover{background-color:var(--react-international-phone-selected-dropdown-item-background-color, var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke));cursor:pointer}.react-international-phone-country-selector-dropdown__list-item--selected,.react-international-phone-country-selector-dropdown__list-item--focused{background-color:var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke);color:var(--react-international-phone-selected-dropdown-item-text-color, var(--react-international-phone-text-color, #222))}.react-international-phone-country-selector-dropdown__list-item--selected .react-international-phone-country-selector-dropdown__list-item-dial-code,.react-international-phone-country-selector-dropdown__list-item--focused .react-international-phone-country-selector-dropdown__list-item-dial-code{color:var(--react-international-phone-selected-dropdown-item-dial-code-color, var(--react-international-phone-dropdown-item-dial-code-color, gray))}.react-international-phone-country-selector-dropdown__list-item--focused{background-color:var(--react-international-phone-selected-dropdown-item-background-color, var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke))}.react-international-phone-dial-code-preview{display:flex;align-items:center;justify-content:center;padding:0 8px;border:1px solid var(--react-international-phone-dial-code-preview-border-color, var(--react-international-phone-border-color, gainsboro));margin-right:-1px;background-color:var(--react-international-phone-dial-code-preview-background-color, var(--react-international-phone-background-color, white));color:var(--react-international-phone-dial-code-preview-text-color, var(--react-international-phone-text-color, #222));font-size:var(--react-international-phone-dial-code-preview-font-size, var(--react-international-phone-font-size, 13px))}.react-international-phone-dial-code-preview--disabled{background-color:var(--react-international-phone-dial-code-preview-disabled-background-color, var(--react-international-phone-disabled-background-color, whitesmoke));color:var(--react-international-phone-dial-code-preview-disabled-text-color, var(--react-international-phone-disabled-text-color, #666))}.react-international-phone-input-container{display:flex}.react-international-phone-input-container .react-international-phone-country-selector-button{border-radius:var(--react-international-phone-border-radius, 4px);margin-right:-1px;border-bottom-right-radius:0;border-top-right-radius:0}.react-international-phone-input-container .react-international-phone-input{overflow:visible;height:var(--react-international-phone-height, 36px);box-sizing:border-box;padding:0 8px;border:1px solid var(--react-international-phone-border-color, gainsboro);border-radius:var(--react-international-phone-border-radius, 4px);margin:0;background-color:var(--react-international-phone-background-color, white);border-bottom-left-radius:0;border-top-left-radius:0;color:var(--react-international-phone-text-color, #222);font-family:inherit;font-size:var(--react-international-phone-font-size, 13px)}.react-international-phone-input-container .react-international-phone-input:focus{outline:none}.react-international-phone-input-container .react-international-phone-input--disabled{background-color:var(--react-international-phone-disabled-background-color, whitesmoke);color:var(--react-international-phone-disabled-text-color, #666)}
|
|
12585
12611
|
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
width: 100%;
|
|
12591
|
-
height: 100%;
|
|
12592
|
-
display: flex;
|
|
12593
|
-
align-items: center;
|
|
12594
|
-
justify-content: center;
|
|
12595
|
-
margin-top: 12px;
|
|
12596
|
-
|
|
12597
|
-
box-shadow: var(--ck-secondary-button-box-shadow);
|
|
12598
|
-
background: var(--ck-secondary-button-background);
|
|
12599
|
-
|
|
12600
|
-
padding-right: 20px;
|
|
12601
|
-
|
|
12602
|
-
&:focus-within {
|
|
12603
|
-
box-shadow: var(--ck-secondary-button-hover-box-shadow);
|
|
12604
|
-
}
|
|
12605
|
-
|
|
12606
|
-
input {
|
|
12607
|
-
padding-left: 20px;
|
|
12608
|
-
padding-right: 10px;
|
|
12609
|
-
|
|
12610
|
-
border: none !important;
|
|
12611
|
-
outline: none !important;
|
|
12612
|
-
background: transparent !important;
|
|
12613
|
-
box-shadow: none !important;
|
|
12612
|
+
const TickList = ({ items }) => {
|
|
12613
|
+
return (jsx(TickListContainer, { children: items.map((item) => (jsxs(TickItem, { children: [jsx(TickIconWrapper, { children: jsx(TickIcon, {}) }), jsx("span", { children: item })] }, item))) }));
|
|
12614
|
+
};
|
|
12615
|
+
TickList.displayName = 'TickList';
|
|
12614
12616
|
|
|
12615
|
-
|
|
12616
|
-
color: var(--ck-body-color-muted);
|
|
12617
|
-
}
|
|
12618
|
-
|
|
12619
|
-
width: 100%;
|
|
12620
|
-
height: 100%;
|
|
12621
|
-
}
|
|
12617
|
+
var wave = (jsxs("svg", { "aria-hidden": "true", width: "298", height: "188", viewBox: "0 0 298 188", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("path", { d: "M1 55.2757L21.6438 46.0285C55.5896 30.8228 94.4104 30.8228 128.356 46.0286L169.644 64.5229C203.59 79.7287 242.41 79.7286 276.356 64.5229L297 55.2757M1 44.2118L21.6438 34.9646C55.5896 19.7589 94.4104 19.7589 128.356 34.9646L169.644 53.459C203.59 68.6647 242.41 68.6647 276.356 53.459L297 44.2118M1 33.1477L21.6438 23.9005C55.5896 8.69479 94.4104 8.69479 128.356 23.9005L169.644 42.3949C203.59 57.6006 242.41 57.6006 276.356 42.3949L297 33.1477M1 22.1477L21.6438 12.9005C55.5896 -2.30521 94.4104 -2.30521 128.356 12.9005L169.644 31.3949C203.59 46.6006 242.41 46.6006 276.356 31.3949L297 22.1477M1 66.3398L21.6438 57.0926C55.5896 41.8869 94.4104 41.8869 128.356 57.0926L169.644 75.587C203.59 90.7927 242.41 90.7927 276.356 75.587L297 66.3398M1 77.404L21.6438 68.1568C55.5896 52.9511 94.4104 52.9511 128.356 68.1569L169.644 86.6512C203.59 101.857 242.41 101.857 276.356 86.6512L297 77.404M1 88.4681L21.6438 79.2209C55.5896 64.0152 94.4104 64.0152 128.356 79.2209L169.644 97.7153C203.59 112.921 242.41 112.921 276.356 97.7153L297 88.4681M1 121.66L21.6438 112.413C55.5896 97.2075 94.4104 97.2075 128.356 112.413L169.644 130.908C203.59 146.113 242.41 146.113 276.356 130.908L297 121.66M1 110.596L21.6438 101.349C55.5896 86.1433 94.4104 86.1433 128.356 101.349L169.644 119.843C203.59 135.049 242.41 135.049 276.356 119.843L297 110.596M1 99.5321L21.6438 90.2849C55.5896 75.0792 94.4104 75.0792 128.356 90.2849L169.644 108.779C203.59 123.985 242.41 123.985 276.356 108.779L297 99.5321M1 132.724L21.6438 123.477C55.5896 108.271 94.4104 108.271 128.356 123.477L169.644 141.971C203.59 157.177 242.41 157.177 276.356 141.971L297 132.724M1 143.788L21.6438 134.541C55.5896 119.336 94.4104 119.336 128.356 134.541L169.644 153.036C203.59 168.241 242.41 168.241 276.356 153.036L297 143.788M1 154.853L21.6438 145.605C55.5896 130.4 94.4104 130.4 128.356 145.605L169.644 164.1C203.59 179.305 242.41 179.305 276.356 164.1L297 154.853M1 165.853L21.6438 156.605C55.5896 141.4 94.4104 141.4 128.356 156.605L169.644 175.1C203.59 190.305 242.41 190.305 276.356 175.1L297 165.853", stroke: "url(#paint0_linear_1094_2077)", strokeOpacity: "0.9", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("defs", { children: jsxs("linearGradient", { id: "paint0_linear_1094_2077", x1: "1", y1: "112.587", x2: "297.034", y2: "79.6111", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-01)" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-02)", offset: "0.239583" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-03)", offset: "0.515625" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-04)", offset: "0.739583" }), jsx("stop", { stopColor: "var(--ck-graphic-wave-stop-05)", offset: "1" })] }) })] }));
|
|
12622
12618
|
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12619
|
+
const Graphic = styled(motion.div) `
|
|
12620
|
+
position: relative;
|
|
12621
|
+
margin-top: ${({ $marginTop }) => $marginTop !== null && $marginTop !== void 0 ? $marginTop : '16px'};
|
|
12622
|
+
margin-bottom: ${({ $marginBottom }) => $marginBottom !== null && $marginBottom !== void 0 ? $marginBottom : '20px'};
|
|
12623
|
+
margin-left: auto;
|
|
12624
|
+
margin-right: auto;
|
|
12625
|
+
height: ${({ $height }) => $height !== null && $height !== void 0 ? $height : '190px'};
|
|
12626
|
+
max-width: 295px;
|
|
12627
|
+
pointer-events: none;
|
|
12628
|
+
user-select: none;
|
|
12629
|
+
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
|
|
12630
|
+
height: 200px;
|
|
12631
|
+
max-width: 100%;
|
|
12632
|
+
margin-bottom: 32px;
|
|
12632
12633
|
}
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12634
|
+
`;
|
|
12635
|
+
const LogoGroup = styled(motion.div) `
|
|
12636
|
+
position: absolute;
|
|
12637
|
+
inset: 0;
|
|
12638
|
+
z-index: 2;
|
|
12639
|
+
`;
|
|
12640
|
+
const graphicIn = keyframes `
|
|
12641
|
+
0%{
|
|
12642
|
+
opacity:0;
|
|
12643
|
+
transform:scale(0.9);
|
|
12636
12644
|
}
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
border-right: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent !important;
|
|
12641
|
-
border-left: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent !important;
|
|
12642
|
-
margin-right: 4px;
|
|
12643
|
-
transition: all .1s ease-out;
|
|
12645
|
+
100%{
|
|
12646
|
+
opacity:1;
|
|
12647
|
+
transform:none;
|
|
12644
12648
|
}
|
|
12645
12649
|
`;
|
|
12646
|
-
const
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12650
|
+
const GraphicBackground = styled(motion.div) `
|
|
12651
|
+
z-index: 1;
|
|
12652
|
+
position: absolute;
|
|
12653
|
+
inset: 0;
|
|
12654
|
+
top: -2px;
|
|
12655
|
+
overflow: hidden;
|
|
12656
|
+
&:before {
|
|
12657
|
+
content: '';
|
|
12658
|
+
position: absolute;
|
|
12659
|
+
inset: 0;
|
|
12660
|
+
background: var(--ck-body-background);
|
|
12661
|
+
background: radial-gradient(
|
|
12662
|
+
closest-side,
|
|
12663
|
+
var(--ck-body-background-transparent, transparent) 18.75%,
|
|
12664
|
+
var(--ck-body-background) 100%
|
|
12665
|
+
);
|
|
12666
|
+
background-size: 100%;
|
|
12667
|
+
}
|
|
12651
12668
|
svg {
|
|
12652
12669
|
display: block;
|
|
12653
|
-
|
|
12654
|
-
|
|
12670
|
+
width: 100%;
|
|
12671
|
+
height: auto;
|
|
12655
12672
|
}
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
&:hover {
|
|
12660
|
-
background: var(--ck-body-background-secondary);
|
|
12661
|
-
color: var(--ck-body-action-hover-color);
|
|
12662
|
-
}
|
|
12663
|
-
&:active {
|
|
12664
|
-
transform: scale(0.9);
|
|
12665
|
-
}
|
|
12673
|
+
animation: ${graphicIn} 1000ms 100ms ease both;
|
|
12674
|
+
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
|
|
12675
|
+
animation: none;
|
|
12666
12676
|
}
|
|
12667
12677
|
`;
|
|
12668
|
-
const
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
font-weight: var(--ck-primary-button-font-weight, 500);
|
|
12673
|
-
line-height: 20px;
|
|
12674
|
-
}
|
|
12675
|
-
|
|
12676
|
-
${ProviderInputInner} {
|
|
12677
|
-
height: 64px;
|
|
12678
|
-
}
|
|
12679
|
-
|
|
12680
|
-
&:first-of-type {
|
|
12681
|
-
${ButtonContainer}, ${ProviderInputInner} {
|
|
12682
|
-
margin-top: 0;
|
|
12683
|
-
}
|
|
12684
|
-
}
|
|
12685
|
-
|
|
12686
|
-
${ButtonContainerInner} {
|
|
12687
|
-
padding: 0 20px;
|
|
12688
|
-
justify-content: space-between;
|
|
12678
|
+
const logoIn = keyframes `
|
|
12679
|
+
0%{
|
|
12680
|
+
opacity:0;
|
|
12681
|
+
transform:scale(0) translateY(40%);
|
|
12689
12682
|
}
|
|
12690
|
-
|
|
12691
|
-
|
|
12692
|
-
|
|
12693
|
-
width: 100%;
|
|
12694
|
-
max-width: 100%;
|
|
12683
|
+
100%{
|
|
12684
|
+
opacity:1;
|
|
12685
|
+
transform:none;
|
|
12695
12686
|
}
|
|
12696
12687
|
`;
|
|
12697
|
-
const
|
|
12698
|
-
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
overflow: hidden;
|
|
12703
|
-
white-space: nowrap;
|
|
12704
|
-
text-overflow: ellipsis;
|
|
12705
|
-
padding: 2px 0;
|
|
12688
|
+
const LogoPosition = styled(motion.div) `
|
|
12689
|
+
position: absolute;
|
|
12690
|
+
inset: 0;
|
|
12691
|
+
animation: cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite both;
|
|
12692
|
+
animation-delay: inherit;
|
|
12706
12693
|
`;
|
|
12707
|
-
const
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12694
|
+
const LogoInner = styled(motion.div) `
|
|
12695
|
+
position: absolute;
|
|
12696
|
+
`;
|
|
12697
|
+
const LogoGraphic$1 = styled(motion.div) `
|
|
12698
|
+
position: relative;
|
|
12699
|
+
overflow: hidden;
|
|
12700
|
+
height: 58px;
|
|
12701
|
+
width: 58px;
|
|
12702
|
+
border-radius: 13.84px;
|
|
12703
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 20px 0 rgba(0, 0, 0, 0.03);
|
|
12704
|
+
|
|
12705
|
+
svg {
|
|
12713
12706
|
display: block;
|
|
12714
|
-
position: relative;
|
|
12715
|
-
pointer-events: none;
|
|
12716
|
-
overflow: hidden;
|
|
12717
12707
|
width: 100%;
|
|
12718
12708
|
height: 100%;
|
|
12719
12709
|
}
|
|
12720
|
-
|
|
12721
|
-
&[data-shape='squircle'] {
|
|
12722
|
-
border-radius: 22.5%;
|
|
12723
|
-
}
|
|
12724
|
-
&[data-shape='circle'] {
|
|
12725
|
-
border-radius: 100%;
|
|
12726
|
-
}
|
|
12727
|
-
&[data-shape='square'] {
|
|
12728
|
-
border-radius: 0;
|
|
12729
|
-
}
|
|
12730
12710
|
`;
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
color: var(--ck-body-color-muted);
|
|
12735
|
-
background: none;
|
|
12736
|
-
font-size: 14px;
|
|
12737
|
-
margin-top: 10px;
|
|
12738
|
-
transition: color 0.2s;
|
|
12739
|
-
|
|
12740
|
-
&:hover {
|
|
12741
|
-
color: var(--ck-body-color);
|
|
12742
|
-
}
|
|
12711
|
+
const float = keyframes `
|
|
12712
|
+
0%,100%{ transform:none; }
|
|
12713
|
+
50%{ transform: translateY(-10%) }
|
|
12743
12714
|
`;
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12715
|
+
const FloatWrapper = styled(motion.div) `
|
|
12716
|
+
position: relative;
|
|
12717
|
+
animation: cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite both;
|
|
12718
|
+
animation-name: ${float};
|
|
12719
|
+
animation-duration: 3600ms;
|
|
12720
|
+
`;
|
|
12721
|
+
const rotate = keyframes `
|
|
12722
|
+
0%,100%{ transform:rotate(-3deg); }
|
|
12723
|
+
50%{ transform:rotate(3deg); }
|
|
12724
|
+
`;
|
|
12725
|
+
const RotateWrapper = styled(motion.div) `
|
|
12726
|
+
position: relative;
|
|
12727
|
+
animation: cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite both;
|
|
12728
|
+
animation-name: ${rotate};
|
|
12729
|
+
animation-duration: 3200ms;
|
|
12730
|
+
`;
|
|
12731
|
+
const Logo$1 = styled(motion.div) `
|
|
12732
|
+
position: absolute;
|
|
12733
|
+
inset: 0;
|
|
12734
|
+
|
|
12735
|
+
animation: ${logoIn} 750ms cubic-bezier(0.19, 1, 0.22, 1) both;
|
|
12736
|
+
&:nth-child(1){ z-index:2; animation-delay:0ms; }
|
|
12737
|
+
&:nth-child(2){ z-index:1; animation-delay:60ms; }
|
|
12738
|
+
&:nth-child(3){ z-index:1; animation-delay:30ms; }
|
|
12739
|
+
&:nth-child(4){ z-index:1; animation-delay:90ms; }
|
|
12740
|
+
&:nth-child(5){ z-index:1; animation-delay:120ms;}
|
|
12741
|
+
|
|
12742
|
+
&:nth-child(1){ ${RotateWrapper}{ animation-delay:0ms; } }
|
|
12743
|
+
&:nth-child(2){ ${RotateWrapper}{ animation-delay:-600ms; } }
|
|
12744
|
+
&:nth-child(3){ ${RotateWrapper}{ animation-delay:-1200ms; } }
|
|
12745
|
+
&:nth-child(4){ ${RotateWrapper}{ animation-delay:-1800ms; } }
|
|
12746
|
+
&:nth-child(5){ ${RotateWrapper}{ animation-delay:-2400ms; } }
|
|
12747
|
+
|
|
12748
|
+
&:nth-child(1){ ${FloatWrapper}{ animation-delay:-200ms; } }
|
|
12749
|
+
&:nth-child(2){ ${FloatWrapper}{ animation-delay:-600ms; } }
|
|
12750
|
+
&:nth-child(3){ ${FloatWrapper}{ animation-delay:-800ms; } }
|
|
12751
|
+
&:nth-child(4){ ${FloatWrapper}{ animation-delay:-300ms; } }
|
|
12752
|
+
&:nth-child(5){ ${FloatWrapper}{ animation-delay:-3200ms; } }
|
|
12753
|
+
|
|
12754
|
+
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
|
|
12755
|
+
animation: none !important;
|
|
12756
|
+
${RotateWrapper},${FloatWrapper} {
|
|
12757
|
+
animation: none !important;
|
|
12773
12758
|
}
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
|
|
12785
|
-
|
|
12786
|
-
if (response.error) {
|
|
12787
|
-
logger.log('Error creating wallet', response.error);
|
|
12788
|
-
}
|
|
12789
|
-
})();
|
|
12790
|
-
}
|
|
12791
|
-
}, [shouldCreateWallet]);
|
|
12792
|
-
useEffect(() => {
|
|
12793
|
-
if (embeddedState === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
|
|
12794
|
-
setShouldCreateWallet(true);
|
|
12795
|
-
}
|
|
12796
|
-
}, [embeddedState]);
|
|
12797
|
-
return (jsx(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: jsx(Loader, { header: "Creating wallet..." }) }));
|
|
12798
|
-
};
|
|
12799
|
-
const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
12800
|
-
const { triggerResize } = useOpenfort();
|
|
12801
|
-
const { createWallet, error: recoveryError } = useWallets();
|
|
12802
|
-
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
12803
|
-
const { embeddedState } = useOpenfortCore();
|
|
12804
|
-
useEffect(() => {
|
|
12805
|
-
// To ensure the wallet is created only once
|
|
12806
|
-
if (shouldCreateWallet) {
|
|
12807
|
-
(async () => {
|
|
12808
|
-
logger.log('Creating wallet passkey recovery');
|
|
12809
|
-
const response = await createWallet({
|
|
12810
|
-
recovery: {
|
|
12811
|
-
recoveryMethod: RecoveryMethod.PASSKEY,
|
|
12812
|
-
},
|
|
12813
|
-
});
|
|
12814
|
-
if (response.error) {
|
|
12815
|
-
logger.log('Error creating wallet', response.error);
|
|
12816
|
-
setShouldCreateWallet(false);
|
|
12817
|
-
}
|
|
12818
|
-
})();
|
|
12819
|
-
}
|
|
12820
|
-
}, [shouldCreateWallet]);
|
|
12821
|
-
useEffect(() => {
|
|
12822
|
-
if (embeddedState === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
|
|
12823
|
-
setShouldCreateWallet(true);
|
|
12824
|
-
}
|
|
12825
|
-
}, [embeddedState]);
|
|
12826
|
-
useEffect(() => {
|
|
12827
|
-
if (recoveryError)
|
|
12828
|
-
triggerResize();
|
|
12829
|
-
}, [recoveryError]);
|
|
12830
|
-
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(Loader, { icon: jsx(FingerPrintIcon, {}), isError: !!recoveryError, header: recoveryError ? 'Invalid passkey.' : 'Creating wallet with passkey...', description: recoveryError ? 'There was an error creating your passkey. Please try again.' : undefined, onRetry: () => setShouldCreateWallet(true) }), jsx(OtherMethod, { currentMethod: RecoveryMethod.PASSKEY, onChangeMethod: onChangeMethod })] }));
|
|
12831
|
-
};
|
|
12832
|
-
const CreateWalletPasswordRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
12833
|
-
const [recoveryPhrase, setRecoveryPhrase] = useState('');
|
|
12834
|
-
const [recoveryError, setRecoveryError] = useState(false);
|
|
12835
|
-
const { triggerResize } = useOpenfort();
|
|
12836
|
-
const [showPasswordIsTooWeakError, setShowPasswordIsTooWeakError] = useState(false);
|
|
12837
|
-
const [loading, setLoading] = useState(false);
|
|
12838
|
-
const { createWallet } = useWallets();
|
|
12839
|
-
const handleSubmit = async () => {
|
|
12840
|
-
if (getPasswordStrength(recoveryPhrase) < MEDIUM_SCORE_THRESHOLD) {
|
|
12841
|
-
setShowPasswordIsTooWeakError(true);
|
|
12842
|
-
return;
|
|
12843
|
-
}
|
|
12844
|
-
setLoading(true);
|
|
12845
|
-
const { error } = await createWallet({
|
|
12846
|
-
recovery: {
|
|
12847
|
-
recoveryMethod: RecoveryMethod.PASSWORD,
|
|
12848
|
-
password: recoveryPhrase,
|
|
12849
|
-
},
|
|
12850
|
-
});
|
|
12851
|
-
setLoading(false);
|
|
12852
|
-
if (error) {
|
|
12853
|
-
setRecoveryError(error.message || 'There was an error recovering your account');
|
|
12854
|
-
}
|
|
12855
|
-
else {
|
|
12856
|
-
logger.log('Recovery success');
|
|
12857
|
-
}
|
|
12858
|
-
};
|
|
12859
|
-
useEffect(() => {
|
|
12860
|
-
if (recoveryError)
|
|
12861
|
-
triggerResize();
|
|
12862
|
-
}, [recoveryError]);
|
|
12863
|
-
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(FloatingGraphic, { height: "80px", logoCenter: {
|
|
12864
|
-
logo: jsx(KeyIcon, {}),
|
|
12865
|
-
size: '1.2',
|
|
12866
|
-
}, logoTopLeft: {
|
|
12867
|
-
logo: jsx(ShieldIcon, {}),
|
|
12868
|
-
size: '0.75',
|
|
12869
|
-
}, logoBottomRight: {
|
|
12870
|
-
logo: jsx(LockIcon, {}),
|
|
12871
|
-
size: '0.5',
|
|
12872
|
-
} }), jsx(ModalHeading, { children: "Secure your wallet" }), jsxs(ModalBody, { style: { textAlign: 'center' }, children: [jsx(FitText, { children: "Set a password for your wallet." }), jsxs("form", { onSubmit: (e) => {
|
|
12873
|
-
e.preventDefault();
|
|
12874
|
-
handleSubmit();
|
|
12875
|
-
}, children: [jsx(Input, { value: recoveryPhrase, onChange: (e) => {
|
|
12876
|
-
if (showPasswordIsTooWeakError)
|
|
12877
|
-
setShowPasswordIsTooWeakError(false);
|
|
12878
|
-
setRecoveryPhrase(e.target.value);
|
|
12879
|
-
}, type: "password", placeholder: "Enter your password", autoComplete: "off" }), jsx(PasswordStrengthIndicator, { password: recoveryPhrase, showPasswordIsTooWeakError: showPasswordIsTooWeakError }), jsx(TickList, { items: ['You will use this password to access your wallet', "Make sure it's strong and memorable"] }), recoveryError && (jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, children: jsx(ModalBody, { style: { height: 24, marginTop: 12 }, "$error": true, children: jsx(FitText, { children: recoveryError }) }) }, recoveryError)), jsx(Button, { onClick: handleSubmit, waiting: loading, disabled: loading, children: "Create wallet" })] }), jsx(OtherMethod, { currentMethod: RecoveryMethod.PASSWORD, onChangeMethod: onChangeMethod })] })] }));
|
|
12880
|
-
};
|
|
12881
|
-
const ChooseRecoveryMethod = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
12882
|
-
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(ModalHeading, { children: "Choose a recovery method" }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => onChangeMethod(RecoveryMethod.PASSKEY), children: [jsx(ProviderLabel, { children: "Passkey" }), jsx(ProviderIcon$1, { children: jsx(FingerPrintIcon, {}) })] }) }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => onChangeMethod(RecoveryMethod.PASSWORD), children: [jsx(ProviderLabel, { children: "Password" }), jsx(ProviderIcon$1, { children: jsx(KeyIcon, {}) })] }) }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => onChangeMethod(RecoveryMethod.AUTOMATIC), children: [jsx(ProviderLabel, { children: "Automatic" }), jsx(ProviderIcon$1, { children: jsx(LockIcon, {}) })] }) })] }));
|
|
12883
|
-
};
|
|
12884
|
-
const CreateEmbeddedWallet = ({ onBack, logoutOnBack }) => {
|
|
12885
|
-
const { uiConfig, triggerResize } = useOpenfort();
|
|
12886
|
-
const [userSelectedMethod, setUserSelectedMethod] = useState(null);
|
|
12887
|
-
useEffect(() => {
|
|
12888
|
-
triggerResize();
|
|
12889
|
-
}, [userSelectedMethod]);
|
|
12890
|
-
const method = userSelectedMethod !== null && userSelectedMethod !== void 0 ? userSelectedMethod : uiConfig.walletRecovery.defaultMethod;
|
|
12891
|
-
switch (method) {
|
|
12892
|
-
case RecoveryMethod.PASSWORD:
|
|
12893
|
-
return (jsx(CreateWalletPasswordRecovery, { onChangeMethod: setUserSelectedMethod, onBack: onBack, logoutOnBack: logoutOnBack }));
|
|
12894
|
-
case RecoveryMethod.AUTOMATIC:
|
|
12895
|
-
return jsx(CreateWalletAutomaticRecovery, { onBack: onBack, logoutOnBack: logoutOnBack });
|
|
12896
|
-
case RecoveryMethod.PASSKEY:
|
|
12897
|
-
return (jsx(CreateWalletPasskeyRecovery, { onChangeMethod: setUserSelectedMethod, onBack: onBack, logoutOnBack: logoutOnBack }));
|
|
12898
|
-
case 'other':
|
|
12899
|
-
return (jsx(ChooseRecoveryMethod, { onChangeMethod: setUserSelectedMethod, onBack: () => {
|
|
12900
|
-
setUserSelectedMethod(null);
|
|
12901
|
-
}, logoutOnBack: logoutOnBack }));
|
|
12902
|
-
default:
|
|
12903
|
-
logger.error(`Unsupported recovery method: ${userSelectedMethod}${uiConfig.walletRecovery.defaultMethod}`);
|
|
12904
|
-
return null;
|
|
12759
|
+
}
|
|
12760
|
+
|
|
12761
|
+
${LogoInner} {
|
|
12762
|
+
transform: translate(-50%, -50%);
|
|
12763
|
+
}
|
|
12764
|
+
|
|
12765
|
+
&:nth-child(1) ${LogoPosition} {
|
|
12766
|
+
transform: translate(50%, 50%);
|
|
12767
|
+
${LogoGraphic$1} {
|
|
12768
|
+
border-radius: 17.2px;
|
|
12769
|
+
width: 72px;
|
|
12770
|
+
height: 72px;
|
|
12905
12771
|
}
|
|
12772
|
+
}
|
|
12773
|
+
&:nth-child(2) ${LogoPosition} {
|
|
12774
|
+
transform: translate(21%, 21.5%);
|
|
12775
|
+
}
|
|
12776
|
+
&:nth-child(3) ${LogoPosition} {
|
|
12777
|
+
transform: translate(78%, 14%);
|
|
12778
|
+
}
|
|
12779
|
+
&:nth-child(4) ${LogoPosition} {
|
|
12780
|
+
transform: translate(22.5%, 76%);
|
|
12781
|
+
}
|
|
12782
|
+
&:nth-child(5) ${LogoPosition} {
|
|
12783
|
+
transform: translate(76%, 80%);
|
|
12784
|
+
}
|
|
12785
|
+
`;
|
|
12786
|
+
|
|
12787
|
+
const LogoGraphic = ({ size = '100%', logo }) => {
|
|
12788
|
+
return (jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { style: { transform: `scale(${size})` }, children: logo }) }) }) }) }) }));
|
|
12906
12789
|
};
|
|
12907
|
-
const
|
|
12908
|
-
|
|
12909
|
-
const { setRoute } = useOpenfort();
|
|
12910
|
-
if (showCreateEmbeddedWallet)
|
|
12911
|
-
return jsx(CreateEmbeddedWallet, { onBack: () => setShowCreateEmbeddedWallet(false), logoutOnBack: false });
|
|
12912
|
-
return (jsxs(PageContent, { onBack: routes.PROVIDERS, logoutOnBack: true, children: [jsx(ModalHeading, { children: "Choose an option" }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => setShowCreateEmbeddedWallet(true), children: [jsx(ProviderLabel, { children: "Create Wallet" }), jsx(ProviderIcon$1, { children: jsx(PlusIcon, {}) })] }) }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => {
|
|
12913
|
-
setRoute({ route: routes.CONNECTORS, connectType: 'link' });
|
|
12914
|
-
}, children: [jsx(ProviderLabel, { children: "Connect Wallet" }), jsx(ProviderIcon$1, { children: jsx(Logos.OtherWallets, {}) })] }) })] }));
|
|
12790
|
+
const FloatingGraphic = ({ height = '130px', marginBottom, marginTop, logoCenter, logoTopRight, logoTopLeft, logoBottomRight, logoBottomLeft, }) => {
|
|
12791
|
+
return (jsxs(Graphic, { "$height": height, "$marginBottom": marginBottom, "$marginTop": marginTop, children: [jsxs(LogoGroup, { children: [jsx(LogoGraphic, { ...logoCenter }), logoTopLeft ? jsx(LogoGraphic, { ...logoTopLeft }) : jsx("div", {}), logoTopRight ? jsx(LogoGraphic, { ...logoTopRight }) : jsx("div", {}), logoBottomLeft ? jsx(LogoGraphic, { ...logoBottomLeft }) : jsx("div", {}), logoBottomRight ? jsx(LogoGraphic, { ...logoBottomRight }) : jsx("div", {})] }), jsx(GraphicBackground, { children: wave })] }));
|
|
12915
12792
|
};
|
|
12916
|
-
|
|
12917
|
-
|
|
12918
|
-
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12793
|
+
|
|
12794
|
+
/**
|
|
12795
|
+
* Password utility helpers for strength calculation and validation.
|
|
12796
|
+
*
|
|
12797
|
+
* Provides functions for password strength calculation, passphrase generation, and password validation.
|
|
12798
|
+
*/
|
|
12799
|
+
// ============================================================================
|
|
12800
|
+
// Constants and Regular Expressions
|
|
12801
|
+
// ============================================================================
|
|
12802
|
+
/**
|
|
12803
|
+
* Regular expression to match lowercase letters.
|
|
12804
|
+
*/
|
|
12805
|
+
const LOWERCASE_REGEX = /[a-z]/;
|
|
12806
|
+
/**
|
|
12807
|
+
* Regular expression to match uppercase letters.
|
|
12808
|
+
*/
|
|
12809
|
+
const UPPERCASE_REGEX = /[A-Z]/;
|
|
12810
|
+
/**
|
|
12811
|
+
* Regular expression to match digits.
|
|
12812
|
+
*/
|
|
12813
|
+
const DIGIT_REGEX = /[0-9]/;
|
|
12814
|
+
/**
|
|
12815
|
+
* Special characters allowed in passwords.
|
|
12816
|
+
*/
|
|
12817
|
+
const SPECIAL_CHARACTERS = '!@#$%^&()\\-*+.';
|
|
12818
|
+
/**
|
|
12819
|
+
* Escape regex metacharacters for safe use inside a character class.
|
|
12820
|
+
*/
|
|
12821
|
+
function escapeForCharClass(str) {
|
|
12822
|
+
return str.replace(/[-\\^]/g, '\\$&');
|
|
12823
|
+
// escapes -, \, and ^ (the only risky chars in [])
|
|
12824
|
+
}
|
|
12825
|
+
/**
|
|
12826
|
+
* Regular expression to match special characters.
|
|
12827
|
+
*/
|
|
12828
|
+
const SPECIAL_CHARACTER_REGEX = new RegExp(`[${escapeForCharClass(SPECIAL_CHARACTERS)}]`);
|
|
12829
|
+
/**
|
|
12830
|
+
* Maximum entropy score for normalization.
|
|
12831
|
+
*/
|
|
12832
|
+
const MAX_ENTROPY_SCORE = 95;
|
|
12833
|
+
/**
|
|
12834
|
+
* Minimum password length for security.
|
|
12835
|
+
*/
|
|
12836
|
+
const MIN_PASSWORD_LENGTH = 8;
|
|
12837
|
+
/**
|
|
12838
|
+
* Weight for diversity score in overall strength calculation.
|
|
12839
|
+
*/
|
|
12840
|
+
const DIVERSITY_WEIGHT = 0.3;
|
|
12841
|
+
const ENTROPY_WEIGHT = 0.7;
|
|
12842
|
+
const MEDIUM_SCORE_THRESHOLD = 0.5;
|
|
12843
|
+
const STRONG_SCORE_THRESHOLD = 0.75;
|
|
12844
|
+
const VERY_STRONG_SCORE_THRESHOLD = 0.9;
|
|
12845
|
+
/**
|
|
12846
|
+
* Converts a numeric password strength score to a human-readable label.
|
|
12847
|
+
*
|
|
12848
|
+
* @param score - The strength score (0-1).
|
|
12849
|
+
* @returns The corresponding strength label.
|
|
12850
|
+
*
|
|
12851
|
+
* @example
|
|
12852
|
+
* ```ts
|
|
12853
|
+
* const label = getPasswordStrengthLabel(0.8);
|
|
12854
|
+
* // label === 'Strong'
|
|
12855
|
+
* ```
|
|
12856
|
+
*/
|
|
12857
|
+
function getPasswordStrengthLabel(score) {
|
|
12858
|
+
if (score > VERY_STRONG_SCORE_THRESHOLD) {
|
|
12859
|
+
return 'Very Strong';
|
|
12926
12860
|
}
|
|
12927
|
-
if (
|
|
12928
|
-
|
|
12929
|
-
|
|
12861
|
+
else if (score > STRONG_SCORE_THRESHOLD) {
|
|
12862
|
+
return 'Strong';
|
|
12863
|
+
}
|
|
12864
|
+
else if (score > MEDIUM_SCORE_THRESHOLD) {
|
|
12865
|
+
return 'Medium';
|
|
12866
|
+
}
|
|
12867
|
+
else {
|
|
12868
|
+
return 'Weak';
|
|
12930
12869
|
}
|
|
12931
|
-
return jsx(CreateEmbeddedWallet, { onBack: routes.PROVIDERS, logoutOnBack: true });
|
|
12932
|
-
};
|
|
12933
|
-
|
|
12934
|
-
function useWindowSize() {
|
|
12935
|
-
const [windowSize, setWindowSize] = useState({
|
|
12936
|
-
width: 0,
|
|
12937
|
-
height: 0,
|
|
12938
|
-
});
|
|
12939
|
-
useEffect(() => {
|
|
12940
|
-
function handleResize() {
|
|
12941
|
-
setWindowSize({
|
|
12942
|
-
width: window.innerWidth,
|
|
12943
|
-
height: window.innerHeight,
|
|
12944
|
-
});
|
|
12945
|
-
}
|
|
12946
|
-
window.addEventListener('resize', handleResize);
|
|
12947
|
-
handleResize();
|
|
12948
|
-
return () => window.removeEventListener('resize', handleResize);
|
|
12949
|
-
}, []);
|
|
12950
|
-
return windowSize;
|
|
12951
12870
|
}
|
|
12952
|
-
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
12976
|
-
|
|
12977
|
-
|
|
12978
|
-
|
|
12979
|
-
|
|
12980
|
-
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
}, [ecl, size, uri]);
|
|
13001
|
-
return (jsxs("svg", { height: size, width: size, viewBox: `0 0 ${size} ${size}`, style: {
|
|
13002
|
-
width: size,
|
|
13003
|
-
height: size,
|
|
13004
|
-
}, children: [jsx("title", { children: "QR Code" }), jsx("rect", { fill: "transparent", height: size, width: size }), dots] }));
|
|
12871
|
+
/**
|
|
12872
|
+
* Calculates the diversity score of a password based on character types used.
|
|
12873
|
+
*
|
|
12874
|
+
* Considers lowercase, uppercase, digits, and special characters.
|
|
12875
|
+
*
|
|
12876
|
+
* @param password - The password to analyse.
|
|
12877
|
+
* @returns A score between 0 and 1 representing character diversity.
|
|
12878
|
+
*
|
|
12879
|
+
* @example
|
|
12880
|
+
* ```ts
|
|
12881
|
+
* const diversity = calculatePasswordDiversityScore('Password123!');
|
|
12882
|
+
* ```
|
|
12883
|
+
*/
|
|
12884
|
+
function calculatePasswordDiversityScore(password) {
|
|
12885
|
+
// Passwords shorter than minimum length get a score of 0
|
|
12886
|
+
if (password.length < MIN_PASSWORD_LENGTH) {
|
|
12887
|
+
return 0;
|
|
12888
|
+
}
|
|
12889
|
+
let characterTypesUsed = 0;
|
|
12890
|
+
if (LOWERCASE_REGEX.test(password)) {
|
|
12891
|
+
characterTypesUsed += 1;
|
|
12892
|
+
}
|
|
12893
|
+
if (UPPERCASE_REGEX.test(password)) {
|
|
12894
|
+
characterTypesUsed += 1;
|
|
12895
|
+
}
|
|
12896
|
+
if (DIGIT_REGEX.test(password)) {
|
|
12897
|
+
characterTypesUsed += 1;
|
|
12898
|
+
}
|
|
12899
|
+
if (SPECIAL_CHARACTER_REGEX.test(password)) {
|
|
12900
|
+
characterTypesUsed += 1;
|
|
12901
|
+
}
|
|
12902
|
+
return Math.max(0, Math.min(1, characterTypesUsed / 4));
|
|
12903
|
+
}
|
|
12904
|
+
/**
|
|
12905
|
+
* Calculates the overall password strength combining diversity and entropy.
|
|
12906
|
+
*
|
|
12907
|
+
* @param password - The password to analyse.
|
|
12908
|
+
* @returns A strength score between 0 and 1.
|
|
12909
|
+
*
|
|
12910
|
+
* @example
|
|
12911
|
+
* ```ts
|
|
12912
|
+
* const strength = getPasswordStrength('Password123!');
|
|
12913
|
+
* ```
|
|
12914
|
+
*/
|
|
12915
|
+
function getPasswordStrength(password = '') {
|
|
12916
|
+
const diversityScore = calculatePasswordDiversityScore(password);
|
|
12917
|
+
const entropyScore = calculateEntropy(password) / MAX_ENTROPY_SCORE;
|
|
12918
|
+
return Math.min(diversityScore * DIVERSITY_WEIGHT + entropyScore * ENTROPY_WEIGHT, 1);
|
|
13005
12919
|
}
|
|
13006
12920
|
|
|
13007
|
-
const
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
13015
|
-
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
background: var(--ck-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
|
|
13026
|
-
|
|
12921
|
+
const Container$1 = styled.div `
|
|
12922
|
+
display: flex;
|
|
12923
|
+
flex-direction: column;
|
|
12924
|
+
gap: 0.5rem;
|
|
12925
|
+
margin-top: 0.5rem;
|
|
12926
|
+
margin-bottom: 0.5rem;
|
|
12927
|
+
text-align: left;
|
|
12928
|
+
`;
|
|
12929
|
+
const BarWrapper = styled.div `
|
|
12930
|
+
width: 100%;
|
|
12931
|
+
height: 4px;
|
|
12932
|
+
background: var(--ck-secondary-button-background);
|
|
12933
|
+
border-radius: 4px;
|
|
12934
|
+
overflow: hidden;
|
|
12935
|
+
`;
|
|
12936
|
+
const Progress = styled(motion.div) `
|
|
12937
|
+
height: 100%;
|
|
12938
|
+
background: ${({ color }) => color};
|
|
12939
|
+
border-radius: 4px;
|
|
12940
|
+
`;
|
|
12941
|
+
const Label$1 = styled.div `
|
|
12942
|
+
font-size: 0.875rem;
|
|
12943
|
+
font-weight: 500;
|
|
12944
|
+
color: var(--ck-body-color-muted);
|
|
12945
|
+
`;
|
|
12946
|
+
const LabelColor = styled.span `
|
|
12947
|
+
color: ${({ color }) => color};
|
|
12948
|
+
`;
|
|
12949
|
+
const PasswordStrengthIndicator = ({ password, showPasswordIsTooWeakError, }) => {
|
|
12950
|
+
const passwordStrength = getPasswordStrength(password); // should return a number between 0 and 1
|
|
12951
|
+
const label = getPasswordStrengthLabel(passwordStrength);
|
|
12952
|
+
const color = useMemo(() => {
|
|
12953
|
+
switch (label) {
|
|
12954
|
+
case 'Weak':
|
|
12955
|
+
return '#ef4444'; // red-500
|
|
12956
|
+
case 'Medium':
|
|
12957
|
+
return '#f59e0b'; // amber-500
|
|
12958
|
+
case 'Strong':
|
|
12959
|
+
return '#10b981'; // emerald-500
|
|
12960
|
+
case 'Very Strong':
|
|
12961
|
+
return '#3b82f6'; // blue-500
|
|
12962
|
+
default:
|
|
12963
|
+
return '#d1d5db'; // gray-300
|
|
12964
|
+
}
|
|
12965
|
+
}, [label]);
|
|
12966
|
+
return (jsxs(Container$1, { children: [jsx(BarWrapper, { children: jsx(Progress, { color: color, initial: { width: 0 }, animate: { width: `${passwordStrength * 100}%` }, transition: { ease: 'easeOut', duration: 0.5 } }) }), jsxs("div", { style: { position: 'relative' }, children: [jsx(motion.div, { initial: { opacity: 1 }, animate: {
|
|
12967
|
+
opacity: showPasswordIsTooWeakError ? 0 : 1,
|
|
12968
|
+
y: showPasswordIsTooWeakError ? 5 : 0,
|
|
12969
|
+
}, transition: { duration: 0.3 }, children: jsxs(Label$1, { children: ["Password strength: ", jsx(LabelColor, { color: color, children: label })] }) }), jsx(motion.div, { initial: { opacity: 0 }, animate: {
|
|
12970
|
+
opacity: showPasswordIsTooWeakError ? 1 : 0,
|
|
12971
|
+
y: showPasswordIsTooWeakError ? 0 : -5,
|
|
12972
|
+
}, transition: { duration: 0.3 }, style: { color: '#ef4444', fontSize: '0.875rem', fontWeight: 500, position: 'absolute', top: '0' }, children: "Password is too weak" })] })] }));
|
|
12973
|
+
};
|
|
12974
|
+
|
|
12975
|
+
const Body$1 = styled.p `
|
|
12976
|
+
color: var(--ck-body-color);
|
|
12977
|
+
text-align: center;
|
|
12978
|
+
margin-bottom: 16px;
|
|
13027
12979
|
`;
|
|
13028
|
-
const
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
12980
|
+
const ResultContainer$1 = styled.div `
|
|
12981
|
+
margin-top: 16px;
|
|
12982
|
+
height: 24px;
|
|
12983
|
+
text-align: center;
|
|
12984
|
+
`;
|
|
12985
|
+
const FooterButtonText$1 = styled.button `
|
|
12986
|
+
background: none;
|
|
12987
|
+
border: none;
|
|
12988
|
+
cursor: pointer;
|
|
12989
|
+
padding: 0;
|
|
12990
|
+
color: var(--ck-body-color-muted);
|
|
12991
|
+
transition: color 0.3s;
|
|
12992
|
+
|
|
12993
|
+
&:disabled {
|
|
12994
|
+
color: var(--ck-body-color-muted) !important;
|
|
12995
|
+
cursor: not-allowed;
|
|
13034
12996
|
}
|
|
13035
12997
|
`;
|
|
13036
|
-
const
|
|
13037
|
-
|
|
13038
|
-
|
|
12998
|
+
const FooterTextButton$1 = styled.p `
|
|
12999
|
+
color: var(--ck-body-color-muted);
|
|
13000
|
+
text-align: center;
|
|
13001
|
+
margin-top: 16px;
|
|
13002
|
+
&:hover {
|
|
13003
|
+
${FooterButtonText$1} {
|
|
13004
|
+
color: var(--ck-body-color);
|
|
13005
|
+
}
|
|
13006
|
+
}
|
|
13039
13007
|
`;
|
|
13040
|
-
const QRPlaceholder = styled(motion.div) `
|
|
13041
|
-
--color: var(--ck-qr-dot-color);
|
|
13042
|
-
--bg: var(--ck-qr-background, var(--ck-body-background));
|
|
13043
13008
|
|
|
13044
|
-
|
|
13045
|
-
|
|
13009
|
+
const ProviderInputInner = styled.div `
|
|
13010
|
+
// Styles from react-international-phone (imported here to avoid importing the whole CSS file for nextjs compatibility)
|
|
13011
|
+
.react-international-phone-country-selector{position:relative}.react-international-phone-country-selector-button{display:flex;height:var(--react-international-phone-height, 36px);box-sizing:border-box;align-items:center;justify-content:center;padding:0;border:1px solid var(--react-international-phone-country-selector-border-color, var(--react-international-phone-border-color, gainsboro));margin:0;appearance:button;-webkit-appearance:button;background-color:var(--react-international-phone-country-selector-background-color, var(--react-international-phone-background-color, white));cursor:pointer;text-transform:none;user-select:none}.react-international-phone-country-selector-button:hover{background-color:var(--react-international-phone-country-selector-background-color-hover, whitesmoke)}.react-international-phone-country-selector-button--hide-dropdown{cursor:auto}.react-international-phone-country-selector-button--hide-dropdown:hover{background-color:transparent}.react-international-phone-country-selector-button__button-content{display:flex;align-items:center;justify-content:center}.react-international-phone-country-selector-button__flag-emoji{margin:0 4px}.react-international-phone-country-selector-button__flag-emoji--disabled{opacity:.75}.react-international-phone-country-selector-button__dropdown-arrow{border-top:var(--react-international-phone-country-selector-arrow-size, 4px) solid var(--react-international-phone-country-selector-arrow-color, #777);border-right:var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;border-left:var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;margin-right:4px;transition:all .1s ease-out}.react-international-phone-country-selector-button__dropdown-arrow--active{transform:rotateX(180deg)}.react-international-phone-country-selector-button__dropdown-arrow--disabled{border-top-color:var(--react-international-phone-disabled-country-selector-arrow-color, #999)}.react-international-phone-country-selector-button--disabled,.react-international-phone-country-selector-button--disabled:hover{background-color:var(--react-international-phone-disabled-country-selector-background-color, var(--react-international-phone-disabled-background-color, whitesmoke))}.react-international-phone-country-selector-button--disabled{cursor:auto}.react-international-phone-flag-emoji{width:var(--react-international-phone-flag-width, 24px);height:var(--react-international-phone-flag-height, 24px);box-sizing:border-box}.react-international-phone-country-selector-dropdown{position:absolute;z-index:1;top:var(--react-international-phone-dropdown-top, 44px);left:var(--react-international-phone-dropdown-left, 0);display:flex;width:300px;max-height:200px;flex-direction:column;padding:4px 0;margin:0;background-color:var(--react-international-phone-dropdown-item-background-color, var(--react-international-phone-background-color, white));box-shadow:var(--react-international-phone-dropdown-shadow, 2px 2px 16px rgba(0, 0, 0, .25));color:var(--react-international-phone-dropdown-item-text-color, var(--react-international-phone-text-color, #222));list-style:none;overflow-y:scroll}.react-international-phone-country-selector-dropdown__preferred-list-divider{height:1px;border:none;margin:var(--react-international-phone-dropdown-preferred-list-divider-margin, 0);background:var(--react-international-phone-dropdown-preferred-list-divider-color, var(--react-international-phone-border-color, gainsboro))}.react-international-phone-country-selector-dropdown__list-item{display:flex;min-height:var(--react-international-phone-dropdown-item-height, 28px);box-sizing:border-box;align-items:center;padding:2px 8px}.react-international-phone-country-selector-dropdown__list-item-flag-emoji{margin-right:8px}.react-international-phone-country-selector-dropdown__list-item-country-name{overflow:hidden;margin-right:8px;font-size:var(--react-international-phone-dropdown-item-font-size, 14px);text-overflow:ellipsis;white-space:nowrap}.react-international-phone-country-selector-dropdown__list-item-dial-code{color:var(--react-international-phone-dropdown-item-dial-code-color, gray);font-size:var(--react-international-phone-dropdown-item-font-size, 14px)}.react-international-phone-country-selector-dropdown__list-item:hover{background-color:var(--react-international-phone-selected-dropdown-item-background-color, var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke));cursor:pointer}.react-international-phone-country-selector-dropdown__list-item--selected,.react-international-phone-country-selector-dropdown__list-item--focused{background-color:var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke);color:var(--react-international-phone-selected-dropdown-item-text-color, var(--react-international-phone-text-color, #222))}.react-international-phone-country-selector-dropdown__list-item--selected .react-international-phone-country-selector-dropdown__list-item-dial-code,.react-international-phone-country-selector-dropdown__list-item--focused .react-international-phone-country-selector-dropdown__list-item-dial-code{color:var(--react-international-phone-selected-dropdown-item-dial-code-color, var(--react-international-phone-dropdown-item-dial-code-color, gray))}.react-international-phone-country-selector-dropdown__list-item--focused{background-color:var(--react-international-phone-selected-dropdown-item-background-color, var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke))}.react-international-phone-dial-code-preview{display:flex;align-items:center;justify-content:center;padding:0 8px;border:1px solid var(--react-international-phone-dial-code-preview-border-color, var(--react-international-phone-border-color, gainsboro));margin-right:-1px;background-color:var(--react-international-phone-dial-code-preview-background-color, var(--react-international-phone-background-color, white));color:var(--react-international-phone-dial-code-preview-text-color, var(--react-international-phone-text-color, #222));font-size:var(--react-international-phone-dial-code-preview-font-size, var(--react-international-phone-font-size, 13px))}.react-international-phone-dial-code-preview--disabled{background-color:var(--react-international-phone-dial-code-preview-disabled-background-color, var(--react-international-phone-disabled-background-color, whitesmoke));color:var(--react-international-phone-dial-code-preview-disabled-text-color, var(--react-international-phone-disabled-text-color, #666))}.react-international-phone-input-container{display:flex}.react-international-phone-input-container .react-international-phone-country-selector-button{border-radius:var(--react-international-phone-border-radius, 4px);margin-right:-1px;border-bottom-right-radius:0;border-top-right-radius:0}.react-international-phone-input-container .react-international-phone-input{overflow:visible;height:var(--react-international-phone-height, 36px);box-sizing:border-box;padding:0 8px;border:1px solid var(--react-international-phone-border-color, gainsboro);border-radius:var(--react-international-phone-border-radius, 4px);margin:0;background-color:var(--react-international-phone-background-color, white);border-bottom-left-radius:0;border-top-left-radius:0;color:var(--react-international-phone-text-color, #222);font-family:inherit;font-size:var(--react-international-phone-font-size, 13px)}.react-international-phone-input-container .react-international-phone-input:focus{outline:none}.react-international-phone-input-container .react-international-phone-input--disabled{background-color:var(--react-international-phone-disabled-background-color, whitesmoke);color:var(--react-international-phone-disabled-text-color, #666)}
|
|
13012
|
+
|
|
13013
|
+
border-radius: var(--ck-secondary-button-border-radius);
|
|
13014
|
+
font-size: 1rem;
|
|
13015
|
+
color: var(--ck-body-color);
|
|
13016
|
+
transition: all 0.2s;
|
|
13017
|
+
width: 100%;
|
|
13018
|
+
height: 100%;
|
|
13046
13019
|
display: flex;
|
|
13047
13020
|
align-items: center;
|
|
13048
13021
|
justify-content: center;
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13022
|
+
margin-top: 12px;
|
|
13023
|
+
|
|
13024
|
+
box-shadow: var(--ck-secondary-button-box-shadow);
|
|
13025
|
+
background: var(--ck-secondary-button-background);
|
|
13026
|
+
|
|
13027
|
+
padding-right: 20px;
|
|
13028
|
+
|
|
13029
|
+
&:focus-within {
|
|
13030
|
+
box-shadow: var(--ck-secondary-button-hover-box-shadow);
|
|
13057
13031
|
}
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
border-radius: 3px;
|
|
13071
|
-
box-shadow: 0 0 0 4px var(--bg);
|
|
13072
|
-
}
|
|
13073
|
-
&:nth-child(1) {
|
|
13074
|
-
top: 0;
|
|
13075
|
-
left: 0;
|
|
13076
|
-
}
|
|
13077
|
-
&:nth-child(2) {
|
|
13078
|
-
top: 0;
|
|
13079
|
-
right: 0;
|
|
13080
|
-
}
|
|
13081
|
-
&:nth-child(3) {
|
|
13082
|
-
bottom: 0;
|
|
13083
|
-
left: 0;
|
|
13032
|
+
|
|
13033
|
+
input {
|
|
13034
|
+
padding-left: 20px;
|
|
13035
|
+
padding-right: 10px;
|
|
13036
|
+
|
|
13037
|
+
border: none !important;
|
|
13038
|
+
outline: none !important;
|
|
13039
|
+
background: transparent !important;
|
|
13040
|
+
box-shadow: none !important;
|
|
13041
|
+
|
|
13042
|
+
::placeholder {
|
|
13043
|
+
color: var(--ck-body-color-muted);
|
|
13084
13044
|
}
|
|
13045
|
+
|
|
13046
|
+
width: 100%;
|
|
13047
|
+
height: 100%;
|
|
13085
13048
|
}
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
background-
|
|
13093
|
-
|
|
13049
|
+
|
|
13050
|
+
.react-international-phone-country-selector-button {
|
|
13051
|
+
padding-left: 20px;
|
|
13052
|
+
padding-right: 10px;
|
|
13053
|
+
--react-international-phone-border-color: none;
|
|
13054
|
+
--react-international-phone-border-radius: var(--ck-secondary-button-border-radius);
|
|
13055
|
+
--react-international-phone-background-color: var(--ck-secondary-button-background);
|
|
13056
|
+
--react-international-phone-text-color: var(--ck-body-color);
|
|
13057
|
+
border-radius: var(--ck-secondary-button-border-radius) 0px 0px var(--ck-secondary-button-border-radius);
|
|
13058
|
+
transition: all .2s ease-out;
|
|
13094
13059
|
}
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
);
|
|
13107
|
-
background-size: 200% 100%;
|
|
13108
|
-
animation: ${PlaceholderKeyframes} 1000ms linear infinite both;
|
|
13060
|
+
|
|
13061
|
+
.react-international-phone-country-selector-dropdown {
|
|
13062
|
+
box-shadow: var(--ck-secondary-button-hover-box-shadow);
|
|
13063
|
+
}
|
|
13064
|
+
|
|
13065
|
+
.react-international-phone-country-selector-button__dropdown-arrow {
|
|
13066
|
+
border-top: var(--react-international-phone-country-selector-arrow-size, 4px) solid var(--react-international-phone-country-selector-arrow-color, #777) !important;
|
|
13067
|
+
border-right: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent !important;
|
|
13068
|
+
border-left: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent !important;
|
|
13069
|
+
margin-right: 4px;
|
|
13070
|
+
transition: all .1s ease-out;
|
|
13109
13071
|
}
|
|
13110
13072
|
`;
|
|
13111
|
-
const
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13073
|
+
const EmailInnerButton = styled(motion.button) `
|
|
13074
|
+
color: var(--ck-body-action-color);
|
|
13075
|
+
transition: background-color 200ms ease, transform 100ms ease, color 200ms ease, transition 200ms ease, opacity 200ms ease;
|
|
13076
|
+
border-radius: 16px;
|
|
13077
|
+
|
|
13078
|
+
svg {
|
|
13079
|
+
display: block;
|
|
13080
|
+
position: relative;
|
|
13081
|
+
padding: 4px;
|
|
13082
|
+
}
|
|
13083
|
+
|
|
13084
|
+
&:enabled {
|
|
13085
|
+
cursor: pointer;
|
|
13086
|
+
&:hover {
|
|
13087
|
+
background: var(--ck-body-background-secondary);
|
|
13088
|
+
color: var(--ck-body-action-hover-color);
|
|
13089
|
+
}
|
|
13090
|
+
&:active {
|
|
13091
|
+
transform: scale(0.9);
|
|
13092
|
+
}
|
|
13093
|
+
}
|
|
13119
13094
|
`;
|
|
13120
|
-
const
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13124
|
-
|
|
13095
|
+
const ProvidersButton = styled.div `
|
|
13096
|
+
${ButtonContainer} {
|
|
13097
|
+
height: 64px;
|
|
13098
|
+
font-size: 17px;
|
|
13099
|
+
font-weight: var(--ck-primary-button-font-weight, 500);
|
|
13100
|
+
line-height: 20px;
|
|
13101
|
+
}
|
|
13102
|
+
|
|
13103
|
+
${ProviderInputInner} {
|
|
13104
|
+
height: 64px;
|
|
13105
|
+
}
|
|
13106
|
+
|
|
13107
|
+
&:first-of-type {
|
|
13108
|
+
${ButtonContainer}, ${ProviderInputInner} {
|
|
13109
|
+
margin-top: 0;
|
|
13110
|
+
}
|
|
13111
|
+
}
|
|
13125
13112
|
|
|
13126
|
-
|
|
13113
|
+
${ButtonContainerInner} {
|
|
13114
|
+
padding: 0 20px;
|
|
13115
|
+
justify-content: space-between;
|
|
13116
|
+
}
|
|
13127
13117
|
|
|
13128
|
-
|
|
13118
|
+
${InnerContainer} {
|
|
13119
|
+
justify-content: space-between;
|
|
13120
|
+
width: 100%;
|
|
13121
|
+
max-width: 100%;
|
|
13122
|
+
}
|
|
13123
|
+
`;
|
|
13124
|
+
const ProviderLabel = styled.span `
|
|
13125
|
+
display: flex;
|
|
13126
|
+
align-items: center;
|
|
13127
|
+
gap: 9px;
|
|
13128
|
+
width: 100%;
|
|
13129
|
+
overflow: hidden;
|
|
13130
|
+
white-space: nowrap;
|
|
13131
|
+
text-overflow: ellipsis;
|
|
13132
|
+
padding: 2px 0;
|
|
13133
|
+
`;
|
|
13134
|
+
const ProviderIcon$1 = styled.div `
|
|
13135
|
+
width: 32px;
|
|
13136
|
+
height: 32px;
|
|
13137
|
+
flex-shrink: 0;
|
|
13138
|
+
svg,
|
|
13139
|
+
img {
|
|
13129
13140
|
display: block;
|
|
13130
13141
|
position: relative;
|
|
13142
|
+
pointer-events: none;
|
|
13143
|
+
overflow: hidden;
|
|
13131
13144
|
width: 100%;
|
|
13132
13145
|
height: 100%;
|
|
13133
13146
|
}
|
|
13134
13147
|
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
&:before {
|
|
13145
|
-
pointer-events: none;
|
|
13146
|
-
z-index: 2;
|
|
13147
|
-
content: '';
|
|
13148
|
-
position: absolute;
|
|
13149
|
-
inset: 0;
|
|
13150
|
-
border-radius: inherit;
|
|
13151
|
-
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.02);
|
|
13152
|
-
}
|
|
13153
|
-
`}
|
|
13148
|
+
&[data-shape='squircle'] {
|
|
13149
|
+
border-radius: 22.5%;
|
|
13150
|
+
}
|
|
13151
|
+
&[data-shape='circle'] {
|
|
13152
|
+
border-radius: 100%;
|
|
13153
|
+
}
|
|
13154
|
+
&[data-shape='square'] {
|
|
13155
|
+
border-radius: 0;
|
|
13156
|
+
}
|
|
13154
13157
|
`;
|
|
13155
13158
|
|
|
13156
|
-
|
|
13157
|
-
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
|
|
13161
|
-
|
|
13162
|
-
|
|
13163
|
-
}, children: jsx(QRCode, { uri: value, size: 288, ecl: "M", clearArea: !!(imagePosition === 'center' && image) }) }, value)) : (jsxs(QRPlaceholder, { initial: { opacity: 0.1 }, animate: { opacity: 0.1 }, exit: { opacity: 0, position: 'absolute', inset: [0, 0] }, transition: {
|
|
13164
|
-
duration: 0.2,
|
|
13165
|
-
}, children: [jsx("span", {}), jsx("span", {}), jsx("span", {}), jsx("div", {})] })) })] }) }));
|
|
13166
|
-
}
|
|
13167
|
-
CustomQRCode.displayName = 'CustomQRCode';
|
|
13168
|
-
|
|
13169
|
-
const DownloadApp = () => {
|
|
13170
|
-
var _a, _b, _c;
|
|
13171
|
-
const context = useOpenfort();
|
|
13172
|
-
const wallet = useWallet(context.connector.id);
|
|
13173
|
-
const locales = useLocales({
|
|
13174
|
-
CONNECTORNAME: wallet === null || wallet === void 0 ? void 0 : wallet.name,
|
|
13175
|
-
});
|
|
13176
|
-
if (!wallet)
|
|
13177
|
-
return jsx(Fragment, { children: "Wallet not found" });
|
|
13178
|
-
const downloads = {
|
|
13179
|
-
ios: (_a = wallet.downloadUrls) === null || _a === void 0 ? void 0 : _a.ios,
|
|
13180
|
-
android: (_b = wallet.downloadUrls) === null || _b === void 0 ? void 0 : _b.android,
|
|
13181
|
-
redirect: (_c = wallet.downloadUrls) === null || _c === void 0 ? void 0 : _c.download,
|
|
13182
|
-
};
|
|
13183
|
-
const bodycopy = downloads.ios && downloads.android
|
|
13184
|
-
? locales.downloadAppScreen_iosAndroid
|
|
13185
|
-
: downloads.ios
|
|
13186
|
-
? locales.downloadAppScreen_ios
|
|
13187
|
-
: locales.downloadAppScreen_android;
|
|
13188
|
-
return (jsx(PageContent, { children: jsxs(ModalContent, { style: { paddingBottom: 4, gap: 14 }, children: [downloads.redirect && jsx(CustomQRCode, { value: downloads.redirect }), !downloads.redirect && jsx(Fragment, { children: "No download link available" }), jsx(ModalBody, { style: { fontSize: 15, lineHeight: '20px', padding: '0 12px' }, children: bodycopy })] }) }));
|
|
13189
|
-
};
|
|
13159
|
+
const OtherMethodButton = styled.button `
|
|
13160
|
+
width: 100%;
|
|
13161
|
+
color: var(--ck-body-color-muted);
|
|
13162
|
+
background: none;
|
|
13163
|
+
font-size: 14px;
|
|
13164
|
+
margin-top: 10px;
|
|
13165
|
+
transition: color 0.2s;
|
|
13190
13166
|
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13167
|
+
&:hover {
|
|
13168
|
+
color: var(--ck-body-color);
|
|
13169
|
+
}
|
|
13170
|
+
`;
|
|
13195
13171
|
|
|
13196
|
-
const
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
|
|
13205
|
-
if (
|
|
13206
|
-
|
|
13172
|
+
const OtherMethod = ({ currentMethod, onChangeMethod, }) => {
|
|
13173
|
+
const { uiConfig } = useOpenfort();
|
|
13174
|
+
const otherMethods = useMemo(() => {
|
|
13175
|
+
const allowedMethods = uiConfig.walletRecovery.allowedMethods;
|
|
13176
|
+
const otherMethods = allowedMethods.filter((method) => method !== currentMethod);
|
|
13177
|
+
return otherMethods;
|
|
13178
|
+
}, [uiConfig, currentMethod]);
|
|
13179
|
+
if (otherMethods.length === 0)
|
|
13180
|
+
return null;
|
|
13181
|
+
if (otherMethods.length === 1) {
|
|
13182
|
+
const method = otherMethods[0];
|
|
13183
|
+
let text;
|
|
13184
|
+
switch (method) {
|
|
13185
|
+
case RecoveryMethod.PASSWORD:
|
|
13186
|
+
text = 'Use password recovery instead';
|
|
13187
|
+
break;
|
|
13188
|
+
case RecoveryMethod.AUTOMATIC:
|
|
13189
|
+
text = 'Skip for now';
|
|
13190
|
+
break;
|
|
13191
|
+
case RecoveryMethod.PASSKEY:
|
|
13192
|
+
text = 'Use passkey recovery instead';
|
|
13193
|
+
break;
|
|
13194
|
+
default:
|
|
13195
|
+
text = method;
|
|
13196
|
+
}
|
|
13197
|
+
return (jsx(OtherMethodButton, { onClick: () => {
|
|
13198
|
+
onChangeMethod(method);
|
|
13199
|
+
}, children: text }));
|
|
13207
13200
|
}
|
|
13208
|
-
return
|
|
13201
|
+
return jsx(OtherMethodButton, { onClick: () => onChangeMethod('other'), children: "Choose another recovery method" });
|
|
13209
13202
|
};
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
* });
|
|
13229
|
-
*
|
|
13230
|
-
* // Sign up with email and password
|
|
13231
|
-
* await emailAuth.signUpEmail({
|
|
13232
|
-
* email: 'user@example.com',
|
|
13233
|
-
* password: 'securePassword123',
|
|
13234
|
-
* name: 'John Doe',
|
|
13235
|
-
* });
|
|
13236
|
-
*
|
|
13237
|
-
* // Sign in with email and password
|
|
13238
|
-
* await emailAuth.signInEmail({
|
|
13239
|
-
* email: 'user@example.com',
|
|
13240
|
-
* password: 'securePassword123',
|
|
13241
|
-
* });
|
|
13242
|
-
*
|
|
13243
|
-
* // Request password reset
|
|
13244
|
-
* await emailAuth.requestResetPassword({
|
|
13245
|
-
* email: 'user@example.com',
|
|
13246
|
-
* });
|
|
13247
|
-
*
|
|
13248
|
-
* // Reset password with state token
|
|
13249
|
-
* await emailAuth.resetPassword({
|
|
13250
|
-
* email: 'user@example.com',
|
|
13251
|
-
* password: 'newPassword123',
|
|
13252
|
-
* state: 'reset-token-from-email',
|
|
13253
|
-
* });
|
|
13254
|
-
*
|
|
13255
|
-
* // Verify email with state token
|
|
13256
|
-
* await emailAuth.verifyEmail({
|
|
13257
|
-
* email: 'user@example.com',
|
|
13258
|
-
* state: 'verification-token-from-email',
|
|
13259
|
-
* });
|
|
13260
|
-
*
|
|
13261
|
-
* // Link email to existing authenticated account
|
|
13262
|
-
* await emailAuth.linkEmail({
|
|
13263
|
-
* email: 'secondary@example.com',
|
|
13264
|
-
* password: 'password123',
|
|
13265
|
-
* });
|
|
13266
|
-
*
|
|
13267
|
-
* // Check authentication state
|
|
13268
|
-
* if (emailAuth.isLoading) {
|
|
13269
|
-
* console.log('Processing authentication...');
|
|
13270
|
-
* } else if (emailAuth.isError) {
|
|
13271
|
-
* console.error('Authentication error:', emailAuth.error);
|
|
13272
|
-
* } else if (emailAuth.isSuccess) {
|
|
13273
|
-
* console.log('Authentication successful');
|
|
13274
|
-
* }
|
|
13275
|
-
*
|
|
13276
|
-
* // Handle email verification requirement
|
|
13277
|
-
* if (emailAuth.requiresEmailVerification) {
|
|
13278
|
-
* console.log('Please check your email to verify your account');
|
|
13279
|
-
* }
|
|
13280
|
-
* ```
|
|
13281
|
-
*/
|
|
13282
|
-
const useEmailAuth = (hookOptions = {}) => {
|
|
13283
|
-
const { client, updateUser } = useOpenfortCore();
|
|
13284
|
-
const { isOpen } = useUI();
|
|
13285
|
-
const [requiresEmailVerification, setRequiresEmailVerification] = useState(false);
|
|
13286
|
-
const [status, setStatus] = useState({
|
|
13287
|
-
status: 'idle',
|
|
13288
|
-
});
|
|
13289
|
-
const reset = useCallback(() => {
|
|
13290
|
-
setStatus({
|
|
13291
|
-
status: 'idle',
|
|
13203
|
+
const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
13204
|
+
var _a;
|
|
13205
|
+
const { embeddedState } = useOpenfortCore();
|
|
13206
|
+
const { setRoute, triggerResize } = useOpenfort();
|
|
13207
|
+
const [recoveryError, setRecoveryError] = useState(null);
|
|
13208
|
+
const { createWallet, isWalletRecoveryOTPEnabled, requestWalletRecoverOTP } = useWallets();
|
|
13209
|
+
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
13210
|
+
const [needsOTP, setNeedsOTP] = useState(false);
|
|
13211
|
+
const [otpResponse, setOtpResponse] = useState(null);
|
|
13212
|
+
const [otpStatus, setOtpStatus] = useState('idle');
|
|
13213
|
+
const [error, setError] = useState(false);
|
|
13214
|
+
const handleCompleteOtp = async (otp) => {
|
|
13215
|
+
setOtpStatus('loading');
|
|
13216
|
+
const response = await createWallet({
|
|
13217
|
+
recovery: {
|
|
13218
|
+
recoveryMethod: RecoveryMethod.AUTOMATIC,
|
|
13219
|
+
otpCode: otp,
|
|
13220
|
+
},
|
|
13292
13221
|
});
|
|
13293
|
-
|
|
13222
|
+
if (response.error) {
|
|
13223
|
+
setOtpStatus('error');
|
|
13224
|
+
setError(response.error.message || 'There was an error verifying the OTP');
|
|
13225
|
+
logger.log('Error verifying OTP for wallet recovery', response.error);
|
|
13226
|
+
setTimeout(() => {
|
|
13227
|
+
setOtpStatus('idle');
|
|
13228
|
+
setError(false);
|
|
13229
|
+
}, 1000);
|
|
13230
|
+
}
|
|
13231
|
+
else {
|
|
13232
|
+
setOtpStatus('success');
|
|
13233
|
+
// setTimeout(() => {
|
|
13234
|
+
// setRoute(routes.CONNECTED_SUCCESS)
|
|
13235
|
+
// }, 1000)
|
|
13236
|
+
}
|
|
13237
|
+
};
|
|
13238
|
+
useEffect(() => {
|
|
13239
|
+
// To ensure the wallet is created only once
|
|
13240
|
+
if (shouldCreateWallet) {
|
|
13241
|
+
(async () => {
|
|
13242
|
+
logger.log('Creating wallet Automatic recover');
|
|
13243
|
+
const response = await createWallet();
|
|
13244
|
+
if (response.isOTPRequired && isWalletRecoveryOTPEnabled) {
|
|
13245
|
+
const response = await requestWalletRecoverOTP();
|
|
13246
|
+
setNeedsOTP(true);
|
|
13247
|
+
setOtpResponse(response);
|
|
13248
|
+
if (response.error) {
|
|
13249
|
+
logger.log('Error requesting OTP for wallet recovery', response.error);
|
|
13250
|
+
setRecoveryError(response.error);
|
|
13251
|
+
}
|
|
13252
|
+
}
|
|
13253
|
+
else if (response.error) {
|
|
13254
|
+
logger.log('Error creating wallet', response.error);
|
|
13255
|
+
setRecoveryError(response.error);
|
|
13256
|
+
}
|
|
13257
|
+
triggerResize();
|
|
13258
|
+
})();
|
|
13259
|
+
}
|
|
13260
|
+
}, [shouldCreateWallet]);
|
|
13261
|
+
const [canSendOtp, setCanSendOtp] = useState(true);
|
|
13262
|
+
useEffect(() => {
|
|
13263
|
+
if (embeddedState === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
|
|
13264
|
+
setShouldCreateWallet(true);
|
|
13265
|
+
}
|
|
13266
|
+
}, [embeddedState]);
|
|
13267
|
+
const handleResendClick = useCallback(() => {
|
|
13268
|
+
setOtpStatus('send-otp');
|
|
13269
|
+
setCanSendOtp(false);
|
|
13294
13270
|
}, []);
|
|
13295
|
-
const
|
|
13296
|
-
const
|
|
13297
|
-
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
|
|
13306
|
-
|
|
13307
|
-
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
|
|
13327
|
-
const result = await client.auth.logInWithEmailPassword({
|
|
13328
|
-
email: options.email,
|
|
13329
|
-
password: options.password,
|
|
13330
|
-
});
|
|
13331
|
-
if ('action' in result) {
|
|
13332
|
-
setStatus({
|
|
13333
|
-
status: 'awaiting-input',
|
|
13334
|
-
});
|
|
13335
|
-
client.auth.requestEmailVerification({
|
|
13336
|
-
email: options.email,
|
|
13337
|
-
redirectUrl: buildCallbackUrl({
|
|
13338
|
-
email: options.email,
|
|
13339
|
-
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
13340
|
-
provider: 'email',
|
|
13341
|
-
isOpen,
|
|
13342
|
-
}),
|
|
13343
|
-
});
|
|
13344
|
-
setRequiresEmailVerification(true);
|
|
13345
|
-
return onSuccess({
|
|
13346
|
-
data: { requiresEmailVerification: true },
|
|
13347
|
-
hookOptions,
|
|
13348
|
-
options,
|
|
13349
|
-
});
|
|
13350
|
-
}
|
|
13351
|
-
else {
|
|
13352
|
-
const { wallet } = await tryUseWallet({
|
|
13353
|
-
logoutOnError: (_b = options.logoutOnError) !== null && _b !== void 0 ? _b : hookOptions.logoutOnError,
|
|
13354
|
-
recoverWalletAutomatically: (_c = options.recoverWalletAutomatically) !== null && _c !== void 0 ? _c : hookOptions.recoverWalletAutomatically,
|
|
13355
|
-
});
|
|
13356
|
-
setStatus({
|
|
13357
|
-
status: 'success',
|
|
13358
|
-
});
|
|
13359
|
-
const user = result.user;
|
|
13360
|
-
await updateUser();
|
|
13361
|
-
return onSuccess({
|
|
13362
|
-
data: { user, wallet },
|
|
13363
|
-
hookOptions,
|
|
13364
|
-
options,
|
|
13271
|
+
const isResendDisabled = !canSendOtp || otpStatus === 'sending-otp' || otpStatus === 'send-otp';
|
|
13272
|
+
const sendButtonText = useMemo(() => {
|
|
13273
|
+
if (!canSendOtp)
|
|
13274
|
+
return 'Code Sent!';
|
|
13275
|
+
if (otpStatus === 'sending-otp')
|
|
13276
|
+
return 'Sending...';
|
|
13277
|
+
return 'Resend Code';
|
|
13278
|
+
}, [canSendOtp, otpStatus]);
|
|
13279
|
+
if (needsOTP && isWalletRecoveryOTPEnabled) {
|
|
13280
|
+
if ((!(otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.email) && !(otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.phone)) || ((_a = otpResponse.email) === null || _a === void 0 ? void 0 : _a.includes('@openfort.anonymous'))) {
|
|
13281
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(Loader, { isError: true, description: 'You cannot create a wallet without authentication, please link email or phone to continue.', header: 'Cannot create wallet.' }), jsx(Button, { onClick: () => setRoute(routes.PROVIDERS), children: "Add an authentication method" })] }));
|
|
13282
|
+
}
|
|
13283
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(ModalHeading, { children: "Enter your code" }), jsx(FloatingGraphic, { height: "100px", marginTop: "8px", marginBottom: "10px", logoCenter: {
|
|
13284
|
+
logo: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? jsx(PhoneIcon, {}) : jsx(EmailIcon, {}),
|
|
13285
|
+
} }), jsxs(ModalBody, { children: [jsxs(Body$1, { children: ["Please check ", jsx("b", { children: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.phone : otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.email }), " and enter your code below."] }), jsx(OtpInputStandalone, { length: 9, scale: "80%", onComplete: handleCompleteOtp, isLoading: otpStatus === 'loading', isError: otpStatus === 'error', isSuccess: otpStatus === 'success' }), jsxs(ResultContainer$1, { children: [otpStatus === 'success' && jsx(ModalBody, { "$valid": true, children: "Code verified successfully!" }), otpStatus === 'error' && jsx(ModalBody, { "$error": true, children: error || 'Invalid code. Please try again.' })] }), jsxs(FooterTextButton$1, { children: ["Didn't receive the code?", ' ', jsx(FooterButtonText$1, { type: "button", onClick: handleResendClick, disabled: isResendDisabled, children: sendButtonText })] })] })] }));
|
|
13286
|
+
}
|
|
13287
|
+
return (jsx(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: jsx(Loader, { isError: !!recoveryError, header: recoveryError ? 'Error creating wallet.' : `Creating wallet...`, description: recoveryError ? recoveryError.message : undefined }) }));
|
|
13288
|
+
};
|
|
13289
|
+
const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
13290
|
+
const { triggerResize } = useOpenfort();
|
|
13291
|
+
const { createWallet, error: recoveryError } = useWallets();
|
|
13292
|
+
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
13293
|
+
const { embeddedState } = useOpenfortCore();
|
|
13294
|
+
useEffect(() => {
|
|
13295
|
+
// To ensure the wallet is created only once
|
|
13296
|
+
if (shouldCreateWallet) {
|
|
13297
|
+
(async () => {
|
|
13298
|
+
logger.log('Creating wallet passkey recovery');
|
|
13299
|
+
const response = await createWallet({
|
|
13300
|
+
recovery: {
|
|
13301
|
+
recoveryMethod: RecoveryMethod.PASSKEY,
|
|
13302
|
+
},
|
|
13365
13303
|
});
|
|
13366
|
-
|
|
13304
|
+
if (response.error) {
|
|
13305
|
+
logger.log('Error creating wallet', response.error);
|
|
13306
|
+
setShouldCreateWallet(false);
|
|
13307
|
+
}
|
|
13308
|
+
})();
|
|
13367
13309
|
}
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
error: error,
|
|
13373
|
-
});
|
|
13374
|
-
return onError({
|
|
13375
|
-
hookOptions,
|
|
13376
|
-
options,
|
|
13377
|
-
error: error,
|
|
13378
|
-
});
|
|
13310
|
+
}, [shouldCreateWallet]);
|
|
13311
|
+
useEffect(() => {
|
|
13312
|
+
if (embeddedState === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
|
|
13313
|
+
setShouldCreateWallet(true);
|
|
13379
13314
|
}
|
|
13380
|
-
}, [
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
});
|
|
13399
|
-
setRequiresEmailVerification(false);
|
|
13400
|
-
await client.auth.requestResetPassword({
|
|
13401
|
-
email: options.email,
|
|
13402
|
-
redirectUrl: buildCallbackUrl({
|
|
13403
|
-
email: options.email,
|
|
13404
|
-
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
13405
|
-
provider: 'password',
|
|
13406
|
-
isOpen,
|
|
13407
|
-
}),
|
|
13408
|
-
});
|
|
13409
|
-
setStatus({
|
|
13410
|
-
status: 'success',
|
|
13411
|
-
});
|
|
13412
|
-
setRequiresEmailVerification(true);
|
|
13413
|
-
return onSuccess({
|
|
13414
|
-
data: { requiresEmailVerification: true },
|
|
13415
|
-
hookOptions,
|
|
13416
|
-
options,
|
|
13417
|
-
});
|
|
13315
|
+
}, [embeddedState]);
|
|
13316
|
+
useEffect(() => {
|
|
13317
|
+
if (recoveryError)
|
|
13318
|
+
triggerResize();
|
|
13319
|
+
}, [recoveryError]);
|
|
13320
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(Loader, { icon: jsx(FingerPrintIcon, {}), isError: !!recoveryError, header: recoveryError ? 'Invalid passkey.' : 'Creating wallet with passkey...', description: recoveryError ? 'There was an error creating your passkey. Please try again.' : undefined, onRetry: () => setShouldCreateWallet(true) }), jsx(OtherMethod, { currentMethod: RecoveryMethod.PASSKEY, onChangeMethod: onChangeMethod })] }));
|
|
13321
|
+
};
|
|
13322
|
+
const CreateWalletPasswordRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
13323
|
+
const [recoveryPhrase, setRecoveryPhrase] = useState('');
|
|
13324
|
+
const [recoveryError, setRecoveryError] = useState(false);
|
|
13325
|
+
const { triggerResize } = useOpenfort();
|
|
13326
|
+
const [showPasswordIsTooWeakError, setShowPasswordIsTooWeakError] = useState(false);
|
|
13327
|
+
const [loading, setLoading] = useState(false);
|
|
13328
|
+
const { createWallet } = useWallets();
|
|
13329
|
+
const handleSubmit = async () => {
|
|
13330
|
+
if (getPasswordStrength(recoveryPhrase) < MEDIUM_SCORE_THRESHOLD) {
|
|
13331
|
+
setShowPasswordIsTooWeakError(true);
|
|
13332
|
+
return;
|
|
13418
13333
|
}
|
|
13419
|
-
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13427
|
-
|
|
13428
|
-
|
|
13429
|
-
|
|
13430
|
-
|
|
13334
|
+
setLoading(true);
|
|
13335
|
+
const { error } = await createWallet({
|
|
13336
|
+
recovery: {
|
|
13337
|
+
recoveryMethod: RecoveryMethod.PASSWORD,
|
|
13338
|
+
password: recoveryPhrase,
|
|
13339
|
+
},
|
|
13340
|
+
});
|
|
13341
|
+
setLoading(false);
|
|
13342
|
+
if (error) {
|
|
13343
|
+
setRecoveryError(error.message || 'There was an error recovering your account');
|
|
13344
|
+
}
|
|
13345
|
+
else {
|
|
13346
|
+
logger.log('Recovery success');
|
|
13347
|
+
}
|
|
13348
|
+
};
|
|
13349
|
+
useEffect(() => {
|
|
13350
|
+
if (recoveryError)
|
|
13351
|
+
triggerResize();
|
|
13352
|
+
}, [recoveryError]);
|
|
13353
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(FloatingGraphic, { height: "80px", logoCenter: {
|
|
13354
|
+
logo: jsx(KeyIcon, {}),
|
|
13355
|
+
size: '1.2',
|
|
13356
|
+
}, logoTopLeft: {
|
|
13357
|
+
logo: jsx(ShieldIcon, {}),
|
|
13358
|
+
size: '0.75',
|
|
13359
|
+
}, logoBottomRight: {
|
|
13360
|
+
logo: jsx(LockIcon, {}),
|
|
13361
|
+
size: '0.5',
|
|
13362
|
+
} }), jsx(ModalHeading, { children: "Secure your wallet" }), jsxs(ModalBody, { style: { textAlign: 'center' }, children: [jsx(FitText, { children: "Set a password for your wallet." }), jsxs("form", { onSubmit: (e) => {
|
|
13363
|
+
e.preventDefault();
|
|
13364
|
+
handleSubmit();
|
|
13365
|
+
}, children: [jsx(Input, { value: recoveryPhrase, onChange: (e) => {
|
|
13366
|
+
if (showPasswordIsTooWeakError)
|
|
13367
|
+
setShowPasswordIsTooWeakError(false);
|
|
13368
|
+
setRecoveryPhrase(e.target.value);
|
|
13369
|
+
}, type: "password", placeholder: "Enter your password", autoComplete: "off" }), jsx(PasswordStrengthIndicator, { password: recoveryPhrase, showPasswordIsTooWeakError: showPasswordIsTooWeakError }), jsx(TickList, { items: ['You will use this password to access your wallet', "Make sure it's strong and memorable"] }), recoveryError && (jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, children: jsx(ModalBody, { style: { height: 24, marginTop: 12 }, "$error": true, children: jsx(FitText, { children: recoveryError }) }) }, recoveryError)), jsx(Button, { onClick: handleSubmit, waiting: loading, disabled: loading, children: "Create wallet" })] }), jsx(OtherMethod, { currentMethod: RecoveryMethod.PASSWORD, onChangeMethod: onChangeMethod })] })] }));
|
|
13370
|
+
};
|
|
13371
|
+
const ChooseRecoveryMethod = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
13372
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(ModalHeading, { children: "Choose a recovery method" }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => onChangeMethod(RecoveryMethod.PASSKEY), children: [jsx(ProviderLabel, { children: "Passkey" }), jsx(ProviderIcon$1, { children: jsx(FingerPrintIcon, {}) })] }) }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => onChangeMethod(RecoveryMethod.PASSWORD), children: [jsx(ProviderLabel, { children: "Password" }), jsx(ProviderIcon$1, { children: jsx(KeyIcon, {}) })] }) }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => onChangeMethod(RecoveryMethod.AUTOMATIC), children: [jsx(ProviderLabel, { children: "Automatic" }), jsx(ProviderIcon$1, { children: jsx(LockIcon, {}) })] }) })] }));
|
|
13373
|
+
};
|
|
13374
|
+
const CreateEmbeddedWallet = ({ onBack, logoutOnBack }) => {
|
|
13375
|
+
const { uiConfig, triggerResize } = useOpenfort();
|
|
13376
|
+
const [userSelectedMethod, setUserSelectedMethod] = useState(null);
|
|
13377
|
+
useEffect(() => {
|
|
13378
|
+
triggerResize();
|
|
13379
|
+
}, [userSelectedMethod]);
|
|
13380
|
+
const method = userSelectedMethod !== null && userSelectedMethod !== void 0 ? userSelectedMethod : uiConfig.walletRecovery.defaultMethod;
|
|
13381
|
+
switch (method) {
|
|
13382
|
+
case RecoveryMethod.PASSWORD:
|
|
13383
|
+
return (jsx(CreateWalletPasswordRecovery, { onChangeMethod: setUserSelectedMethod, onBack: onBack, logoutOnBack: logoutOnBack }));
|
|
13384
|
+
case RecoveryMethod.AUTOMATIC:
|
|
13385
|
+
return jsx(CreateWalletAutomaticRecovery, { onBack: onBack, logoutOnBack: logoutOnBack });
|
|
13386
|
+
case RecoveryMethod.PASSKEY:
|
|
13387
|
+
return (jsx(CreateWalletPasskeyRecovery, { onChangeMethod: setUserSelectedMethod, onBack: onBack, logoutOnBack: logoutOnBack }));
|
|
13388
|
+
case 'other':
|
|
13389
|
+
return (jsx(ChooseRecoveryMethod, { onChangeMethod: setUserSelectedMethod, onBack: () => {
|
|
13390
|
+
setUserSelectedMethod(null);
|
|
13391
|
+
}, logoutOnBack: logoutOnBack }));
|
|
13392
|
+
default:
|
|
13393
|
+
logger.error(`Unsupported recovery method: ${userSelectedMethod}${uiConfig.walletRecovery.defaultMethod}`);
|
|
13394
|
+
return null;
|
|
13395
|
+
}
|
|
13396
|
+
};
|
|
13397
|
+
const CreateOrConnectWallet = () => {
|
|
13398
|
+
const [showCreateEmbeddedWallet, setShowCreateEmbeddedWallet] = useState(false);
|
|
13399
|
+
const { setRoute } = useOpenfort();
|
|
13400
|
+
if (showCreateEmbeddedWallet)
|
|
13401
|
+
return jsx(CreateEmbeddedWallet, { onBack: () => setShowCreateEmbeddedWallet(false), logoutOnBack: false });
|
|
13402
|
+
return (jsxs(PageContent, { onBack: routes.PROVIDERS, logoutOnBack: true, children: [jsx(ModalHeading, { children: "Choose an option" }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => setShowCreateEmbeddedWallet(true), children: [jsx(ProviderLabel, { children: "Create Wallet" }), jsx(ProviderIcon$1, { children: jsx(PlusIcon, {}) })] }) }), jsx(ProvidersButton, { children: jsxs(Button, { onClick: () => {
|
|
13403
|
+
setRoute({ route: routes.CONNECTORS, connectType: 'link' });
|
|
13404
|
+
}, children: [jsx(ProviderLabel, { children: "Connect Wallet" }), jsx(ProviderIcon$1, { children: jsx(Logos.OtherWallets, {}) })] }) })] }));
|
|
13405
|
+
};
|
|
13406
|
+
const CreateWallet = () => {
|
|
13407
|
+
const { uiConfig, walletConfig, setRoute } = useOpenfort();
|
|
13408
|
+
const { user } = useOpenfortCore();
|
|
13409
|
+
const { isConnected } = useAccount();
|
|
13410
|
+
useEffect(() => {
|
|
13411
|
+
if (isConnected && user)
|
|
13412
|
+
setRoute(routes.CONNECTED_SUCCESS);
|
|
13413
|
+
}, [isConnected, user]);
|
|
13414
|
+
if (uiConfig.linkWalletOnSignUp === LinkWalletOnSignUpOption.OPTIONAL) {
|
|
13415
|
+
return jsx(CreateOrConnectWallet, {});
|
|
13416
|
+
}
|
|
13417
|
+
if (uiConfig.linkWalletOnSignUp === LinkWalletOnSignUpOption.REQUIRED ||
|
|
13418
|
+
(!walletConfig && uiConfig.linkWalletOnSignUp !== LinkWalletOnSignUpOption.DISABLED)) {
|
|
13419
|
+
return jsx(Connectors, { logoutOnBack: true });
|
|
13420
|
+
}
|
|
13421
|
+
return jsx(CreateEmbeddedWallet, { onBack: routes.PROVIDERS, logoutOnBack: true });
|
|
13422
|
+
};
|
|
13423
|
+
|
|
13424
|
+
function useWindowSize() {
|
|
13425
|
+
const [windowSize, setWindowSize] = useState({
|
|
13426
|
+
width: 0,
|
|
13427
|
+
height: 0,
|
|
13428
|
+
});
|
|
13429
|
+
useEffect(() => {
|
|
13430
|
+
function handleResize() {
|
|
13431
|
+
setWindowSize({
|
|
13432
|
+
width: window.innerWidth,
|
|
13433
|
+
height: window.innerHeight,
|
|
13431
13434
|
});
|
|
13432
13435
|
}
|
|
13433
|
-
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13436
|
+
window.addEventListener('resize', handleResize);
|
|
13437
|
+
handleResize();
|
|
13438
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
13439
|
+
}, []);
|
|
13440
|
+
return windowSize;
|
|
13441
|
+
}
|
|
13442
|
+
|
|
13443
|
+
const generateMatrix = (value, errorCorrectionLevel) => {
|
|
13444
|
+
const arr = Array.prototype.slice.call(QRCodeUtil.create(value, { errorCorrectionLevel }).modules.data, 0);
|
|
13445
|
+
const sqrt = Math.sqrt(arr.length);
|
|
13446
|
+
return arr.reduce((rows, key, index) => (index % sqrt === 0 ? rows.push([key]) : rows[rows.length - 1].push(key)) && rows, []);
|
|
13447
|
+
};
|
|
13448
|
+
function QRCode({ ecl = 'M', size: sizeProp = 200, uri, clearArea = false, image, imageBackground = 'transparent', }) {
|
|
13449
|
+
const logoSize = clearArea ? 76 : 0;
|
|
13450
|
+
const size = sizeProp - 10 * 2;
|
|
13451
|
+
const dots = useMemo(() => {
|
|
13452
|
+
const dots = [];
|
|
13453
|
+
const matrix = generateMatrix(uri, ecl);
|
|
13454
|
+
const cellSize = size / matrix.length;
|
|
13455
|
+
const qrList = [
|
|
13456
|
+
{ x: 0, y: 0 },
|
|
13457
|
+
{ x: 1, y: 0 },
|
|
13458
|
+
{ x: 0, y: 1 },
|
|
13459
|
+
];
|
|
13460
|
+
qrList.forEach(({ x, y }) => {
|
|
13461
|
+
const x1 = (matrix.length - 7) * cellSize * x;
|
|
13462
|
+
const y1 = (matrix.length - 7) * cellSize * y;
|
|
13463
|
+
for (let i = 0; i < 3; i++) {
|
|
13464
|
+
dots.push(jsx("rect", { fill: i % 2 !== 0 ? 'var(--ck-qr-background, var(--ck-body-background))' : 'var(--ck-qr-dot-color)', rx: (i - 2) * -5 + (i === 0 ? 2 : 3), ry: (i - 2) * -5 + (i === 0 ? 2 : 3), width: cellSize * (7 - i * 2), height: cellSize * (7 - i * 2), x: x1 + cellSize * i, y: y1 + cellSize * i }, `${i}-${x}-${y}`));
|
|
13447
13465
|
}
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
password: options.password,
|
|
13454
|
-
token: options.state,
|
|
13455
|
-
});
|
|
13456
|
-
setStatus({
|
|
13457
|
-
status: 'success',
|
|
13458
|
-
});
|
|
13459
|
-
setRequiresEmailVerification(true);
|
|
13460
|
-
return onSuccess({
|
|
13461
|
-
data: { requiresEmailVerification: true },
|
|
13462
|
-
hookOptions,
|
|
13463
|
-
options,
|
|
13464
|
-
});
|
|
13466
|
+
});
|
|
13467
|
+
if (image) {
|
|
13468
|
+
const x1 = (matrix.length - 7) * cellSize * 1;
|
|
13469
|
+
const y1 = (matrix.length - 7) * cellSize * 1;
|
|
13470
|
+
dots.push(jsxs(Fragment, { children: [jsx("rect", { fill: imageBackground, rx: (0 - 2) * -5 + 2, ry: (0 - 2) * -5 + 2, width: cellSize * (7 - 0 * 2), height: cellSize * (7 - 0 * 2), x: x1 + cellSize * 0, y: y1 + cellSize * 0 }), jsx("foreignObject", { width: cellSize * (7 - 0 * 2), height: cellSize * (7 - 0 * 2), x: x1 + cellSize * 0, y: y1 + cellSize * 0, children: jsx("div", { style: { borderRadius: (0 - 2) * -5 + 2, overflow: 'hidden' }, children: image }) })] }));
|
|
13465
13471
|
}
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13472
|
+
const clearArenaSize = Math.floor((logoSize + 25) / cellSize);
|
|
13473
|
+
const matrixMiddleStart = matrix.length / 2 - clearArenaSize / 2;
|
|
13474
|
+
const matrixMiddleEnd = matrix.length / 2 + clearArenaSize / 2 - 1;
|
|
13475
|
+
matrix.forEach((row, i) => {
|
|
13476
|
+
row.forEach((_, j) => {
|
|
13477
|
+
if (matrix[i][j]) {
|
|
13478
|
+
// Do not render dots under position squares
|
|
13479
|
+
if (!((i < 7 && j < 7) || (i > matrix.length - 8 && j < 7) || (i < 7 && j > matrix.length - 8))) {
|
|
13480
|
+
//if (image && i > matrix.length - 9 && j > matrix.length - 9) return;
|
|
13481
|
+
if (image ||
|
|
13482
|
+
!(i > matrixMiddleStart && i < matrixMiddleEnd && j > matrixMiddleStart && j < matrixMiddleEnd)) {
|
|
13483
|
+
dots.push(jsx("circle", { cx: i * cellSize + cellSize / 2, cy: j * cellSize + cellSize / 2, fill: "var(--ck-qr-dot-color)", r: cellSize / 3 }, `qr-dot-${i}-${j}`));
|
|
13484
|
+
}
|
|
13485
|
+
}
|
|
13486
|
+
}
|
|
13478
13487
|
});
|
|
13479
|
-
}
|
|
13480
|
-
|
|
13481
|
-
|
|
13488
|
+
});
|
|
13489
|
+
return dots;
|
|
13490
|
+
}, [ecl, size, uri]);
|
|
13491
|
+
return (jsxs("svg", { height: size, width: size, viewBox: `0 0 ${size} ${size}`, style: {
|
|
13492
|
+
width: size,
|
|
13493
|
+
height: size,
|
|
13494
|
+
}, children: [jsx("title", { children: "QR Code" }), jsx("rect", { fill: "transparent", height: size, width: size }), dots] }));
|
|
13495
|
+
}
|
|
13496
|
+
|
|
13497
|
+
const QRCodeContainer = styled(motion.div) `
|
|
13498
|
+
z-index: 3;
|
|
13499
|
+
position: relative;
|
|
13500
|
+
overflow: hidden;
|
|
13501
|
+
height: 0;
|
|
13502
|
+
padding-bottom: 100% !important;
|
|
13503
|
+
display: flex;
|
|
13504
|
+
align-items: center;
|
|
13505
|
+
justify-content: center;
|
|
13506
|
+
margin: 1px 0 2px;
|
|
13507
|
+
border-radius: var(--ck-qr-border-radius, 24px);
|
|
13508
|
+
background: var(--ck-qr-background, transparent);
|
|
13509
|
+
box-shadow: 0 0 0 1px var(--ck-qr-border-color);
|
|
13510
|
+
backface-visibility: hidden;
|
|
13511
|
+
svg {
|
|
13512
|
+
display: block;
|
|
13513
|
+
max-width: 100%;
|
|
13514
|
+
width: 100%;
|
|
13515
|
+
height: auto;
|
|
13516
|
+
}
|
|
13517
|
+
`;
|
|
13518
|
+
const QRCodeContent = styled(motion.div) `
|
|
13519
|
+
position: absolute;
|
|
13520
|
+
inset: 13px;
|
|
13521
|
+
svg {
|
|
13522
|
+
width: 100% !important;
|
|
13523
|
+
height: auto !important;
|
|
13524
|
+
}
|
|
13525
|
+
`;
|
|
13526
|
+
const PlaceholderKeyframes = keyframes `
|
|
13527
|
+
0%{ background-position: 100% 0; }
|
|
13528
|
+
100%{ background-position: -100% 0; }
|
|
13529
|
+
`;
|
|
13530
|
+
const QRPlaceholder = styled(motion.div) `
|
|
13531
|
+
--color: var(--ck-qr-dot-color);
|
|
13532
|
+
--bg: var(--ck-qr-background, var(--ck-body-background));
|
|
13533
|
+
|
|
13534
|
+
position: absolute;
|
|
13535
|
+
inset: 0;
|
|
13536
|
+
display: flex;
|
|
13537
|
+
align-items: center;
|
|
13538
|
+
justify-content: center;
|
|
13539
|
+
> div {
|
|
13540
|
+
z-index: 4;
|
|
13541
|
+
position: relative;
|
|
13542
|
+
width: 28%;
|
|
13543
|
+
height: 28%;
|
|
13544
|
+
border-radius: 20px;
|
|
13545
|
+
background: var(--bg);
|
|
13546
|
+
box-shadow: 0 0 0 7px var(--bg);
|
|
13547
|
+
}
|
|
13548
|
+
> span {
|
|
13549
|
+
z-index: 4;
|
|
13550
|
+
position: absolute;
|
|
13551
|
+
background: var(--color);
|
|
13552
|
+
border-radius: 12px;
|
|
13553
|
+
width: 13.25%;
|
|
13554
|
+
height: 13.25%;
|
|
13555
|
+
box-shadow: 0 0 0 4px var(--bg);
|
|
13556
|
+
&:before {
|
|
13557
|
+
content: '';
|
|
13558
|
+
position: absolute;
|
|
13559
|
+
inset: 9px;
|
|
13560
|
+
border-radius: 3px;
|
|
13561
|
+
box-shadow: 0 0 0 4px var(--bg);
|
|
13562
|
+
}
|
|
13563
|
+
&:nth-child(1) {
|
|
13564
|
+
top: 0;
|
|
13565
|
+
left: 0;
|
|
13566
|
+
}
|
|
13567
|
+
&:nth-child(2) {
|
|
13568
|
+
top: 0;
|
|
13569
|
+
right: 0;
|
|
13570
|
+
}
|
|
13571
|
+
&:nth-child(3) {
|
|
13572
|
+
bottom: 0;
|
|
13573
|
+
left: 0;
|
|
13574
|
+
}
|
|
13575
|
+
}
|
|
13576
|
+
&:before {
|
|
13577
|
+
z-index: 3;
|
|
13578
|
+
content: '';
|
|
13579
|
+
position: absolute;
|
|
13580
|
+
inset: 0;
|
|
13581
|
+
background: repeat;
|
|
13582
|
+
background-size: 1.888% 1.888%;
|
|
13583
|
+
background-image: radial-gradient(var(--color) 41%, transparent 41%);
|
|
13584
|
+
}
|
|
13585
|
+
&:after {
|
|
13586
|
+
z-index: 5;
|
|
13587
|
+
content: '';
|
|
13588
|
+
position: absolute;
|
|
13589
|
+
inset: 0;
|
|
13590
|
+
transform: scale(1.5) rotate(45deg);
|
|
13591
|
+
background-image: linear-gradient(
|
|
13592
|
+
90deg,
|
|
13593
|
+
rgba(255, 255, 255, 0) 50%,
|
|
13594
|
+
rgba(255, 255, 255, 1),
|
|
13595
|
+
rgba(255, 255, 255, 0)
|
|
13596
|
+
);
|
|
13597
|
+
background-size: 200% 100%;
|
|
13598
|
+
animation: ${PlaceholderKeyframes} 1000ms linear infinite both;
|
|
13599
|
+
}
|
|
13600
|
+
`;
|
|
13601
|
+
const LogoContainer$1 = styled(motion.div) `
|
|
13602
|
+
z-index: 6;
|
|
13603
|
+
position: absolute;
|
|
13604
|
+
top: 0;
|
|
13605
|
+
left: 0;
|
|
13606
|
+
width: 100%;
|
|
13607
|
+
height: 100%;
|
|
13608
|
+
transform: translateY(50%) scale(0.9999); // Shifting fix
|
|
13609
|
+
`;
|
|
13610
|
+
const LogoIcon = styled(motion.div) `
|
|
13611
|
+
z-index: 6;
|
|
13612
|
+
position: absolute;
|
|
13613
|
+
left: 50%;
|
|
13614
|
+
overflow: hidden;
|
|
13615
|
+
|
|
13616
|
+
transform: translate(-50%, -50%) scale(0.9999); // Shifting fix
|
|
13617
|
+
|
|
13618
|
+
svg {
|
|
13619
|
+
display: block;
|
|
13620
|
+
position: relative;
|
|
13621
|
+
width: 100%;
|
|
13622
|
+
height: 100%;
|
|
13623
|
+
}
|
|
13624
|
+
|
|
13625
|
+
${(props) => props.$wcLogo
|
|
13626
|
+
? css `
|
|
13627
|
+
width: 29%;
|
|
13628
|
+
height: 20.5%;
|
|
13629
|
+
`
|
|
13630
|
+
: css `
|
|
13631
|
+
width: 28%;
|
|
13632
|
+
height: 28%;
|
|
13633
|
+
border-radius: 17px;
|
|
13634
|
+
&:before {
|
|
13635
|
+
pointer-events: none;
|
|
13636
|
+
z-index: 2;
|
|
13637
|
+
content: '';
|
|
13638
|
+
position: absolute;
|
|
13639
|
+
inset: 0;
|
|
13640
|
+
border-radius: inherit;
|
|
13641
|
+
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.02);
|
|
13642
|
+
}
|
|
13643
|
+
`}
|
|
13644
|
+
`;
|
|
13645
|
+
|
|
13646
|
+
function CustomQRCode({ value, image, imageBackground, imagePosition = 'center', tooltipMessage }) {
|
|
13647
|
+
const windowSize = useWindowSize();
|
|
13648
|
+
const Logo = windowSize.width > 920 && tooltipMessage ? (jsx(Tooltip, { xOffset: 139, yOffset: 5, delay: 0.1, message: tooltipMessage, children: image })) : (image);
|
|
13649
|
+
return (jsx(QRCodeContainer, { children: jsxs(QRCodeContent, { children: [image && (jsx(LogoContainer$1, { children: jsx(LogoIcon, { "$wcLogo": imagePosition !== 'center', style: {
|
|
13650
|
+
background: imagePosition === 'center' ? imageBackground : undefined,
|
|
13651
|
+
}, children: Logo }) })), jsx(AnimatePresence, { initial: false, children: value ? (jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0, position: 'absolute', inset: [0, 0] }, transition: {
|
|
13652
|
+
duration: 0.2,
|
|
13653
|
+
}, children: jsx(QRCode, { uri: value, size: 288, ecl: "M", clearArea: !!(imagePosition === 'center' && image) }) }, value)) : (jsxs(QRPlaceholder, { initial: { opacity: 0.1 }, animate: { opacity: 0.1 }, exit: { opacity: 0, position: 'absolute', inset: [0, 0] }, transition: {
|
|
13654
|
+
duration: 0.2,
|
|
13655
|
+
}, children: [jsx("span", {}), jsx("span", {}), jsx("span", {}), jsx("div", {})] })) })] }) }));
|
|
13656
|
+
}
|
|
13657
|
+
CustomQRCode.displayName = 'CustomQRCode';
|
|
13658
|
+
|
|
13659
|
+
const DownloadApp = () => {
|
|
13660
|
+
var _a, _b, _c;
|
|
13661
|
+
const context = useOpenfort();
|
|
13662
|
+
const wallet = useWallet(context.connector.id);
|
|
13663
|
+
const locales = useLocales({
|
|
13664
|
+
CONNECTORNAME: wallet === null || wallet === void 0 ? void 0 : wallet.name,
|
|
13665
|
+
});
|
|
13666
|
+
if (!wallet)
|
|
13667
|
+
return jsx(Fragment, { children: "Wallet not found" });
|
|
13668
|
+
const downloads = {
|
|
13669
|
+
ios: (_a = wallet.downloadUrls) === null || _a === void 0 ? void 0 : _a.ios,
|
|
13670
|
+
android: (_b = wallet.downloadUrls) === null || _b === void 0 ? void 0 : _b.android,
|
|
13671
|
+
redirect: (_c = wallet.downloadUrls) === null || _c === void 0 ? void 0 : _c.download,
|
|
13672
|
+
};
|
|
13673
|
+
const bodycopy = downloads.ios && downloads.android
|
|
13674
|
+
? locales.downloadAppScreen_iosAndroid
|
|
13675
|
+
: downloads.ios
|
|
13676
|
+
? locales.downloadAppScreen_ios
|
|
13677
|
+
: locales.downloadAppScreen_android;
|
|
13678
|
+
return (jsx(PageContent, { children: jsxs(ModalContent, { style: { paddingBottom: 4, gap: 14 }, children: [downloads.redirect && jsx(CustomQRCode, { value: downloads.redirect }), !downloads.redirect && jsx(Fragment, { children: "No download link available" }), jsx(ModalBody, { style: { fontSize: 15, lineHeight: '20px', padding: '0 12px' }, children: bodycopy })] }) }));
|
|
13679
|
+
};
|
|
13680
|
+
|
|
13681
|
+
const isValidEmail = (email) => {
|
|
13682
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
13683
|
+
return emailRegex.test(email);
|
|
13684
|
+
};
|
|
13685
|
+
|
|
13686
|
+
const buildCallbackUrl = ({ email, callbackUrl, provider, isOpen, }) => {
|
|
13687
|
+
if (callbackUrl && !callbackUrl.startsWith('http')) {
|
|
13688
|
+
callbackUrl = `${window.location.origin}${callbackUrl.startsWith('/') ? '' : '/'}${callbackUrl}`;
|
|
13689
|
+
}
|
|
13690
|
+
const redirectUrl = new URL(callbackUrl || window.location.origin);
|
|
13691
|
+
redirectUrl.searchParams.append('openfortAuthProvider', provider);
|
|
13692
|
+
if (email) {
|
|
13693
|
+
redirectUrl.searchParams.append('email', email);
|
|
13694
|
+
}
|
|
13695
|
+
if (isOpen) {
|
|
13696
|
+
redirectUrl.searchParams.append('openfortEmailVerificationUI', 'true');
|
|
13697
|
+
}
|
|
13698
|
+
return redirectUrl.toString();
|
|
13699
|
+
};
|
|
13700
|
+
|
|
13701
|
+
/**
|
|
13702
|
+
* Hook for email-based authentication operations
|
|
13703
|
+
*
|
|
13704
|
+
* This hook manages email authentication flows including sign-in, sign-up, password reset,
|
|
13705
|
+
* email verification, and email linking. It handles both password and passwordless authentication
|
|
13706
|
+
* and automatically manages wallet connection after successful authentication.
|
|
13707
|
+
*
|
|
13708
|
+
* @param hookOptions - Optional configuration with callback functions and authentication options
|
|
13709
|
+
* @returns Current authentication state with email auth actions
|
|
13710
|
+
*
|
|
13711
|
+
* @example
|
|
13712
|
+
* ```tsx
|
|
13713
|
+
* const emailAuth = useEmailAuth({
|
|
13714
|
+
* onSignInEmailSuccess: (result) => console.log('Signed in:', result.user),
|
|
13715
|
+
* onSignInEmailError: (error) => console.error('Sign-in failed:', error),
|
|
13716
|
+
* emailVerificationRedirectTo: 'https://yourapp.com/verify',
|
|
13717
|
+
* recoverWalletAutomatically: true,
|
|
13718
|
+
* });
|
|
13719
|
+
*
|
|
13720
|
+
* // Sign up with email and password
|
|
13721
|
+
* await emailAuth.signUpEmail({
|
|
13722
|
+
* email: 'user@example.com',
|
|
13723
|
+
* password: 'securePassword123',
|
|
13724
|
+
* name: 'John Doe',
|
|
13725
|
+
* });
|
|
13726
|
+
*
|
|
13727
|
+
* // Sign in with email and password
|
|
13728
|
+
* await emailAuth.signInEmail({
|
|
13729
|
+
* email: 'user@example.com',
|
|
13730
|
+
* password: 'securePassword123',
|
|
13731
|
+
* });
|
|
13732
|
+
*
|
|
13733
|
+
* // Request password reset
|
|
13734
|
+
* await emailAuth.requestResetPassword({
|
|
13735
|
+
* email: 'user@example.com',
|
|
13736
|
+
* });
|
|
13737
|
+
*
|
|
13738
|
+
* // Reset password with state token
|
|
13739
|
+
* await emailAuth.resetPassword({
|
|
13740
|
+
* email: 'user@example.com',
|
|
13741
|
+
* password: 'newPassword123',
|
|
13742
|
+
* state: 'reset-token-from-email',
|
|
13743
|
+
* });
|
|
13744
|
+
*
|
|
13745
|
+
* // Verify email with state token
|
|
13746
|
+
* await emailAuth.verifyEmail({
|
|
13747
|
+
* email: 'user@example.com',
|
|
13748
|
+
* state: 'verification-token-from-email',
|
|
13749
|
+
* });
|
|
13750
|
+
*
|
|
13751
|
+
* // Link email to existing authenticated account
|
|
13752
|
+
* await emailAuth.linkEmail({
|
|
13753
|
+
* email: 'secondary@example.com',
|
|
13754
|
+
* password: 'password123',
|
|
13755
|
+
* });
|
|
13756
|
+
*
|
|
13757
|
+
* // Check authentication state
|
|
13758
|
+
* if (emailAuth.isLoading) {
|
|
13759
|
+
* console.log('Processing authentication...');
|
|
13760
|
+
* } else if (emailAuth.isError) {
|
|
13761
|
+
* console.error('Authentication error:', emailAuth.error);
|
|
13762
|
+
* } else if (emailAuth.isSuccess) {
|
|
13763
|
+
* console.log('Authentication successful');
|
|
13764
|
+
* }
|
|
13765
|
+
*
|
|
13766
|
+
* // Handle email verification requirement
|
|
13767
|
+
* if (emailAuth.requiresEmailVerification) {
|
|
13768
|
+
* console.log('Please check your email to verify your account');
|
|
13769
|
+
* }
|
|
13770
|
+
* ```
|
|
13771
|
+
*/
|
|
13772
|
+
const useEmailAuth = (hookOptions = {}) => {
|
|
13773
|
+
const { client, updateUser } = useOpenfortCore();
|
|
13774
|
+
const { isOpen } = useUI();
|
|
13775
|
+
const [requiresEmailVerification, setRequiresEmailVerification] = useState(false);
|
|
13776
|
+
const [status, setStatus] = useState({
|
|
13777
|
+
status: 'idle',
|
|
13778
|
+
});
|
|
13779
|
+
const reset = useCallback(() => {
|
|
13780
|
+
setStatus({
|
|
13781
|
+
status: 'idle',
|
|
13782
|
+
});
|
|
13783
|
+
setRequiresEmailVerification(false);
|
|
13784
|
+
}, []);
|
|
13785
|
+
const { tryUseWallet } = useConnectToWalletPostAuth();
|
|
13786
|
+
const signInEmail = useCallback(async (options) => {
|
|
13482
13787
|
var _a, _b, _c;
|
|
13483
13788
|
try {
|
|
13484
|
-
if (!options.email || !options.password) {
|
|
13485
|
-
const error = new OpenfortError('Email and password are required', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13486
|
-
setStatus({
|
|
13487
|
-
status: 'error',
|
|
13488
|
-
error,
|
|
13489
|
-
});
|
|
13490
|
-
return onError({
|
|
13491
|
-
hookOptions,
|
|
13492
|
-
options,
|
|
13493
|
-
error,
|
|
13494
|
-
});
|
|
13495
|
-
}
|
|
13496
|
-
if (!isValidEmail(options.email)) {
|
|
13497
|
-
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13498
|
-
setStatus({
|
|
13499
|
-
status: 'error',
|
|
13500
|
-
error,
|
|
13501
|
-
});
|
|
13502
|
-
return onError({
|
|
13503
|
-
hookOptions,
|
|
13504
|
-
options,
|
|
13505
|
-
error,
|
|
13506
|
-
});
|
|
13507
|
-
}
|
|
13508
13789
|
setStatus({
|
|
13509
13790
|
status: 'loading',
|
|
13510
13791
|
});
|
|
13511
13792
|
setRequiresEmailVerification(false);
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
password: options.password,
|
|
13515
|
-
callbackURL: buildCallbackUrl({
|
|
13516
|
-
email: options.email,
|
|
13517
|
-
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
13518
|
-
provider: 'email',
|
|
13519
|
-
isOpen,
|
|
13520
|
-
}),
|
|
13521
|
-
...(options.name && { name: options.name }),
|
|
13522
|
-
});
|
|
13523
|
-
// TODO: TMP FIX
|
|
13524
|
-
if ('token' in result && result.token !== null) {
|
|
13525
|
-
const { wallet } = await tryUseWallet({
|
|
13526
|
-
logoutOnError: (_b = options.logoutOnError) !== null && _b !== void 0 ? _b : hookOptions.logoutOnError,
|
|
13527
|
-
recoverWalletAutomatically: (_c = options.recoverWalletAutomatically) !== null && _c !== void 0 ? _c : hookOptions.recoverWalletAutomatically,
|
|
13528
|
-
});
|
|
13529
|
-
setStatus({
|
|
13530
|
-
status: 'success',
|
|
13531
|
-
});
|
|
13532
|
-
const user = result.user;
|
|
13533
|
-
await updateUser(user);
|
|
13534
|
-
return onSuccess({
|
|
13535
|
-
data: { user, wallet },
|
|
13536
|
-
hookOptions,
|
|
13537
|
-
options,
|
|
13538
|
-
});
|
|
13539
|
-
}
|
|
13540
|
-
else {
|
|
13541
|
-
setStatus({
|
|
13542
|
-
status: 'awaiting-input',
|
|
13543
|
-
});
|
|
13544
|
-
setRequiresEmailVerification(true);
|
|
13545
|
-
return onSuccess({
|
|
13546
|
-
data: { requiresEmailVerification: true },
|
|
13547
|
-
hookOptions,
|
|
13548
|
-
options,
|
|
13549
|
-
});
|
|
13550
|
-
}
|
|
13551
|
-
}
|
|
13552
|
-
catch (e) {
|
|
13553
|
-
const error = new OpenfortError('Failed to login with email and password', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: e });
|
|
13554
|
-
setStatus({
|
|
13555
|
-
status: 'error',
|
|
13556
|
-
error,
|
|
13557
|
-
});
|
|
13558
|
-
return onError({
|
|
13559
|
-
hookOptions,
|
|
13560
|
-
options,
|
|
13561
|
-
error: error,
|
|
13562
|
-
});
|
|
13563
|
-
}
|
|
13564
|
-
}, [client, setStatus, updateUser, hookOptions, isOpen]);
|
|
13565
|
-
const linkEmail = useCallback(async (options) => {
|
|
13566
|
-
var _a;
|
|
13567
|
-
try {
|
|
13568
|
-
if (!isValidEmail(options.email)) {
|
|
13569
|
-
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13793
|
+
if (!options.email || !options.password) {
|
|
13794
|
+
const error = new OpenfortError('Email and password are required', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13570
13795
|
setStatus({
|
|
13571
13796
|
status: 'error',
|
|
13572
13797
|
error,
|
|
@@ -13577,11 +13802,8 @@ const useEmailAuth = (hookOptions = {}) => {
|
|
|
13577
13802
|
error,
|
|
13578
13803
|
});
|
|
13579
13804
|
}
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
if (!authToken) {
|
|
13583
|
-
logger.log('No token found');
|
|
13584
|
-
const error = new OpenfortError('No token found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
13805
|
+
if (!isValidEmail(options.email)) {
|
|
13806
|
+
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13585
13807
|
setStatus({
|
|
13586
13808
|
status: 'error',
|
|
13587
13809
|
error,
|
|
@@ -13592,29 +13814,49 @@ const useEmailAuth = (hookOptions = {}) => {
|
|
|
13592
13814
|
error,
|
|
13593
13815
|
});
|
|
13594
13816
|
}
|
|
13595
|
-
await client.auth.
|
|
13596
|
-
// name: options.name || '',
|
|
13817
|
+
const result = await client.auth.logInWithEmailPassword({
|
|
13597
13818
|
email: options.email,
|
|
13598
|
-
|
|
13599
|
-
// method: 'password',
|
|
13600
|
-
callbackURL: buildCallbackUrl({
|
|
13601
|
-
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
13602
|
-
email: options.email,
|
|
13603
|
-
provider: 'email',
|
|
13604
|
-
isOpen,
|
|
13605
|
-
}),
|
|
13606
|
-
});
|
|
13607
|
-
logger.log('Email linked successfully');
|
|
13608
|
-
return onSuccess({
|
|
13609
|
-
data: {},
|
|
13610
|
-
hookOptions,
|
|
13611
|
-
options,
|
|
13819
|
+
password: options.password,
|
|
13612
13820
|
});
|
|
13821
|
+
if ('action' in result) {
|
|
13822
|
+
setStatus({
|
|
13823
|
+
status: 'awaiting-input',
|
|
13824
|
+
});
|
|
13825
|
+
client.auth.requestEmailVerification({
|
|
13826
|
+
email: options.email,
|
|
13827
|
+
redirectUrl: buildCallbackUrl({
|
|
13828
|
+
email: options.email,
|
|
13829
|
+
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
13830
|
+
provider: 'email',
|
|
13831
|
+
isOpen,
|
|
13832
|
+
}),
|
|
13833
|
+
});
|
|
13834
|
+
setRequiresEmailVerification(true);
|
|
13835
|
+
return onSuccess({
|
|
13836
|
+
data: { requiresEmailVerification: true },
|
|
13837
|
+
hookOptions,
|
|
13838
|
+
options,
|
|
13839
|
+
});
|
|
13840
|
+
}
|
|
13841
|
+
else {
|
|
13842
|
+
const { wallet } = await tryUseWallet({
|
|
13843
|
+
logoutOnError: (_b = options.logoutOnError) !== null && _b !== void 0 ? _b : hookOptions.logoutOnError,
|
|
13844
|
+
recoverWalletAutomatically: (_c = options.recoverWalletAutomatically) !== null && _c !== void 0 ? _c : hookOptions.recoverWalletAutomatically,
|
|
13845
|
+
});
|
|
13846
|
+
setStatus({
|
|
13847
|
+
status: 'success',
|
|
13848
|
+
});
|
|
13849
|
+
const user = result.user;
|
|
13850
|
+
await updateUser();
|
|
13851
|
+
return onSuccess({
|
|
13852
|
+
data: { user, wallet },
|
|
13853
|
+
hookOptions,
|
|
13854
|
+
options,
|
|
13855
|
+
});
|
|
13856
|
+
}
|
|
13613
13857
|
}
|
|
13614
13858
|
catch (e) {
|
|
13615
|
-
const error = new OpenfortError('Failed to
|
|
13616
|
-
error: e,
|
|
13617
|
-
});
|
|
13859
|
+
const error = new OpenfortError('Failed to login with email and password', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: e });
|
|
13618
13860
|
setStatus({
|
|
13619
13861
|
status: 'error',
|
|
13620
13862
|
error: error,
|
|
@@ -13625,11 +13867,9 @@ const useEmailAuth = (hookOptions = {}) => {
|
|
|
13625
13867
|
error: error,
|
|
13626
13868
|
});
|
|
13627
13869
|
}
|
|
13628
|
-
}, [client, setStatus, updateUser, hookOptions
|
|
13629
|
-
const
|
|
13630
|
-
|
|
13631
|
-
status: 'loading',
|
|
13632
|
-
});
|
|
13870
|
+
}, [client, setStatus, updateUser, hookOptions]);
|
|
13871
|
+
const requestResetPassword = useCallback(async (options) => {
|
|
13872
|
+
var _a;
|
|
13633
13873
|
try {
|
|
13634
13874
|
if (!isValidEmail(options.email)) {
|
|
13635
13875
|
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
@@ -13643,199 +13883,46 @@ const useEmailAuth = (hookOptions = {}) => {
|
|
|
13643
13883
|
error,
|
|
13644
13884
|
});
|
|
13645
13885
|
}
|
|
13646
|
-
|
|
13647
|
-
|
|
13886
|
+
setStatus({
|
|
13887
|
+
status: 'loading',
|
|
13888
|
+
});
|
|
13889
|
+
setRequiresEmailVerification(false);
|
|
13890
|
+
await client.auth.requestResetPassword({
|
|
13891
|
+
email: options.email,
|
|
13892
|
+
redirectUrl: buildCallbackUrl({
|
|
13893
|
+
email: options.email,
|
|
13894
|
+
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
13895
|
+
provider: 'password',
|
|
13896
|
+
isOpen,
|
|
13897
|
+
}),
|
|
13648
13898
|
});
|
|
13649
13899
|
setStatus({
|
|
13650
13900
|
status: 'success',
|
|
13651
13901
|
});
|
|
13902
|
+
setRequiresEmailVerification(true);
|
|
13652
13903
|
return onSuccess({
|
|
13904
|
+
data: { requiresEmailVerification: true },
|
|
13653
13905
|
hookOptions,
|
|
13654
13906
|
options,
|
|
13655
|
-
data: {
|
|
13656
|
-
email: options.email,
|
|
13657
|
-
},
|
|
13658
13907
|
});
|
|
13659
13908
|
}
|
|
13660
13909
|
catch (e) {
|
|
13661
|
-
const error = new OpenfortError('Failed to
|
|
13910
|
+
const error = new OpenfortError('Failed to reset password', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
|
|
13662
13911
|
error: e,
|
|
13663
|
-
});
|
|
13664
|
-
setStatus({
|
|
13665
|
-
status: 'error',
|
|
13666
|
-
error,
|
|
13667
|
-
});
|
|
13668
|
-
logger.log('Error verifying email', e);
|
|
13669
|
-
return onError({
|
|
13670
|
-
hookOptions,
|
|
13671
|
-
options,
|
|
13672
|
-
error,
|
|
13673
|
-
});
|
|
13674
|
-
}
|
|
13675
|
-
}, [client, hookOptions]);
|
|
13676
|
-
return {
|
|
13677
|
-
signInEmail,
|
|
13678
|
-
signUpEmail,
|
|
13679
|
-
verifyEmail,
|
|
13680
|
-
linkEmail,
|
|
13681
|
-
requestResetPassword,
|
|
13682
|
-
resetPassword,
|
|
13683
|
-
reset,
|
|
13684
|
-
...mapStatus(status),
|
|
13685
|
-
requiresEmailVerification,
|
|
13686
|
-
isAwaitingInput: status.status === 'awaiting-input',
|
|
13687
|
-
};
|
|
13688
|
-
};
|
|
13689
|
-
|
|
13690
|
-
const FooterContainer = styled.span `
|
|
13691
|
-
padding: 12px 4px 0px 0px;
|
|
13692
|
-
display: flex;
|
|
13693
|
-
align-items: center;
|
|
13694
|
-
justify-content: center;
|
|
13695
|
-
gap: 6px;
|
|
13696
|
-
line-height: 1rem;
|
|
13697
|
-
color: var(--ck-body-disclaimer-color, var(--ck-body-color-muted, inherit));
|
|
13698
|
-
|
|
13699
|
-
& button {
|
|
13700
|
-
color: var(--ck-body-disclaimer-link-color, inherit);
|
|
13701
|
-
font-weight: var(--ck-body-disclaimer-font-weight, 400);
|
|
13702
|
-
text-decoration: none;
|
|
13703
|
-
transition: color 200ms ease;
|
|
13704
|
-
&:hover {
|
|
13705
|
-
color: var(--ck-body-disclaimer-link-hover-color, inherit);
|
|
13706
|
-
}
|
|
13707
|
-
}
|
|
13708
|
-
`;
|
|
13709
|
-
|
|
13710
|
-
// TODO: Localize
|
|
13711
|
-
const textVariants$1 = {
|
|
13712
|
-
initial: {
|
|
13713
|
-
opacity: 0,
|
|
13714
|
-
},
|
|
13715
|
-
animate: {
|
|
13716
|
-
opacity: 1,
|
|
13717
|
-
transition: {
|
|
13718
|
-
duration: 0.3,
|
|
13719
|
-
ease: [0.25, 1, 0.5, 1],
|
|
13720
|
-
},
|
|
13721
|
-
},
|
|
13722
|
-
exit: {
|
|
13723
|
-
position: 'absolute',
|
|
13724
|
-
opacity: 0,
|
|
13725
|
-
transition: {
|
|
13726
|
-
duration: 0,
|
|
13727
|
-
},
|
|
13728
|
-
},
|
|
13729
|
-
};
|
|
13730
|
-
const EmailLogin = () => {
|
|
13731
|
-
const [password, setPassword] = React.useState('');
|
|
13732
|
-
const { setRoute, triggerResize, setEmailInput: setEmail, emailInput: email, previousRoute } = useOpenfort();
|
|
13733
|
-
const [isRegister, setIsRegister] = React.useState(false);
|
|
13734
|
-
const { signUpEmail, signInEmail, error: loginError, isLoading: loginLoading, } = useEmailAuth({
|
|
13735
|
-
recoverWalletAutomatically: false,
|
|
13736
|
-
});
|
|
13737
|
-
const handleSubmit = async () => {
|
|
13738
|
-
if (isRegister) {
|
|
13739
|
-
return handleSignUp();
|
|
13740
|
-
}
|
|
13741
|
-
setIsRegister(false);
|
|
13742
|
-
setTimeout(() => {
|
|
13743
|
-
triggerResize();
|
|
13744
|
-
});
|
|
13745
|
-
const { error, requiresEmailVerification } = await signInEmail({
|
|
13746
|
-
email,
|
|
13747
|
-
password,
|
|
13748
|
-
});
|
|
13749
|
-
logger.log('SIGN IN RESPONSE', { error, requiresEmailVerification });
|
|
13750
|
-
if (!error) {
|
|
13751
|
-
if (requiresEmailVerification) {
|
|
13752
|
-
setRoute(routes.EMAIL_VERIFICATION);
|
|
13753
|
-
}
|
|
13754
|
-
else {
|
|
13755
|
-
setRoute(routes.LOAD_WALLETS);
|
|
13756
|
-
}
|
|
13757
|
-
}
|
|
13758
|
-
else {
|
|
13759
|
-
setTimeout(() => {
|
|
13760
|
-
triggerResize();
|
|
13761
|
-
}, 100);
|
|
13762
|
-
}
|
|
13763
|
-
};
|
|
13764
|
-
const handleSignUp = async () => {
|
|
13765
|
-
setIsRegister(true);
|
|
13766
|
-
setTimeout(() => {
|
|
13767
|
-
triggerResize();
|
|
13768
|
-
});
|
|
13769
|
-
const { error, requiresEmailVerification } = await signUpEmail({
|
|
13770
|
-
email,
|
|
13771
|
-
password,
|
|
13772
|
-
});
|
|
13773
|
-
logger.log('SIGN UP RESPONSE', { error, requiresEmailVerification });
|
|
13774
|
-
if (!error) {
|
|
13775
|
-
if (requiresEmailVerification) {
|
|
13776
|
-
setRoute(routes.EMAIL_VERIFICATION);
|
|
13777
|
-
}
|
|
13778
|
-
else {
|
|
13779
|
-
setEmail('');
|
|
13780
|
-
setRoute(routes.LOAD_WALLETS);
|
|
13781
|
-
}
|
|
13782
|
-
}
|
|
13783
|
-
else {
|
|
13784
|
-
setTimeout(() => {
|
|
13785
|
-
triggerResize();
|
|
13786
|
-
}, 100);
|
|
13787
|
-
}
|
|
13788
|
-
};
|
|
13789
|
-
const handleToggle = () => {
|
|
13790
|
-
setIsRegister((prev) => !prev);
|
|
13791
|
-
};
|
|
13792
|
-
const errorMessage = loginError
|
|
13793
|
-
? loginError.message === 'Unauthorized'
|
|
13794
|
-
? 'Invalid email or password'
|
|
13795
|
-
: loginError.message
|
|
13796
|
-
: null;
|
|
13797
|
-
const onBack = useMemo(() => {
|
|
13798
|
-
if ((previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.route) === routes.EMAIL_VERIFICATION)
|
|
13799
|
-
return routes.PROVIDERS;
|
|
13800
|
-
return 'back';
|
|
13801
|
-
}, [previousRoute]);
|
|
13802
|
-
return (jsxs(PageContent, { onBack: onBack, children: [jsxs("form", { onSubmit: (e) => {
|
|
13803
|
-
e.preventDefault();
|
|
13804
|
-
handleSubmit();
|
|
13805
|
-
}, noValidate: true, children: [jsx(Input, { style: { marginTop: 0 }, value: email, onChange: (e) => setEmail(e.target.value), type: "email", placeholder: "Enter your email", disabled: loginLoading }), jsx(Input, { value: password, onChange: (e) => setPassword(e.target.value), type: "password", placeholder: "Enter your password", disabled: loginLoading, autoFocus: true }), jsx(ModalBody, { style: { marginTop: 12 }, "$error": !!loginError, children: jsx(AnimatePresence, { initial: false, children: jsxs(motion.div, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: [jsx(FitText, { maxFontSize: 80, children: jsx("span", { style: { textAlign: 'center', color: 'var(--color-error)', marginRight: '4px' }, children: errorMessage }) }, loginError ? 'text-error' : 'text-no-error'), jsx(FitText, { maxFontSize: 80, children: jsx(TextLinkButton, { type: "button", onClick: () => {
|
|
13806
|
-
setRoute(routes.FORGOT_PASSWORD);
|
|
13807
|
-
}, children: "Forgot password?" }) })] }, loginError ? 'error' : 'no-error') }) }), jsx(Button, { onClick: handleSubmit, disabled: loginLoading, waiting: loginLoading, children: jsx(AnimatePresence, { initial: false, children: loginLoading ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: isRegister ? 'Signing up...' : 'Logging in...' }, "connectedText")) : isRegister ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: "Sign up" }, "connectedText")) : (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: "Sign in" }, "connectedText")) }) })] }), jsxs(FooterContainer, { children: ["or", jsx("button", { type: "button", onClick: handleToggle, disabled: loginLoading, children: isRegister ? 'Sign in' : 'Sign up' })] })] }));
|
|
13808
|
-
};
|
|
13809
|
-
|
|
13810
|
-
const useEmailOtpAuth = (hookOptions = {}) => {
|
|
13811
|
-
const { client, updateUser } = useOpenfortCore();
|
|
13812
|
-
const [status, setStatus] = useState({
|
|
13813
|
-
status: 'idle',
|
|
13814
|
-
});
|
|
13815
|
-
const reset = useCallback(() => {
|
|
13816
|
-
setStatus({
|
|
13817
|
-
status: 'idle',
|
|
13818
|
-
});
|
|
13819
|
-
}, []);
|
|
13820
|
-
const { tryUseWallet } = useConnectToWalletPostAuth();
|
|
13821
|
-
const signInEmailOtp = useCallback(async (options) => {
|
|
13822
|
-
var _a, _b;
|
|
13823
|
-
try {
|
|
13912
|
+
});
|
|
13824
13913
|
setStatus({
|
|
13825
|
-
status: '
|
|
13914
|
+
status: 'error',
|
|
13915
|
+
error,
|
|
13826
13916
|
});
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
error,
|
|
13837
|
-
});
|
|
13838
|
-
}
|
|
13917
|
+
return onError({
|
|
13918
|
+
hookOptions,
|
|
13919
|
+
options,
|
|
13920
|
+
error: error,
|
|
13921
|
+
});
|
|
13922
|
+
}
|
|
13923
|
+
}, [client, setStatus, updateUser, hookOptions]);
|
|
13924
|
+
const resetPassword = useCallback(async (options) => {
|
|
13925
|
+
try {
|
|
13839
13926
|
if (!isValidEmail(options.email)) {
|
|
13840
13927
|
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13841
13928
|
setStatus({
|
|
@@ -13848,32 +13935,31 @@ const useEmailOtpAuth = (hookOptions = {}) => {
|
|
|
13848
13935
|
error,
|
|
13849
13936
|
});
|
|
13850
13937
|
}
|
|
13851
|
-
|
|
13852
|
-
|
|
13853
|
-
otp: options.otp,
|
|
13938
|
+
setStatus({
|
|
13939
|
+
status: 'loading',
|
|
13854
13940
|
});
|
|
13855
|
-
|
|
13856
|
-
|
|
13857
|
-
|
|
13941
|
+
setRequiresEmailVerification(false);
|
|
13942
|
+
await client.auth.resetPassword({
|
|
13943
|
+
password: options.password,
|
|
13944
|
+
token: options.state,
|
|
13858
13945
|
});
|
|
13859
13946
|
setStatus({
|
|
13860
13947
|
status: 'success',
|
|
13861
13948
|
});
|
|
13862
|
-
|
|
13863
|
-
await updateUser();
|
|
13949
|
+
setRequiresEmailVerification(true);
|
|
13864
13950
|
return onSuccess({
|
|
13865
|
-
data: {
|
|
13951
|
+
data: { requiresEmailVerification: true },
|
|
13866
13952
|
hookOptions,
|
|
13867
13953
|
options,
|
|
13868
13954
|
});
|
|
13869
13955
|
}
|
|
13870
13956
|
catch (e) {
|
|
13871
|
-
const error = new OpenfortError('Failed to
|
|
13957
|
+
const error = new OpenfortError('Failed to reset password', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
|
|
13872
13958
|
error: e,
|
|
13873
13959
|
});
|
|
13874
13960
|
setStatus({
|
|
13875
13961
|
status: 'error',
|
|
13876
|
-
error
|
|
13962
|
+
error,
|
|
13877
13963
|
});
|
|
13878
13964
|
return onError({
|
|
13879
13965
|
hookOptions,
|
|
@@ -13882,13 +13968,11 @@ const useEmailOtpAuth = (hookOptions = {}) => {
|
|
|
13882
13968
|
});
|
|
13883
13969
|
}
|
|
13884
13970
|
}, [client, setStatus, updateUser, hookOptions]);
|
|
13885
|
-
const
|
|
13971
|
+
const signUpEmail = useCallback(async (options) => {
|
|
13972
|
+
var _a, _b, _c;
|
|
13886
13973
|
try {
|
|
13887
|
-
|
|
13888
|
-
|
|
13889
|
-
});
|
|
13890
|
-
if (!options.email) {
|
|
13891
|
-
const error = new OpenfortError('Email is required', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13974
|
+
if (!options.email || !options.password) {
|
|
13975
|
+
const error = new OpenfortError('Email and password are required', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
13892
13976
|
setStatus({
|
|
13893
13977
|
status: 'error',
|
|
13894
13978
|
error,
|
|
@@ -13911,12 +13995,106 @@ const useEmailOtpAuth = (hookOptions = {}) => {
|
|
|
13911
13995
|
error,
|
|
13912
13996
|
});
|
|
13913
13997
|
}
|
|
13914
|
-
|
|
13998
|
+
setStatus({
|
|
13999
|
+
status: 'loading',
|
|
14000
|
+
});
|
|
14001
|
+
setRequiresEmailVerification(false);
|
|
14002
|
+
const result = await client.auth.signUpWithEmailPassword({
|
|
13915
14003
|
email: options.email,
|
|
14004
|
+
password: options.password,
|
|
14005
|
+
callbackURL: buildCallbackUrl({
|
|
14006
|
+
email: options.email,
|
|
14007
|
+
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
14008
|
+
provider: 'email',
|
|
14009
|
+
isOpen,
|
|
14010
|
+
}),
|
|
14011
|
+
...(options.name && { name: options.name }),
|
|
13916
14012
|
});
|
|
14013
|
+
// TODO: TMP FIX
|
|
14014
|
+
if ('token' in result && result.token !== null) {
|
|
14015
|
+
const { wallet } = await tryUseWallet({
|
|
14016
|
+
logoutOnError: (_b = options.logoutOnError) !== null && _b !== void 0 ? _b : hookOptions.logoutOnError,
|
|
14017
|
+
recoverWalletAutomatically: (_c = options.recoverWalletAutomatically) !== null && _c !== void 0 ? _c : hookOptions.recoverWalletAutomatically,
|
|
14018
|
+
});
|
|
14019
|
+
setStatus({
|
|
14020
|
+
status: 'success',
|
|
14021
|
+
});
|
|
14022
|
+
const user = result.user;
|
|
14023
|
+
await updateUser(user);
|
|
14024
|
+
return onSuccess({
|
|
14025
|
+
data: { user, wallet },
|
|
14026
|
+
hookOptions,
|
|
14027
|
+
options,
|
|
14028
|
+
});
|
|
14029
|
+
}
|
|
14030
|
+
else {
|
|
14031
|
+
setStatus({
|
|
14032
|
+
status: 'awaiting-input',
|
|
14033
|
+
});
|
|
14034
|
+
setRequiresEmailVerification(true);
|
|
14035
|
+
return onSuccess({
|
|
14036
|
+
data: { requiresEmailVerification: true },
|
|
14037
|
+
hookOptions,
|
|
14038
|
+
options,
|
|
14039
|
+
});
|
|
14040
|
+
}
|
|
14041
|
+
}
|
|
14042
|
+
catch (e) {
|
|
14043
|
+
const error = new OpenfortError('Failed to login with email and password', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: e });
|
|
13917
14044
|
setStatus({
|
|
13918
|
-
status: '
|
|
14045
|
+
status: 'error',
|
|
14046
|
+
error,
|
|
14047
|
+
});
|
|
14048
|
+
return onError({
|
|
14049
|
+
hookOptions,
|
|
14050
|
+
options,
|
|
14051
|
+
error: error,
|
|
14052
|
+
});
|
|
14053
|
+
}
|
|
14054
|
+
}, [client, setStatus, updateUser, hookOptions, isOpen]);
|
|
14055
|
+
const linkEmail = useCallback(async (options) => {
|
|
14056
|
+
var _a;
|
|
14057
|
+
try {
|
|
14058
|
+
if (!isValidEmail(options.email)) {
|
|
14059
|
+
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
14060
|
+
setStatus({
|
|
14061
|
+
status: 'error',
|
|
14062
|
+
error,
|
|
14063
|
+
});
|
|
14064
|
+
return onError({
|
|
14065
|
+
hookOptions,
|
|
14066
|
+
options,
|
|
14067
|
+
error,
|
|
14068
|
+
});
|
|
14069
|
+
}
|
|
14070
|
+
await client.validateAndRefreshToken();
|
|
14071
|
+
const authToken = await client.getAccessToken();
|
|
14072
|
+
if (!authToken) {
|
|
14073
|
+
logger.log('No token found');
|
|
14074
|
+
const error = new OpenfortError('No token found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
|
|
14075
|
+
setStatus({
|
|
14076
|
+
status: 'error',
|
|
14077
|
+
error,
|
|
14078
|
+
});
|
|
14079
|
+
return onError({
|
|
14080
|
+
hookOptions,
|
|
14081
|
+
options,
|
|
14082
|
+
error,
|
|
14083
|
+
});
|
|
14084
|
+
}
|
|
14085
|
+
await client.auth.addEmail({
|
|
14086
|
+
// name: options.name || '',
|
|
14087
|
+
email: options.email,
|
|
14088
|
+
// password: options.password,
|
|
14089
|
+
// method: 'password',
|
|
14090
|
+
callbackURL: buildCallbackUrl({
|
|
14091
|
+
callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
|
|
14092
|
+
email: options.email,
|
|
14093
|
+
provider: 'email',
|
|
14094
|
+
isOpen,
|
|
14095
|
+
}),
|
|
13919
14096
|
});
|
|
14097
|
+
logger.log('Email linked successfully');
|
|
13920
14098
|
return onSuccess({
|
|
13921
14099
|
data: {},
|
|
13922
14100
|
hookOptions,
|
|
@@ -13924,7 +14102,7 @@ const useEmailOtpAuth = (hookOptions = {}) => {
|
|
|
13924
14102
|
});
|
|
13925
14103
|
}
|
|
13926
14104
|
catch (e) {
|
|
13927
|
-
const error = new OpenfortError('Failed to
|
|
14105
|
+
const error = new OpenfortError('Failed to link email', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
|
|
13928
14106
|
error: e,
|
|
13929
14107
|
});
|
|
13930
14108
|
setStatus({
|
|
@@ -13937,298 +14115,328 @@ const useEmailOtpAuth = (hookOptions = {}) => {
|
|
|
13937
14115
|
error: error,
|
|
13938
14116
|
});
|
|
13939
14117
|
}
|
|
13940
|
-
}, [client, setStatus, updateUser, hookOptions]);
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
const
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
}
|
|
14001
|
-
|
|
14002
|
-
${({ isLoading }) => isLoading &&
|
|
14003
|
-
css `
|
|
14004
|
-
animation: ${pulse} 1s ease-in-out infinite;
|
|
14005
|
-
`}
|
|
14006
|
-
|
|
14007
|
-
${({ isError }) => isError &&
|
|
14008
|
-
css `
|
|
14009
|
-
animation: ${shakeKeyframes} 220ms ease-out both;
|
|
14010
|
-
`}
|
|
14011
|
-
|
|
14012
|
-
${({ isSuccess }) => isSuccess &&
|
|
14013
|
-
css `
|
|
14014
|
-
border-radius: 3rem;
|
|
14015
|
-
min-width: 3.5rem;
|
|
14016
|
-
${OTPSlotWrapper} {
|
|
14017
|
-
width: 0;
|
|
14018
|
-
border: 0;
|
|
14019
|
-
transition: width .5s, border .5s;
|
|
14020
|
-
}
|
|
14021
|
-
animation: ${keyframeSuccess} 220ms ease-out both;
|
|
14022
|
-
animation-delay: 250ms;
|
|
14023
|
-
`}
|
|
14024
|
-
`;
|
|
14025
|
-
const OTPSlotWrapper = styled.div `
|
|
14026
|
-
position: relative;
|
|
14027
|
-
width: 2.5rem;
|
|
14028
|
-
height: 3.5rem;
|
|
14029
|
-
font-size: 2rem;
|
|
14118
|
+
}, [client, setStatus, updateUser, hookOptions, isOpen]);
|
|
14119
|
+
const verifyEmail = useCallback(async (options) => {
|
|
14120
|
+
setStatus({
|
|
14121
|
+
status: 'loading',
|
|
14122
|
+
});
|
|
14123
|
+
try {
|
|
14124
|
+
if (!isValidEmail(options.email)) {
|
|
14125
|
+
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
14126
|
+
setStatus({
|
|
14127
|
+
status: 'error',
|
|
14128
|
+
error,
|
|
14129
|
+
});
|
|
14130
|
+
return onError({
|
|
14131
|
+
hookOptions,
|
|
14132
|
+
options,
|
|
14133
|
+
error,
|
|
14134
|
+
});
|
|
14135
|
+
}
|
|
14136
|
+
await client.auth.verifyEmail({
|
|
14137
|
+
token: options.state,
|
|
14138
|
+
});
|
|
14139
|
+
setStatus({
|
|
14140
|
+
status: 'success',
|
|
14141
|
+
});
|
|
14142
|
+
return onSuccess({
|
|
14143
|
+
hookOptions,
|
|
14144
|
+
options,
|
|
14145
|
+
data: {
|
|
14146
|
+
email: options.email,
|
|
14147
|
+
},
|
|
14148
|
+
});
|
|
14149
|
+
}
|
|
14150
|
+
catch (e) {
|
|
14151
|
+
const error = new OpenfortError('Failed to verify email', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
|
|
14152
|
+
error: e,
|
|
14153
|
+
});
|
|
14154
|
+
setStatus({
|
|
14155
|
+
status: 'error',
|
|
14156
|
+
error,
|
|
14157
|
+
});
|
|
14158
|
+
logger.log('Error verifying email', e);
|
|
14159
|
+
return onError({
|
|
14160
|
+
hookOptions,
|
|
14161
|
+
options,
|
|
14162
|
+
error,
|
|
14163
|
+
});
|
|
14164
|
+
}
|
|
14165
|
+
}, [client, hookOptions]);
|
|
14166
|
+
return {
|
|
14167
|
+
signInEmail,
|
|
14168
|
+
signUpEmail,
|
|
14169
|
+
verifyEmail,
|
|
14170
|
+
linkEmail,
|
|
14171
|
+
requestResetPassword,
|
|
14172
|
+
resetPassword,
|
|
14173
|
+
reset,
|
|
14174
|
+
...mapStatus(status),
|
|
14175
|
+
requiresEmailVerification,
|
|
14176
|
+
isAwaitingInput: status.status === 'awaiting-input',
|
|
14177
|
+
};
|
|
14178
|
+
};
|
|
14030
14179
|
|
|
14180
|
+
const FooterContainer = styled.span `
|
|
14181
|
+
padding: 12px 4px 0px 0px;
|
|
14031
14182
|
display: flex;
|
|
14032
14183
|
align-items: center;
|
|
14033
14184
|
justify-content: center;
|
|
14185
|
+
gap: 6px;
|
|
14186
|
+
line-height: 1rem;
|
|
14187
|
+
color: var(--ck-body-disclaimer-color, var(--ck-body-color-muted, inherit));
|
|
14034
14188
|
|
|
14035
|
-
|
|
14036
|
-
|
|
14037
|
-
|
|
14038
|
-
|
|
14039
|
-
|
|
14040
|
-
|
|
14041
|
-
|
|
14042
|
-
|
|
14043
|
-
border-left: 1px solid var(--border);
|
|
14044
|
-
border-radius: 0.375rem 0 0 0.375rem;
|
|
14045
|
-
}
|
|
14046
|
-
|
|
14047
|
-
&:last-child {
|
|
14048
|
-
border-radius: 0 0.375rem 0.375rem 0;
|
|
14189
|
+
& button {
|
|
14190
|
+
color: var(--ck-body-disclaimer-link-color, inherit);
|
|
14191
|
+
font-weight: var(--ck-body-disclaimer-font-weight, 400);
|
|
14192
|
+
text-decoration: none;
|
|
14193
|
+
transition: color 200ms ease;
|
|
14194
|
+
&:hover {
|
|
14195
|
+
color: var(--ck-body-disclaimer-link-hover-color, inherit);
|
|
14196
|
+
}
|
|
14049
14197
|
}
|
|
14050
|
-
|
|
14051
|
-
outline: ${({ isActive }) => (isActive ? '2px solid var(--ck-connectbutton-color)' : '0')};
|
|
14052
|
-
z-index: ${({ isActive }) => (isActive ? 1 : 0)};
|
|
14053
|
-
outline-offset: 0;
|
|
14054
|
-
|
|
14055
|
-
cursor: text;
|
|
14056
|
-
color: var(--ck-body-color);
|
|
14057
|
-
`;
|
|
14058
|
-
const OTPNumberValue = styled.div `
|
|
14059
|
-
opacity: ${({ $hide }) => ($hide ? 0 : 1)};
|
|
14060
|
-
transition: opacity 0.3s;
|
|
14061
|
-
`;
|
|
14062
|
-
const OTPHiddenInput = styled.input `
|
|
14063
|
-
position: absolute;
|
|
14064
|
-
inset: 0;
|
|
14065
|
-
opacity: 0;
|
|
14066
|
-
cursor: text;
|
|
14067
|
-
caret-color: transparent; /* Hide native caret */
|
|
14068
|
-
`;
|
|
14069
|
-
const FakeCaretWrapper = styled.div `
|
|
14070
|
-
position: absolute;
|
|
14071
|
-
inset: 0;
|
|
14072
|
-
pointer-events: none;
|
|
14073
|
-
|
|
14074
|
-
display: flex;
|
|
14075
|
-
align-items: center;
|
|
14076
|
-
justify-content: center;
|
|
14077
|
-
|
|
14078
|
-
animation: ${caretBlink} 1.2s ease-out infinite;
|
|
14079
|
-
`;
|
|
14080
|
-
const CaretBar = styled.div `
|
|
14081
|
-
width: 1px;
|
|
14082
|
-
height: 2rem;
|
|
14083
|
-
background: var(--ck-body-color);
|
|
14084
|
-
`;
|
|
14085
|
-
const keyframeWrapper = keyframes `
|
|
14086
|
-
0% { transform: scale(0); }
|
|
14087
|
-
100% { transform: scale(1); }
|
|
14088
|
-
`;
|
|
14089
|
-
const SuccessTickWrapper = styled.div `
|
|
14090
|
-
position: absolute;
|
|
14091
|
-
inset: 5px;
|
|
14092
|
-
display: flex;
|
|
14093
|
-
animation: ${keyframeWrapper} 200ms ease-out both;
|
|
14094
|
-
animation-delay: 200ms;
|
|
14095
|
-
color: var(--ck-body-color-valid);
|
|
14096
14198
|
`;
|
|
14097
14199
|
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
|
|
14107
|
-
|
|
14108
|
-
|
|
14109
|
-
|
|
14110
|
-
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14118
|
-
|
|
14119
|
-
|
|
14200
|
+
// TODO: Localize
|
|
14201
|
+
const textVariants$1 = {
|
|
14202
|
+
initial: {
|
|
14203
|
+
opacity: 0,
|
|
14204
|
+
},
|
|
14205
|
+
animate: {
|
|
14206
|
+
opacity: 1,
|
|
14207
|
+
transition: {
|
|
14208
|
+
duration: 0.3,
|
|
14209
|
+
ease: [0.25, 1, 0.5, 1],
|
|
14210
|
+
},
|
|
14211
|
+
},
|
|
14212
|
+
exit: {
|
|
14213
|
+
position: 'absolute',
|
|
14214
|
+
opacity: 0,
|
|
14215
|
+
transition: {
|
|
14216
|
+
duration: 0,
|
|
14217
|
+
},
|
|
14218
|
+
},
|
|
14219
|
+
};
|
|
14220
|
+
const EmailLogin = () => {
|
|
14221
|
+
const [password, setPassword] = React.useState('');
|
|
14222
|
+
const { setRoute, triggerResize, setEmailInput: setEmail, emailInput: email, previousRoute } = useOpenfort();
|
|
14223
|
+
const [isRegister, setIsRegister] = React.useState(false);
|
|
14224
|
+
const { signUpEmail, signInEmail, error: loginError, isLoading: loginLoading, } = useEmailAuth({
|
|
14225
|
+
recoverWalletAutomatically: false,
|
|
14226
|
+
});
|
|
14227
|
+
const handleSubmit = async () => {
|
|
14228
|
+
if (isRegister) {
|
|
14229
|
+
return handleSignUp();
|
|
14120
14230
|
}
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
|
|
14124
|
-
|
|
14231
|
+
setIsRegister(false);
|
|
14232
|
+
setTimeout(() => {
|
|
14233
|
+
triggerResize();
|
|
14234
|
+
});
|
|
14235
|
+
const { error, requiresEmailVerification } = await signInEmail({
|
|
14236
|
+
email,
|
|
14237
|
+
password,
|
|
14238
|
+
});
|
|
14239
|
+
logger.log('SIGN IN RESPONSE', { error, requiresEmailVerification });
|
|
14240
|
+
if (!error) {
|
|
14241
|
+
if (requiresEmailVerification) {
|
|
14242
|
+
setRoute(routes.EMAIL_VERIFICATION);
|
|
14243
|
+
}
|
|
14244
|
+
else {
|
|
14245
|
+
setRoute(routes.LOAD_WALLETS);
|
|
14246
|
+
}
|
|
14125
14247
|
}
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
14130
|
-
|
|
14131
|
-
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14248
|
+
else {
|
|
14249
|
+
setTimeout(() => {
|
|
14250
|
+
triggerResize();
|
|
14251
|
+
}, 100);
|
|
14252
|
+
}
|
|
14253
|
+
};
|
|
14254
|
+
const handleSignUp = async () => {
|
|
14255
|
+
setIsRegister(true);
|
|
14256
|
+
setTimeout(() => {
|
|
14257
|
+
triggerResize();
|
|
14258
|
+
});
|
|
14259
|
+
const { error, requiresEmailVerification } = await signUpEmail({
|
|
14260
|
+
email,
|
|
14261
|
+
password,
|
|
14262
|
+
});
|
|
14263
|
+
logger.log('SIGN UP RESPONSE', { error, requiresEmailVerification });
|
|
14264
|
+
if (!error) {
|
|
14265
|
+
if (requiresEmailVerification) {
|
|
14266
|
+
setRoute(routes.EMAIL_VERIFICATION);
|
|
14267
|
+
}
|
|
14268
|
+
else {
|
|
14269
|
+
setEmail('');
|
|
14270
|
+
setRoute(routes.LOAD_WALLETS);
|
|
14135
14271
|
}
|
|
14136
|
-
newValues[index - 1] = '';
|
|
14137
14272
|
}
|
|
14138
14273
|
else {
|
|
14139
|
-
|
|
14274
|
+
setTimeout(() => {
|
|
14275
|
+
triggerResize();
|
|
14276
|
+
}, 100);
|
|
14140
14277
|
}
|
|
14141
|
-
setValues(newValues);
|
|
14142
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
|
|
14143
14278
|
};
|
|
14144
|
-
const
|
|
14145
|
-
|
|
14146
|
-
|
|
14147
|
-
|
|
14148
|
-
|
|
14149
|
-
|
|
14150
|
-
|
|
14151
|
-
|
|
14152
|
-
|
|
14279
|
+
const handleToggle = () => {
|
|
14280
|
+
setIsRegister((prev) => !prev);
|
|
14281
|
+
};
|
|
14282
|
+
const errorMessage = loginError
|
|
14283
|
+
? loginError.message === 'Unauthorized'
|
|
14284
|
+
? 'Invalid email or password'
|
|
14285
|
+
: loginError.message
|
|
14286
|
+
: null;
|
|
14287
|
+
const onBack = useMemo(() => {
|
|
14288
|
+
if ((previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.route) === routes.EMAIL_VERIFICATION)
|
|
14289
|
+
return routes.PROVIDERS;
|
|
14290
|
+
return 'back';
|
|
14291
|
+
}, [previousRoute]);
|
|
14292
|
+
return (jsxs(PageContent, { onBack: onBack, children: [jsxs("form", { onSubmit: (e) => {
|
|
14293
|
+
e.preventDefault();
|
|
14294
|
+
handleSubmit();
|
|
14295
|
+
}, noValidate: true, children: [jsx(Input, { style: { marginTop: 0 }, value: email, onChange: (e) => setEmail(e.target.value), type: "email", placeholder: "Enter your email", disabled: loginLoading }), jsx(Input, { value: password, onChange: (e) => setPassword(e.target.value), type: "password", placeholder: "Enter your password", disabled: loginLoading, autoFocus: true }), jsx(ModalBody, { style: { marginTop: 12 }, "$error": !!loginError, children: jsx(AnimatePresence, { initial: false, children: jsxs(motion.div, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: [jsx(FitText, { maxFontSize: 80, children: jsx("span", { style: { textAlign: 'center', color: 'var(--color-error)', marginRight: '4px' }, children: errorMessage }) }, loginError ? 'text-error' : 'text-no-error'), jsx(FitText, { maxFontSize: 80, children: jsx(TextLinkButton, { type: "button", onClick: () => {
|
|
14296
|
+
setRoute(routes.FORGOT_PASSWORD);
|
|
14297
|
+
}, children: "Forgot password?" }) })] }, loginError ? 'error' : 'no-error') }) }), jsx(Button, { onClick: handleSubmit, disabled: loginLoading, waiting: loginLoading, children: jsx(AnimatePresence, { initial: false, children: loginLoading ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: isRegister ? 'Signing up...' : 'Logging in...' }, "connectedText")) : isRegister ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: "Sign up" }, "connectedText")) : (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: "Sign in" }, "connectedText")) }) })] }), jsxs(FooterContainer, { children: ["or", jsx("button", { type: "button", onClick: handleToggle, disabled: loginLoading, children: isRegister ? 'Sign in' : 'Sign up' })] })] }));
|
|
14298
|
+
};
|
|
14299
|
+
|
|
14300
|
+
const useEmailOtpAuth = (hookOptions = {}) => {
|
|
14301
|
+
const { client, updateUser } = useOpenfortCore();
|
|
14302
|
+
const [status, setStatus] = useState({
|
|
14303
|
+
status: 'idle',
|
|
14304
|
+
});
|
|
14305
|
+
const reset = useCallback(() => {
|
|
14306
|
+
setStatus({
|
|
14307
|
+
status: 'idle',
|
|
14153
14308
|
});
|
|
14154
|
-
|
|
14155
|
-
|
|
14156
|
-
|
|
14157
|
-
setActiveIndex(finalIndex);
|
|
14158
|
-
(_a = inputsRef.current[finalIndex]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
14159
|
-
};
|
|
14160
|
-
const handleFocus = (i) => {
|
|
14309
|
+
}, []);
|
|
14310
|
+
const { tryUseWallet } = useConnectToWalletPostAuth();
|
|
14311
|
+
const signInEmailOtp = useCallback(async (options) => {
|
|
14161
14312
|
var _a, _b;
|
|
14162
|
-
|
|
14163
|
-
|
|
14164
|
-
|
|
14313
|
+
try {
|
|
14314
|
+
setStatus({
|
|
14315
|
+
status: 'loading',
|
|
14316
|
+
});
|
|
14317
|
+
if (!options.email || !options.otp) {
|
|
14318
|
+
const error = new OpenfortError('Email and OTP are required', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
14319
|
+
setStatus({
|
|
14320
|
+
status: 'error',
|
|
14321
|
+
error,
|
|
14322
|
+
});
|
|
14323
|
+
return onError({
|
|
14324
|
+
hookOptions,
|
|
14325
|
+
options,
|
|
14326
|
+
error,
|
|
14327
|
+
});
|
|
14328
|
+
}
|
|
14329
|
+
if (!isValidEmail(options.email)) {
|
|
14330
|
+
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
14331
|
+
setStatus({
|
|
14332
|
+
status: 'error',
|
|
14333
|
+
error,
|
|
14334
|
+
});
|
|
14335
|
+
return onError({
|
|
14336
|
+
hookOptions,
|
|
14337
|
+
options,
|
|
14338
|
+
error,
|
|
14339
|
+
});
|
|
14340
|
+
}
|
|
14341
|
+
const result = await client.auth.logInWithEmailOtp({
|
|
14342
|
+
email: options.email,
|
|
14343
|
+
otp: options.otp,
|
|
14344
|
+
});
|
|
14345
|
+
const { wallet } = await tryUseWallet({
|
|
14346
|
+
logoutOnError: (_a = options.logoutOnError) !== null && _a !== void 0 ? _a : hookOptions.logoutOnError,
|
|
14347
|
+
recoverWalletAutomatically: (_b = options.recoverWalletAutomatically) !== null && _b !== void 0 ? _b : hookOptions.recoverWalletAutomatically,
|
|
14348
|
+
});
|
|
14349
|
+
setStatus({
|
|
14350
|
+
status: 'success',
|
|
14351
|
+
});
|
|
14352
|
+
const user = result.user;
|
|
14353
|
+
await updateUser();
|
|
14354
|
+
return onSuccess({
|
|
14355
|
+
data: { user, wallet },
|
|
14356
|
+
hookOptions,
|
|
14357
|
+
options,
|
|
14358
|
+
});
|
|
14165
14359
|
}
|
|
14166
|
-
|
|
14167
|
-
|
|
14168
|
-
|
|
14169
|
-
|
|
14360
|
+
catch (e) {
|
|
14361
|
+
const error = new OpenfortError('Failed to login with email OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
|
|
14362
|
+
error: e,
|
|
14363
|
+
});
|
|
14364
|
+
setStatus({
|
|
14365
|
+
status: 'error',
|
|
14366
|
+
error: error,
|
|
14367
|
+
});
|
|
14368
|
+
return onError({
|
|
14369
|
+
hookOptions,
|
|
14370
|
+
options,
|
|
14371
|
+
error: error,
|
|
14372
|
+
});
|
|
14170
14373
|
}
|
|
14171
|
-
|
|
14172
|
-
|
|
14173
|
-
|
|
14374
|
+
}, [client, setStatus, updateUser, hookOptions]);
|
|
14375
|
+
const requestEmailOtp = useCallback(async (options) => {
|
|
14376
|
+
try {
|
|
14377
|
+
setStatus({
|
|
14378
|
+
status: 'requesting',
|
|
14379
|
+
});
|
|
14380
|
+
if (!options.email) {
|
|
14381
|
+
const error = new OpenfortError('Email is required', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
14382
|
+
setStatus({
|
|
14383
|
+
status: 'error',
|
|
14384
|
+
error,
|
|
14385
|
+
});
|
|
14386
|
+
return onError({
|
|
14387
|
+
hookOptions,
|
|
14388
|
+
options,
|
|
14389
|
+
error,
|
|
14390
|
+
});
|
|
14391
|
+
}
|
|
14392
|
+
if (!isValidEmail(options.email)) {
|
|
14393
|
+
const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
|
|
14394
|
+
setStatus({
|
|
14395
|
+
status: 'error',
|
|
14396
|
+
error,
|
|
14397
|
+
});
|
|
14398
|
+
return onError({
|
|
14399
|
+
hookOptions,
|
|
14400
|
+
options,
|
|
14401
|
+
error,
|
|
14402
|
+
});
|
|
14403
|
+
}
|
|
14404
|
+
await client.auth.requestEmailOtp({
|
|
14405
|
+
email: options.email,
|
|
14406
|
+
});
|
|
14407
|
+
setStatus({
|
|
14408
|
+
status: 'success',
|
|
14409
|
+
});
|
|
14410
|
+
return onSuccess({
|
|
14411
|
+
data: {},
|
|
14412
|
+
hookOptions,
|
|
14413
|
+
options,
|
|
14414
|
+
});
|
|
14174
14415
|
}
|
|
14175
|
-
|
|
14176
|
-
|
|
14177
|
-
|
|
14178
|
-
|
|
14179
|
-
|
|
14180
|
-
|
|
14181
|
-
|
|
14416
|
+
catch (e) {
|
|
14417
|
+
const error = new OpenfortError('Failed to request email OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
|
|
14418
|
+
error: e,
|
|
14419
|
+
});
|
|
14420
|
+
setStatus({
|
|
14421
|
+
status: 'error',
|
|
14422
|
+
error: error,
|
|
14423
|
+
});
|
|
14424
|
+
return onError({
|
|
14425
|
+
hookOptions,
|
|
14426
|
+
options,
|
|
14427
|
+
error: error,
|
|
14428
|
+
});
|
|
14182
14429
|
}
|
|
14183
|
-
}, [
|
|
14184
|
-
return
|
|
14185
|
-
|
|
14186
|
-
|
|
14187
|
-
|
|
14188
|
-
|
|
14189
|
-
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
|
|
14193
|
-
handleBackspace(index);
|
|
14194
|
-
}
|
|
14195
|
-
}, onChange: (e) => handleInput(index, e.target.value) }), value && jsx(OTPNumberValue, { "$hide": isSuccess, children: value }), !value && activeIndex === index && jsx(FakeCaret, {})] }, index));
|
|
14196
|
-
}), isSuccess && (jsx(SuccessTickWrapper, { children: jsx(TickIcon, { width: '100%', height: '100%' }) }))] }) }));
|
|
14197
|
-
}
|
|
14198
|
-
|
|
14199
|
-
const Body$1 = styled.p `
|
|
14200
|
-
color: var(--ck-body-color);
|
|
14201
|
-
text-align: center;
|
|
14202
|
-
margin-bottom: 16px;
|
|
14203
|
-
`;
|
|
14204
|
-
const ResultContainer$1 = styled.div `
|
|
14205
|
-
margin-top: 16px;
|
|
14206
|
-
height: 24px;
|
|
14207
|
-
text-align: center;
|
|
14208
|
-
`;
|
|
14209
|
-
const FooterButtonText$1 = styled.button `
|
|
14210
|
-
background: none;
|
|
14211
|
-
border: none;
|
|
14212
|
-
cursor: pointer;
|
|
14213
|
-
padding: 0;
|
|
14214
|
-
color: var(--ck-body-color-muted);
|
|
14215
|
-
transition: color 0.3s;
|
|
14216
|
-
|
|
14217
|
-
&:disabled {
|
|
14218
|
-
color: var(--ck-body-color-muted) !important;
|
|
14219
|
-
cursor: not-allowed;
|
|
14220
|
-
}
|
|
14221
|
-
`;
|
|
14222
|
-
const FooterTextButton$1 = styled.p `
|
|
14223
|
-
color: var(--ck-body-color-muted);
|
|
14224
|
-
text-align: center;
|
|
14225
|
-
margin-top: 16px;
|
|
14226
|
-
&:hover {
|
|
14227
|
-
${FooterButtonText$1} {
|
|
14228
|
-
color: var(--ck-body-color);
|
|
14229
|
-
}
|
|
14230
|
-
}
|
|
14231
|
-
`;
|
|
14430
|
+
}, [client, setStatus, updateUser, hookOptions]);
|
|
14431
|
+
return {
|
|
14432
|
+
signInEmailOtp,
|
|
14433
|
+
requestEmailOtp,
|
|
14434
|
+
reset,
|
|
14435
|
+
isRequesting: status.status === 'requesting',
|
|
14436
|
+
...mapStatus(status),
|
|
14437
|
+
isAwaitingInput: status.status === 'awaiting-input',
|
|
14438
|
+
};
|
|
14439
|
+
};
|
|
14232
14440
|
|
|
14233
14441
|
const RESEND_COOLDOWN_MS$1 = 10000;
|
|
14234
14442
|
const SUCCESS_REDIRECT_DELAY_MS$1 = 2000;
|
|
@@ -14600,7 +14808,7 @@ const LinkEmail = () => {
|
|
|
14600
14808
|
return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Link your email" }), jsxs("form", { onSubmit: (e) => {
|
|
14601
14809
|
e.preventDefault();
|
|
14602
14810
|
handleSubmit();
|
|
14603
|
-
}, children: [jsx(Input, { style: { marginTop: 0 }, value: email, onChange: (e) => setEmail(e.target.value), type: "email", placeholder: "Enter your email", disabled: loginLoading }), loginError && (jsx(ModalBody, { style: { height: 24, marginTop: 12 }, "$error": true, children:
|
|
14811
|
+
}, children: [jsx(Input, { style: { marginTop: 0 }, value: email, onChange: (e) => setEmail(e.target.value), type: "email", placeholder: "Enter your email", disabled: loginLoading }), loginError && (jsx(ModalBody, { style: { height: 24, marginTop: 12 }, "$error": true, children: loginError })), jsx(Button, { onClick: handleSubmit, disabled: loginLoading, waiting: loginLoading, children: jsx(AnimatePresence, { initial: false, children: loginLoading ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants, children: "Linking email..." }, "connectedText")) : (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants, children: "Link email" }, "connectedText")) }) })] })] }));
|
|
14604
14812
|
};
|
|
14605
14813
|
|
|
14606
14814
|
const getProviderName = (provider) => {
|
|
@@ -15861,16 +16069,25 @@ const RecoverPasskeyWallet = ({ wallet, onBack, logoutOnBack, }) => {
|
|
|
15861
16069
|
};
|
|
15862
16070
|
const RecoverAutomaticWallet = ({ walletAddress, onBack, logoutOnBack, }) => {
|
|
15863
16071
|
const { embeddedState } = useOpenfortCore();
|
|
15864
|
-
const { setActiveWallet } = useWallets();
|
|
16072
|
+
const { setActiveWallet, isWalletRecoveryOTPEnabled, requestWalletRecoverOTP } = useWallets();
|
|
15865
16073
|
const { setRoute } = useOpenfort();
|
|
15866
16074
|
const [error, setError] = useState(false);
|
|
16075
|
+
const [needsOTP, setNeedsOTP] = useState(false);
|
|
16076
|
+
const [otpResponse, setOtpResponse] = useState(null);
|
|
16077
|
+
const [otpStatus, setOtpStatus] = useState('idle');
|
|
15867
16078
|
const recoverWallet = useCallback(async () => {
|
|
15868
16079
|
if (embeddedState === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
|
|
15869
16080
|
logger.log('Automatically recovering wallet', walletAddress);
|
|
15870
16081
|
const response = await setActiveWallet({
|
|
15871
16082
|
walletId: embeddedWalletId,
|
|
16083
|
+
address: walletAddress,
|
|
15872
16084
|
});
|
|
15873
|
-
if (response.
|
|
16085
|
+
if (response.isOTPRequired && isWalletRecoveryOTPEnabled) {
|
|
16086
|
+
const response = await requestWalletRecoverOTP();
|
|
16087
|
+
setNeedsOTP(true);
|
|
16088
|
+
setOtpResponse(response);
|
|
16089
|
+
}
|
|
16090
|
+
else if (response.error) {
|
|
15874
16091
|
setError(response.error.message || 'There was an error recovering your account');
|
|
15875
16092
|
logger.log('Error recovering wallet', response.error);
|
|
15876
16093
|
}
|
|
@@ -15878,7 +16095,7 @@ const RecoverAutomaticWallet = ({ walletAddress, onBack, logoutOnBack, }) => {
|
|
|
15878
16095
|
setRoute(routes.CONNECTED_SUCCESS);
|
|
15879
16096
|
}
|
|
15880
16097
|
}
|
|
15881
|
-
}, [walletAddress, setActiveWallet, setRoute]);
|
|
16098
|
+
}, [walletAddress, setActiveWallet, setRoute, isWalletRecoveryOTPEnabled, requestWalletRecoverOTP]);
|
|
15882
16099
|
const shouldRecoverWallet = useRef(false);
|
|
15883
16100
|
useEffect(() => {
|
|
15884
16101
|
if (shouldRecoverWallet.current)
|
|
@@ -15886,6 +16103,67 @@ const RecoverAutomaticWallet = ({ walletAddress, onBack, logoutOnBack, }) => {
|
|
|
15886
16103
|
shouldRecoverWallet.current = true;
|
|
15887
16104
|
recoverWallet();
|
|
15888
16105
|
}, []);
|
|
16106
|
+
const handleCompleteOtp = async (otp) => {
|
|
16107
|
+
setOtpStatus('loading');
|
|
16108
|
+
const response = await setActiveWallet({
|
|
16109
|
+
walletId: embeddedWalletId,
|
|
16110
|
+
recovery: {
|
|
16111
|
+
recoveryMethod: RecoveryMethod.AUTOMATIC,
|
|
16112
|
+
otpCode: otp,
|
|
16113
|
+
},
|
|
16114
|
+
address: walletAddress,
|
|
16115
|
+
});
|
|
16116
|
+
if (response.error) {
|
|
16117
|
+
setOtpStatus('error');
|
|
16118
|
+
setError(response.error.message || 'There was an error verifying the OTP');
|
|
16119
|
+
logger.log('Error verifying OTP for wallet recovery', response.error);
|
|
16120
|
+
setTimeout(() => {
|
|
16121
|
+
setOtpStatus('idle');
|
|
16122
|
+
setError(false);
|
|
16123
|
+
}, 1000);
|
|
16124
|
+
}
|
|
16125
|
+
else {
|
|
16126
|
+
setOtpStatus('success');
|
|
16127
|
+
setTimeout(() => {
|
|
16128
|
+
setRoute(routes.CONNECTED_SUCCESS);
|
|
16129
|
+
}, 1000);
|
|
16130
|
+
}
|
|
16131
|
+
};
|
|
16132
|
+
const ensFallbackConfig = useEnsFallbackConfig();
|
|
16133
|
+
const { data: ensName } = useEnsName({
|
|
16134
|
+
chainId: 1,
|
|
16135
|
+
address: walletAddress,
|
|
16136
|
+
config: ensFallbackConfig,
|
|
16137
|
+
});
|
|
16138
|
+
const walletDisplay = ensName !== null && ensName !== void 0 ? ensName : truncateEthAddress(walletAddress);
|
|
16139
|
+
const [canSendOtp, setCanSendOtp] = useState(true);
|
|
16140
|
+
// Handle resend cooldown
|
|
16141
|
+
useEffect(() => {
|
|
16142
|
+
if (canSendOtp)
|
|
16143
|
+
return;
|
|
16144
|
+
const timerId = setTimeout(() => {
|
|
16145
|
+
setCanSendOtp(true);
|
|
16146
|
+
}, 10000);
|
|
16147
|
+
return () => clearTimeout(timerId);
|
|
16148
|
+
}, [canSendOtp]);
|
|
16149
|
+
const handleResendClick = useCallback(() => {
|
|
16150
|
+
setOtpStatus('send-otp');
|
|
16151
|
+
setCanSendOtp(false);
|
|
16152
|
+
}, []);
|
|
16153
|
+
const isResendDisabled = !canSendOtp || otpStatus === 'sending-otp' || otpStatus === 'send-otp';
|
|
16154
|
+
// Memoize button text to avoid recalculation
|
|
16155
|
+
const sendButtonText = useMemo(() => {
|
|
16156
|
+
if (!canSendOtp)
|
|
16157
|
+
return 'Code Sent!';
|
|
16158
|
+
if (otpStatus === 'sending-otp')
|
|
16159
|
+
return 'Sending...';
|
|
16160
|
+
return 'Resend Code';
|
|
16161
|
+
}, [canSendOtp, otpStatus]);
|
|
16162
|
+
if (needsOTP && isWalletRecoveryOTPEnabled) {
|
|
16163
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(ModalHeading, { children: "Enter your code" }), jsx(FloatingGraphic, { height: "100px", marginTop: "8px", marginBottom: "10px", logoCenter: {
|
|
16164
|
+
logo: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? jsx(PhoneIcon, {}) : jsx(EmailIcon, {}),
|
|
16165
|
+
} }), jsxs(ModalBody, { children: [jsxs(Body$1, { children: ["Recovering wallet ", jsx(CopyText, { value: walletAddress, children: walletDisplay }), "Please check ", jsx("b", { children: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.phone : otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.email }), " and enter your code below."] }), jsx(OtpInputStandalone, { length: 9, scale: "80%", onComplete: handleCompleteOtp, isLoading: otpStatus === 'loading', isError: otpStatus === 'error', isSuccess: otpStatus === 'success' }), jsxs(ResultContainer$1, { children: [otpStatus === 'success' && jsx(ModalBody, { "$valid": true, children: "Code verified successfully!" }), otpStatus === 'error' && jsx(ModalBody, { "$error": true, children: error || 'Invalid code. Please try again.' })] }), jsxs(FooterTextButton$1, { children: ["Didn't receive the code?", ' ', jsx(FooterButtonText$1, { type: "button", onClick: handleResendClick, disabled: isResendDisabled, children: sendButtonText })] })] })] }));
|
|
16166
|
+
}
|
|
15889
16167
|
if (error) {
|
|
15890
16168
|
return (jsx(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: jsx(ModalBody, { style: { textAlign: 'center' }, "$error": true, children: jsx(FitText, { children: error }) }) }));
|
|
15891
16169
|
}
|
|
@@ -18390,6 +18668,10 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
|
|
|
18390
18668
|
})), children, jsx(ConnectModal, { lang: ckLang, theme: ckTheme, mode: (_e = safeUiConfig.mode) !== null && _e !== void 0 ? _e : ckMode, customTheme: ckCustomTheme })] }) }));
|
|
18391
18669
|
};
|
|
18392
18670
|
|
|
18671
|
+
const PageLayout = ({ children, width, header }) => {
|
|
18672
|
+
return (jsx(PageContent, { width: width, header: header, onBack: null, children: children }));
|
|
18673
|
+
};
|
|
18674
|
+
|
|
18393
18675
|
/**
|
|
18394
18676
|
* Hook for OAuth-based authentication operations
|
|
18395
18677
|
*
|
|
@@ -19305,5 +19587,5 @@ const wallets = Object.keys(walletConfigs).reduce((acc, key) => {
|
|
|
19305
19587
|
return acc;
|
|
19306
19588
|
}, {});
|
|
19307
19589
|
|
|
19308
|
-
export { UIAuthProvider as AuthProvider, Avatar, Chain as ChainIcon, LinkWalletOnSignUpOption, OPENFORT_VERSION, OpenfortButton, OpenfortError, OpenfortReactErrorType as OpenfortErrorType, OpenfortProvider, embeddedWalletId, defaultConfig as getDefaultConfig, defaultConnectors as getDefaultConnectors, use7702Authorization, useAuthCallback, useChainIsSupported, useChains, useConnectWithSiwe, useEmailAuth, useEmailOtpAuth, useGrantPermissions, useGuestAuth, useOAuth, useOpenfortCore as useOpenfort, usePhoneOtpAuth, useRevokePermissions, useSignOut, useUI, useUser, useWalletAssets, useWalletAuth, useWallets, wallets };
|
|
19590
|
+
export { UIAuthProvider as AuthProvider, Avatar, Chain as ChainIcon, LinkWalletOnSignUpOption, OPENFORT_VERSION, OpenfortButton, OpenfortError, OpenfortReactErrorType as OpenfortErrorType, OpenfortProvider, PageLayout, embeddedWalletId, defaultConfig as getDefaultConfig, defaultConnectors as getDefaultConnectors, use7702Authorization, useAuthCallback, useChainIsSupported, useChains, useConnectWithSiwe, useEmailAuth, useEmailOtpAuth, useGrantPermissions, useGuestAuth, useOAuth, useOpenfortCore as useOpenfort, usePhoneOtpAuth, useRevokePermissions, useSignOut, useUI, useUser, useWalletAssets, useWalletAuth, useWallets, wallets };
|
|
19309
19591
|
//# sourceMappingURL=index.es.js.map
|