mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-21 14:04:03 +01:00
chore: 🔧 add no auth and logout url
This commit is contained in:
parent
4c39f79cb3
commit
1dcea164d5
9 changed files with 80 additions and 19 deletions
2
.env
2
.env
|
@ -39,3 +39,5 @@
|
|||
# SSO_SERVER_URL='127.0.0.1:10009'
|
||||
# SSO_CERT_PATH='/path/to/certificate/tls.cert'
|
||||
# SSO_MACAROON_PATH='/path/to/folder/containing/macaroons'
|
||||
# DANGEROUS_NO_SSO_AUTH=false
|
||||
# LOGOUT_URL='http://thunderhub.io'
|
||||
|
|
33
README.md
33
README.md
|
@ -138,10 +138,11 @@ You can define an account to work with SSO cookie authentication by adding the f
|
|||
# -----------
|
||||
# SSO Account Configs
|
||||
# -----------
|
||||
COOKIE_PATH = '/path/to/cookie/file/.cookie'; # i.e. '/data/.cookie'
|
||||
SSO_SERVER_URL = 'url and port to node'; # i.e. '127.0.0.1:10009'
|
||||
SSO_CERT_PATH = '/path/to/tls/certificate'; # i.e. '\lnd\alice\tls.cert'
|
||||
SSO_MACAROON_PATH = '/path/to/macaroon/folder'; # i.e. '\lnd\alice\data\chain\bitcoin\regtest\'
|
||||
COOKIE_PATH = '/path/to/cookie/file/.cookie' # i.e. '/data/.cookie'
|
||||
SSO_SERVER_URL = 'url and port to node' # i.e. '127.0.0.1:10009'
|
||||
SSO_CERT_PATH = '/path/to/tls/certificate' # i.e. '\lnd\alice\tls.cert'
|
||||
SSO_MACAROON_PATH = '/path/to/macaroon/folder' # i.e. '\lnd\alice\data\chain\bitcoin\regtest\'
|
||||
LOGOUT_URL = 'http://LogoutToThisUrl.com' # If not set it will logout to "/login"
|
||||
```
|
||||
|
||||
To login to this account you must add the cookie file content to the end of your ThunderHub url. For example:
|
||||
|
@ -152,6 +153,30 @@ http://localhost:3000/sso?token=[COOKIE]
|
|||
|
||||
Replace `[COOKIE]` with the contents of the `.cookie` file.
|
||||
|
||||
### SSO Account without authentication
|
||||
|
||||
You can DANGEROUSLY remove SSO authentication. This is useful for example if you plan on running ThunderHub **only** on your local network or through TOR.
|
||||
|
||||
**DO NOT enable this option if your ThunderHub instance is available on the internet or your funds will probably be lost.**
|
||||
|
||||
The configuration for a non authenticated SSO account would look like this:
|
||||
|
||||
```bash
|
||||
# -----------
|
||||
# SSO Account Configs
|
||||
# -----------
|
||||
SSO_SERVER_URL = 'url and port to node'; # i.e. '127.0.0.1:10009'
|
||||
SSO_CERT_PATH = '/path/to/tls/certificate'; # i.e. '\lnd\alice\tls.cert'
|
||||
SSO_MACAROON_PATH = '/path/to/macaroon/folder'; # i.e. '\lnd\alice\data\chain\bitcoin\regtest\'
|
||||
DANGEROUS_NO_SSO_AUTH = 'true' # Default: false
|
||||
```
|
||||
|
||||
To login to this account go to the following url:
|
||||
|
||||
```
|
||||
http://localhost:3000/sso?token=1
|
||||
```
|
||||
|
||||
### Server Accounts
|
||||
|
||||
You can add accounts on the server by adding this parameter to the `.env` file:
|
||||
|
|
|
@ -14,6 +14,8 @@ module.exports = withBundleAnalyzer({
|
|||
lnCertPath: process.env.SSO_CERT_PATH || '',
|
||||
macaroonPath: process.env.SSO_MACAROON_PATH || '',
|
||||
accountConfigPath: process.env.ACCOUNT_CONFIG_PATH || '',
|
||||
dangerousNoSSOAuth:
|
||||
process.env.DANGEROUS_NO_SSO_AUTH === 'true' ? true : false,
|
||||
},
|
||||
publicRuntimeConfig: {
|
||||
nodeEnv: process.env.NODE_ENV || 'development',
|
||||
|
@ -28,5 +30,6 @@ module.exports = withBundleAnalyzer({
|
|||
disableLinks: process.env.DISABLE_LINKS === 'true' ? true : false,
|
||||
disableLnMarkets: process.env.DISABLE_LNMARKETS === 'true' ? true : false,
|
||||
noVersionCheck: process.env.NO_VERSION_CHECK === 'true' ? true : false,
|
||||
logoutUrl: process.env.LOGOUT_URL || '',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ import { toWithError } from 'server/helpers/async';
|
|||
import { decodeMacaroon, isCorrectPassword } from 'server/helpers/crypto';
|
||||
|
||||
const { serverRuntimeConfig } = getConfig() || {};
|
||||
const { cookiePath, nodeEnv } = serverRuntimeConfig || {};
|
||||
const { cookiePath, nodeEnv, dangerousNoSSOAuth } = serverRuntimeConfig || {};
|
||||
|
||||
export const authResolvers = {
|
||||
Mutation: {
|
||||
|
@ -33,22 +33,32 @@ export const authResolvers = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!cookie) {
|
||||
return false;
|
||||
}
|
||||
if (dangerousNoSSOAuth) {
|
||||
logger.warn(
|
||||
'SSO authentication is disabled. Make sure this is what you want.'
|
||||
);
|
||||
} else {
|
||||
// No cookie or cookiePath needed when SSO authentication is turned off
|
||||
if (!cookie) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cookiePath === '') {
|
||||
logger.warn('SSO auth not available since no cookie path was provided');
|
||||
return false;
|
||||
if (cookiePath === '') {
|
||||
logger.warn(
|
||||
'SSO auth not available since no cookie path was provided'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const cookieFile = readCookie(cookiePath);
|
||||
|
||||
if (
|
||||
(cookieFile && cookieFile.trim() === cookie.trim()) ||
|
||||
nodeEnv === 'development'
|
||||
nodeEnv === 'development' ||
|
||||
dangerousNoSSOAuth
|
||||
) {
|
||||
refreshCookie(cookiePath);
|
||||
cookiePath && refreshCookie(cookiePath);
|
||||
|
||||
const { lnd } = authenticatedLndGrpc(sso);
|
||||
const [, error] = await toWithError<GetWalletInfoType>(
|
||||
|
|
|
@ -4,8 +4,12 @@ import { appendBasePath } from 'src/utils/basePath';
|
|||
import { getUrlParam } from 'src/utils/url';
|
||||
import { toast } from 'react-toastify';
|
||||
import { getErrorContent } from 'src/utils/error';
|
||||
import getConfig from 'next/config';
|
||||
import { useGetAuthTokenMutation } from 'src/graphql/mutations/__generated__/getAuthToken.generated';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { logoutUrl } = publicRuntimeConfig;
|
||||
|
||||
export const ServerAccounts: React.FC = () => {
|
||||
const { push, query } = useRouter();
|
||||
|
||||
|
@ -16,7 +20,7 @@ export const ServerAccounts: React.FC = () => {
|
|||
refetchQueries: ['GetNodeInfo'],
|
||||
onError: error => {
|
||||
toast.error(getErrorContent(error));
|
||||
push(appendBasePath('/login'));
|
||||
push(logoutUrl || appendBasePath('/login'));
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -24,7 +28,7 @@ export const ServerAccounts: React.FC = () => {
|
|||
if (cookieParam) {
|
||||
getToken();
|
||||
} else {
|
||||
push(appendBasePath('/login'));
|
||||
push(logoutUrl || appendBasePath('/login'));
|
||||
}
|
||||
}, [cookieParam, push, getToken]);
|
||||
|
||||
|
|
|
@ -7,9 +7,13 @@ import { HeaderNavButton } from 'src/layouts/header/Header.styled';
|
|||
import styled from 'styled-components';
|
||||
import { themeColors } from 'src/styles/Themes';
|
||||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
||||
import getConfig from 'next/config';
|
||||
import { appendBasePath } from '../../utils/basePath';
|
||||
import { useChatDispatch } from '../../context/ChatContext';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { logoutUrl } = publicRuntimeConfig;
|
||||
|
||||
const Logout = styled.button`
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
@ -33,7 +37,8 @@ export const LogoutButton = () => {
|
|||
if (data && data.logout) {
|
||||
dispatchChat({ type: 'disconnected' });
|
||||
client.clearStore();
|
||||
push(appendBasePath('/login'));
|
||||
|
||||
push(logoutUrl || appendBasePath('/login'));
|
||||
}
|
||||
}, [data, dispatchChat, push, client]);
|
||||
|
||||
|
|
|
@ -2,8 +2,12 @@ import { useEffect } from 'react';
|
|||
import { useRouter } from 'next/router';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useGetNodeInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||
import getConfig from 'next/config';
|
||||
import { appendBasePath } from '../../utils/basePath';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { logoutUrl } = publicRuntimeConfig;
|
||||
|
||||
export const StatusCheck: React.FC = () => {
|
||||
const { push } = useRouter();
|
||||
|
||||
|
@ -17,7 +21,7 @@ export const StatusCheck: React.FC = () => {
|
|||
if (error) {
|
||||
toast.error(`Unable to connect to node`);
|
||||
stopPolling();
|
||||
push(appendBasePath('/login'));
|
||||
push(logoutUrl || appendBasePath('/login'));
|
||||
}
|
||||
}, [error, push, stopPolling]);
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ import { parseCookies } from 'src/utils/cookies';
|
|||
import { DocumentNode } from 'graphql';
|
||||
import { appConstants } from 'server/utils/appConstants';
|
||||
import { GET_AUTH_TOKEN } from 'src/graphql/mutations/getAuthToken';
|
||||
import getConfig from 'next/config';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { logoutUrl } = publicRuntimeConfig;
|
||||
|
||||
const cookieProps = (
|
||||
context: NextPageContext,
|
||||
|
@ -17,7 +21,7 @@ const cookieProps = (
|
|||
const hasToken = !!cookies[appConstants.tokenCookieName];
|
||||
|
||||
if (!cookies[appConstants.cookieName] && !noAuth) {
|
||||
context.res?.writeHead(302, { Location: '/login' });
|
||||
context.res?.writeHead(302, { Location: logoutUrl || '/login' });
|
||||
context.res?.end();
|
||||
|
||||
return { theme: 'dark', authenticated: false, hasToken };
|
||||
|
|
|
@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|||
import { AlertCircle } from 'react-feather';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useLogoutMutation } from 'src/graphql/mutations/__generated__/logout.generated';
|
||||
import getConfig from 'next/config';
|
||||
import {
|
||||
Card,
|
||||
CardWithTitle,
|
||||
|
@ -15,6 +16,9 @@ import { ColorButton } from '../../components/buttons/colorButton/ColorButton';
|
|||
import { appendBasePath } from '../../utils/basePath';
|
||||
import { useChatDispatch } from '../../context/ChatContext';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { logoutUrl } = publicRuntimeConfig;
|
||||
|
||||
export const ButtonRow = styled.div`
|
||||
width: auto;
|
||||
display: flex;
|
||||
|
@ -56,7 +60,7 @@ export const DangerView = () => {
|
|||
const { push } = useRouter();
|
||||
|
||||
const [logout] = useLogoutMutation({
|
||||
onCompleted: () => push(appendBasePath('/login')),
|
||||
onCompleted: () => push(logoutUrl || appendBasePath('/login')),
|
||||
});
|
||||
|
||||
const handleDeleteAll = () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue