mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-10-06 17:52:28 +00:00
112 lines
3.5 KiB
TypeScript
112 lines
3.5 KiB
TypeScript
/*
|
|
* 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 {Logger, SMTP} from '@openstapps/logger';
|
|
import {SendMailOptions} from 'nodemailer';
|
|
import Queue from 'promise-queue';
|
|
/**
|
|
* A queue that can send mails in serial
|
|
*/
|
|
export class MailQueue {
|
|
/**
|
|
* Number of allowed verification attempts after which the initialization of transport fails
|
|
*/
|
|
static readonly MAX_VERIFICATION_ATTEMPTS = 5;
|
|
|
|
/**
|
|
* Number of milliseconds after which verification check should be repeated
|
|
*/
|
|
static readonly VERIFICATION_TIMEOUT = 5000;
|
|
|
|
/**
|
|
* 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: SendMailOptions[];
|
|
|
|
/**
|
|
* 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 Transport which is used for sending mails
|
|
*/
|
|
constructor(private readonly 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();
|
|
}
|
|
|
|
/**
|
|
* Adds a mail into the queue so it gets send when the queue is ready
|
|
* @param mail Information required for sending a mail
|
|
*/
|
|
private async addToQueue(mail: SendMailOptions) {
|
|
return this.queue.add<string>(() => this.transport.sendMail(mail));
|
|
}
|
|
|
|
/**
|
|
* Verify the given transport
|
|
*/
|
|
private checkForVerification() {
|
|
if (this.verificationCounter >= MailQueue.MAX_VERIFICATION_ATTEMPTS) {
|
|
throw new Error('Failed to initialize the SMTP transport for the mail queue');
|
|
}
|
|
|
|
if (this.transport.isVerified()) {
|
|
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
|
|
for (const mail of this.dryQueue) {
|
|
void this.addToQueue(mail);
|
|
}
|
|
} else {
|
|
this.verificationCounter++;
|
|
setTimeout(() => {
|
|
Logger.warn('Transport not verified yet. Trying to send mails here...');
|
|
this.checkForVerification();
|
|
}, MailQueue.VERIFICATION_TIMEOUT);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Push a mail into the queue so it gets send when the queue is ready
|
|
* @param mail Information required for sending a mail
|
|
*/
|
|
public async push(mail: SendMailOptions) {
|
|
if (this.transport.isVerified()) {
|
|
await this.addToQueue(mail);
|
|
} else {
|
|
// 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);
|
|
}
|
|
}
|
|
}
|