diff --git a/calendar/experiments/calendar/parent/ext-calendar-provider.js b/calendar/experiments/calendar/parent/ext-calendar-provider.js index b1d2a68..a5f6e3d 100644 --- a/calendar/experiments/calendar/parent/ext-calendar-provider.js +++ b/calendar/experiments/calendar/parent/ext-calendar-provider.js @@ -131,42 +131,17 @@ class ExtCalendarProvider extends cal.provider.BaseClass { scheme = "mailto"; async sendItems(aRecipients, aItipItem) { - let responseMethod = aItipItem.responseMethod; let transport = super.getProperty("itip.transport").wrappedJSObject; let { subject, body } = transport._prepareItems(aItipItem); - let serializer = Cc["@mozilla.org/calendar/ics-serializer;1"].createInstance(Ci.calIIcsSerializer); - let itemList = aItipItem.getItemList(); - serializer.addItems(itemList, itemList.length); - let methodProp = cal.getIcsService().createIcalProperty("METHOD"); - methodProp.value = responseMethod; - serializer.addProperty(methodProp); - let icsText = serializer.serializeToString(); - let boundary = Array.from({ length: 24 }, () => Math.floor(Math.random() * 16).toString(16)).join(""); - let headers = new Map(); - headers.set("Date", [new Date()]); - headers.set("Subject", [subject]); - headers.set("To", aRecipients.map(attendee => ({ name: attendee.commonName, email: attendee.id.replace(/^mailto:/, "")}))); - headers.set("Content-Type", ["multipart/mixed; boundary=\"" + boundary + "\""]); - let mimeContent = jsmime.headeremitter.emitStructuredHeaders(headers, { hardMargin: 800 }) + "\r\n"; - mimeContent += "--" + boundary + "\r\n"; - mimeContent += "Content-Type: text/plain; charset=UTF-8\r\n\r\n"; - mimeContent += body + "\r\n"; - mimeContent += "--" + boundary + "\r\n"; - mimeContent += "Content-Type: text/calendar; method=" + responseMethod + "; charset=UTF-8\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n"; - mimeContent += icsText; - mimeContent += "--" + boundary + "\r\n"; - mimeContent += "Content-Type: application/ics; name=\"invite.ics\"\r\nContent-Disposition: attachment; filename=\"invite.ics\"\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n"; - mimeContent += icsText; - mimeContent += "--" + boundary + "--\r\n"; - let recipients = aRecipients.map(attendee => attendee.id.replace(/^mailto:/, "")); - let responses = await this.extension.emit("calendar.provider.onBeforeSend", this, { responseMethod, recipients, subject, body, icsText, mimeContent }); + let recipients = aRecipients.map(attendee => ({ name: attendee.commonName, email: attendee.id.replace(/^mailto:/, "")})); + let responses = await this.extension.emit("calendar.provider.onBeforeSend", this, aItipItem, { recipients, subject, body }); for (let response of responses) { if (response === true) { return; } if (Array.isArray(response?.recipients)) { for (let recipient of response.recipients) { - aRecipients = aRecipients.filter(attendee => attendee.id.replace(/^mailto:/, "") != recipient); + aRecipients = aRecipients.filter(attendee => attendee.id.replace(/^mailto:/, "") != recipient.email); } } } @@ -509,8 +484,41 @@ this.calendar_provider = class extends ExtensionAPI { onBeforeSend: new EventManager({ context, name: "calendar.provider.onBeforeSend", - register: fire => { - let listener = (event, calendar, content) => { + register: (fire, options) => { + let listener = (event, calendar, itipItem, content) => { + content.responseMethod = itipItem.responseMethod; + if (["ics", "mime"].includes(options?.returnFormat)) { + let serializer = Cc["@mozilla.org/calendar/ics-serializer;1"].createInstance(Ci.calIIcsSerializer); + serializer.addItems(itipItem.getItemList()); + let methodProp = cal.getIcsService().createIcalProperty("METHOD"); + methodProp.value = content.responseMethod; + serializer.addProperty(methodProp); + let icsText = serializer.serializeToString(); + if (options.returnFormat == "mime") { + let boundary = Array.from({ length: 24 }, () => Math.floor(Math.random() * 16).toString(16)).join(""); + let headers = new Map(); + headers.set("Date", [new Date()]); + headers.set("Subject", [content.subject]); + headers.set("To", content.recipients); + headers.set("Content-Type", ["multipart/mixed; boundary=\"" + boundary + "\""]); + let mimeContent = jsmime.headeremitter.emitStructuredHeaders(headers, { hardMargin: 800 }) + "\r\n"; + mimeContent += "--" + boundary + "\r\n"; + mimeContent += "Content-Type: text/plain; charset=UTF-8\r\n\r\n"; + mimeContent += content.body + "\r\n"; + mimeContent += "--" + boundary + "\r\n"; + mimeContent += "Content-Type: text/calendar; method=" + content.responseMethod + "; charset=UTF-8\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n"; + mimeContent += icsText; + mimeContent += "--" + boundary + "\r\n"; + mimeContent += "Content-Type: application/ics; name=\"invite.ics\"\r\nContent-Disposition: attachment; filename=\"invite.ics\"\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n"; + mimeContent += icsText; + mimeContent += "--" + boundary + "--\r\n"; + content.mimeContent = mimeContent; + } else { + content.icsText = icsText; + } + } else { + content.items = itipItem.getItemList().map(item => convertItem(item, options, context.extension)); + } return fire.async(convertCalendar(context.extension, calendar), content); }; diff --git a/calendar/experiments/calendar/schema/calendar-provider.json b/calendar/experiments/calendar/schema/calendar-provider.json index 70e3659..20ac293 100644 --- a/calendar/experiments/calendar/schema/calendar-provider.json +++ b/calendar/experiments/calendar/schema/calendar-provider.json @@ -93,15 +93,38 @@ "parameters": [ { "name": "calendar", "$ref": "calendar.calendars.Calendar" }, { - "name": "mimeContent", + "name": "content", "type": "object", "properties": { "responseMethod": { "type": "string" }, - "recipients": { "type": "array", "items": { "type": "string" } }, + "recipients": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "email": { "type": "string" } + } + } + }, "subject": { "type": "string" }, "body": { "type": "string" }, - "icsText": { "type": "string" }, - "mimeContent": { "type": "string" } + "items": { "type": "array", "items": { "$ref": "calendar.items.CalendarItem" }, "optional": true }, + "icsText": { "type": "string", "optional": true }, + "mimeContent": { "type": "string", "optional": true } + } + } + ], + "extraParameters": [ + { + "type": "object", + "optional": true, + "properties": { + "returnFormat": { + "optional": true, + "type": "string", + "enum": ["ical", "jcal", "ics", "mime"] + } } } ]