mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-23 22:46:35 +01:00
330 lines
8.6 KiB
TypeScript
330 lines
8.6 KiB
TypeScript
import { existsSync, readFileSync } from 'fs';
|
|
import path from 'path';
|
|
import {
|
|
getParsedAccount,
|
|
hashPasswords,
|
|
getAccountsFromYaml,
|
|
AccountType,
|
|
} from '../fileHelpers';
|
|
|
|
const mockedExistsSync: jest.Mock = existsSync as any;
|
|
const mockedReadFileSync: jest.Mock = readFileSync as any;
|
|
|
|
jest.mock('fs');
|
|
|
|
describe('getParsedAccount', () => {
|
|
const masterPassword = 'master password';
|
|
it('returns null without an account name', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: '',
|
|
certificate: 'RAW CERT',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account).toBeNull();
|
|
});
|
|
|
|
it('returns null on invalid network', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'name',
|
|
certificate: 'RAW CERT',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
network: 'foo' as any,
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account).toBeNull();
|
|
});
|
|
|
|
it('returns null without an account server url', () => {
|
|
const raw = {
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
serverUrl: '',
|
|
macaroon: 'RAW MACAROON',
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account).toBeNull();
|
|
});
|
|
|
|
it('defaults to given bitcoin network', () => {
|
|
const raw = {
|
|
name: 'NAME',
|
|
serverUrl: 'server.url',
|
|
lndDir: 'lnd dir',
|
|
};
|
|
|
|
mockedExistsSync.mockReturnValue(true);
|
|
mockedReadFileSync.mockImplementation(file => {
|
|
if ((file as string).includes('tls.cert')) {
|
|
return 'cert';
|
|
}
|
|
|
|
if ((file as string).includes(path.join('regtest', 'admin.macaroon'))) {
|
|
return 'macaroon';
|
|
}
|
|
return 'something else ';
|
|
});
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'regtest');
|
|
expect(account?.macaroon).toContain('macaroon');
|
|
});
|
|
|
|
it('picks up other networks', () => {
|
|
const raw = {
|
|
name: 'NAME',
|
|
serverUrl: 'server.url',
|
|
lndDir: 'lnd dir',
|
|
network: 'testnet',
|
|
} as const;
|
|
|
|
mockedExistsSync.mockReturnValue(true);
|
|
mockedReadFileSync.mockImplementation(file => {
|
|
if ((file as string).includes('tls.cert')) {
|
|
return 'cert';
|
|
}
|
|
|
|
if ((file as string).includes(path.join('testnet', 'admin.macaroon'))) {
|
|
return 'macaroon';
|
|
}
|
|
return 'something else ';
|
|
});
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.macaroon).toContain('macaroon');
|
|
});
|
|
|
|
describe('macaroon handling', () => {
|
|
it('defaults to raw macaroon', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
macaroonPath: 'MACAROON PATH',
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.macaroon).toBe('RAW MACAROON');
|
|
});
|
|
it('falls back to macaroon path after that', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
certificatePath: 'CERT PATH',
|
|
serverUrl: 'server.url',
|
|
macaroon: '',
|
|
macaroonPath: 'MACAROON PATH',
|
|
};
|
|
mockedExistsSync.mockReturnValueOnce(true);
|
|
mockedReadFileSync.mockImplementationOnce(file => {
|
|
if ((file as string).includes(raw.macaroonPath)) {
|
|
return 'yay';
|
|
} else {
|
|
return 'nay';
|
|
}
|
|
});
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.macaroon).toBe('yay');
|
|
});
|
|
|
|
it('falls back to lnd dir finally', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
certificatePath: 'CERT PATH',
|
|
serverUrl: 'server.url',
|
|
macaroon: '',
|
|
macaroonPath: '',
|
|
};
|
|
mockedExistsSync.mockReturnValueOnce(true);
|
|
mockedReadFileSync.mockImplementationOnce(file => {
|
|
if ((file as string).includes(raw.lndDir)) {
|
|
return 'yay';
|
|
} else {
|
|
return 'nay';
|
|
}
|
|
});
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.macaroon).toBe('yay');
|
|
});
|
|
});
|
|
|
|
describe('certificate handling', () => {
|
|
it('defaults to raw certificate', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
certificatePath: 'CERT PATH',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.cert).toBe('RAW CERT');
|
|
});
|
|
|
|
it('falls back to certificate path after that', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
certificatePath: 'CERT PATH',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
};
|
|
mockedExistsSync.mockReturnValueOnce(true);
|
|
mockedReadFileSync.mockImplementationOnce(file => {
|
|
if ((file as string).includes(raw.certificatePath)) {
|
|
return 'yay';
|
|
} else {
|
|
return 'nay';
|
|
}
|
|
});
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.cert).toBe('yay');
|
|
});
|
|
|
|
it('falls back to lnd dir finally', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
};
|
|
mockedExistsSync.mockReturnValueOnce(true);
|
|
mockedReadFileSync.mockImplementationOnce(file => {
|
|
if ((file as string).includes(raw.lndDir)) {
|
|
return 'yay';
|
|
} else {
|
|
return 'nay';
|
|
}
|
|
});
|
|
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
|
expect(account?.cert).toBe('yay');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('encrypted accounts', () => {
|
|
it('returns correct props when encrypted', () => {
|
|
const raw: AccountType = {
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
encrypted: true,
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, 'master password', 'mainnet');
|
|
expect(account?.encrypted).toBeTruthy();
|
|
expect(account?.macaroon).toBe(raw.macaroon);
|
|
expect((account as any)?.encryptedMacaroon).toBe(raw.macaroon);
|
|
});
|
|
it('returns correct props when not encrypted', () => {
|
|
const raw = {
|
|
lndDir: 'LND DIR',
|
|
name: 'NAME',
|
|
certificate: 'RAW CERT',
|
|
serverUrl: 'server.url',
|
|
macaroon: 'RAW MACAROON',
|
|
};
|
|
|
|
const account = getParsedAccount(raw, 0, 'master password', 'mainnet');
|
|
expect(account?.encrypted).toBeFalsy();
|
|
expect(account).not.toHaveProperty('encryptedMacaroon');
|
|
});
|
|
});
|
|
|
|
describe('hashPasswords', () => {
|
|
it('does not throw on missing master password', () => {
|
|
const config = {
|
|
hashed: false,
|
|
masterPassword: null,
|
|
defaultNetwork: null,
|
|
accounts: [],
|
|
};
|
|
expect(hashPasswords(false, config, 'file-path')).toEqual({
|
|
accounts: [],
|
|
defaultNetwork: null,
|
|
hashed: false,
|
|
masterPassword: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getAccountsFromYaml', () => {
|
|
it('needs either account password or master password', () => {
|
|
const conf = {
|
|
hashed: false,
|
|
masterPassword: 'masterPassword',
|
|
defaultNetwork: null,
|
|
accounts: [
|
|
{
|
|
name: 'first account',
|
|
serverUrl: 'server.url',
|
|
password: 'accountPassword',
|
|
certificate: 'cert',
|
|
macaroon: 'macaroon',
|
|
},
|
|
],
|
|
};
|
|
|
|
// no password and no account password
|
|
expect(
|
|
getAccountsFromYaml(
|
|
{
|
|
...conf,
|
|
masterPassword: null,
|
|
accounts: [
|
|
{
|
|
...conf.accounts[0],
|
|
password: null,
|
|
},
|
|
],
|
|
},
|
|
'file-path'
|
|
)
|
|
).toHaveLength(0);
|
|
|
|
// just master password
|
|
expect(
|
|
getAccountsFromYaml(
|
|
{
|
|
...conf,
|
|
accounts: [
|
|
{
|
|
...conf.accounts[0],
|
|
password: null,
|
|
},
|
|
],
|
|
},
|
|
'file-path'
|
|
)
|
|
).toHaveLength(1);
|
|
|
|
// just account password
|
|
expect(
|
|
getAccountsFromYaml(
|
|
{
|
|
...conf,
|
|
masterPassword: null,
|
|
accounts: [
|
|
{
|
|
...conf.accounts[0],
|
|
password: 'accountPassword',
|
|
},
|
|
],
|
|
},
|
|
'file-path'
|
|
)
|
|
).toHaveLength(1);
|
|
});
|
|
});
|