diff --git a/src/models/calendar/events/credentials.service.ts b/src/models/calendar/events/credentials.service.ts index 7a9bc12..2f5eda9 100644 --- a/src/models/calendar/events/credentials.service.ts +++ b/src/models/calendar/events/credentials.service.ts @@ -29,6 +29,19 @@ export const checkMemberPrivileges = async (sessionId: string, sessionKey: strin return password == process.env.MEMBER_CREDENTIAL; } +/** + * Checks if the password gives choir view privileges + * @param password + */ +export const checkChoirPrivileges = async (sessionId: string, sessionKey: string, password: string, ip: string) => { + if(sessionId) { + let user = await UserService.checkSession(sessionId, sessionKey, ip); + return user.isActive; + } + + return password == process.env.CHOIR_CREDENTIAL; +} + /** * Checks if the password gives management view privileges * @param password @@ -48,6 +61,8 @@ export const hasAccess = async (calendarName: string, sessionId: string, session return true; case 'members': return await checkMemberPrivileges(sessionId, sessionKey, password, ip); + case 'choir': + return await checkChoirPrivileges(sessionId, sessionKey, password, ip); case 'management': return await checkManagementPrivileges(sessionId, sessionKey, password, ip); default: diff --git a/src/models/calendar/events/events.router.ts b/src/models/calendar/events/events.router.ts index 0422e6a..f60ff4f 100644 --- a/src/models/calendar/events/events.router.ts +++ b/src/models/calendar/events/events.router.ts @@ -24,6 +24,7 @@ export const eventsRouter = express.Router(); export const calendarNames = new Map([ ['public', {id: 1, name: 'Nachklang_calendar'}], ['members', {id: 2, name: 'Nachklang_internal_calendar'}], + ['choir', {id: 4, name: 'Nachklang_choir_calendar'}], ['management', {id: 3, name: 'Nachklang_management_calendar'}] ]); @@ -55,6 +56,7 @@ eventsRouter.get('/:calendar/json', async (req: Request, res: Response) => { let user = await UserService.checkSession(sessionId, sessionKey, ip); + // If no user was found, check if the password gives access to the calendar if(user === null || !user.isActive) { if (! await CredentialService.hasAccess(calendarName, sessionId, sessionKey, password, ip)) { res.status(403).send({'message': 'You do not have access to the specified calendar.'}); diff --git a/src/models/calendar/events/events.service.ts b/src/models/calendar/events/events.service.ts index 8c1392b..60cdb59 100644 --- a/src/models/calendar/events/events.service.ts +++ b/src/models/calendar/events/events.service.ts @@ -14,6 +14,14 @@ export const getAllEvents = async (calendarId: number): Promise => { let conn = await NachklangCalendarDB.getConnection(); let eventRows: Event[] = []; try { + const calendarQuery = 'SELECT calendar_id, includes_calendars FROM calendars WHERE calendar_id = ?'; + const calendarRes = await conn.query(calendarQuery, calendarId); + let calendarsToFetch: number[] = [calendarId]; + for(let row of calendarRes) { + let includes: number[] = JSON.parse(row.includes_calendars); + calendarsToFetch = [...calendarsToFetch, ...includes]; + } + const eventsQuery = ` SELECT e.calendar_id, e.uuid, e.created_date, e.created_by_id, u.full_name, v.* FROM events e INNER JOIN ( @@ -25,9 +33,9 @@ export const getAllEvents = async (calendarId: number): Promise => { INNER JOIN event_versions v ON v.event_id = latest_versions.event_id AND v.event_version_id = latest_versions.latest_version LEFT OUTER JOIN users u ON u.user_id = e.created_by_id - WHERE e.calendar_id = ? AND v.status = 'PUBLIC' + WHERE e.calendar_id IN (?) AND v.status = 'PUBLIC' ORDER BY e.event_id`; - const eventsRes = await conn.query(eventsQuery, calendarId); + const eventsRes = await conn.query(eventsQuery, [calendarsToFetch]); for (let row of eventsRes) { eventRows.push({ @@ -56,6 +64,11 @@ export const getAllEvents = async (calendarId: number): Promise => { } }; +/** + * Returns all events for the given calendar for the admin UI (therefore includes admin relevant information and + * ignores the calendar includes + * @param calendarId + */ export const getAllEventsAdmin = async (calendarId: number): Promise => { let conn = await NachklangCalendarDB.getConnection(); let eventRows: Event[] = []; diff --git a/src/models/calendar/events/icalgenerator.service.ts b/src/models/calendar/events/icalgenerator.service.ts index 5e2c4d2..bd9805d 100644 --- a/src/models/calendar/events/icalgenerator.service.ts +++ b/src/models/calendar/events/icalgenerator.service.ts @@ -1,5 +1,9 @@ import {Event} from './event.interface'; +/** + * Interface to external classes - Turns the given events into an ical string + * @param events + */ export const convertToIcal = async (events: Event[]): Promise => { try { let ical: iCalFile = {body: []}; @@ -15,6 +19,10 @@ export const convertToIcal = async (events: Event[]): Promise => { } }; +/** + * Method to serialize an iCalFile object into an ical string + * @param ical + */ const serializeIcalFile = (ical: iCalFile): string => { let returnString = ''; @@ -27,6 +35,10 @@ const serializeIcalFile = (ical: iCalFile): string => { return returnString; }; +/** + * Method to serialize a single ical event into an ical event string + * @param icalevent + */ const serializeIcalEvent = (icalevent: iCalEvent): string => { let returnString = ''; @@ -50,7 +62,10 @@ const serializeIcalEvent = (icalevent: iCalEvent): string => { return returnString; }; - +/** + * Method to generate the ical header string + * @param ical + */ const generateHeaderInfo = (ical: iCalFile) => { ical.header = 'BEGIN:VCALENDAR\n' + 'VERSION:2.0\n' + @@ -78,14 +93,27 @@ const generateHeaderInfo = (ical: iCalFile) => { 'END:VTIMEZONE\n'; }; +/** + * Method to generate the ical footer info + * @param ical + */ const generateFooterInfo = (ical: iCalFile) => { ical.footer = 'END:VCALENDAR'; }; +/** + * Method to add events to the iCalFile object + * @param ical + * @param event + */ const addEventToFile = (ical: iCalFile, event: Event) => { ical.body.push(createIcalEvent(event)); }; +/** + * Method to turn an event object into an iCalEvent object + * @param event + */ const createIcalEvent = (event: Event): iCalEvent => { let description = event.description ? event.description + '\n' : ''; let location = event.location ? event.location + '\n' : ''; @@ -107,6 +135,12 @@ const createIcalEvent = (event: Event): iCalEvent => { }; }; +/** + * Helper method to format dates in a valid iCal format + * @param date + * @param wholeDayFormat + * @param isEndDate + */ const formatDate = (date: Date, wholeDayFormat: boolean = false, isEndDate: boolean = false): string => { let returnString = '';