fune/browser/components/preferences/fxaPairDevice.js
Cristian Tuns b3bf09cc0d Backed out 6 changesets (bug 1816934, bug 1817182, bug 1817179, bug 1817183) for causing dt failures in browser_jsterm_autocomplete_null.js CLOSED TREE
Backed out changeset 17d4c013ed92 (bug 1817183)
Backed out changeset cfed8d9c23f3 (bug 1817183)
Backed out changeset 62fe2f589efe (bug 1817182)
Backed out changeset 557bd773fb85 (bug 1817179)
Backed out changeset 7f8a7865868b (bug 1816934)
Backed out changeset d6c1d4c0d2a0 (bug 1816934)
2023-02-17 10:51:33 -05:00

146 lines
4.8 KiB
JavaScript

// 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 { XPCOMUtils } = ChromeUtils.importESModule(
"resource://gre/modules/XPCOMUtils.sys.mjs"
);
const { FxAccounts } = ChromeUtils.import(
"resource://gre/modules/FxAccounts.jsm"
);
const { Weave } = ChromeUtils.importESModule(
"resource://services-sync/main.sys.mjs"
);
ChromeUtils.defineESModuleGetters(this, {
EventEmitter: "resource://gre/modules/EventEmitter.sys.mjs",
});
XPCOMUtils.defineLazyModuleGetters(this, {
FxAccountsPairingFlow: "resource://gre/modules/FxAccountsPairing.jsm",
});
const { require } = ChromeUtils.importESModule(
"resource://devtools/shared/loader/Loader.sys.mjs"
);
const QR = require("devtools/shared/qrcode/index");
// This is only for "labor illusion", see
// https://www.fastcompany.com/3061519/the-ux-secret-that-will-ruin-apps-for-you
const MIN_PAIRING_LOADING_TIME_MS = 1000;
/**
* Communication between FxAccountsPairingFlow and gFxaPairDeviceDialog
* is done using an emitter via the following messages:
* <- [view:SwitchToWebContent] - Notifies the view to navigate to a specific URL.
* <- [view:Error] - Notifies the view something went wrong during the pairing process.
* -> [view:Closed] - Notifies the pairing module the view was closed.
*/
var gFxaPairDeviceDialog = {
init() {
this._resetBackgroundQR();
// We let the modal show itself before eventually showing a primary-password dialog later.
Services.tm.dispatchToMainThread(() => this.startPairingFlow());
},
uninit() {
// When the modal closes we want to remove any query params
// To prevent refreshes/restores from reopening the dialog
const browser = window.docShell.chromeEventHandler;
browser.loadURI(Services.io.newURI("about:preferences#sync"), {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
this.teardownListeners();
this._emitter.emit("view:Closed");
},
async startPairingFlow() {
this._resetBackgroundQR();
document
.getElementById("qrWrapper")
.setAttribute("pairing-status", "loading");
this._emitter = new EventEmitter();
this.setupListeners();
try {
if (!Weave.Utils.ensureMPUnlocked()) {
throw new Error("Master-password locked.");
}
// To keep consistent with our accounts.firefox.com counterpart
// we restyle the parent dialog this is contained in
this._styleParentDialog();
const [, uri] = await Promise.all([
new Promise(res => setTimeout(res, MIN_PAIRING_LOADING_TIME_MS)),
FxAccountsPairingFlow.start({ emitter: this._emitter }),
]);
const imgData = QR.encodeToDataURI(uri, "L");
document.getElementById(
"qrContainer"
).style.backgroundImage = `url("${imgData.src}")`;
document
.getElementById("qrWrapper")
.setAttribute("pairing-status", "ready");
} catch (e) {
this.onError(e);
}
},
_styleParentDialog() {
// Since the dialog title is in the above document, we can't query the
// document in this level and need to go up one
let dialogParent = window.parent.document;
// To allow the firefox icon to go over the dialog
let dialogBox = dialogParent.querySelector(".dialogBox");
dialogBox.style.overflow = "visible";
dialogBox.style.borderRadius = "12px";
let dialogTitle = dialogParent.querySelector(".dialogTitleBar");
dialogTitle.style.borderBottom = "none";
dialogTitle.classList.add("fxaPairDeviceIcon");
},
_resetBackgroundQR() {
// The text we encode doesn't really matter as it is un-scannable (blurry and very transparent).
const imgData = QR.encodeToDataURI(
"https://accounts.firefox.com/pair",
"L"
);
document.getElementById(
"qrContainer"
).style.backgroundImage = `url("${imgData.src}")`;
},
onError(err) {
console.error(err);
this.teardownListeners();
document
.getElementById("qrWrapper")
.setAttribute("pairing-status", "error");
},
_switchToUrl(url) {
const browser = window.docShell.chromeEventHandler;
browser.fixupAndLoadURIString(url, {
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
{}
),
});
},
setupListeners() {
this._switchToWebContent = (_, url) => this._switchToUrl(url);
this._onError = (_, error) => this.onError(error);
this._emitter.once("view:SwitchToWebContent", this._switchToWebContent);
this._emitter.on("view:Error", this._onError);
},
teardownListeners() {
try {
this._emitter.off("view:SwitchToWebContent", this._switchToWebContent);
this._emitter.off("view:Error", this._onError);
} catch (e) {
console.warn("Error while tearing down listeners.", e);
}
},
};