const {getDatabase} = require("./MongodbService"); let Db = null getDatabase("brief04").then((value)=>{Db = value}) const { Logger } = require('tslog'); const {Event} = require('../models/Event') const logger = new Logger({ name: "Auth Controller" }); //TODO Better return error integration === /** * Retrieves an event from the database using the specified ID. * @param {string} id - The ID of the event to retrieve. * @return {Promise} - A Promise that resolves to an object representing the event. */ async function getEventFromIdService(id) { return await Db.collection("events").findOne({id: id}); } //TODO Get owned event //TODO - To test /** * Retrieves all events from the database. * * @param {string} sourceId - The source ID to query the events from. * @return {object} - An object containing: * - updatedAt : The timestamp when the events were last updated. * - events : An array of sanitized event objects. Each event object contains the following properties: * - id : The event ID. * - title : The event title. * - subTitle : The event subtitle. * - base64Banner : The base64 encoded banner image of the event. * - desc : The event description. * - date : The event date. * - were : The event location. * - maxMembers : The maximum number of members allowed for the event. * - authorId : The ID of the event author. * - members : The number of members currently participating in the event. * - length : The number of events returned. */ async function getAllEventsService(sourceId) { logger.info(`EVENT :> Query all threads (${sourceId})`) let eventsArray = [] eventsArray = await Db.collection("events").find().toArray(); if (!eventsArray) { logger.error('No event found.') return null } const sanitizedEvents = eventsArray.map((event)=>{ return { id: event.id, title: event.title, subTitle: event.subTitle, base64Banner: event.base64Banner, desc: event.desc, date: event.date, were: event.were, maxMembers: event.maxMembers, authorId: event.authorId, members: event.members } }) console.log(` -> Returned ${sanitizedEvents.length} event(s)`) return { updatedAt: Date.now(), events: sanitizedEvents, length: sanitizedEvents.length } } /** * Retrieves the subscribed event(s) for a given user. * * @param {string} targetId - The id of the target user. * * @return {Promise} * - A promise that resolves to an object containing information about the * subscribed event(s). * - If there are subscribed event(s), the resolved object will include the * following properties: * - iat: The current timestamp in milliseconds. * - subscribedEvent: An array of the subscribed event(s) retrieved from the database. * - length: The number of subscribed event(s). * - If no subscribed event is found for the given targetId, the resolved object will * include the following error property: * - error: "noSubscribedEventFound" */ async function getUserSubscribedEventService(targetId) { const subscribedEvent = await Db.collection("events").find({ members: { $in: [`${targetId}`] }}).toArray(); if (!subscribedEvent) { logger.error(`No subscribed event found for USERID:${targetId}`) return { error: "noSubscribedEventFound" } } return { iat: Date.now(), subscribedEvent: subscribedEvent, length: subscribedEvent.length } } //TODO - To test /** * Modify the subscription state of a user for an event. * * @param {string} userId - The ID of the user. * @param {string} eventId - The ID of the event. * @param {boolean} state - The desired subscription state (true for subscribed, false for unsubscribed). * * @return {object} - The result of the operation. * - If the user is not found, { error: "userNotFound" } is returned. * - If the event is not found, { error: "eventNotFound" } is returned. * - If the user is already subscribed to the event and the state is true, { error: "alreadySubscribed" } is returned. * - If the user is not subscribed to the event and the state is false, { error: "notSubscribed" } is returned. * - If the event update fails, { error: "updateFailed" } is returned. * - If the operation is successful, { error: "none" } is returned. */ async function alterUserSubscribedEventStateService(userId, eventId, state){ const user = await Db.collection("users").findOne({id: userId}); if (!user) { logger.error(`User not found (${userId})`); return { error: "userNotFound" }; } const event = await Db.collection("events").findOne({id: eventId}); if (!event) { logger.error(`Event not found (${eventId})`); return { error: "eventNotFound" }; } const isUserSubscribed = event.members.includes(userId); if (state === true && isUserSubscribed) { logger.error(`User already subscribed to the event (${userId}, ${eventId})`); return { error: "alreadySubscribed" }; } if (state === false && !isUserSubscribed) { logger.error(`User is not subscribed to the event (${userId}, ${eventId})`); return { error: "notSubscribed" }; } if (state === true) { event.members.push(userId); } else if (state === false) { event.members = event.members.filter(memberId => memberId !== userId); } const updatedEventResult = await Db.collection("events").updateOne({id: eventId}, {$set: event}); if (updatedEventResult.modifiedCount === 0) { logger.error(`Failed to update event (${eventId})`); return { error: "updateFailed" }; } logger.info(`User ${state === true ? "subscribed" : "unsubscribed"} successfully to the event. (${userId}, ${eventId})`); return { error: "none" }; } //TODO - To test /** * Edits an event in the database. * * @param {string} eventId * - The ID of the event to be edited. * @param {object} sanitizedData * - The sanitized data used to update the event. * * @return {object} * - An object with an "error" property. * - If the event is not found, the "error" property will be "eventNotFound". * - If the event is edited successfully, the "error" property will be "none". */ async function editEventService(eventId, sanitizedData) { try { const updatedEventResult = await Db.collection("events").updateOne({id: eventId}, {$set: sanitizedData}); if (updatedEventResult.modifiedCount === 0) { logger.info(`EDIT :> Event not found (${eventId})`) return { error: "eventNotFound" }; } logger.info(`EDIT :> Event edited successfully (${eventId})`); return { error: "none" }; } catch (e) { logger.error(e) } } //TODO Delete event - Owner || Admin === async function deleteEventService(eventId) { const deletedEventResult = await Db.collection("events").deleteOne({id: eventId}); if (deletedEventResult.deletedCount === 0) { logger.error(`Failed to delete event (${eventId})`); return { error: "deleteFailed" }; } logger.info(`Event deleted successfully (${eventId})`); return { error: "none" }; } //TODO - To test /** * Create a new event and store it in the database. * * @param {string} ownerId - The ID of the event owner. * @param {object} sanitizedData - The sanitized data object containing event details. * @return {object} - An object indicating the success or failure of the event creation. */ async function createEventService(ownerId, sanitizedData) { const newEvent = new Event( `${sanitizedData.title}`, `${sanitizedData.subTitle}`, `${sanitizedData.base64Banner}`, `${sanitizedData.desc}`, `${sanitizedData.date}`, `${sanitizedData.were}`, Number.parseInt(`${sanitizedData.maxMembers}`), `${ownerId}`,) const event = { id: newEvent.id, title: newEvent.title, subTitle: newEvent.subTitle, base64Banner: newEvent.base64Banner, desc: newEvent.desc, date: newEvent.date, were: newEvent.were, maxMembers: newEvent.maxMembers, authorId: newEvent.authorId, members: newEvent.members }; const insertedEventResult = await Db.collection("events").insertOne(event); if (insertedEventResult.insertedCount === 0) { logger.error(`Failed to create event (${event.id})`); return { error: "createFailed" }; } logger.info(`Event created successfully (${event.id})`); return { error: "none", eventId: event.id }; } module.exports = { getEventFromIdService, getAllEventsService, getUserSubscribedEventService, alterUserSubscribedEventStateService, editEventService, createEventService, deleteEventService }