enable-backup-encryption.mjs (6469B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { html, ifDefined } from "chrome://global/content/vendor/lit.all.mjs"; 6 import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; 7 8 // eslint-disable-next-line import/no-unassigned-import 9 import "chrome://global/content/elements/moz-message-bar.mjs"; 10 // eslint-disable-next-line import/no-unassigned-import 11 import "chrome://browser/content/backup/password-validation-inputs.mjs"; 12 13 import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs"; 14 15 /** 16 * Valid attributes for the enable-backup-encryption dialog type. 17 * 18 * @see EnableBackupEncryption.type 19 */ 20 const VALID_TYPES = Object.freeze({ 21 SET_PASSWORD: "set-password", 22 CHANGE_PASSWORD: "change-password", 23 }); 24 25 const VALID_L10N_IDS = new Map([ 26 [VALID_TYPES.SET_PASSWORD, "enable-backup-encryption-header"], 27 [VALID_TYPES.CHANGE_PASSWORD, "change-backup-encryption-header"], 28 ]); 29 30 const ERROR_L10N_IDS = Object.freeze({ 31 [ERRORS.INVALID_PASSWORD]: "backup-error-password-requirements", 32 [ERRORS.UNKNOWN]: "backup-error-retry", 33 }); 34 35 /** 36 * @param {number} errorCode Error code from backup-constants.mjs 37 * @returns {string} Localization ID for error message 38 */ 39 function getErrorL10nId(errorCode) { 40 return ERROR_L10N_IDS[errorCode] ?? ERROR_L10N_IDS[ERRORS.UNKNOWN]; 41 } 42 43 /** 44 * The widget for enabling password protection if the backup is not yet 45 * encrypted. 46 */ 47 export default class EnableBackupEncryption extends MozLitElement { 48 static properties = { 49 // internal state 50 _inputPassValue: { type: String, state: true }, 51 _passwordsMatch: { type: Boolean, state: true }, 52 53 // passed from parents 54 supportBaseLink: { type: String }, 55 /** 56 * The "type" attribute changes the layout. 57 * 58 * @see VALID_TYPES 59 */ 60 type: { type: String, reflect: true }, 61 62 // managed by BackupUIChild 63 enableEncryptionErrorCode: { type: Number }, 64 }; 65 66 static get queries() { 67 return { 68 cancelButtonEl: "#backup-enable-encryption-cancel-button", 69 confirmButtonEl: "#backup-enable-encryption-confirm-button", 70 contentEl: "#backup-enable-encryption-content", 71 textHeaderEl: "#backup-enable-encryption-header", 72 textDescriptionEl: "#backup-enable-encryption-description", 73 passwordInputsEl: "#backup-enable-encryption-password-inputs", 74 errorEl: "#enable-backup-encryption-error", 75 }; 76 } 77 78 constructor() { 79 super(); 80 this.supportBaseLink = ""; 81 this.type = VALID_TYPES.SET_PASSWORD; 82 this._inputPassValue = ""; 83 this._passwordsMatch = false; 84 this.enableEncryptionErrorCode = 0; 85 } 86 87 connectedCallback() { 88 super.connectedCallback(); 89 // Listening to events from child <password-validation-inputs> 90 this.addEventListener("ValidPasswordsDetected", this); 91 this.addEventListener("InvalidPasswordsDetected", this); 92 } 93 94 handleEvent(event) { 95 if (event.type == "ValidPasswordsDetected") { 96 let { password } = event.detail; 97 this._passwordsMatch = true; 98 this._inputPassValue = password; 99 } else if (event.type == "InvalidPasswordsDetected") { 100 this._passwordsMatch = false; 101 this._inputPassValue = ""; 102 } 103 } 104 105 close() { 106 this.dispatchEvent( 107 new CustomEvent("dialogCancel", { 108 bubbles: true, 109 composed: true, 110 }) 111 ); 112 } 113 114 reset() { 115 this._inputPassValue = ""; 116 this._passwordsMatch = false; 117 this.passwordInputsEl.reset(); 118 this.enableEncryptionErrorCode = 0; 119 } 120 121 handleConfirm() { 122 this.dispatchEvent( 123 new CustomEvent("BackupUI:EnableEncryption", { 124 bubbles: true, 125 detail: { 126 password: this._inputPassValue, 127 }, 128 }) 129 ); 130 } 131 132 descriptionTemplate() { 133 return html` 134 <div id="backup-enable-encryption-description"> 135 <span 136 id="backup-enable-encryption-description-span" 137 data-l10n-id="settings-sensitive-data-encryption-description" 138 > 139 </span> 140 <a 141 id="backup-enable-encryption-learn-more-link" 142 is="moz-support-link" 143 support-page="firefox-backup" 144 data-l10n-id="enable-backup-encryption-support-link" 145 utm-content="add-password" 146 ></a> 147 </div> 148 `; 149 } 150 151 buttonGroupTemplate() { 152 return html` 153 <moz-button-group id="backup-enable-encryption-button-group"> 154 <moz-button 155 id="backup-enable-encryption-cancel-button" 156 @click=${this.close} 157 data-l10n-id="enable-backup-encryption-cancel-button" 158 ></moz-button> 159 <moz-button 160 id="backup-enable-encryption-confirm-button" 161 @click=${this.handleConfirm} 162 type="primary" 163 data-l10n-id="enable-backup-encryption-confirm-button" 164 ?disabled=${!this._passwordsMatch} 165 ></moz-button> 166 </moz-button-group> 167 `; 168 } 169 170 errorTemplate() { 171 let messageId = getErrorL10nId(this.enableEncryptionErrorCode); 172 return html` 173 <moz-message-bar 174 id="enable-backup-encryption-error" 175 type="error" 176 .messageL10nId=${messageId} 177 ></moz-message-bar> 178 `; 179 } 180 181 contentTemplate() { 182 return html` 183 <div 184 id="backup-enable-encryption-wrapper" 185 aria-labelledby="backup-enable-encryption-header" 186 aria-describedby="backup-enable-encryption-description" 187 > 188 <h1 189 id="backup-enable-encryption-header" 190 class="heading-medium" 191 data-l10n-id=${ifDefined(VALID_L10N_IDS.get(this.type))} 192 ></h1> 193 <div id="backup-enable-encryption-content"> 194 ${this.type === VALID_TYPES.SET_PASSWORD 195 ? this.descriptionTemplate() 196 : null} 197 <password-validation-inputs 198 id="backup-enable-encryption-password-inputs" 199 .supportBaseLink=${this.supportBaseLink} 200 > 201 </password-validation-inputs> 202 203 ${this.enableEncryptionErrorCode ? this.errorTemplate() : null} 204 </div> 205 ${this.buttonGroupTemplate()} 206 </div> 207 `; 208 } 209 210 render() { 211 return html` 212 <link 213 rel="stylesheet" 214 href="chrome://browser/content/backup/enable-backup-encryption.css" 215 /> 216 ${this.contentTemplate()} 217 `; 218 } 219 } 220 221 customElements.define("enable-backup-encryption", EnableBackupEncryption);