summaryrefslogtreecommitdiffstats
path: root/comm/calendar/itip/CalItipOutgoingMessage.jsm
blob: f85374c4362166c2483c6478f0de3c415ee38d80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const EXPORTED_SYMBOLS = ["CalItipOutgoingMessage"];

const { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");

/**
 * CalItipOutgoingMessage contains information needed for sending an outgoing
 * iTIP message via a calIItipTransport instance.
 */
class CalItipOutgoingMessage {
  /**
   * @param {string} method - The iTIP request method.
   * @param {calIAttendee[]} recipients - A list of attendees who will receive
   *                                      the message.
   * @param {calIEvent} item - The item the message relates to.
   * @param {?calIAttendee} sender - The attendee the message comes from for
   *                                 replies.
   * @param {?object} autoResponse - The inout object whether the transport
   *                                 should ask before sending
   */
  constructor(method, recipients, item, sender, autoResponse) {
    this.method = method;
    this.recipients = recipients;
    this.item = item;
    this.sender = sender;
    this.autoResponse = autoResponse;
  }

  /**
   * Sends the iTIP message using the item's calendar transport.
   *
   * @param {calIItipTransport} transport - The transport to use when sending.
   *
   * @returns {boolean} - True, if the message could be sent
   */
  send(transport) {
    if (this.item.calendar && this.item.calendar.supportsScheduling) {
      let calendar = this.item.calendar.getSchedulingSupport();
      if (calendar.canNotify(this.method, this.item)) {
        // provider will handle that, so we return - we leave it also to the provider to
        // deal with user canceled notifications (if possible), so set the return value
        // to true as false would prevent any further notification within this cycle
        return true;
      }
    }

    if (this.recipients.length == 0 || !transport) {
      return false;
    }

    let { method, sender, autoResponse } = this;
    let _sendItem = function (aSendToList, aSendItem) {
      let itipItem = Cc["@mozilla.org/calendar/itip-item;1"].createInstance(Ci.calIItipItem);
      itipItem.init(cal.item.serialize(aSendItem));
      itipItem.responseMethod = method;
      itipItem.targetCalendar = aSendItem.calendar;
      itipItem.autoResponse = autoResponse.mode;
      // we switch to AUTO for each subsequent call of _sendItem()
      autoResponse.mode = Ci.calIItipItem.AUTO;
      // XXX I don't know whether the below is used at all, since we don't use the itip processor
      itipItem.isSend = true;

      return transport.sendItems(aSendToList, itipItem, sender);
    };

    // split up transport, if attendee undisclosure is requested
    // and this is a message send by the organizer
    if (
      this.item.getProperty("X-MOZ-SEND-INVITATIONS-UNDISCLOSED") == "TRUE" &&
      this.method != "REPLY" &&
      this.method != "REFRESH" &&
      this.method != "COUNTER"
    ) {
      for (let recipient of this.recipients) {
        // create a list with a single recipient
        let sendToList = [recipient];
        // remove other recipients from vevent attendee list
        let sendItem = this.item.clone();
        sendItem.removeAllAttendees();
        sendItem.addAttendee(recipient);
        // send message
        if (!_sendItem(sendToList, sendItem)) {
          return false;
        }
      }
      return true;
    }
    return _sendItem(this.recipients, this.item);
  }
}