import * as dotenv from 'dotenv'; dotenv.config(); const mariadb = require('mariadb'); const prod_pool = mariadb.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.PARTYPLANER_PROD_DATABASE, connectionLimit: 5 }); const dev_pool = mariadb.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.PARTYPLANER_DEV_DATABASE, connectionLimit: 5 }); /** * Used in the getUserData method as return value */ export interface UserData { username: string; email: string; firstName: string; lastName: string; lastLogin: string; emailIsVerified: string; isPremiumUser: string; } /** * Used in the getSessionData method as return value */ export interface SessionData { sessionId: string; type: string; lastLogin: string; lastIp: string; } /** * Used in the getFriendshipData method as a return value */ export interface Friendship { friendshipId: string; friendId: string; friendFirstName: string; friendLastName: string; friendUsername: string; } /** * Used in the getEventData method */ export interface Invite { inviteId: string; inviteKey: string; validUntil: Date; alreadyUsed: boolean; invitedPersonName: string; } /** * Used in the getEventData method */ export interface Registration { registrationId: string; name: string; registeredDate: Date; takesPart: boolean; comment: string; } /** * Used in the getEventData method as a return value */ export interface Event { eventId: string; name: string; description: string; takesPlaceDate: Date; registrationUntilDate: Date; maxParticipants: number; invites: Invite[]; registrations: Registration[]; } /** * Returns all data about the given user * @param useDev If the dev or prod database should be used * @param userId The userId of the user to return the data for * @return UserData An object containing the user data */ export const getUserData = async (useDev: boolean, userId: string): Promise<UserData> => { let conn; try { if (useDev) { conn = await dev_pool.getConnection(); } else { conn = await prod_pool.getConnection(); } let rows = await conn.query('SELECT username, email, first_name, last_Name, last_login, email_is_verified, is_premium_user FROM users WHERE user_id = ?', userId); let user: UserData = {} as UserData; for (let row of rows) { user = { username: row.username, email: row.email, firstName: row.first_name, lastName: row.last_name, lastLogin: row.last_login, emailIsVerified: row.email_is_verified, isPremiumUser: row.is_premium_user }; } return user; } catch (err) { throw err; } finally { if (conn) { conn.end(); } } }; /** * Returns all active sessions of the given user * @param useDev If the dev or prod database should be used * @param userId The userId of the user to return the sessions for * @return SessionData[] A list containing objects with the session data */ export const getSessionData = async (useDev: boolean, userId: string): Promise<SessionData[]> => { let conn; try { if (useDev) { conn = await dev_pool.getConnection(); } else { conn = await prod_pool.getConnection(); } let rows = await conn.query('SELECT session_id, type, last_login, last_ip FROM sessions WHERE user_id = ? AND valid_until > NOW()', userId); let sessions: SessionData[] = []; for (let row of rows) { sessions.push({ sessionId: row.session_id, type: row.type, lastLogin: row.last_login, lastIp: row.last_ip }); } return sessions; } catch (err) { throw err; } finally { if (conn) { conn.end(); } } }; /** * Returns all friends of the given user * @param useDev If the dev or prod database should be used * @param userId The userId of the user to fetch the friends for * @return Friendship[] A list of friends */ export const getFriendshipData = async (useDev: boolean, userId: string): Promise<Friendship[]> => { let conn; try { if (useDev) { conn = await dev_pool.getConnection(); } else { conn = await prod_pool.getConnection(); } let rows = await conn.query('SELECT f.friendship_id, f.friend_id, u.first_name as friend_first_name, u.last_name as friend_last_name, u.username as friend_username FROM friendships f LEFT OUTER JOIN users u ON f.friend_id = u.user_id WHERE f.user_id = ?', userId); let friends: Friendship[] = []; for (let row of rows) { friends.push({ friendshipId: row.friendship_id, friendId: row.friend_id, friendFirstName: row.friend_first_name, friendLastName: row.friend_last_name, friendUsername: row.friend_username }); } return friends; } catch (err) { throw err; } finally { if (conn) { conn.end(); } } }; /** * Returns all events of the given user * @param useDev If the dev or prod database should be used * @param userId The userId of the user to fetch the friends for * @return Event[] A list of events */ export const getEventData = async (useDev: boolean, userId: string): Promise<Event[]> => { let conn; try { if (useDev) { conn = await dev_pool.getConnection(); } else { conn = await prod_pool.getConnection(); } let eventRows = await conn.query('SELECT event_id, name, description, takes_place_date, registration_until_date, max_participants FROM events WHERE creator_id = ?', userId); let eventsMap = new Map<string, Event>(); let eventIds: string[] = []; for (let row of eventRows) { eventIds.push(row.event_id); let event = { eventId: row.event_id, name: row.name, description: row.description, takesPlaceDate: row.takes_place_date, registrationUntilDate: row.registration_until_date, maxParticipants: row.max_participants, invites: [], registrations: [] }; eventsMap.set(row.event_id, event); } let registrationRows = await conn.query('SELECT registration_id, name, registered_date, takes_part, comment, event_id FROM event_registration WHERE event_id IN (?)', eventIds); for (let row of registrationRows) { let event = eventsMap.get(row.event_id); if (!event) continue; event.registrations.push({ registrationId: row.registration_id, name: row.name, registeredDate: row.registered_date, takesPart: row.takes_part, comment: row.comment }); } let inviteRows = await conn.query('SELECT invite_id, invite_key, valid_until, already_used, invited_person_name, event_id FROM invitations WHERE event_id IN (?)', eventIds); for (let row of inviteRows) { let event = eventsMap.get(row.event_id); if (!event) continue; event.invites.push({ inviteId: row.invite_id, inviteKey: row.invite_key, validUntil: row.valid_until, alreadyUsed: row.already_used, invitedPersonName: row.invited_person_name }); } let eventsList: Event[] = []; for (let event of eventsMap.values()) { eventsList.push(event); } return eventsList; } catch (err) { throw err; } finally { if (conn) { conn.end(); } } };