API-23: Refactoring for better architecture (#12)
Some checks failed
Jenkins Production Deployment
Some checks failed
Jenkins Production Deployment
Endpoints are separated into distinct packages and interfaces are extracted into files Co-authored-by: Patrick Müller <patrick@mueller-patrick.tech> Reviewed-on: #12 Co-authored-by: Patrick Müller <patrick@plutodev.de> Co-committed-by: Patrick Müller <patrick@plutodev.de>
This commit is contained in:
parent
a3d137f1c6
commit
7ee812bbb3
|
@ -2,10 +2,14 @@
|
||||||
* Required External Modules and Interfaces
|
* Required External Modules and Interfaces
|
||||||
*/
|
*/
|
||||||
import express, {Request, Response} from 'express';
|
import express, {Request, Response} from 'express';
|
||||||
import {dataRouter} from './data/Data.router';
|
|
||||||
import {registerRouter} from './register/Register.router';
|
import {registerRouter} from './register/Register.router';
|
||||||
import logger from '../../middleware/logger';
|
import logger from '../../middleware/logger';
|
||||||
import {loginRouter} from './login/Login.router';
|
import {loginRouter} from './login/Login.router';
|
||||||
|
import {userRouter} from './user/User.router';
|
||||||
|
import {eventRouter} from './event/Event.router';
|
||||||
|
import {friendshipRouter} from './friendship/Friendship.router';
|
||||||
|
import {inviteRouter} from './invite/Invite.router';
|
||||||
|
import {sessionRouter} from './session/Session.router';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router Definition
|
* Router Definition
|
||||||
|
@ -13,9 +17,13 @@ import {loginRouter} from './login/Login.router';
|
||||||
export const partyPlanerRouter = express.Router();
|
export const partyPlanerRouter = express.Router();
|
||||||
|
|
||||||
// Sub-Endpoints
|
// Sub-Endpoints
|
||||||
partyPlanerRouter.use('/data', dataRouter);
|
partyPlanerRouter.use('/event', eventRouter);
|
||||||
partyPlanerRouter.use('/register', registerRouter);
|
partyPlanerRouter.use('/friendship', friendshipRouter);
|
||||||
|
partyPlanerRouter.use('/invite', inviteRouter);
|
||||||
partyPlanerRouter.use('/login', loginRouter);
|
partyPlanerRouter.use('/login', loginRouter);
|
||||||
|
partyPlanerRouter.use('/register', registerRouter);
|
||||||
|
partyPlanerRouter.use('/session', sessionRouter);
|
||||||
|
partyPlanerRouter.use('/user', userRouter);
|
||||||
|
|
||||||
partyPlanerRouter.get('/', async (req: Request, res: Response) => {
|
partyPlanerRouter.get('/', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
/**
|
|
||||||
* Required External Modules and Interfaces
|
|
||||||
*/
|
|
||||||
import express, {Request, Response} from 'express';
|
|
||||||
import * as DataService from './data.service';
|
|
||||||
import * as UserService from '../userService/user.service';
|
|
||||||
import logger from '../../../middleware/logger';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Router Definition
|
|
||||||
*/
|
|
||||||
export const dataRouter = express.Router();
|
|
||||||
|
|
||||||
dataRouter.get('/user/:isDevCall', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
let userId = (req.query.userId ?? '').toString();
|
|
||||||
let sessionId = (req.query.sessionId ?? '').toString();
|
|
||||||
let sessionKey = (req.query.sessionKey ?? '').toString();
|
|
||||||
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
|
||||||
|
|
||||||
if (userId === '' || sessionId === '' || sessionKey === '') {
|
|
||||||
res.status(400).send({
|
|
||||||
'status': 'WRONG_PARAMS',
|
|
||||||
'message': 'Missing or wrong parameters'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
|
||||||
res.status(403).send({
|
|
||||||
'status': 'INVALID_SESSION',
|
|
||||||
'message': 'The user or session could not be found or the session is invalid'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await DataService.getUserData(useDev, userId);
|
|
||||||
|
|
||||||
res.status(200).send(data);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Error handling a request: ' + e.message);
|
|
||||||
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dataRouter.get('/session/:isDevCall', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
let userId = (req.query.userId ?? '').toString();
|
|
||||||
let sessionId = (req.query.sessionId ?? '').toString();
|
|
||||||
let sessionKey = (req.query.sessionKey ?? '').toString();
|
|
||||||
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
|
||||||
|
|
||||||
if (userId === '' || sessionId === '' || sessionKey === '') {
|
|
||||||
res.status(400).send({
|
|
||||||
'status': 'WRONG_PARAMS',
|
|
||||||
'message': 'Missing or wrong parameters'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
|
||||||
res.status(403).send({
|
|
||||||
'status': 'INVALID_SESSION',
|
|
||||||
'message': 'The user or session could not be found or the session is invalid'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await DataService.getSessionData(useDev, userId);
|
|
||||||
|
|
||||||
res.status(200).send(data);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Error handling a request: ' + e.message);
|
|
||||||
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dataRouter.get('/friendship/:isDevCall', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
let userId = (req.query.userId ?? '').toString();
|
|
||||||
let sessionId = (req.query.sessionId ?? '').toString();
|
|
||||||
let sessionKey = (req.query.sessionKey ?? '').toString();
|
|
||||||
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
|
||||||
|
|
||||||
if (userId === '' || sessionId === '' || sessionKey === '') {
|
|
||||||
res.status(400).send({
|
|
||||||
'status': 'WRONG_PARAMS',
|
|
||||||
'message': 'Missing or wrong parameters'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
|
||||||
res.status(403).send({
|
|
||||||
'status': 'INVALID_SESSION',
|
|
||||||
'message': 'The user or session could not be found or the session is invalid'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await DataService.getFriendshipData(useDev, userId);
|
|
||||||
|
|
||||||
res.status(200).send(data);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Error handling a request: ' + e.message);
|
|
||||||
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dataRouter.get('/event/:isDevCall', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
let userId = (req.query.userId ?? '').toString();
|
|
||||||
let sessionId = (req.query.sessionId ?? '').toString();
|
|
||||||
let sessionKey = (req.query.sessionKey ?? '').toString();
|
|
||||||
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
|
||||||
|
|
||||||
if (userId === '' || sessionId === '' || sessionKey === '') {
|
|
||||||
res.status(400).send({
|
|
||||||
'status': 'WRONG_PARAMS',
|
|
||||||
'message': 'Missing or wrong parameters'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
|
||||||
res.status(403).send({
|
|
||||||
'status': 'INVALID_SESSION',
|
|
||||||
'message': 'The user or session could not be found or the session is invalid'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await DataService.getEventData(useDev, userId);
|
|
||||||
|
|
||||||
res.status(200).send(data);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Error handling a request: ' + e.message);
|
|
||||||
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dataRouter.get('/invite/:isDevCall', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
let userId = (req.query.userId ?? '').toString();
|
|
||||||
let sessionId = (req.query.sessionId ?? '').toString();
|
|
||||||
let sessionKey = (req.query.sessionKey ?? '').toString();
|
|
||||||
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
|
||||||
|
|
||||||
if (userId === '' || sessionId === '' || sessionKey === '') {
|
|
||||||
res.status(400).send({
|
|
||||||
'status': 'WRONG_PARAMS',
|
|
||||||
'message': 'Missing or wrong parameters'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
|
||||||
res.status(403).send({
|
|
||||||
'status': 'INVALID_SESSION',
|
|
||||||
'message': 'The user or session could not be found or the session is invalid'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await DataService.getInvitesData(useDev, userId);
|
|
||||||
|
|
||||||
res.status(200).send(data);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Error handling a request: ' + e.message);
|
|
||||||
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,349 +0,0 @@
|
||||||
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[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used in the getInvitesData method as a return value
|
|
||||||
*/
|
|
||||||
export interface ReceivedInvite {
|
|
||||||
inviteId: string;
|
|
||||||
validUntil: Date;
|
|
||||||
alreadyUsed: boolean;
|
|
||||||
inviteKey: string;
|
|
||||||
eventName: string;
|
|
||||||
eventDescription: string;
|
|
||||||
takesPlaceDate: Date;
|
|
||||||
registrationUntilDate: Date;
|
|
||||||
maxParticipants: number;
|
|
||||||
eventCreatorId: string;
|
|
||||||
creatorFirstName: string;
|
|
||||||
creatorLastName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all events the user is invited to
|
|
||||||
* @param useDev If the dev or prod database should be used
|
|
||||||
* @param userId The userId of the user to fetch the friends for
|
|
||||||
* @return ReceivedInvite[] A list of invites
|
|
||||||
*/
|
|
||||||
export const getInvitesData = async (useDev: boolean, userId: string): Promise<ReceivedInvite[]> => {
|
|
||||||
let conn;
|
|
||||||
try {
|
|
||||||
if (useDev) {
|
|
||||||
conn = await dev_pool.getConnection();
|
|
||||||
} else {
|
|
||||||
conn = await prod_pool.getConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
let rows = await conn.query('SELECT i.invite_id, i.valid_until, i.already_used, i.invite_key, e.name as event_name, e.description as event_description, e.takes_place_date, e.registration_until_date, e.max_participants, e.creator_id, u.first_name, u.last_name FROM invitations i LEFT OUTER JOIN events e ON e.event_id = i.event_id LEFT OUTER JOIN users u ON u.user_id = e.creator_id WHERE i.user_id = ?', userId);
|
|
||||||
|
|
||||||
let invites: ReceivedInvite[] = [];
|
|
||||||
|
|
||||||
for (let row of rows) {
|
|
||||||
invites.push({
|
|
||||||
inviteId: row.invite_id,
|
|
||||||
validUntil: row.valid_until,
|
|
||||||
alreadyUsed: row.already_used,
|
|
||||||
inviteKey: row.invite_key,
|
|
||||||
eventName: row.event_name,
|
|
||||||
eventDescription: row.event_description,
|
|
||||||
takesPlaceDate: row.takes_place_date,
|
|
||||||
registrationUntilDate: row.registration_until_date,
|
|
||||||
maxParticipants: row.max_participants,
|
|
||||||
eventCreatorId: row.creator_id,
|
|
||||||
creatorFirstName: row.first_name,
|
|
||||||
creatorLastName: row.last_name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return invites;
|
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
} finally {
|
|
||||||
if (conn) {
|
|
||||||
conn.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
16
src/models/partyplaner/event/Event.interface.ts
Normal file
16
src/models/partyplaner/event/Event.interface.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import {Invite} from './Invite.interface';
|
||||||
|
import {Registration} from './Registration.interface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[];
|
||||||
|
}
|
44
src/models/partyplaner/event/Event.router.ts
Normal file
44
src/models/partyplaner/event/Event.router.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Required External Modules and Interfaces
|
||||||
|
*/
|
||||||
|
import express, {Request, Response} from 'express';
|
||||||
|
import * as EventService from './event.service';
|
||||||
|
import * as UserService from '../user/user.service';
|
||||||
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Router Definition
|
||||||
|
*/
|
||||||
|
export const eventRouter = express.Router();
|
||||||
|
|
||||||
|
eventRouter.get('/:isDevCall', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
let userId = (req.query.userId ?? '').toString();
|
||||||
|
let sessionId = (req.query.sessionId ?? '').toString();
|
||||||
|
let sessionKey = (req.query.sessionKey ?? '').toString();
|
||||||
|
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
||||||
|
|
||||||
|
if (userId === '' || sessionId === '' || sessionKey === '') {
|
||||||
|
res.status(400).send({
|
||||||
|
'status': 'WRONG_PARAMS',
|
||||||
|
'message': 'Missing or wrong parameters'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
||||||
|
res.status(403).send({
|
||||||
|
'status': 'INVALID_SESSION',
|
||||||
|
'message': 'The user or session could not be found or the session is invalid'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = await EventService.getEventData(useDev, userId);
|
||||||
|
|
||||||
|
res.status(200).send(data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Error handling a request: ' + e.message);
|
||||||
|
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
||||||
|
}
|
||||||
|
});
|
10
src/models/partyplaner/event/Invite.interface.ts
Normal file
10
src/models/partyplaner/event/Invite.interface.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* Used in the getEventData method
|
||||||
|
*/
|
||||||
|
export interface Invite {
|
||||||
|
inviteId: string;
|
||||||
|
inviteKey: string;
|
||||||
|
validUntil: Date;
|
||||||
|
alreadyUsed: boolean;
|
||||||
|
invitedPersonName: string;
|
||||||
|
}
|
10
src/models/partyplaner/event/Registration.interface.ts
Normal file
10
src/models/partyplaner/event/Registration.interface.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* Used in the getEventData method
|
||||||
|
*/
|
||||||
|
export interface Registration {
|
||||||
|
registrationId: string;
|
||||||
|
name: string;
|
||||||
|
registeredDate: Date;
|
||||||
|
takesPart: boolean;
|
||||||
|
comment: string;
|
||||||
|
}
|
98
src/models/partyplaner/event/event.service.ts
Normal file
98
src/models/partyplaner/event/event.service.ts
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
import {Event} from './event.interface';
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
10
src/models/partyplaner/friendship/Friendship.interface.ts
Normal file
10
src/models/partyplaner/friendship/Friendship.interface.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* Used in the getFriendshipData method as a return value
|
||||||
|
*/
|
||||||
|
export interface Friendship {
|
||||||
|
friendshipId: string;
|
||||||
|
friendId: string;
|
||||||
|
friendFirstName: string;
|
||||||
|
friendLastName: string;
|
||||||
|
friendUsername: string;
|
||||||
|
}
|
44
src/models/partyplaner/friendship/Friendship.router.ts
Normal file
44
src/models/partyplaner/friendship/Friendship.router.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Required External Modules and Interfaces
|
||||||
|
*/
|
||||||
|
import express, {Request, Response} from 'express';
|
||||||
|
import * as FriendshipService from './friendship.service';
|
||||||
|
import * as UserService from '../user/user.service';
|
||||||
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Router Definition
|
||||||
|
*/
|
||||||
|
export const friendshipRouter = express.Router();
|
||||||
|
|
||||||
|
friendshipRouter.get('/:isDevCall', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
let userId = (req.query.userId ?? '').toString();
|
||||||
|
let sessionId = (req.query.sessionId ?? '').toString();
|
||||||
|
let sessionKey = (req.query.sessionKey ?? '').toString();
|
||||||
|
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
||||||
|
|
||||||
|
if (userId === '' || sessionId === '' || sessionKey === '') {
|
||||||
|
res.status(400).send({
|
||||||
|
'status': 'WRONG_PARAMS',
|
||||||
|
'message': 'Missing or wrong parameters'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
||||||
|
res.status(403).send({
|
||||||
|
'status': 'INVALID_SESSION',
|
||||||
|
'message': 'The user or session could not be found or the session is invalid'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = await FriendshipService.getFriendshipData(useDev, userId);
|
||||||
|
|
||||||
|
res.status(200).send(data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Error handling a request: ' + e.message);
|
||||||
|
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
||||||
|
}
|
||||||
|
});
|
59
src/models/partyplaner/friendship/friendship.service.ts
Normal file
59
src/models/partyplaner/friendship/friendship.service.ts
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
import {Friendship} from './Friendship.interface';
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
44
src/models/partyplaner/invite/Invite.router.ts
Normal file
44
src/models/partyplaner/invite/Invite.router.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Required External Modules and Interfaces
|
||||||
|
*/
|
||||||
|
import express, {Request, Response} from 'express';
|
||||||
|
import * as InviteService from './invite.service';
|
||||||
|
import * as UserService from '../user/user.service';
|
||||||
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Router Definition
|
||||||
|
*/
|
||||||
|
export const inviteRouter = express.Router();
|
||||||
|
|
||||||
|
inviteRouter.get('/:isDevCall', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
let userId = (req.query.userId ?? '').toString();
|
||||||
|
let sessionId = (req.query.sessionId ?? '').toString();
|
||||||
|
let sessionKey = (req.query.sessionKey ?? '').toString();
|
||||||
|
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
||||||
|
|
||||||
|
if (userId === '' || sessionId === '' || sessionKey === '') {
|
||||||
|
res.status(400).send({
|
||||||
|
'status': 'WRONG_PARAMS',
|
||||||
|
'message': 'Missing or wrong parameters'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
||||||
|
res.status(403).send({
|
||||||
|
'status': 'INVALID_SESSION',
|
||||||
|
'message': 'The user or session could not be found or the session is invalid'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = await InviteService.getInvitesData(useDev, userId);
|
||||||
|
|
||||||
|
res.status(200).send(data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Error handling a request: ' + e.message);
|
||||||
|
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
||||||
|
}
|
||||||
|
});
|
17
src/models/partyplaner/invite/ReceivedInvite.interface.ts
Normal file
17
src/models/partyplaner/invite/ReceivedInvite.interface.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
* Used in the getInvitesData method as a return value
|
||||||
|
*/
|
||||||
|
export interface ReceivedInvite {
|
||||||
|
inviteId: string;
|
||||||
|
validUntil: Date;
|
||||||
|
alreadyUsed: boolean;
|
||||||
|
inviteKey: string;
|
||||||
|
eventName: string;
|
||||||
|
eventDescription: string;
|
||||||
|
takesPlaceDate: Date;
|
||||||
|
registrationUntilDate: Date;
|
||||||
|
maxParticipants: number;
|
||||||
|
eventCreatorId: string;
|
||||||
|
creatorFirstName: string;
|
||||||
|
creatorLastName: string;
|
||||||
|
}
|
66
src/models/partyplaner/invite/invite.service.ts
Normal file
66
src/models/partyplaner/invite/invite.service.ts
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
import {ReceivedInvite} from './ReceivedInvite.interface';
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all events the user is invited to
|
||||||
|
* @param useDev If the dev or prod database should be used
|
||||||
|
* @param userId The userId of the user to fetch the friends for
|
||||||
|
* @return ReceivedInvite[] A list of invites
|
||||||
|
*/
|
||||||
|
export const getInvitesData = async (useDev: boolean, userId: string): Promise<ReceivedInvite[]> => {
|
||||||
|
let conn;
|
||||||
|
try {
|
||||||
|
if (useDev) {
|
||||||
|
conn = await dev_pool.getConnection();
|
||||||
|
} else {
|
||||||
|
conn = await prod_pool.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
let rows = await conn.query('SELECT i.invite_id, i.valid_until, i.already_used, i.invite_key, e.name as event_name, e.description as event_description, e.takes_place_date, e.registration_until_date, e.max_participants, e.creator_id, u.first_name, u.last_name FROM invitations i LEFT OUTER JOIN events e ON e.event_id = i.event_id LEFT OUTER JOIN users u ON u.user_id = e.creator_id WHERE i.user_id = ?', userId);
|
||||||
|
|
||||||
|
let invites: ReceivedInvite[] = [];
|
||||||
|
|
||||||
|
for (let row of rows) {
|
||||||
|
invites.push({
|
||||||
|
inviteId: row.invite_id,
|
||||||
|
validUntil: row.valid_until,
|
||||||
|
alreadyUsed: row.already_used,
|
||||||
|
inviteKey: row.invite_key,
|
||||||
|
eventName: row.event_name,
|
||||||
|
eventDescription: row.event_description,
|
||||||
|
takesPlaceDate: row.takes_place_date,
|
||||||
|
registrationUntilDate: row.registration_until_date,
|
||||||
|
maxParticipants: row.max_participants,
|
||||||
|
eventCreatorId: row.creator_id,
|
||||||
|
creatorFirstName: row.first_name,
|
||||||
|
creatorLastName: row.last_name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return invites;
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
} finally {
|
||||||
|
if (conn) {
|
||||||
|
conn.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -2,7 +2,7 @@
|
||||||
* Required External Modules and Interfaces
|
* Required External Modules and Interfaces
|
||||||
*/
|
*/
|
||||||
import express, {Request, Response} from 'express';
|
import express, {Request, Response} from 'express';
|
||||||
import * as UserService from '../userService/user.service';
|
import * as UserService from '../user/user.service';
|
||||||
import logger from '../../../middleware/logger';
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Required External Modules and Interfaces
|
* Required External Modules and Interfaces
|
||||||
*/
|
*/
|
||||||
import express, {Request, Response} from 'express';
|
import express, {Request, Response} from 'express';
|
||||||
import * as UserService from '../userService/user.service';
|
import * as UserService from '../user/user.service';
|
||||||
import logger from '../../../middleware/logger';
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
44
src/models/partyplaner/session/Session.router.ts
Normal file
44
src/models/partyplaner/session/Session.router.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Required External Modules and Interfaces
|
||||||
|
*/
|
||||||
|
import express, {Request, Response} from 'express';
|
||||||
|
import * as SessionService from './session.service';
|
||||||
|
import * as UserService from '../user/user.service';
|
||||||
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Router Definition
|
||||||
|
*/
|
||||||
|
export const sessionRouter = express.Router();
|
||||||
|
|
||||||
|
sessionRouter.get('/:isDevCall', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
let userId = (req.query.userId ?? '').toString();
|
||||||
|
let sessionId = (req.query.sessionId ?? '').toString();
|
||||||
|
let sessionKey = (req.query.sessionKey ?? '').toString();
|
||||||
|
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
||||||
|
|
||||||
|
if (userId === '' || sessionId === '' || sessionKey === '') {
|
||||||
|
res.status(400).send({
|
||||||
|
'status': 'WRONG_PARAMS',
|
||||||
|
'message': 'Missing or wrong parameters'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
||||||
|
res.status(403).send({
|
||||||
|
'status': 'INVALID_SESSION',
|
||||||
|
'message': 'The user or session could not be found or the session is invalid'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = await SessionService.getSessionData(useDev, userId);
|
||||||
|
|
||||||
|
res.status(200).send(data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Error handling a request: ' + e.message);
|
||||||
|
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
||||||
|
}
|
||||||
|
});
|
9
src/models/partyplaner/session/SessionData.interface.ts
Normal file
9
src/models/partyplaner/session/SessionData.interface.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Used in the getSessionData method as return value
|
||||||
|
*/
|
||||||
|
export interface SessionData {
|
||||||
|
sessionId: string;
|
||||||
|
type: string;
|
||||||
|
lastLogin: string;
|
||||||
|
lastIp: string;
|
||||||
|
}
|
58
src/models/partyplaner/session/session.service.ts
Normal file
58
src/models/partyplaner/session/session.service.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
import {SessionData} from './SessionData.interface';
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
8
src/models/partyplaner/user/Session.interface.ts
Normal file
8
src/models/partyplaner/user/Session.interface.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Used in the registerUser and loginUser methods as return value
|
||||||
|
*/
|
||||||
|
export interface Session {
|
||||||
|
userId: string;
|
||||||
|
sessionId: string;
|
||||||
|
sessionKey: string;
|
||||||
|
}
|
8
src/models/partyplaner/user/Status.interface.ts
Normal file
8
src/models/partyplaner/user/Status.interface.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Used in the checkUsernameAndEmail method as return value
|
||||||
|
*/
|
||||||
|
export interface Status {
|
||||||
|
hasProblems: boolean;
|
||||||
|
messages: string[];
|
||||||
|
status: string[];
|
||||||
|
}
|
43
src/models/partyplaner/user/User.router.ts
Normal file
43
src/models/partyplaner/user/User.router.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* Required External Modules and Interfaces
|
||||||
|
*/
|
||||||
|
import express, {Request, Response} from 'express';
|
||||||
|
import * as UserService from './user.service';
|
||||||
|
import logger from '../../../middleware/logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Router Definition
|
||||||
|
*/
|
||||||
|
export const userRouter = express.Router();
|
||||||
|
|
||||||
|
userRouter.get('/:isDevCall', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
let userId = (req.query.userId ?? '').toString();
|
||||||
|
let sessionId = (req.query.sessionId ?? '').toString();
|
||||||
|
let sessionKey = (req.query.sessionKey ?? '').toString();
|
||||||
|
let useDev: boolean = (req.params.isDevCall ?? '') === 'dev'; // TBD
|
||||||
|
|
||||||
|
if (userId === '' || sessionId === '' || sessionKey === '') {
|
||||||
|
res.status(400).send({
|
||||||
|
'status': 'WRONG_PARAMS',
|
||||||
|
'message': 'Missing or wrong parameters'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await UserService.checkSession(useDev, userId, sessionId, sessionKey)) {
|
||||||
|
res.status(403).send({
|
||||||
|
'status': 'INVALID_SESSION',
|
||||||
|
'message': 'The user or session could not be found or the session is invalid'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = await UserService.getUserData(useDev, userId);
|
||||||
|
|
||||||
|
res.status(200).send(data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Error handling a request: ' + e.message);
|
||||||
|
res.status(500).send({'message': 'Internal Server Error. Try again later.'});
|
||||||
|
}
|
||||||
|
});
|
12
src/models/partyplaner/user/UserData.interface.ts
Normal file
12
src/models/partyplaner/user/UserData.interface.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
import * as dotenv from 'dotenv';
|
import * as dotenv from 'dotenv';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import {Guid} from 'guid-typescript';
|
import {Guid} from 'guid-typescript';
|
||||||
|
import {UserData} from './UserData.interface';
|
||||||
|
import {Session} from './Session.interface';
|
||||||
|
import {Status} from './Status.interface';
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
@ -21,22 +24,45 @@ const dev_pool = mariadb.createPool({
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used in the registerUser and loginUser methods as return value
|
* 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 interface Session {
|
export const getUserData = async (useDev: boolean, userId: string): Promise<UserData> => {
|
||||||
userId: string;
|
let conn;
|
||||||
sessionId: string;
|
try {
|
||||||
sessionKey: string;
|
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);
|
||||||
* Used in the checkUsernameAndEmail method as return value
|
|
||||||
*/
|
let user: UserData = {} as UserData;
|
||||||
export interface Status {
|
|
||||||
hasProblems: boolean;
|
for (let row of rows) {
|
||||||
messages: string[];
|
user = {
|
||||||
status: string[];
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches all usernames and emails from the database and returns them in an object
|
* Fetches all usernames and emails from the database and returns them in an object
|
Loading…
Reference in New Issue
Block a user