caldav-adapter 9.3.9 → 9.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/common/tags.js +55 -11
  2. package/index.js +14 -11
  3. package/package.json +1 -1
package/common/tags.js CHANGED
@@ -516,7 +516,29 @@ module.exports = function (options) {
516
516
  // https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-pubsubdiscovery.txt
517
517
  doc: 'https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-pubsubdiscovery.txt',
518
518
  async resp({ resource, calendar, ctx }) {
519
- if (resource !== 'principal' && resource !== 'calendar') return;
519
+ //
520
+ // Apple's caldav-pubsubdiscovery.txt places <CS:push-transports>
521
+ // on the principal AND on the calendar-home (see the spec's
522
+ // examples which target the calendar-home-set, and the Cyrus
523
+ // implementation in imap/http_caldav.c which advertises it on
524
+ // the home). In this adapter, the calendar-home resource is
525
+ // named `calCollection` (see routes/calendar/user/propfind.js),
526
+ // the per-collection resource is `calendar`, and the principal
527
+ // resource is `principal`.
528
+ //
529
+ // Previously this guard accepted only `principal` and `calendar`,
530
+ // which meant iOS Calendar (which queries push-transports on the
531
+ // calendar-home, NOT on individual collections) never saw the
532
+ // advertisement and consequently never POST'd to the subscription
533
+ // URL to register for push notifications. We now also accept
534
+ // `calCollection`.
535
+ //
536
+ if (
537
+ resource !== 'principal' &&
538
+ resource !== 'calendar' &&
539
+ resource !== 'calCollection'
540
+ )
541
+ return;
520
542
  if (typeof options.pushTopicProvider !== 'function') return;
521
543
  let topic;
522
544
  try {
@@ -560,17 +582,39 @@ module.exports = function (options) {
560
582
  pushkey: {
561
583
  // https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-pubsubdiscovery.txt
562
584
  doc: 'https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-pubsubdiscovery.txt',
563
- async resp({ resource, calendar }) {
564
- if (resource !== 'calendar' || !calendar) return;
585
+ async resp({ resource, calendar, ctx }) {
565
586
  if (typeof options.pushTopicProvider !== 'function') return;
566
- // pushkey is the opaque per-collection identifier iOS sends back
567
- // in /apns POST so we can map device_token -> calendar.
568
- const key =
569
- calendar.calendarId ||
570
- (calendar._id &&
571
- calendar._id.toString &&
572
- calendar._id.toString()) ||
573
- '';
587
+ //
588
+ // Per Apple's caldav-pubsubdiscovery.txt the calendar-home itself
589
+ // also exposes a <CS:pushkey> covering home-level changes
590
+ // (calendar add/delete, principal property changes). iOS
591
+ // subscribes to that key so it can react to home-level mutations
592
+ // without having to subscribe to every individual calendar.
593
+ //
594
+ // We use the calendar identifier as the per-collection key and
595
+ // the principal id as the home-level key. These opaque values
596
+ // are echoed back to us by iOS in the /apns POST/GET, allowing
597
+ // us to map (device_token, key) -> (user, calendar|home).
598
+ //
599
+ let key;
600
+ if (resource === 'calendar' && calendar) {
601
+ key =
602
+ calendar.calendarId ||
603
+ (calendar._id &&
604
+ calendar._id.toString &&
605
+ calendar._id.toString()) ||
606
+ '';
607
+ } else if (resource === 'calCollection') {
608
+ key =
609
+ (ctx &&
610
+ ctx.state &&
611
+ ctx.state.params &&
612
+ ctx.state.params.principalId) ||
613
+ '';
614
+ } else {
615
+ return;
616
+ }
617
+
574
618
  if (!key) return;
575
619
  return {
576
620
  [buildTag(cs, 'pushkey')]: key
package/index.js CHANGED
@@ -44,17 +44,20 @@ module.exports = function (options) {
44
44
  principalRegex.keys
45
45
  );
46
46
 
47
- const calendarRoutes = cal({
48
- logEnabled: options.logEnabled,
49
- logLevel: options.logLevel,
50
- data: options.data
51
- });
52
-
53
- const principalRoutes = pri({
54
- logEnabled: options.logEnabled,
55
- logLevel: options.logLevel,
56
- data: options.data
57
- });
47
+ //
48
+ // IMPORTANT: forward the *entire* options object (not just `data`,
49
+ // `logEnabled`, and `logLevel`) so that downstream tag handlers
50
+ // (common/tags.js) receive `pushTopicProvider`, `pushSubscriptionURL`,
51
+ // `pushEnv`, and `pushRefreshInterval`. Without this, iOS Calendar
52
+ // never sees the <CS:push-transports> advertisement on the calendar
53
+ // home and never POSTs to /apns to register for silent push (the
54
+ // tags handler short-circuits via `typeof options.pushTopicProvider
55
+ // !== 'function'`). See Apple's caldav-pubsubdiscovery.txt:
56
+ // https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-pubsubdiscovery.txt
57
+ //
58
+ const calendarRoutes = cal(options);
59
+
60
+ const principalRoutes = pri(options);
58
61
 
59
62
  const fillParameters = function (ctx) {
60
63
  ctx.state.params = {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "caldav-adapter",
3
3
  "description": "CalDAV server for Node.js and Koa. Modernized and maintained for Forward Email.",
4
- "version": "9.3.9",
4
+ "version": "9.3.11",
5
5
  "author": "Sanders DeNardi and Forward Email LLC",
6
6
  "contributors": [
7
7
  "Sanders DeNardi <sedenardi@gmail.com> (http://www.sandersdenardi.com/)",