From e502da66e28319d0f4c9ed0f31c6d9865cfcfc68 Mon Sep 17 00:00:00 2001 From: "C. Fuhrman" Date: Fri, 14 Mar 2025 00:42:49 -0400 Subject: [PATCH] one passing test --- server/__tests__/folders.mongodb.test.js | 478 +++++++++++ server/app.js | 4 +- server/config/db.js | 25 +- server/jest-mongodb-config.js | 12 + server/jest.setup.js | 7 + server/models/authProvider.js | 10 +- server/models/authUserAssociation.js | 14 +- server/models/folders.js | 36 +- server/models/images.js | 8 +- server/models/{quiz.js => quizzes.js} | 32 +- server/models/room.js | 27 +- server/models/users.js | 21 +- server/package-lock.json | 963 ++++++++++++++++------- server/package.json | 22 +- 14 files changed, 1279 insertions(+), 380 deletions(-) create mode 100644 server/__tests__/folders.mongodb.test.js create mode 100644 server/jest-mongodb-config.js create mode 100644 server/jest.setup.js rename server/models/{quiz.js => quizzes.js} (85%) diff --git a/server/__tests__/folders.mongodb.test.js b/server/__tests__/folders.mongodb.test.js new file mode 100644 index 0000000..60fa3ab --- /dev/null +++ b/server/__tests__/folders.mongodb.test.js @@ -0,0 +1,478 @@ +const Folder = require('../models/folders'); +const Quiz = require('../models/quizzes'); +const db = require('../config/db'); + +console.log('db:', db); // Debugging line +console.log('db.getConnection:', db.getConnection); // Debugging line + +describe('Folders', () => { + let database; + + beforeAll(async () => { + console.log('beforeAll: db.getConnection:', db.getConnection); // Debugging line + database = await db.getConnection(); + }); + + afterAll(async () => { + await db.closeConnection(); + }); + + it('should insert a folder into collection', async () => { + const folders = new Folder(db, Quiz); + const folderId = await folders.create('Test Folder', '12345'); + const result = await database.collection('folders').findOne({ _id: folderId }); + expect(result).toBeTruthy(); + console.log('found folder result:', result); // Debugging line + expect(result.title).toBe('Test Folder'); + }); + + // beforeEach(() => { + // jest.clearAllMocks(); // Clear any previous mock calls + + // // Mock the collection object + // collection = { + // findOne: jest.fn(), + // insertOne: jest.fn(), + // find: jest.fn().mockReturnValue({ toArray: jest.fn() }), // Mock the find method + // deleteOne: jest.fn(), + // deleteMany: jest.fn(), + // updateOne: jest.fn(), + // }; + + // // Mock the database connection + // db = { + // connect: jest.fn(), + // getConnection: jest.fn().mockReturnThis(), // Add getConnection method + // collection: jest.fn().mockReturnValue(collection), + // }; + + // quizzes = new Quizzes(db); + // folders = new Folders(db, quizzes); + + // }); + + // // create + // describe('create', () => { + // it('should create a new folder and return the new folder ID', async () => { + // const title = 'Test Folder'; + + // // Mock the database response + // collection.findOne.mockResolvedValue(null); + // collection.insertOne.mockResolvedValue({ insertedId: new ObjectId() }); + + // const result = await folders.create(title, '12345'); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ title, userId: '12345' }); + // expect(collection.insertOne).toHaveBeenCalledWith(expect.objectContaining({ title, userId: '12345' })); + // expect(result).toBeDefined(); + // }); + + // // throw an error if userId is undefined + // it('should throw an error if userId is undefined', async () => { + // const title = 'Test Folder'; + + // await expect(folders.create(title, undefined)).rejects.toThrow('Missing required parameter(s)'); + + // expect(db.connect).not.toHaveBeenCalled(); + // }); + + // it('should throw an error if the folder already exists', async () => { + // const title = 'Existing Folder'; + // const userId = '66fc70bea1b9e87655cf17c9'; + + // // Mock the database response of a found folder + // collection.findOne.mockResolvedValue( + // // real result from mongosh + // { + // _id: ObjectId.createFromHexString('66fd33fd81758a882ce99aae'), + // userId: userId, + // title: title, + // created_at: new Date('2024-10-02T11:52:29.797Z') + // } + // ); + + // await expect(folders.create(title, userId)).rejects.toThrow('Folder already exists'); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ title, userId: userId }); + // }); + // }); + + // // getUserFolders + // describe('getUserFolders', () => { + // it('should return all folders for a user', async () => { + // const userId = '12345'; + // const userFolders = [ + // { title: 'Folder 1', userId }, + // { title: 'Folder 2', userId }, + // ]; + + // // Mock the database response + // collection.find().toArray.mockResolvedValue(userFolders); + + // const result = await folders.getUserFolders(userId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.find).toHaveBeenCalledWith({ userId }); + // expect(result).toEqual(userFolders); + // }); + // }); + + // // getOwner + // describe('getOwner', () => { + // it('should return the owner of a folder', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const userId = '12345'; + + // // Mock the database response + // collection.findOne.mockResolvedValue({ userId }); + + // const result = await folders.getOwner(folderId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // expect(result).toBe(userId); + // }); + // }); + + // // write a test for getContent + // describe('getContent', () => { + // it('should return the content of a folder', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const content = [ + // { title: 'Quiz 1', content: [] }, + // { title: 'Quiz 2', content: [] }, + // ]; + + // // Mock the database response + // collection.find().toArray.mockResolvedValue(content); + + // const result = await folders.getContent(folderId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('files'); + // expect(collection.find).toHaveBeenCalledWith({ folderId }); + // expect(result).toEqual(content); + // }); + + // it('should return an empty array if the folder has no content', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + + // // Mock the database response + // collection.find().toArray.mockResolvedValue([]); + + // const result = await folders.getContent(folderId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('files'); + // expect(collection.find).toHaveBeenCalledWith({ folderId }); + // expect(result).toEqual([]); + // }); + // }); + + // // delete + // describe('delete', () => { + // it('should delete a folder and return true', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + + // // Mock the database response + // collection.deleteOne.mockResolvedValue({ deletedCount: 1 }); + + + // // Mock the folders.quizModel.deleteQuizzesByFolderId() + // jest.spyOn(quizzes, 'deleteQuizzesByFolderId').mockResolvedValue(true); + + // const result = await folders.delete(folderId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.deleteOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // expect(result).toBe(true); + // }); + + // it('should return false if the folder does not exist', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + + // // Mock the database response + // collection.deleteOne.mockResolvedValue({ deletedCount: 0 }); + + // const result = await folders.delete(folderId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.deleteOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // expect(result).toBe(false); + // }); + // }); + + // // rename + // describe('rename', () => { + // it('should rename a folder and return true', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const newTitle = 'New Folder Name'; + // const userId = '12345'; + + // // Mock the database response + // collection.updateOne.mockResolvedValue({ modifiedCount: 1 }); + + // const result = await folders.rename(folderId, userId, newTitle); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // // { _id: ObjectId.createFromHexString(folderId), userId: userId }, { $set: { title: newTitle } } + // expect(collection.updateOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId), userId: userId }, { $set: { title: newTitle } }); + // expect(result).toBe(true); + // }); + + // it('should return false if the folder does not exist', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const newTitle = 'New Folder Name'; + // const userId = '12345'; + + // // Mock the database response + // collection.updateOne.mockResolvedValue({ modifiedCount: 0 }); + + // const result = await folders.rename(folderId, userId, newTitle); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.updateOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId), userId: userId }, { $set: { title: newTitle } }); + // expect(result).toBe(false); + // }); + + // it('should throw an error if the new title is already in use', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const newTitle = 'Existing Folder'; + // const userId = '12345'; + + // // Mock the database response + // collection.findOne.mockResolvedValue({ title: newTitle }); + // collection.updateOne.mockResolvedValue({ modifiedCount: 0 }); + + // await expect(folders.rename(folderId, userId, newTitle)).rejects.toThrow(`Folder with name '${newTitle}' already exists.`); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // // expect(collection.updateOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }, { $set: { title: newTitle } }); + // expect(collection.findOne).toHaveBeenCalledWith({ userId: userId, title: newTitle }); + // }); + // }); + + // // duplicate + // describe('duplicate', () => { + // it('should duplicate a folder and return the new folder ID', async () => { + // const userId = '12345'; + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const sourceFolder = {title: 'SourceFolder', userId: userId, content: []}; + // const duplicatedFolder = {title: 'SourceFolder (1)', userId: userId, created_at: expect.any(Date), content: []}; + + // // Mock the database responses for the folder and the new folder (first one is found, second one is null) + // // mock the findOne method + // jest.spyOn(collection, 'findOne') + // .mockResolvedValueOnce(sourceFolder) // source file exists + // .mockResolvedValueOnce(null); // new name is not found + + // // Mock the folder create method + // const createSpy = jest.spyOn(folders, 'create').mockResolvedValue(new ObjectId()); + + // // mock the folder.getContent method + // jest.spyOn(folders, 'getContent').mockResolvedValue([{ title: 'Quiz 1', content: [] }]); + + // // Mock the quizzes.create method + // jest.spyOn(quizzes, 'create').mockResolvedValue(new ObjectId()); + + // const result = await folders.duplicate(folderId, userId); + + // expect(db.collection).toHaveBeenCalledWith('folders'); + + // // expect folders.create method was called + // expect(createSpy).toHaveBeenCalledWith(duplicatedFolder.title, userId); + // // expect the getContent method was called + // expect(folders.getContent).toHaveBeenCalledWith(folderId); + // // expect the quizzes.create method was called + // expect(quizzes.create).toHaveBeenCalledWith('Quiz 1', [], expect.any(String), userId); + + // expect(result).toBeDefined(); + // }); + + // it('should throw an error if the folder does not exist', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + + // // Mock the database response for the source + // collection.findOne.mockResolvedValue(null); + + // await expect(folders.duplicate(folderId, '54321')).rejects.toThrow(`Folder ${folderId} not found`); + + // // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId), userId: '54321' }); + // }); + // }); + + // describe('folderExists', () => { + // it('should return true if folder exists', async () => { + // const title = 'Test Folder'; + // const userId = '12345'; + + // // Mock the database response + // collection.findOne.mockResolvedValue({ title, userId }); + + // const result = await folders.folderExists(title, userId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ title, userId }); + // expect(result).toBe(true); + // }); + + // it('should return false if folder does not exist', async () => { + // const title = 'Nonexistent Folder'; + // const userId = '12345'; + + // // Mock the database response + // collection.findOne.mockResolvedValue(null); + + // const result = await folders.folderExists(title, userId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ title, userId }); + // expect(result).toBe(false); + // }); + // }); + + // describe('copy', () => { + // it('should copy a folder and return the new folder ID', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const userId = '12345'; + // const newFolderId = new ObjectId(); + // // Mock some quizzes that are in folder.content + // const sourceFolder = { + // title: 'Test Folder', + // content: [ + // { title: 'Quiz 1', content: [] }, + // { title: 'Quiz 2', content: [] }, + // ], + // }; + + // // Mock the response from getFolderWithContent + // jest.spyOn(folders, 'getFolderWithContent').mockResolvedValue(sourceFolder); + // jest.spyOn(folders, 'create').mockResolvedValue(newFolderId); + // // Mock the response from Quiz.createQuiz + // jest.spyOn(quizzes, 'create').mockImplementation(() => {}); + + // const result = await folders.copy(folderId, userId); + + // // expect(db.connect).toHaveBeenCalled(); + // // expect(db.collection).toHaveBeenCalledWith('folders'); + // // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // // expect(collection.insertOne).toHaveBeenCalledWith(expect.objectContaining({ userId })); + // expect(result).toBe(newFolderId); + // }); + + // it('should throw an error if the folder does not exist', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const userId = '12345'; + + // // Mock the response from getFolderWithContent + // jest.spyOn(folders, 'getFolderWithContent').mockImplementation(() => { + // throw new Error(`Folder ${folderId} not found`); + // }); + + // await expect(folders.copy(folderId, userId)).rejects.toThrow(`Folder ${folderId} not found`); + + // // expect(db.connect).toHaveBeenCalled(); + // // expect(db.collection).toHaveBeenCalledWith('folders'); + // // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // }); + // }); + + // // write a test for getFolderWithContent + // describe('getFolderWithContent', () => { + // it('should return a folder with content', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const folder = { + // _id: new ObjectId(folderId), + // title: 'Test Folder', + // }; + // const content = { + // content : [ + // { title: 'Quiz 1', content: [] }, + // { title: 'Quiz 2', content: [] }, + // ]}; + + // // Mock the response from getFolderById + // jest.spyOn(folders, 'getFolderById').mockResolvedValue(folder); + + // // Mock the response from getContent + // jest.spyOn(folders, 'getContent').mockResolvedValue(content); + + // const result = await folders.getFolderWithContent(folderId); + + // // expect(db.connect).toHaveBeenCalled(); + // // expect(db.collection).toHaveBeenCalledWith('folders'); + // // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // expect(result).toEqual({ + // ...folder, + // content: content + // }); + // }); + + // it('should throw an error if the folder does not exist', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + + // // // Mock the database response + // // collection.findOne.mockResolvedValue(null); + + // // Mock getFolderById to throw an error + // jest.spyOn(folders, 'getFolderById').mockImplementation(() => { + // throw new Error(`Folder ${folderId} not found`); + // }); + + // await expect(folders.getFolderWithContent(folderId)).rejects.toThrow(`Folder ${folderId} not found`); + + // // expect(db.connect).toHaveBeenCalled(); + // // expect(db.collection).toHaveBeenCalledWith('folders'); + // // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // }); + // }); + + // // write a test for getFolderById + // describe('getFolderById', () => { + // it('should return a folder by ID', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + // const folder = { + // _id: new ObjectId(folderId), + // title: 'Test Folder', + // }; + + // // Mock the database response + // collection.findOne.mockResolvedValue(folder); + + // const result = await folders.getFolderById(folderId); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // expect(result).toEqual(folder); + // }); + + // it('should throw an error if the folder does not exist', async () => { + // const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; + + // // Mock the database response + // collection.findOne.mockResolvedValue(null); + + // await expect(folders.getFolderById(folderId)).resolves.toThrow(`Folder ${folderId} not found`); + + // expect(db.connect).toHaveBeenCalled(); + // expect(db.collection).toHaveBeenCalledWith('folders'); + // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); + // }); + // }); +}); diff --git a/server/app.js b/server/app.js index 938d2f0..431e854 100644 --- a/server/app.js +++ b/server/app.js @@ -118,8 +118,8 @@ async function start() { const port = process.env.PORT || 4400; // Check DB connection - await db.connect(); - db.getConnection(); + + await db.getConnection(); console.log(`Connexion MongoDB établie`); server.listen(port, () => { diff --git a/server/config/db.js b/server/config/db.js index ccc43e7..0f0576b 100644 --- a/server/config/db.js +++ b/server/config/db.js @@ -5,14 +5,17 @@ dotenv.config(); class DBConnection { constructor() { - this.mongoURI = process.env.MONGO_URI; - this.databaseName = process.env.MONGO_DATABASE; + // for testing with @shelf/jest-mongodb + this.mongoURI = globalThis.__MONGO_URI__ || process.env.MONGO_URI; + this.databaseName = globalThis.__MONGO_DB_NAME__ || process.env.MONGO_DATABASE; this.client = null; this.connection = null; + console.log(`db.js: Mongo URI: ${this.mongoURI}`); + console.log(`db.js: Mongo DB: ${this.databaseName}`); } - // Connect to the database, but don't reconnect if already connected - async connect() { + // Return the current database connection, creating it if necessary + async getConnection() { if (this.connection) { console.log('Using existing MongoDB connection'); return this.connection; @@ -20,7 +23,10 @@ class DBConnection { try { // Create the MongoClient only if the connection does not exist - this.client = new MongoClient(this.mongoURI); + this.client = new MongoClient(this.mongoURI, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); await this.client.connect(); this.connection = this.client.db(this.databaseName); console.log('MongoDB connected'); @@ -31,18 +37,11 @@ class DBConnection { } } - // Return the current database connection - getConnection() { - if (!this.connection) { - throw new Error('MongoDB connection not established'); - } - return this.connection; - } - // Close the MongoDB connection gracefully async closeConnection() { if (this.client) { await this.client.close(); + this.connection = null; console.log('MongoDB connection closed'); } } diff --git a/server/jest-mongodb-config.js b/server/jest-mongodb-config.js new file mode 100644 index 0000000..661c912 --- /dev/null +++ b/server/jest-mongodb-config.js @@ -0,0 +1,12 @@ +module.exports = { + mongodbMemoryServerOptions: { + binary: { + version: '4.0.3', + skipMD5: true, + }, + instance: { + dbName: 'jest', + }, + autoStart: false, + }, + }; diff --git a/server/jest.setup.js b/server/jest.setup.js new file mode 100644 index 0000000..6326302 --- /dev/null +++ b/server/jest.setup.js @@ -0,0 +1,7 @@ +require('dotenv').config(); + +module.exports = { + preset: '@shelf/jest-mongodb', +}; + +console.log('jest.setup.js: MongoDB URI:', process.env.MONGO_URI); diff --git a/server/models/authProvider.js b/server/models/authProvider.js index ab92da4..d7516cd 100644 --- a/server/models/authProvider.js +++ b/server/models/authProvider.js @@ -8,8 +8,8 @@ class AuthProvider { } async getId(name){ - await db.connect() - const conn = db.getConnection(); + + const conn = await db.getConnection(); const collection = conn.collection('authprovider'); @@ -22,8 +22,8 @@ class AuthProvider { } async create(name) { - await db.connect() - const conn = db.getConnection(); + + const conn = await db.getConnection(); const collection = conn.collection('authprovider'); @@ -41,4 +41,4 @@ class AuthProvider { } } -module.exports = new AuthProvider; \ No newline at end of file +module.exports = new AuthProvider; diff --git a/server/models/authUserAssociation.js b/server/models/authUserAssociation.js index b6c1e4d..34a6afa 100644 --- a/server/models/authUserAssociation.js +++ b/server/models/authUserAssociation.js @@ -13,8 +13,8 @@ class AuthUserAssociation { } async find_user_association(provider_name,auth_id){ - await db.connect() - const conn = db.getConnection(); + + const conn = await db.getConnection(); const collection = conn.collection('authUserAssociation'); const provider_id = await authProvider.getId(provider_name) @@ -24,8 +24,8 @@ class AuthUserAssociation { } async link(provider_name,auth_id,user_id){ - await db.connect() - const conn = db.getConnection(); + + const conn = await db.getConnection(); const collection = conn.collection('authUserAssociation'); const provider_id = await authProvider.getId(provider_name) @@ -43,8 +43,8 @@ class AuthUserAssociation { } async unlink(provider_name,user_id){ - await db.connect() - const conn = db.getConnection(); + + const conn = await db.getConnection(); const collection = conn.collection('authUserAssociation'); const provider_id = await authProvider.getId(provider_name) @@ -56,4 +56,4 @@ class AuthUserAssociation { } else return null } } -module.exports = new AuthUserAssociation; \ No newline at end of file +module.exports = new AuthUserAssociation; diff --git a/server/models/folders.js b/server/models/folders.js index 7a5fb30..efaffd2 100644 --- a/server/models/folders.js +++ b/server/models/folders.js @@ -2,7 +2,7 @@ const ObjectId = require('mongodb').ObjectId; const { generateUniqueTitle } = require('./utils'); -class Folders { +class Folder { constructor(db, quizModel) { this.db = db; this.quizModel = quizModel; @@ -14,8 +14,8 @@ class Folders { throw new Error('Missing required parameter(s)'); } - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); @@ -37,8 +37,8 @@ class Folders { } async getUserFolders(userId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); @@ -48,8 +48,8 @@ class Folders { } async getOwner(folderId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); @@ -60,8 +60,8 @@ class Folders { // finds all quizzes in a folder async getContent(folderId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const filesCollection = conn.collection('files'); @@ -71,8 +71,8 @@ class Folders { } async delete(folderId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); @@ -85,8 +85,8 @@ class Folders { } async rename(folderId, userId, newTitle) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); @@ -103,7 +103,7 @@ class Folders { } async duplicate(folderId, userId) { - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); const sourceFolder = await foldersCollection.findOne({ _id: ObjectId.createFromHexString(folderId), userId: userId }); @@ -139,8 +139,7 @@ class Folders { } async folderExists(title, userId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); const existingFolder = await foldersCollection.findOne({ title: title, userId: userId }); @@ -163,8 +162,7 @@ class Folders { } async getFolderById(folderId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const foldersCollection = conn.collection('folders'); @@ -192,4 +190,4 @@ class Folders { } -module.exports = Folders; +module.exports = Folder; diff --git a/server/models/images.js b/server/models/images.js index 67a6583..61edc1a 100644 --- a/server/models/images.js +++ b/server/models/images.js @@ -7,8 +7,8 @@ class Images { } async upload(file, userId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const imagesCollection = conn.collection('images'); @@ -26,8 +26,8 @@ class Images { } async get(id) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const imagesCollection = conn.collection('images'); diff --git a/server/models/quiz.js b/server/models/quizzes.js similarity index 85% rename from server/models/quiz.js rename to server/models/quizzes.js index b388659..e29b057 100644 --- a/server/models/quiz.js +++ b/server/models/quizzes.js @@ -10,8 +10,8 @@ class Quiz { async create(title, content, folderId, userId) { // console.log(`quizzes: create title: ${title}, folderId: ${folderId}, userId: ${userId}`); - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); @@ -37,8 +37,8 @@ class Quiz { } async getOwner(quizId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); @@ -48,8 +48,8 @@ class Quiz { } async getContent(quizId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); @@ -59,8 +59,8 @@ class Quiz { } async delete(quizId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); @@ -71,8 +71,7 @@ class Quiz { return true; } async deleteQuizzesByFolderId(folderId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const quizzesCollection = conn.collection('files'); @@ -82,8 +81,8 @@ class Quiz { } async update(quizId, newTitle, newContent) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); @@ -102,8 +101,8 @@ class Quiz { } async move(quizId, newFolderId) { - await this.db.connect() - const conn = this.db.getConnection(); + + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); @@ -118,7 +117,7 @@ class Quiz { } async duplicate(quizId, userId) { - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const quizCollection = conn.collection('files'); const sourceQuiz = await quizCollection.findOne({ _id: ObjectId.createFromHexString(quizId), userId: userId }); @@ -141,8 +140,7 @@ class Quiz { } async quizExists(title, userId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const filesCollection = conn.collection('files'); const existingFolder = await filesCollection.findOne({ title: title, userId: userId }); diff --git a/server/models/room.js b/server/models/room.js index 1234d07..e7fa5ce 100644 --- a/server/models/room.js +++ b/server/models/room.js @@ -17,8 +17,7 @@ class Rooms throw new Error("Room already exists"); } - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); const newRoom = { @@ -34,8 +33,7 @@ class Rooms async getUserRooms(userId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); @@ -46,8 +44,7 @@ class Rooms async getOwner(roomId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); @@ -60,8 +57,7 @@ class Rooms async getContent(roomId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); if (!ObjectId.isValid(roomId)) { @@ -75,8 +71,7 @@ class Rooms async delete(roomId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); @@ -91,8 +86,7 @@ class Rooms async rename(roomId, userId, newTitle) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); @@ -118,8 +112,7 @@ class Rooms { try { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const existingRoom = await conn.collection("rooms").findOne({ title: title.toUpperCase(), userId: userId, @@ -132,8 +125,7 @@ class Rooms } async getRoomById(roomId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); @@ -159,8 +151,7 @@ class Rooms } async getRoomTitleByUserId(userId) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const roomsCollection = conn.collection("rooms"); diff --git a/server/models/users.js b/server/models/users.js index 2be1aa3..1b4c94c 100644 --- a/server/models/users.js +++ b/server/models/users.js @@ -22,8 +22,7 @@ class Users { } async register(userInfos) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); @@ -56,8 +55,7 @@ class Users { async login(email, password) { console.log(`models/users: login: email: ${email}, password: ${password}`); try { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); const user = await userCollection.findOne({ email: email }); @@ -90,8 +88,7 @@ class Users { } async changePassword(email, newPassword) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); @@ -108,8 +105,7 @@ class Users { } async delete(email) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); @@ -121,8 +117,7 @@ class Users { } async getId(email) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); @@ -136,8 +131,7 @@ class Users { } async getById(id) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); @@ -151,8 +145,7 @@ class Users { } async editUser(userInfo) { - await this.db.connect(); - const conn = this.db.getConnection(); + const conn = await this.db.getConnection(); const userCollection = conn.collection("users"); diff --git a/server/package-lock.json b/server/package-lock.json index 0f006f8..7769b51 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -12,29 +12,30 @@ "dependencies": { "bcrypt": "^5.1.1", "cors": "^2.8.5", - "dotenv": "^16.4.4", + "dotenv": "^16.4.7", "express": "^4.18.2", "express-list-endpoints": "^7.1.1", "express-session": "^1.18.0", "jsonwebtoken": "^9.0.2", - "mongodb": "^6.3.0", + "mongodb": "^6.14.2", "multer": "^1.4.5-lts.1", - "nodemailer": "^6.9.9", + "nodemailer": "^6.10.0", "passport": "^0.7.0", "passport-oauth2": "^1.8.0", "passport-openidconnect": "^0.1.2", "patch-package": "^8.0.0", "socket.io": "^4.7.2", - "socket.io-client": "^4.7.2" + "socket.io-client": "^4.8.1" }, "devDependencies": { - "@eslint/js": "^9.18.0", + "@eslint/js": "^9.22.0", + "@shelf/jest-mongodb": "^5.1.0", "cross-env": "^7.0.3", - "eslint": "^9.18.0", - "globals": "^15.14.0", + "eslint": "^9.22.0", + "globals": "^16.0.0", "jest": "^29.7.0", "jest-mock": "^29.7.0", - "nodemon": "^3.0.1", + "nodemon": "^3.1.9", "supertest": "^6.3.4" }, "engines": { @@ -55,68 +56,20 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@babel/compat-data": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", @@ -342,19 +295,21 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -369,88 +324,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", - "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@babel/parser": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", - "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.10" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -636,14 +531,15 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" @@ -704,14 +600,14 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", - "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -766,13 +662,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", - "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.5", + "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -805,10 +701,20 @@ "dev": true, "license": "MIT" }, + "node_modules/@eslint/config-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", + "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", - "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -819,9 +725,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", "dev": true, "license": "MIT", "dependencies": { @@ -901,9 +807,9 @@ "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", - "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", + "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", "dev": true, "license": "MIT", "engines": { @@ -911,9 +817,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", - "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -921,13 +827,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", - "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.12.0", "levn": "^0.4.1" }, "engines": { @@ -987,9 +893,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", - "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1446,13 +1352,57 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", - "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.0.tgz", + "integrity": "sha512-+ywrb0AqkfaYuhHs6LxKWgqbh3I72EpEgESCw37o+9qPx9WTCkgDm2B+eMrwehGtHBWHFU4GXvnSCNiFhhausg==", + "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } }, + "node_modules/@shelf/jest-mongodb": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@shelf/jest-mongodb/-/jest-mongodb-5.1.0.tgz", + "integrity": "sha512-oA4hsDQCaigJtWk72kMlMIqPga6xrBQAsgRsnlftmXGTeLcxa76bxLQCw9R4LjDKChXcOvcfrtKwQzZGZyTy+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4.3.4", + "mongodb-memory-server": "9.2.0" + }, + "engines": { + "node": ">=22" + }, + "peerDependencies": { + "jest-environment-node": "28.x || 29.x", + "mongodb": "3.x.x || 4.x || 5.x || 6.x" + } + }, + "node_modules/@shelf/jest-mongodb/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@shelf/jest-mongodb/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1648,9 +1598,9 @@ } }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", "bin": { @@ -1811,6 +1761,16 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, + "node_modules/async-mutex": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.1.tgz", + "integrity": "sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1825,6 +1785,13 @@ "node": ">= 4.0.0" } }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -1946,6 +1913,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bare-events": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -2069,13 +2044,24 @@ } }, "node_modules/bson": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", - "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.3.tgz", + "integrity": "sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==", + "license": "Apache-2.0", "engines": { "node": ">=16.20.1" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -2351,6 +2337,13 @@ "node": ">= 0.8" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", @@ -2648,9 +2641,10 @@ } }, "node_modules/dotenv": { - "version": "16.4.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", - "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -2736,23 +2730,25 @@ } }, "node_modules/engine.io-client": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz", - "integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==", + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", "ws": "~8.17.1", - "xmlhttprequest-ssl": "~2.0.0" + "xmlhttprequest-ssl": "~2.1.1" } }, "node_modules/engine.io-client/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2764,9 +2760,10 @@ } }, "node_modules/engine.io-client/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/engine.io-parser": { "version": "5.2.1", @@ -2865,22 +2862,23 @@ } }, "node_modules/eslint": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", - "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", + "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.10.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.18.0", - "@eslint/plugin-kit": "^0.2.5", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.1.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.22.0", + "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -2888,7 +2886,7 @@ "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.2.0", + "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", @@ -2925,9 +2923,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", - "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3296,6 +3294,13 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3365,6 +3370,50 @@ "node": ">= 0.8" } }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -3407,6 +3456,27 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -3626,9 +3696,9 @@ } }, "node_modules/globals": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", - "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", + "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", "dev": true, "license": "MIT", "engines": { @@ -3801,9 +3871,9 @@ "dev": true }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3869,6 +3939,27 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4772,7 +4863,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", @@ -4787,6 +4879,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -5035,17 +5134,6 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -5226,12 +5314,13 @@ } }, "node_modules/mongodb": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", - "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.14.2.tgz", + "integrity": "sha512-kMEHNo0F3P6QKDq17zcDuPeaywK/YaJVCEQRzPF3TOM/Bl9MFg64YE5Tu7ifj37qZJMhwU1tl2Ioivws5gRG5Q==", + "license": "Apache-2.0", "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", + "@mongodb-js/saslprep": "^1.1.9", + "bson": "^6.10.3", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -5239,7 +5328,7 @@ }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", + "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", @@ -5279,6 +5368,208 @@ "whatwg-url": "^13.0.0" } }, + "node_modules/mongodb-memory-server": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-9.2.0.tgz", + "integrity": "sha512-w/usKdYtby5EALERxmA0+et+D0brP0InH3a26shNDgGefXA61hgl6U0P3IfwqZlEGRZdkbZig3n57AHZgDiwvg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "mongodb-memory-server-core": "9.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb-memory-server-core": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-9.2.0.tgz", + "integrity": "sha512-9SWZEy+dGj5Fvm5RY/mtqHZKS64o4heDwReD4SsfR7+uNgtYo+JN41kPCcJeIH3aJf04j25i5Dia2s52KmsMPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-mutex": "^0.4.0", + "camelcase": "^6.3.0", + "debug": "^4.3.4", + "find-cache-dir": "^3.3.2", + "follow-redirects": "^1.15.6", + "https-proxy-agent": "^7.0.4", + "mongodb": "^5.9.1", + "new-find-package-json": "^2.0.0", + "semver": "^7.6.0", + "tar-stream": "^3.1.7", + "tslib": "^2.6.2", + "yauzl": "^3.1.3" + }, + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/bson": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", + "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mongodb-memory-server-core/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/mongodb": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz", + "integrity": "sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bson": "^5.5.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "@mongodb-js/saslprep": "^1.1.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.0.0", + "kerberos": "^1.0.0 || ^2.0.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongodb-memory-server-core/node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mongodb-memory-server-core/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5326,6 +5617,44 @@ "node": ">= 0.6" } }, + "node_modules/new-find-package-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-2.0.0.tgz", + "integrity": "sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/new-find-package-json/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/new-find-package-json/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, "node_modules/node-addon-api": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", @@ -5382,21 +5711,23 @@ "dev": true }, "node_modules/nodemailer": { - "version": "6.9.9", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz", - "integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.0.tgz", + "integrity": "sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==", + "license": "MIT-0", "engines": { "node": ">=6.0.0" } }, "node_modules/nodemon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", - "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.5.2", - "debug": "^3.2.7", + "debug": "^4", "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", @@ -5418,19 +5749,29 @@ } }, "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/nodemon/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nopt": { "version": "1.0.10", @@ -5820,6 +6161,13 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -6124,12 +6472,10 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -6281,6 +6627,17 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/socket.io": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", @@ -6329,13 +6686,14 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/socket.io-client": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", - "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.5.2", + "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" }, "engines": { @@ -6417,6 +6775,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/socks": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6468,6 +6841,20 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", + "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -6652,6 +7039,18 @@ "node": ">=10" } }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -6666,6 +7065,16 @@ "node": ">=8" } }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -6683,15 +7092,6 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6734,6 +7134,13 @@ "node": ">=14" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7020,9 +7427,9 @@ } }, "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", "engines": { "node": ">=0.4.0" } @@ -7087,6 +7494,20 @@ "node": ">=12" } }, + "node_modules/yauzl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/server/package.json b/server/package.json index cd0348b..83f02fa 100644 --- a/server/package.json +++ b/server/package.json @@ -16,39 +16,41 @@ "dependencies": { "bcrypt": "^5.1.1", "cors": "^2.8.5", - "dotenv": "^16.4.4", + "dotenv": "^16.4.7", "express": "^4.18.2", "express-list-endpoints": "^7.1.1", "express-session": "^1.18.0", "jsonwebtoken": "^9.0.2", - "mongodb": "^6.3.0", + "mongodb": "^6.14.2", "multer": "^1.4.5-lts.1", - "nodemailer": "^6.9.9", + "nodemailer": "^6.10.0", "passport": "^0.7.0", "passport-oauth2": "^1.8.0", "passport-openidconnect": "^0.1.2", "patch-package": "^8.0.0", "socket.io": "^4.7.2", - "socket.io-client": "^4.7.2" + "socket.io-client": "^4.8.1" }, "devDependencies": { - "@eslint/js": "^9.18.0", + "@eslint/js": "^9.22.0", + "@shelf/jest-mongodb": "^5.1.0", "cross-env": "^7.0.3", - "eslint": "^9.18.0", - "globals": "^15.14.0", + "eslint": "^9.22.0", + "globals": "^16.0.0", "jest": "^29.7.0", "jest-mock": "^29.7.0", - "nodemon": "^3.0.1", + "nodemon": "^3.1.9", "supertest": "^6.3.4" }, "engines": { "node": "20.x" }, "jest": { - "testEnvironment": "node", + "preset": "@shelf/jest-mongodb", "testMatch": [ "**/__tests__/**/*.js?(x)", "**/?(*.)+(spec|test).js?(x)" - ] + ], + "setupFilesAfterEnv": ["/jest.setup.js"] } }