mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-21 14:04:03 +01:00
chore: 🔧 improve logging
This commit is contained in:
parent
7d7ef5697f
commit
414c20f053
9 changed files with 76 additions and 45 deletions
|
@ -7,6 +7,7 @@ import {
|
|||
CLIENT_ACCOUNT,
|
||||
} from 'src/context/AccountContext';
|
||||
import { ContextType } from 'api/types/apiTypes';
|
||||
import { logger } from './logger';
|
||||
|
||||
const { serverRuntimeConfig } = getConfig();
|
||||
const { nodeEnv } = serverRuntimeConfig;
|
||||
|
@ -35,24 +36,32 @@ export const getCorrectAuth = (
|
|||
): LndAuthType => {
|
||||
if (auth.type === SERVER_ACCOUNT) {
|
||||
const { account } = context;
|
||||
if (!account || account.id !== auth.id)
|
||||
throw new Error('This account is not authenticated');
|
||||
|
||||
const foundAccount = context.accounts.find(a => a.id === account.id);
|
||||
if (!foundAccount) throw new Error('This account does not exist');
|
||||
if (!account) {
|
||||
logger.debug('Account not available in request');
|
||||
throw new Error('AccountNotAuthenticated');
|
||||
}
|
||||
if (account.id !== auth.id) {
|
||||
logger.debug(
|
||||
`Account (${account.id}) in cookie different to requested account (${auth.id})`
|
||||
);
|
||||
throw new Error('AccountNotAuthenticated');
|
||||
}
|
||||
|
||||
return account;
|
||||
}
|
||||
if (auth.type === SSO_ACCOUNT) {
|
||||
if (!context.ssoVerified)
|
||||
throw new Error('This account is not authenticated');
|
||||
if (!context.ssoVerified) {
|
||||
logger.debug('SSO Account is not verified');
|
||||
throw new Error('AccountNotAuthenticated');
|
||||
}
|
||||
|
||||
return { ...context.sso };
|
||||
}
|
||||
if (auth.type === CLIENT_ACCOUNT) {
|
||||
const { host, macaroon, cert } = auth;
|
||||
return { host, macaroon, cert };
|
||||
}
|
||||
throw new Error('This account type does not exist');
|
||||
throw new Error('AccountTypeDoesNotExist');
|
||||
};
|
||||
|
||||
export const getAuthLnd = (auth: LndAuthType) => {
|
||||
|
|
|
@ -2,9 +2,7 @@ import { createLogger, format, transports } from 'winston';
|
|||
import getConfig from 'next/config';
|
||||
|
||||
const { serverRuntimeConfig } = getConfig();
|
||||
const { logLevel, nodeEnv } = serverRuntimeConfig;
|
||||
|
||||
const level = nodeEnv === 'development' ? 'debug' : logLevel;
|
||||
const { logLevel } = serverRuntimeConfig;
|
||||
|
||||
const combinedFormat =
|
||||
// nodeEnv === 'development' ?
|
||||
|
@ -33,7 +31,7 @@ const combinedFormat =
|
|||
// );
|
||||
|
||||
export const logger = createLogger({
|
||||
level,
|
||||
level: logLevel,
|
||||
format: combinedFormat,
|
||||
transports: [new transports.Console()],
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@ import jwt from 'jsonwebtoken';
|
|||
import CryptoJS from 'crypto-js';
|
||||
import { ContextType } from 'api/types/apiTypes';
|
||||
import AES from 'crypto-js/aes';
|
||||
import { logger } from 'api/helpers/logger';
|
||||
import { requestLimiter } from '../../../helpers/rateLimiter';
|
||||
|
||||
export const getSessionToken = {
|
||||
|
@ -17,11 +18,15 @@ export const getSessionToken = {
|
|||
|
||||
const account = context.accounts.find(a => a.id === params.id) || null;
|
||||
|
||||
if (!account) return null;
|
||||
if (!account) {
|
||||
logger.debug(`Account ${params.id} not found`);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const bytes = AES.decrypt(account.macaroon, params.password);
|
||||
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
||||
logger.debug(`Correct password for account ${params.id}`);
|
||||
const token = jwt.sign(
|
||||
{
|
||||
id: params.id,
|
||||
|
@ -33,7 +38,7 @@ export const getSessionToken = {
|
|||
);
|
||||
return AES.encrypt(token, secret).toString();
|
||||
} catch (error) {
|
||||
throw new Error('Wrong password');
|
||||
throw new Error('WrongPasswordForLogin');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
import { getWalletInfo, getClosedChannels } from 'ln-service';
|
||||
import { ContextType } from 'api/types/apiTypes';
|
||||
import { logger } from '../../../helpers/logger';
|
||||
import { to } from 'api/helpers/async';
|
||||
import { requestLimiter } from '../../../helpers/rateLimiter';
|
||||
import {
|
||||
getAuthLnd,
|
||||
getErrorMsg,
|
||||
getCorrectAuth,
|
||||
} from '../../../helpers/helpers';
|
||||
import { getAuthLnd, getCorrectAuth } from '../../../helpers/helpers';
|
||||
import { defaultParams } from '../../../helpers/defaultProps';
|
||||
import { NodeInfoType } from '../../types/QueryType';
|
||||
|
||||
|
@ -36,20 +32,21 @@ export const getNodeInfo = {
|
|||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
try {
|
||||
const info: NodeInfoProps = await getWalletInfo({
|
||||
const info = await to(
|
||||
getWalletInfo({
|
||||
lnd,
|
||||
});
|
||||
const closedChannels: { channels: [] } = await getClosedChannels({
|
||||
})
|
||||
);
|
||||
|
||||
const closedChannels = await to(
|
||||
getClosedChannels({
|
||||
lnd,
|
||||
});
|
||||
return {
|
||||
...info,
|
||||
closed_channels_count: closedChannels.channels.length,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error getting node info: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
...info,
|
||||
closed_channels_count: closedChannels?.channels?.length || 0,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@ const apolloServer = new ApolloServer({
|
|||
|
||||
let ssoVerified = false;
|
||||
if (req?.cookies?.SSOAuth) {
|
||||
logger.silly('SSOAuth cookie found in request');
|
||||
try {
|
||||
jwt.verify(req.cookies.SSOAuth, secret);
|
||||
ssoVerified = true;
|
||||
|
@ -53,6 +54,7 @@ const apolloServer = new ApolloServer({
|
|||
|
||||
let account = null;
|
||||
if (req?.cookies?.AccountAuth) {
|
||||
logger.silly('AccountAuth cookie found in request');
|
||||
try {
|
||||
const bytes = AES.decrypt(req.cookies.AccountAuth, secret);
|
||||
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
||||
|
|
|
@ -3,6 +3,7 @@ import { toast } from 'react-toastify';
|
|||
import { useRouter } from 'next/router';
|
||||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetMessagesQuery } from 'src/graphql/queries/__generated__/getMessages.generated';
|
||||
import { useStatusState } from 'src/context/StatusContext';
|
||||
import { useChatState, useChatDispatch } from '../../context/ChatContext';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
import { useConfigState } from '../../context/ConfigContext';
|
||||
|
@ -12,6 +13,7 @@ export const ChatFetcher = () => {
|
|||
|
||||
const { chatPollingSpeed } = useConfigState();
|
||||
|
||||
const { connected } = useStatusState();
|
||||
const { auth } = useAccountState();
|
||||
const { pathname } = useRouter();
|
||||
const { lastChat, chats, sentChats, initialized } = useChatState();
|
||||
|
@ -20,7 +22,7 @@ export const ChatFetcher = () => {
|
|||
const noChatsAvailable = chats.length <= 0 && sentChats.length <= 0;
|
||||
|
||||
const { data, loading, error } = useGetMessagesQuery({
|
||||
skip: !auth || initialized || noChatsAvailable,
|
||||
skip: !auth || initialized || noChatsAvailable || !connected,
|
||||
pollInterval: chatPollingSpeed,
|
||||
fetchPolicy: 'network-only',
|
||||
variables: { auth, initialize: !noChatsAvailable },
|
||||
|
@ -28,7 +30,7 @@ export const ChatFetcher = () => {
|
|||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
if (data?.getMessages?.messages) {
|
||||
if (data && data.getMessages?.messages) {
|
||||
const messages = [...data.getMessages.messages];
|
||||
let index = -1;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useRouter } from 'next/router';
|
|||
import { toast } from 'react-toastify';
|
||||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetNodeInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||
import { useStatusDispatch } from '../../context/StatusContext';
|
||||
import { useStatusDispatch, useStatusState } from '../../context/StatusContext';
|
||||
import { appendBasePath } from '../../utils/basePath';
|
||||
|
||||
export const StatusCheck = () => {
|
||||
|
@ -11,9 +11,10 @@ export const StatusCheck = () => {
|
|||
const { push } = useRouter();
|
||||
|
||||
const { account, auth } = useAccountState();
|
||||
const { connected } = useStatusState();
|
||||
|
||||
const { data, loading, error, stopPolling } = useGetNodeInfoQuery({
|
||||
skip: !auth,
|
||||
skip: !auth || !connected,
|
||||
fetchPolicy: 'network-only',
|
||||
variables: { auth },
|
||||
pollInterval: 10000,
|
||||
|
@ -55,7 +56,7 @@ export const StatusCheck = () => {
|
|||
|
||||
dispatch({ type: 'connected', state });
|
||||
}
|
||||
}, [data, dispatch, error, loading, push, account]);
|
||||
}, [data, dispatch, error, loading, push, account, stopPolling]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,12 @@ const getMessage = error => {
|
|||
return 'Did not find a possible route.';
|
||||
case 'SendPaymentFail':
|
||||
return 'Failed to send this payments.';
|
||||
case 'AccountNotAuthenticated':
|
||||
return 'This account is not authenticated.';
|
||||
case 'AccountTypeDoesNotExist':
|
||||
return 'This account does not exist.';
|
||||
case 'WrongPasswordForLogin':
|
||||
return 'Wrong password provided.';
|
||||
default:
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import Cookies from 'js-cookie';
|
|||
import { useGetCanConnectLazyQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||
import { useGetSessionTokenLazyQuery } from 'src/graphql/queries/__generated__/getSessionToken.generated';
|
||||
import { getAuthFromAccount } from 'src/context/helpers/context';
|
||||
import { getErrorContent } from 'src/utils/error';
|
||||
import { SingleLine, Sub4Title, Card } from '../../components/generic/Styled';
|
||||
import { getAuthObj } from '../../utils/auth';
|
||||
import { ColorButton } from '../../components/buttons/colorButton/ColorButton';
|
||||
|
@ -43,8 +44,8 @@ export const SessionLogin = () => {
|
|||
|
||||
const [getCanConnect, { data, loading }] = useGetCanConnectLazyQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
onError: () => {
|
||||
toast.error('Unable to connect to this node');
|
||||
onError: err => {
|
||||
toast.error(getErrorContent(err));
|
||||
dispatch({ type: 'disconnected' });
|
||||
},
|
||||
});
|
||||
|
@ -54,14 +55,14 @@ export const SessionLogin = () => {
|
|||
{ data: sData, loading: sLoading },
|
||||
] = useGetSessionTokenLazyQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
onError: () => {
|
||||
toast.error('Wrong password');
|
||||
onError: err => {
|
||||
toast.error(getErrorContent(err));
|
||||
dispatch({ type: 'disconnected' });
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!sLoading && sData?.getSessionToken) {
|
||||
if (!sLoading && sData && sData.getSessionToken) {
|
||||
Cookies.set('AccountAuth', sData.getSessionToken, {
|
||||
sameSite: 'strict',
|
||||
});
|
||||
|
@ -74,11 +75,21 @@ export const SessionLogin = () => {
|
|||
}, [sLoading, sData, push, getCanConnect, account]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && data?.getNodeInfo && account.type === SERVER_ACCOUNT) {
|
||||
if (
|
||||
!loading &&
|
||||
data &&
|
||||
data.getNodeInfo &&
|
||||
account.type === SERVER_ACCOUNT
|
||||
) {
|
||||
dispatch({ type: 'connected' });
|
||||
push(appendBasePath('/home'));
|
||||
}
|
||||
if (!loading && data?.getNodeInfo && account.type === CLIENT_ACCOUNT) {
|
||||
if (
|
||||
!loading &&
|
||||
data &&
|
||||
data.getNodeInfo &&
|
||||
account.type === CLIENT_ACCOUNT
|
||||
) {
|
||||
const bytes = CryptoJS.AES.decrypt(account.admin, pass);
|
||||
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue