feat: add backend

This commit is contained in:
Anselm Stordeur
2019-01-08 12:26:15 +01:00
committed by Rainer Killinger
commit 16bbb7e9e3
66 changed files with 6939 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2019 StApps
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {SMTP} from '@openstapps/logger/lib/SMTP';
import {Transport, TransportWithVerification} from '@openstapps/logger/lib/Transport';
export function isTransportWithVerification(instance: Transport): instance is TransportWithVerification {
return typeof (instance as TransportWithVerification).verify === 'function';
}
/**
* Singleton for getting only one transport service
*
* In the future this may support more than loading SMTP as a transport.
*/
export class BackendTransport {
private static _instance: BackendTransport;
private waitingForVerification: boolean;
protected transport: SMTP | undefined;
public static getTransportInstance(): SMTP | undefined {
if (this._instance) {
return this._instance.transport;
}
this._instance = new this();
return this._instance.transport;
}
private constructor() {
// get SMTP instance for the time
// in the future we may implement some other transport services which can be selected
// via the configuration files
try {
this.transport = SMTP.getInstance();
} catch (error) {
if (process.env.ALLOW_NO_TRANSPORT === 'true') {
/* tslint:disable-next-line:no-console */
console.warn('SMTP error was ignored.');
} else {
throw error;
}
}
if (typeof this.transport !== 'undefined' && isTransportWithVerification(this.transport)) {
this.waitingForVerification = true;
this.transport.verify().then((message) => {
if (typeof message === 'string') {
// tslint:disable-next-line:no-console
console.log(message);
}
}).catch((err) => {
throw err;
});
} else {
this.waitingForVerification = false;
}
}
public isWaitingForVerification(): boolean {
return this.waitingForVerification;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2019 StApps
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.nse along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { SMTP } from '@openstapps/logger/lib/SMTP';
import { MailOptions } from 'nodemailer/lib/sendmail-transport';
import * as Queue from 'promise-queue';
import { logger } from '../common';
/**
* A queue that can send mails in serial
*/
export class MailQueue {
/**
* A queue that saves mails, before the transport is ready. When
* the transport gets ready this mails are getting pushed in to
* the normal queue.
*/
dryQueue: MailOptions[];
/**
* A queue that saves mails, that are being sent in series
*/
queue: Queue;
/**
* A counter for the number of verifications that failed
*/
verificationCounter: number;
/**
* Creates a mail queue
* @param transport
*/
constructor(private transport: SMTP) {
this.queue = new Queue(1);
// this queue saves all request when the transport is not ready yet
this.dryQueue = [];
this.verificationCounter = 0;
// if the transport can be verified it should check if it was done...
this.checkForVerification();
}
/**
* Verify the given transport
*/
private checkForVerification() {
if (this.verificationCounter > 5) {
throw new Error('Failed to initialize the SMTP transport for the mail queue');
}
if (!this.transport.isVerified()) {
this.verificationCounter++;
setTimeout(() => {
logger.warn('Transport not verified yet. Trying to send mails here...');
this.checkForVerification();
}, 5000);
} else {
logger.ok('Transport for mail queue was verified. We can send mails now');
// if the transport finally was verified send all our mails from the dry queue
this.dryQueue.forEach((mail) => {
this.queue.add<string>(() => (this.transport as SMTP).sendMail(mail));
});
}
}
/**
* Push a mail into the queue so it gets send when the queue is ready
* @param mail
*/
public push(mail: MailOptions) {
if (!this.transport.isVerified()) { // the transport has verification, but is not verified yet
// push to a dry queue which gets pushed to the real queue when the transport is verified
this.dryQueue.push(mail);
} else {
this.queue.add<string>(() => (this.transport as SMTP).sendMail(mail));
}
}
}