Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Thumbs.db

# Instance configuration files
.env
.project
.project
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20.20.0-bookworm-slim
FROM node:24.14.1-bookworm-slim

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major version update


ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
Expand Down
50 changes: 30 additions & 20 deletions controllers/bulkApiMailer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const MongoClient = require('mongodb').MongoClient;
const { Worker } = require('bullmq');

const mailingManager = require('./mailing');
const { bulkQueue } = require("../notifyQueue");
const { bulkQueue, workerConnection } = require("../notifyQueue");
const { letUsKnow } = require("./subscriptions");
const BASE_URL = process.env.BASE_URL || "https://apps.canada.ca/x-notify";
const BULK_API = process.env.BULK_API || "https://api.notification.canada.ca/v2/notifications/bulk";
Expand All @@ -20,7 +21,7 @@ let mongoInstance,
dbConn,
_notifyUsNotBeforeTimeLimit = 0;

bulkQueue.process(async (job) => {
const bulkWorker = new Worker('bulk-api-v2', async (job) => {

let jobData, emailLength,
jobSuccess=false;
Expand Down Expand Up @@ -59,7 +60,7 @@ bulkQueue.process(async (job) => {
currDateTime = currDate.getTime();

// Connect to MongoDB
mongoInstance = await MongoClient.connect(process.env.MONGODB_URI || '', { useUnifiedTopology: true });
mongoInstance = await MongoClient.connect(process.env.MONGODB_URI || '');
dbConn = mongoInstance.db(process.env.MONGODB_NAME || 'subs');

// Log the error into MongoDB
Expand Down Expand Up @@ -112,14 +113,22 @@ bulkQueue.process(async (job) => {
await new Promise(resolve => setTimeout( resolve, BULK_Q_JOB_DELAY_TIME )); // delay between each API call set by CDS
}
}
});
}, { connection: workerConnection });

// Listen for failures
bulkQueue.on('failed', (job, err) => {
bulkWorker.on('failed', (job, err) => {
console.error(`bulkQueue Job ${job.id} failed: ${err.message}`);
console.log(err)
});

bulkWorker.on('error', err => {
console.error('bulkQueue worker error:', err);
});

exports.closeWorker = async function closeWorker() {
await bulkWorker.close();
};

exports.sendBulkEmails = async ( mailingId, topicId ) => {
let mailingTopic, mailing_name, emailLength, bulkEmailBody;
try {
Expand Down Expand Up @@ -155,20 +164,21 @@ exports.sendBulkEmails = async ( mailingId, topicId ) => {
emailLength = Buffer.byteLength( JSON.stringify(bulkEmailBody) , "utf8" );

bulkQueue.add(
{
bulkEmailBody: bulkEmailBody,
notifyKey: mailingTopic.notifyKey,
mailingId: mailingId,
},
{
attempts: BULK_Q_ATTEMPTS, // Maximum number of retries
backoff: {
type: BULK_Q_TYPE, // Use exponential backoff or fixed
delay: BULK_Q_DELAY // Initial delay of 1 second (doubles each retry)
'send-bulk-email',
{
bulkEmailBody: bulkEmailBody,
notifyKey: mailingTopic.notifyKey,
mailingId: mailingId,
},
removeOnComplete: BULK_Q_REMOVE_ON_COMP,
removeOnFail: BULK_Q_REMOVE_ON_FAIL
}
{
attempts: BULK_Q_ATTEMPTS, // Maximum number of retries
backoff: {
type: BULK_Q_TYPE, // Use exponential backoff or fixed
delay: BULK_Q_DELAY // Initial delay of 1 second (doubles each retry)
},
removeOnComplete: BULK_Q_REMOVE_ON_COMP,
removeOnFail: BULK_Q_REMOVE_ON_FAIL
}
);
}

Expand All @@ -178,7 +188,7 @@ exports.sendBulkEmails = async ( mailingId, topicId ) => {
const currDate = new Date(),
currDateTime = currDate.getTime();

mongoInstance = await MongoClient.connect(process.env.MONGODB_URI || '', { useUnifiedTopology: true });
mongoInstance = await MongoClient.connect(process.env.MONGODB_URI || '');
dbConn = mongoInstance.db(process.env.MONGODB_NAME || 'subs');

dbConn.collection( "notify_logs" ).insertOne(
Expand Down Expand Up @@ -243,7 +253,7 @@ formatSubsArray = async ( listEmail ) => {
* Utilities function
*/
getConfirmedSubscriberAsArray = async ( topicId ) => {
mongoInstance = await MongoClient.connect(process.env.MONGODB_URI || '', { useUnifiedTopology: true });
mongoInstance = await MongoClient.connect(process.env.MONGODB_URI || '');
dbConn = mongoInstance.db(process.env.MONGODB_NAME || 'subs');

// Get all the emails for the given topic
Expand Down
27 changes: 14 additions & 13 deletions controllers/mailing.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ exports.mailingView = mailingView;
async function mailingView( paramMailingId ) {
// Input: MailingID

const rDoc = await dbConn.collection( "mailing" ).findOne( { _id: ObjectId( paramMailingId ) } );
const rDoc = await dbConn.collection( "mailing" ).findOne( { _id: new ObjectId( paramMailingId ) } );
if ( !rDoc ) {
console.log( "mailingView: Invalid mailing id: " + paramMailingId );
throw new Error( "Mailing unavailable" );
Expand All @@ -125,7 +125,7 @@ exports.mailingGetHistory = async ( mailingId ) => {

const rDoc = await dbConn.collection( "mailingHistory" ).find(
{
mailingId: ObjectId( mailingId )
mailingId: new ObjectId( mailingId )
},
{
sort: {
Expand Down Expand Up @@ -233,7 +233,7 @@ exports.mailingCancelSendToSub = async ( mailingId ) => {
}

exports.mailingSendToSub = async ( mailingId ) => {
let mailing = await dbConn.collection( "mailing" ).findOne( { _id: ObjectId( mailingId ) } );
let mailing = await dbConn.collection( "mailing" ).findOne( { _id: new ObjectId( mailingId ) } );
if ( !mailing ) {
console.log( "mailingSendToSub: Invalid mailing id: " + mailingId );
throw new Error( "mailingSendToSub: Mailing unavailable" );
Expand Down Expand Up @@ -332,15 +332,15 @@ async function mailingUpdate( mailingId, newHistoryState, options ) {
Object.assign( {},
history,
{
mailingId: ObjectId( mailingId )
mailingId: new ObjectId( mailingId )
}
)
);
history.historyId = rInsert.insertedId;

// Update the mailing
let findQuery = {
_id: ObjectId( mailingId )
_id: new ObjectId( mailingId )
};
if ( historyState ) {
findQuery.state = historyState
Expand All @@ -358,12 +358,13 @@ async function mailingUpdate( mailingId, newHistoryState, options ) {
$slice: -7,
}
},
$currentDate: {
updatedAt: true
}

}
);
$currentDate: {
updatedAt: true
}

},
{ includeResultMetadata: true }
);

// Check if the operation was successful, if not, we need to log in the history
if ( !rDoc.ok ) {
Expand All @@ -372,7 +373,7 @@ async function mailingUpdate( mailingId, newHistoryState, options ) {
createdAt: currDate,
state: historyState || _mailingState.draft, // Put it back as draft if previous state is unknown
comments: newHistoryState + " fail",
mailingId: ObjectId( mailingId )
mailingId: new ObjectId( mailingId )
};

const rInsertFail = dbConn.collection( "mailingHistory" ).insertOne(
Expand All @@ -382,7 +383,7 @@ async function mailingUpdate( mailingId, newHistoryState, options ) {

dbConn.collection( "mailing" ).findOneAndUpdate(
{
_id: ObjectId( mailingId ),
_id: new ObjectId( mailingId ),
state: newHistoryState
},
{
Expand Down
10 changes: 4 additions & 6 deletions controllers/mailing_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ async function renderTemplate( tmplName, data ) {
/*
* Management of Mailing
*/
exports.v_mailingManage = async ( req, res, next ) => {

const userId = req.body.userId;

if ( !req.user.accessToTopicId ) {
res.status( 401 );
exports.v_mailingManage = async ( req, res, next ) => {

if ( !req.user.accessToTopicId ) {
res.status( 401 );
res.end();
return
}
Expand Down
5 changes: 3 additions & 2 deletions controllers/managers.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ isAuthorizedToDownload = async( req, task ) => {
$currentDate: {
lastUpdated: true
}
}
},
{ includeResultMetadata: true }
)

if ( !docTopic.value ) {
Expand Down Expand Up @@ -587,7 +588,7 @@ addBulk = async ( emails, topicId, currDate ) => {
removeBulk = async ( emails, topicId ) => {

// Remove from confirmed list
dbConn.collection( "subsConfirmed" ).removeMany({
dbConn.collection( "subsConfirmed" ).deleteMany({
email: {
$in: emails
},
Expand Down
Loading