Main does now wait till provider finished loading

- Provider disable method now takes complete provider instance instead
- Handle when no provider is available
- Remove debug messages
This commit is contained in:
2021-01-26 20:11:59 +01:00
parent e00a4fbf1c
commit 926945f3f9
5 changed files with 59 additions and 35 deletions

View File

@@ -108,7 +108,10 @@ async function run() {
} }
providerManager = new ProviderManager(resolve('./src/helper/providers')); providerManager = new ProviderManager(resolve('./src/helper/providers'));
providerManager.scan(); await providerManager.scan().catch(err => {
logger.error(err);
process.exit(0);
});
invoiceManager = new InvoiceManager(); invoiceManager = new InvoiceManager();

View File

@@ -80,7 +80,7 @@ export async function loginUser(req: Request, res: Response) {
return; return;
} }
// Check if 2FA is turned on (the attack doesn't know yet if the password is wrong) // Check if 2FA is turned on (the attacker doesn't know if the password is wrong yet)
if (user.twoFASecret != undefined) { if (user.twoFASecret != undefined) {
if (twoFA == undefined) { if (twoFA == undefined) {
res.status(401).send({ message: "2FA code is required." }); res.status(401).send({ message: "2FA code is required." });
@@ -135,6 +135,10 @@ export async function MW_User(req: LibrePayRequest, res: Response, next: () => v
} }
} catch (err) { } catch (err) {
if (err) { if (err) {
if (err === "jwt expired") {
res.status(401).send({ message: "Your token expired" });
return;
}
res.status(500).send({ message: "We failed validating your token for some reason." }); res.status(500).send({ message: "We failed validating your token for some reason." });
logger.error(err); logger.error(err);
} }

View File

@@ -29,7 +29,12 @@ export class InvoiceManager {
if (invoice.status === PaymentStatus.PENDING) { this.pendingInvoices.push(invoice); } if (invoice.status === PaymentStatus.PENDING) { this.pendingInvoices.push(invoice); }
if (invoice.status === PaymentStatus.UNCONFIRMED) { this.unconfirmedTranscations.push(invoice); } if (invoice.status === PaymentStatus.UNCONFIRMED) { this.unconfirmedTranscations.push(invoice); }
try {
providerManager.getProvider(invoice.paymentMethod).validateInvoice(invoice); providerManager.getProvider(invoice.paymentMethod).validateInvoice(invoice);
} catch (err) {
logger.debug(`Cannot validate invoice ${invoice.id} because there is no provider for ${invoice.paymentMethod}. Remove ...`);
this.removeInvoice(invoice);
}
}); });
}); });
@@ -162,6 +167,13 @@ export class InvoiceManager {
this.unconfirmedTranscations.forEach(async invoice => { this.unconfirmedTranscations.forEach(async invoice => {
const transcation = invoice.transcationHash; const transcation = invoice.transcationHash;
if (providerManager.getProvider(invoice.paymentMethod) === undefined) {
logger.debug(`Cannot get confirmations of invoice ${invoice.id} because there is no provider for ${invoice.paymentMethod}. Remove ...`);
this.removeInvoice(invoice);
return;
}
const provider = providerManager.getProvider(invoice.paymentMethod); const provider = providerManager.getProvider(invoice.paymentMethod);
const tx = await provider.getTransaction(transcation); const tx = await provider.getTransaction(transcation);
this.setConfirmationCount(invoice, tx.confirmations); this.setConfirmationCount(invoice, tx.confirmations);

View File

@@ -1,4 +1,4 @@
import { readdirSync } from 'fs'; import { readdir } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { config } from '../../config'; import { config } from '../../config';
import { invoiceManager, logger, providerManager } from '../app'; import { invoiceManager, logger, providerManager } from '../app';
@@ -22,25 +22,24 @@ export class ProviderManager {
/** /**
* Scan & load all found providers * Scan & load all found providers
*/ */
scan() { async scan() {
const getDirectories = () => return new Promise<void>(async (resolve, reject) => {
readdirSync(this.providerFilePath, { withFileTypes: true }) await readdir(this.providerFilePath, { withFileTypes: true }, async (err, files) => {
.filter(dirent => dirent.name.endsWith('.ts')) const directories = files.filter(dirent => dirent.name.endsWith('.ts'))
.map(dirent => dirent.name) .map(dirent => dirent.name);
for (let i = 0; i < directories.length; i++) {
getDirectories().forEach(async file => { const file = directories[i];
const absolutePath = join(this.providerFilePath, file); const absolutePath = join(this.providerFilePath, file);
const providerModule = require(absolutePath); const providerModule = require(absolutePath);
const provider = new providerModule.Provider() as BackendProvider; const provider = new providerModule.Provider() as BackendProvider;
provider.CRYPTO.forEach(crypto => { provider.CRYPTO.forEach(crypto => {
if (this.cryptoProvider.has(crypto)) { if (this.cryptoProvider.has(crypto)) {
logger.warn(`Provider ${provider.NAME} will be ignored since there is already another provider active for ${provider.CRYPTO}!`); logger.warn(`Provider ${provider.NAME} will not be activated for ${provider.CRYPTO} since there is already another provider in place!`);
return; } else {
}
this.cryptoProvider.set(crypto, provider); this.cryptoProvider.set(crypto, provider);
config.payment.methods.push(crypto); config.payment.methods.push(crypto);
}
}); });
// Execute onEnable() function of this provider // Execute onEnable() function of this provider
@@ -49,21 +48,30 @@ export class ProviderManager {
logger.info(`Loaded provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) for ${provider.CRYPTO.join(', ')}`); logger.info(`Loaded provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) for ${provider.CRYPTO.join(', ')}`);
} catch (err) { } catch (err) {
logger.error(`Provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) failed to start: ${err}`); logger.error(`Provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) failed to start: ${err}`);
this.disable(provider.NAME); this.disable(provider);
}
} }
if (this.cryptoProvider.size === 0) {
reject('No providers were initialized!');
return;
}
resolve();
});
}); });
} }
/** /**
* This provider will be no longer be used. * This provider will be no longer be used.
*/ */
disable(name: string) { disable(provider: BackendProvider) {
this.cryptoProvider.forEach(provider => { this.cryptoProvider.forEach(cryptoProvider => {
if (provider.NAME === name) { if (provider === cryptoProvider) {
// Disable all coins that are supported by this provider. // Disable all coins that are supported by this provider.
provider.CRYPTO.forEach(crypto => { provider.CRYPTO.forEach(crypto => {
this.cryptoProvider.delete(crypto); this.cryptoProvider.delete(crypto);
config.payment.methods.splice(config.payment.methods.indexOf(crypto), 1);
}); });
logger.warning(`Provider "${provider.NAME}" is now disabled.`); logger.warning(`Provider "${provider.NAME}" is now disabled.`);
} }

View File

@@ -101,7 +101,6 @@ export class Provider implements BackendProvider {
const paymentTransaction = message.result.transfer; const paymentTransaction = message.result.transfer;
if (paymentTransaction === undefined) { if (paymentTransaction === undefined) {
console.log(message)
logger.warning(`Tried to get transfer by txid but failed: ${message}`); logger.warning(`Tried to get transfer by txid but failed: ${message}`);
resolve(null); resolve(null);
return; return;
@@ -175,8 +174,6 @@ export class Provider implements BackendProvider {
return; return;
} }
console.log(payment_id, message);
// The payment has not been made yet // The payment has not been made yet
if (message.result.payments === undefined) { if (message.result.payments === undefined) {
resolve(null); resolve(null);