mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-23 06:35:05 +01:00
feat: test connection before hand
This commit is contained in:
parent
e91d5f156f
commit
37ec4a78d3
6 changed files with 275 additions and 166 deletions
|
@ -1,13 +1,16 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Input, SingleLine, Sub4Title } from '../../components/generic/Styled';
|
||||
import { useAccount } from '../../context/AccountContext';
|
||||
import { getConfigLnd, saveUserAuth } from '../../utils/auth';
|
||||
import { getConfigLnd, saveUserAuth, getAuthString } from '../../utils/auth';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import { LoginButton, PasswordInput } from './Password';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useLazyQuery } from '@apollo/react-hooks';
|
||||
import { GET_CAN_CONNECT } from '../../graphql/query';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
|
||||
interface AuthProps {
|
||||
available?: number;
|
||||
available: number;
|
||||
callback?: () => void;
|
||||
}
|
||||
|
||||
|
@ -20,32 +23,24 @@ export const BTCLoginForm = ({ available, callback }: AuthProps) => {
|
|||
const [hasInfo, setHasInfo] = useState(false);
|
||||
const [isPass, setPass] = useState('');
|
||||
|
||||
if (!available) return null;
|
||||
const [tryToConnect, { data, loading }] = useLazyQuery(GET_CAN_CONNECT, {
|
||||
onError: error => toast.error(getErrorContent(error)),
|
||||
});
|
||||
|
||||
const canConnect = isJson !== '' && !!available;
|
||||
|
||||
const handleClick = () => {
|
||||
try {
|
||||
JSON.parse(isJson);
|
||||
setHasInfo(true);
|
||||
} catch (error) {
|
||||
toast.error('Invalid JSON Object');
|
||||
}
|
||||
};
|
||||
|
||||
const handleConnect = () => {
|
||||
useEffect(() => {
|
||||
if (!loading && data && data.getNodeInfo && data.getNodeInfo.alias) {
|
||||
const { cert, macaroon, readMacaroon, host } = getConfigLnd(isJson);
|
||||
|
||||
const encryptedAdmin =
|
||||
macaroon && isPass !== ''
|
||||
? CryptoJS.AES.encrypt(macaroon, isPass).toString()
|
||||
: undefined;
|
||||
|
||||
if (!host) {
|
||||
toast.error('Invalid connection credentials');
|
||||
return;
|
||||
}
|
||||
|
||||
const encryptedAdmin =
|
||||
macaroon && isPass !== ''
|
||||
? CryptoJS.AES.encrypt(macaroon, isPass).toString()
|
||||
: undefined;
|
||||
|
||||
saveUserAuth({
|
||||
available,
|
||||
name: isName,
|
||||
|
@ -63,10 +58,45 @@ export const BTCLoginForm = ({ available, callback }: AuthProps) => {
|
|||
cert,
|
||||
});
|
||||
|
||||
toast.success('Connected!');
|
||||
callback && callback();
|
||||
}
|
||||
}, [
|
||||
data,
|
||||
loading,
|
||||
available,
|
||||
callback,
|
||||
isJson,
|
||||
isName,
|
||||
isPass,
|
||||
setAccount,
|
||||
]);
|
||||
|
||||
const handleClick = () => {
|
||||
try {
|
||||
JSON.parse(isJson);
|
||||
setHasInfo(true);
|
||||
} catch (error) {
|
||||
toast.error('Invalid JSON Object');
|
||||
}
|
||||
};
|
||||
|
||||
const renderContent = () => (
|
||||
const handleConnect = () => {
|
||||
const { cert, readMacaroon, host } = getConfigLnd(isJson);
|
||||
|
||||
if (!host) {
|
||||
toast.error('Invalid connection credentials');
|
||||
return;
|
||||
}
|
||||
|
||||
tryToConnect({
|
||||
variables: { auth: getAuthString(host, readMacaroon, cert) },
|
||||
});
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
const canConnect = isJson !== '' && !!available;
|
||||
return (
|
||||
<>
|
||||
<SingleLine>
|
||||
<Sub4Title>Name:</Sub4Title>
|
||||
|
@ -88,12 +118,14 @@ export const BTCLoginForm = ({ available, callback }: AuthProps) => {
|
|||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return hasInfo ? (
|
||||
<PasswordInput
|
||||
isPass={isPass}
|
||||
setPass={setPass}
|
||||
callback={handleConnect}
|
||||
loading={loading}
|
||||
/>
|
||||
) : (
|
||||
renderContent()
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Input, SingleLine, Sub4Title } from '../../components/generic/Styled';
|
||||
import { useAccount } from '../../context/AccountContext';
|
||||
import {
|
||||
getAuthLnd,
|
||||
getBase64CertfromDerFormat,
|
||||
saveUserAuth,
|
||||
getAuthString,
|
||||
} from '../../utils/auth';
|
||||
import { LoginButton, PasswordInput } from './Password';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import { useLazyQuery } from '@apollo/react-hooks';
|
||||
import { GET_CAN_CONNECT } from '../../graphql/query';
|
||||
import { toast } from 'react-toastify';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
|
||||
interface AuthProps {
|
||||
available?: number;
|
||||
available: number;
|
||||
callback?: () => void;
|
||||
}
|
||||
|
||||
|
@ -23,11 +28,12 @@ export const ConnectLoginForm = ({ available, callback }: AuthProps) => {
|
|||
const [hasInfo, setHasInfo] = useState(false);
|
||||
const [isPass, setPass] = useState('');
|
||||
|
||||
if (!available) return null;
|
||||
const [tryToConnect, { data, loading }] = useLazyQuery(GET_CAN_CONNECT, {
|
||||
onError: error => toast.error(getErrorContent(error)),
|
||||
});
|
||||
|
||||
const canConnect = isUrl !== '' && !!available;
|
||||
|
||||
const handleConnect = () => {
|
||||
useEffect(() => {
|
||||
if (!loading && data && data.getNodeInfo && data.getNodeInfo.alias) {
|
||||
const { cert, macaroon, socket } = getAuthLnd(isUrl);
|
||||
|
||||
const base64Cert = getBase64CertfromDerFormat(cert) || '';
|
||||
|
@ -37,8 +43,6 @@ export const ConnectLoginForm = ({ available, callback }: AuthProps) => {
|
|||
isPass,
|
||||
).toString();
|
||||
|
||||
console.log(encryptedAdmin);
|
||||
|
||||
saveUserAuth({
|
||||
available,
|
||||
name: isName,
|
||||
|
@ -57,10 +61,24 @@ export const ConnectLoginForm = ({ available, callback }: AuthProps) => {
|
|||
cert: base64Cert,
|
||||
});
|
||||
|
||||
toast.success('Connected!');
|
||||
callback && callback();
|
||||
}
|
||||
}, [data, loading, available, callback, isName, isPass, isUrl, setAccount]);
|
||||
|
||||
const handleConnect = () => {
|
||||
const { cert, macaroon, socket } = getAuthLnd(isUrl);
|
||||
|
||||
const base64Cert = getBase64CertfromDerFormat(cert) || '';
|
||||
|
||||
tryToConnect({
|
||||
variables: { auth: getAuthString(socket, macaroon, base64Cert) },
|
||||
});
|
||||
};
|
||||
|
||||
const renderContent = () => (
|
||||
const renderContent = () => {
|
||||
const canConnect = isUrl !== '' && !!available;
|
||||
return (
|
||||
<>
|
||||
<SingleLine>
|
||||
<Sub4Title>Name:</Sub4Title>
|
||||
|
@ -82,12 +100,14 @@ export const ConnectLoginForm = ({ available, callback }: AuthProps) => {
|
|||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return hasInfo ? (
|
||||
<PasswordInput
|
||||
isPass={isPass}
|
||||
setPass={setPass}
|
||||
callback={handleConnect}
|
||||
loading={loading}
|
||||
/>
|
||||
) : (
|
||||
renderContent()
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Input, SingleLine, Sub4Title } from '../generic/Styled';
|
||||
import { useAccount } from '../../context/AccountContext';
|
||||
import { saveUserAuth } from '../../utils/auth';
|
||||
import { saveUserAuth, getAuthString } from '../../utils/auth';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import base64url from 'base64url';
|
||||
import { PasswordInput, LoginButton } from './Password';
|
||||
import { useLazyQuery } from '@apollo/react-hooks';
|
||||
import { GET_CAN_CONNECT } from '../../graphql/query';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
interface AuthProps {
|
||||
available?: number;
|
||||
available: number;
|
||||
callback?: () => void;
|
||||
}
|
||||
|
||||
|
@ -23,10 +27,9 @@ export const LoginForm = ({ available, callback }: AuthProps) => {
|
|||
const [hasInfo, setHasInfo] = useState(false);
|
||||
const [isPass, setPass] = useState('');
|
||||
|
||||
if (!available) return null;
|
||||
|
||||
const canConnect =
|
||||
isName !== '' && isHost !== '' && isRead !== '' && !!available;
|
||||
const [tryToConnect, { data, loading }] = useLazyQuery(GET_CAN_CONNECT, {
|
||||
onError: error => toast.error(getErrorContent(error)),
|
||||
});
|
||||
|
||||
const handleClick = () => {
|
||||
if (isAdmin !== '') {
|
||||
|
@ -36,7 +39,8 @@ export const LoginForm = ({ available, callback }: AuthProps) => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleConnect = () => {
|
||||
useEffect(() => {
|
||||
if (!loading && data && data.getNodeInfo && data.getNodeInfo.alias) {
|
||||
const admin = base64url.fromBase64(isAdmin);
|
||||
const read = base64url.fromBase64(isRead);
|
||||
const cert = base64url.fromBase64(isCert);
|
||||
|
@ -63,10 +67,41 @@ export const LoginForm = ({ available, callback }: AuthProps) => {
|
|||
cert,
|
||||
});
|
||||
|
||||
toast.success('Connected!');
|
||||
callback && callback();
|
||||
}
|
||||
}, [
|
||||
data,
|
||||
loading,
|
||||
available,
|
||||
callback,
|
||||
isAdmin,
|
||||
isCert,
|
||||
isHost,
|
||||
isName,
|
||||
isPass,
|
||||
isRead,
|
||||
setAccount,
|
||||
]);
|
||||
|
||||
const handleConnect = () => {
|
||||
const admin = base64url.fromBase64(isAdmin);
|
||||
const read = base64url.fromBase64(isRead);
|
||||
const cert = base64url.fromBase64(isCert);
|
||||
|
||||
const correctMacaroon = read ? read : admin;
|
||||
|
||||
tryToConnect({
|
||||
variables: {
|
||||
auth: getAuthString(isHost, correctMacaroon, cert),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const renderContent = () => (
|
||||
const renderContent = () => {
|
||||
const canConnect =
|
||||
isName !== '' && isHost !== '' && isRead !== '' && !!available;
|
||||
return (
|
||||
<>
|
||||
<SingleLine>
|
||||
<Sub4Title>Name:</Sub4Title>
|
||||
|
@ -100,12 +135,14 @@ export const LoginForm = ({ available, callback }: AuthProps) => {
|
|||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return hasInfo ? (
|
||||
<PasswordInput
|
||||
isPass={isPass}
|
||||
setPass={setPass}
|
||||
callback={handleConnect}
|
||||
loading={loading}
|
||||
/>
|
||||
) : (
|
||||
renderContent()
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
import zxcvbn from 'zxcvbn';
|
||||
import styled from 'styled-components';
|
||||
import { progressBackground, textColor } from '../../styles/Themes';
|
||||
import { Loader } from '../generic/Icons';
|
||||
|
||||
const Progress = styled.div`
|
||||
width: 80%;
|
||||
|
@ -65,9 +66,15 @@ interface PasswordProps {
|
|||
isPass: string;
|
||||
setPass: (pass: string) => void;
|
||||
callback: () => void;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export const PasswordInput = ({ isPass, setPass, callback }: PasswordProps) => {
|
||||
export const PasswordInput = ({
|
||||
isPass,
|
||||
setPass,
|
||||
callback,
|
||||
loading = false,
|
||||
}: PasswordProps) => {
|
||||
const strength = (100 * Math.min(zxcvbn(isPass).guesses_log10, 40)) / 40;
|
||||
const needed = 1;
|
||||
return (
|
||||
|
@ -86,7 +93,7 @@ export const PasswordInput = ({ isPass, setPass, callback }: PasswordProps) => {
|
|||
/>
|
||||
</Progress>
|
||||
</SingleLine>
|
||||
{strength >= needed && (
|
||||
{strength >= needed && !loading && (
|
||||
<LoginButton
|
||||
disabled={strength < needed}
|
||||
enabled={strength >= needed}
|
||||
|
@ -96,6 +103,11 @@ export const PasswordInput = ({ isPass, setPass, callback }: PasswordProps) => {
|
|||
Connect
|
||||
</LoginButton>
|
||||
)}
|
||||
{loading && (
|
||||
<LoginButton disabled={true} color={'grey'}>
|
||||
<Loader />
|
||||
</LoginButton>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -99,7 +99,7 @@ export const ForwardChannelsReport = ({ isTime, isType, color }: Props) => {
|
|||
|
||||
const renderRoute = (parsed: {}[]) => {
|
||||
const routes = parsed.map((channel: any, index: number) => (
|
||||
<ChannelRow>
|
||||
<ChannelRow key={index}>
|
||||
<TableLine>{channel.aliasIn}</TableLine>
|
||||
<TableLine>{channel.aliasOut}</TableLine>
|
||||
<LastTableLine>
|
||||
|
|
|
@ -15,6 +15,14 @@ export const GET_NETWORK_INFO = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
export const GET_CAN_CONNECT = gql`
|
||||
query GetNodeInfo($auth: String!) {
|
||||
getNodeInfo(auth: $auth) {
|
||||
alias
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const GET_NODE_INFO = gql`
|
||||
query GetNodeInfo($auth: String!) {
|
||||
getNodeInfo(auth: $auth) {
|
||||
|
|
Loading…
Add table
Reference in a new issue