/** * The MIT License (MIT) * * Copyright (c) 2018-2019 Mailvelope GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /** * OpenPGPEncryptedForm custom HTMLElement */ class OpenPGPEncryptedForm extends HTMLElement { // Invoked when the custom element is first connected to the document's DOM. connectedCallback() { this.dispatchEvent(new Event('connected')); const id = this.getAttribute('id'); if (!id) { const error = new Error('No form id for openpgp-encrypted-tag. Please add a unique identifier.'); error.code = 'NO_FORM_ID'; return this.onError(error); } let html; const scriptTags = this.getElementsByTagName('script'); if (scriptTags.length) { html = scriptTags[0].innerText; } else { const error = new Error('No form template for openpgp-encrypted-tag. Please add a form template.'); error.code = 'NO_FORM_SCRIPT'; return this.onError(error); } window.mailvelope.createEncryptedFormContainer(`#${id}`, html, this.getAttribute('signature')) .then(data => this.onEncrypt(data), error => this.onError(error)); } onEncrypt(data) { this.dispatchEvent(new CustomEvent('encrypt', { detail: {armoredData: data.armoredData}, bubbles: true, cancelable: true })); } onError(error) { this.dispatchEvent(new ErrorEvent('error', { message: error.message, error })); } } class OpenPGPEmailRead extends HTMLElement { connectedCallback() { const id = this.getAttribute('id'); if (!id) { return this.onError(new Error('Missing id attribute on openpgp-email-read tag. Please add a unique identifier.')); } const [armoredElement] = this.getElementsByClassName('armored'); const armored = armoredElement ? armoredElement.textContent : this.dataset.armored; if (!armored) { return this.onError(new Error('Armored message required as <template class="armored"> child element or data-armored attribute.')); } const options = {senderAddress: this.dataset.senderAddress}; if (window.mailvelope) { this.createContainer(id, armored, options); } else { window.addEventListener('mailvelope', () => this.createContainer(id, armored, options), {once: true}); } } async createContainer(id, armored, options) { try { const {error} = await window.mailvelope.createDisplayContainer(`#${id}`, armored, null, options); if (error) { return this.onError(error); } this.onReady(); } catch (e) { this.onError(e); } } onReady() { this.dispatchEvent(new CustomEvent('ready', {bubbles: true, cancelable: true})); } onError(error) { this.dispatchEvent(new ErrorEvent('error', {message: error.message, error})); } } class OpenPGPEmailWrite extends HTMLElement { connectedCallback() { const id = this.getAttribute('id'); if (!id) { return this.onError(new Error('Missing id attribute on openpgp-email-write tag. Please add a unique identifier.')); } const [armoredDraftElement] = this.getElementsByClassName('armored-draft'); const armoredDraft = armoredDraftElement ? armoredDraftElement.textContent : undefined; const [quotedMailElement] = this.getElementsByClassName('quoted-mail'); const quotedMail = quotedMailElement ? quotedMailElement.textContent : undefined; let {quota, signMsg, keepAttachments} = this.dataset; quota = quota ? Number(quota) : undefined; signMsg = signMsg || signMsg === '' ? true : false; keepAttachments = keepAttachments || keepAttachments === '' ? true : false; const options = {armoredDraft, quotedMail, ...this.dataset, quota, signMsg, keepAttachments}; if (window.mailvelope) { this.createEditor(id, options); } else { window.addEventListener('mailvelope', () => this.createEditor(id, options), {once: true}); } } async createEditor(id, options) { try { this.editor = await window.mailvelope.createEditorContainer(`#${id}`, null, options); this.onReady(this.editor); } catch (e) { this.onError(e); } } onReady(editor) { this.dispatchEvent(new CustomEvent('ready', {bubbles: true, cancelable: true, detail: {editor}})); } onError(error) { this.dispatchEvent(new ErrorEvent('error', {message: error.message, error})); } } export function init() { // See. https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements#Specification#Browser_compatibility if (!window.customElements) { return; } window.customElements.define('openpgp-encrypted-form', OpenPGPEncryptedForm); window.customElements.define('openpgp-email-read', OpenPGPEmailRead); window.customElements.define('openpgp-email-write', OpenPGPEmailWrite); }