diff --git a/common/parse-body.js b/common/parse-body.js index 5996bf8..d9ce380 100644 --- a/common/parse-body.js +++ b/common/parse-body.js @@ -1,4 +1,3 @@ -const ical = require('node-ical'); const raw = require('raw-body'); const { DOMParser } = require('@xmldom/xmldom'); @@ -10,7 +9,5 @@ module.exports = async function (ctx) { if (ctx.request.type.includes('xml')) { ctx.request.xml = new DOMParser().parseFromString(ctx.request.body); - } else if (ctx.request.type === 'text/calendar') { - ctx.request.ical = await ical.async.parseICS(ctx.request.body); } }; diff --git a/common/tags.js b/common/tags.js index 6db14a5..b986b68 100644 --- a/common/tags.js +++ b/common/tags.js @@ -83,10 +83,10 @@ module.exports = function (options) { }, getetag: { doc: 'https://tools.ietf.org/html/rfc4791#section-5.3.4', - async resp({ resource, event }) { + async resp({ resource, ctx, event }) { if (resource === 'event') { return { - [buildTag(dav, 'getetag')]: options.data.getETag(event) + [buildTag(dav, 'getetag')]: options.data.getETag(ctx, event) }; } } @@ -199,8 +199,8 @@ module.exports = function (options) { [cal]: { 'calendar-data': { doc: 'https://tools.ietf.org/html/rfc4791#section-9.6', - async resp({ event, calendar }) { - const ics = await options.data.buildICS(event, calendar); + async resp({ event, ctx, calendar }) { + const ics = await options.data.buildICS(ctx, event, calendar); return { [buildTag(cal, 'calendar-data')]: ics }; diff --git a/index.js b/index.js index a5be095..7bd846a 100644 --- a/index.js +++ b/index.js @@ -85,7 +85,7 @@ module.exports = function (options) { return false; } - ctx.state.user = await options.authenticate({ + ctx.state.user = await options.authenticate(ctx, { username: creds.name, password: creds.pass, principalId: ctx.state.params.principalId diff --git a/package.json b/package.json index fe879dc..e98119e 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,9 @@ "dependencies": { "@xmldom/xmldom": "^0.8.10", "basic-auth": "^2.0.1", + "boolean": "3.2.0", "lodash": "^4.17.21", "moment": "^2.30.1", - "node-ical": "^0.17.1", "path-to-regexp": "^6.2.1", "raw-body": "^2.5.2", "winston": "^3.11.0", diff --git a/routes/calendar/calendar.js b/routes/calendar/calendar.js index e49bbee..1520b86 100644 --- a/routes/calendar/calendar.js +++ b/routes/calendar/calendar.js @@ -32,7 +32,7 @@ module.exports = function (options) { if (calendarId) { // Check calendar exists & user has access - const calendar = await options.data.getCalendar({ + const calendar = await options.data.getCalendar(ctx, { principalId: ctx.state.params.principalId, calendarId, user: ctx.state.user diff --git a/routes/calendar/calendar/calendar-multiget.js b/routes/calendar/calendar/calendar-multiget.js index 722b82b..880be52 100644 --- a/routes/calendar/calendar/calendar-multiget.js +++ b/routes/calendar/calendar/calendar-multiget.js @@ -19,7 +19,7 @@ module.exports = function (options) { const hrefParts = href.split('/'); const eventId = hrefParts.at(-1).slice(0, -4); - const event = await options.data.getEvent({ + const event = await options.data.getEvent(ctx, { eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, @@ -31,10 +31,10 @@ module.exports = function (options) { return response(href, status[404]); } - const ics = await options.data.buildICS(event, calendar); + const ics = await options.data.buildICS(ctx, event, calendar); return response(href, status[200], [ { - 'D:getetag': options.data.getETag(event) + 'D:getetag': options.data.getETag(ctx, event) }, { 'CAL:calendar-data': ics diff --git a/routes/calendar/calendar/calendar-query.js b/routes/calendar/calendar/calendar-query.js index 3a44c94..7f1513e 100644 --- a/routes/calendar/calendar/calendar-query.js +++ b/routes/calendar/calendar/calendar-query.js @@ -21,9 +21,9 @@ module.exports = function (options) { }); if (!filters?.[0]) { - const events = await options.data.getEventsForCalendar({ + const events = await options.data.getEventsForCalendar(ctx, { principalId: ctx.state.params.principalId, - calendarId: options.data.getCalendarId(calendar), + calendarId: options.data.getCalendarId(ctx, calendar), user: ctx.state.user, fullData }); @@ -67,9 +67,9 @@ module.exports = function (options) { if (endAttr && endAttr.nodeValue && moment(endAttr.nodeValue).isValid()) end = moment(endAttr.nodeValue).toDate(); - const events = await options.data.getEventsByDate({ + const events = await options.data.getEventsByDate(ctx, { principalId: ctx.state.params.principalId, - calendarId: options.data.getCalendarId(calendar), + calendarId: options.data.getCalendarId(ctx, calendar), start, end, user: ctx.state.user, diff --git a/routes/calendar/calendar/delete.js b/routes/calendar/calendar/delete.js index 9b8dda4..d451da2 100644 --- a/routes/calendar/calendar/delete.js +++ b/routes/calendar/calendar/delete.js @@ -17,7 +17,7 @@ module.exports = function (options) { return; } - const existing = await options.data.getEvent({ + const existing = await options.data.getEvent(ctx, { eventId: ctx.state.params.eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, @@ -26,7 +26,7 @@ module.exports = function (options) { }); log.debug(`existing event${existing ? '' : ' not'} found`); - await options.data.deleteEvent({ + await options.data.deleteEvent(ctx, { eventId: ctx.state.params.eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, diff --git a/routes/calendar/calendar/get.js b/routes/calendar/calendar/get.js index 35fc497..8c9ffd8 100644 --- a/routes/calendar/calendar/get.js +++ b/routes/calendar/calendar/get.js @@ -5,7 +5,7 @@ module.exports = function (options) { const log = winston({ ...options, label: 'calendar/get' }); const exec = async function (ctx, calendar) { - const event = await options.data.getEvent({ + const event = await options.data.getEvent(ctx, { eventId: ctx.state.params.eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, @@ -18,7 +18,7 @@ module.exports = function (options) { return; } - return options.data.buildICS(event, calendar); + return options.data.buildICS(ctx, event, calendar); }; return { diff --git a/routes/calendar/calendar/propfind.js b/routes/calendar/calendar/propfind.js index 8dc9337..b758684 100644 --- a/routes/calendar/calendar/propfind.js +++ b/routes/calendar/calendar/propfind.js @@ -31,7 +31,7 @@ module.exports = function (options) { const calendarUrl = path.join( ctx.state.calendarHomeUrl, - options.data.getCalendarId(calendar), + options.data.getCalendarId(ctx, calendar), '/' ); const props = _.compact(res); @@ -53,9 +53,9 @@ module.exports = function (options) { const fullData = _.some(children, (child) => { return child.localName === 'calendar-data'; }); - const events = await options.data.getEventsForCalendar({ + const events = await options.data.getEventsForCalendar(ctx, { principalId: ctx.state.params.principalId, - calendarId: options.data.getCalendarId(calendar), + calendarId: options.data.getCalendarId(ctx, calendar), user: ctx.state.user, fullData }); diff --git a/routes/calendar/calendar/put.js b/routes/calendar/calendar/put.js index e69b1a1..81b563c 100644 --- a/routes/calendar/calendar/put.js +++ b/routes/calendar/calendar/put.js @@ -1,4 +1,3 @@ -const _ = require('lodash'); const { notFound, preconditionFail } = require('../../../common/x-build'); const { setMissingMethod } = require('../../../common/response'); const winston = require('../../../common/winston'); @@ -19,14 +18,16 @@ module.exports = function (options) { return; } - const incoming = _.find(ctx.request.ical, { type: 'VEVENT' }); - if (!incoming) { + if ( + ctx.request.type !== 'text/calendar' || + typeof ctx.request.body !== 'string' + ) { log.warn('incoming VEVENT not present'); ctx.body = notFound(ctx.url); // Make more meaningful return; } - const existing = await options.data.getEvent({ + const existing = await options.data.getEvent(ctx, { eventId: ctx.state.params.eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, @@ -43,30 +44,28 @@ module.exports = function (options) { return; } - const updateObject = await options.data.updateEvent({ + const updateObject = await options.data.updateEvent(ctx, { eventId: ctx.state.params.eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, - event: incoming, user: ctx.state.user }); log.debug('event updated'); /* https://tools.ietf.org/html/rfc4791#section-5.3.2 */ ctx.status = 201; - ctx.set('ETag', options.data.getETag(updateObject)); + ctx.set('ETag', options.data.getETag(ctx, updateObject)); } else { - const newObject = await options.data.createEvent({ + const newObject = await options.data.createEvent(ctx, { eventId: ctx.state.params.eventId, principalId: ctx.state.params.principalId, calendarId: ctx.state.params.calendarId, - event: incoming, user: ctx.state.user }); log.debug('new event created'); /* https://tools.ietf.org/html/rfc4791#section-5.3.2 */ ctx.status = 201; - ctx.set('ETag', options.data.getETag(newObject)); + ctx.set('ETag', options.data.getETag(ctx, newObject)); } }; diff --git a/routes/calendar/calendar/sync-collection.js b/routes/calendar/calendar/sync-collection.js index 1e52cab..574ddad 100644 --- a/routes/calendar/calendar/sync-collection.js +++ b/routes/calendar/calendar/sync-collection.js @@ -19,9 +19,9 @@ module.exports = function (options) { const fullData = _.some(children, (child) => { return child.localName === 'calendar-data'; }); - const events = await options.data.getEventsForCalendar({ + const events = await options.data.getEventsForCalendar(ctx, { principalId: ctx.state.params.principalId, - calendarId: options.data.getCalendarId(calendar), + calendarId: options.data.getCalendarId(ctx, calendar), user: ctx.state.user, fullData }); diff --git a/routes/calendar/user/propfind.js b/routes/calendar/user/propfind.js index ad31b05..f8d7964 100644 --- a/routes/calendar/user/propfind.js +++ b/routes/calendar/user/propfind.js @@ -36,7 +36,7 @@ module.exports = function (options) { response(ctx.url, props.length > 0 ? status[200] : status[404], props) ]; - const calendars = await options.data.getCalendarsForPrincipal({ + const calendars = await options.data.getCalendarsForPrincipal(ctx, { principalId: ctx.state.params.principalId, user: ctx.state.user }); diff --git a/routes/principal/mkcalendar.js b/routes/principal/mkcalendar.js index 8fb96fd..4142702 100644 --- a/routes/principal/mkcalendar.js +++ b/routes/principal/mkcalendar.js @@ -62,8 +62,8 @@ module.exports = function (options) { // // - const calendarObject = await options.data.createCalendar(calendar); + const calendarObject = await options.data.createCalendar(ctx, calendar); ctx.status = 201; - ctx.set('ETag', options.data.getETag(calendarObject)); + ctx.set('ETag', options.data.getETag(ctx, calendarObject)); }; };