mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Backed out 2 changesets (bug 1650675) for browser-chrome failures in browser/components/aboutlogins/tests/browser/browser_openImport.js. CLOSED TREE
Backed out changeset 6b9b5c6906b8 (bug 1650675) Backed out changeset 8e281a982040 (bug 1650675)
This commit is contained in:
parent
a68bdd9d7c
commit
cc59ccf077
@ -390,10 +390,23 @@ class AboutLoginsParent extends JSWindowActorParent {
|
||||
break;
|
||||
}
|
||||
case "AboutLogins:ImportPasswords": {
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(
|
||||
Ci.nsIFilePicker
|
||||
);
|
||||
async function fpCallback(aResult) {
|
||||
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||
await LoginCSVImport.importFromCSV(fp.file.path);
|
||||
Services.telemetry.recordEvent(
|
||||
"pwmgr",
|
||||
"mgmt_menu_item_used",
|
||||
"import_csv_complete"
|
||||
);
|
||||
}
|
||||
}
|
||||
let [
|
||||
title,
|
||||
okButtonLabel,
|
||||
filterTitle,
|
||||
csvFilterTitle,
|
||||
] = await AboutLoginsL10n.formatValues([
|
||||
{
|
||||
id: "about-logins-import-file-picker-title",
|
||||
@ -405,23 +418,12 @@ class AboutLoginsParent extends JSWindowActorParent {
|
||||
id: "about-logins-import-file-picker-csv-filter-title",
|
||||
},
|
||||
]);
|
||||
let { result, path } = await this.openFilePickerDialog(
|
||||
title,
|
||||
okButtonLabel,
|
||||
filterTitle,
|
||||
"*.csv",
|
||||
ownerGlobal
|
||||
);
|
||||
|
||||
if (result != Ci.nsIFilePicker.returnCancel) {
|
||||
let summary = await LoginCSVImport.importFromCSV(path);
|
||||
this.sendAsyncMessage("AboutLogins:ImportPasswordsDialog", summary);
|
||||
Services.telemetry.recordEvent(
|
||||
"pwmgr",
|
||||
"mgmt_menu_item_used",
|
||||
"import_csv_complete"
|
||||
);
|
||||
}
|
||||
fp.init(ownerGlobal, title, Ci.nsIFilePicker.modeOpen);
|
||||
fp.appendFilter(csvFilterTitle, "*.csv");
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterAll);
|
||||
fp.okButtonLabel = okButtonLabel;
|
||||
fp.open(fpCallback);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -441,25 +443,6 @@ class AboutLoginsParent extends JSWindowActorParent {
|
||||
|
||||
this.sendAsyncMessage("AboutLogins:ShowLoginItemError", messageObject);
|
||||
}
|
||||
|
||||
async openFilePickerDialog(
|
||||
title,
|
||||
okButtonLabel,
|
||||
filterTitle,
|
||||
filterExtension,
|
||||
ownerGlobal
|
||||
) {
|
||||
return new Promise(resolve => {
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(ownerGlobal, title, Ci.nsIFilePicker.modeOpen);
|
||||
fp.appendFilter(filterTitle, filterExtension);
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterAll);
|
||||
fp.okButtonLabel = okButtonLabel;
|
||||
fp.open(async result => {
|
||||
resolve({ result, path: fp.file.path });
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var AboutLogins = {
|
||||
|
@ -13,7 +13,6 @@
|
||||
<link rel="localization" href="browser/branding/brandings.ftl">
|
||||
<link rel="localization" href="browser/aboutLogins.ftl">
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/confirmation-dialog.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/import-summary-dialog.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/fxaccounts-button.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/login-filter.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/login-intro.js"></script>
|
||||
@ -38,7 +37,6 @@
|
||||
<login-item></login-item>
|
||||
<login-intro></login-intro>
|
||||
<confirmation-dialog hidden></confirmation-dialog>
|
||||
<import-summary-dialog hidden></import-summary-dialog>
|
||||
<div id="master-password-required-overlay"></div>
|
||||
|
||||
<template id="confirmation-dialog-template">
|
||||
@ -63,38 +61,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="import-summary-dialog-template">
|
||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/import-summary-dialog.css">
|
||||
<div class="overlay">
|
||||
<div class="container" role="dialog" aria-labelledby="title">
|
||||
<img class="import-icon" src="chrome://browser/skin/import.svg"/>
|
||||
<h1 class="title" id="title" data-l10n-id="about-logins-import-dialog-title"></h1>
|
||||
<div class="content">
|
||||
<div class="import-summary">
|
||||
<div class="import-items-added import-items-row" data-l10n-id="about-logins-import-dialog-items-added" data-l10n-args='{"count": 0}'>
|
||||
<span data-l10n-name="count" class="result-count"></span>
|
||||
</div>
|
||||
<div class="import-items-modified import-items-row" data-l10n-id="about-logins-import-dialog-items-modified" data-l10n-args='{"count": 0}'>
|
||||
<span data-l10n-name="count" class="result-count"></span>
|
||||
</div>
|
||||
<div class="import-items-no-change import-items-row" data-l10n-id="about-logins-import-dialog-items-no-change" data-l10n-name="no-change" data-l10n-args='{"count": 0}'>
|
||||
<span data-l10n-name="count" class="result-count"></span>
|
||||
<span data-l10n-name="meta" class="result-meta"></span>
|
||||
</div>
|
||||
<div class="import-items-errors import-items-row" data-l10n-id="about-logins-import-dialog-items-error" data-l10n-args='{"count": 0}'>
|
||||
<span data-l10n-name="count" class="result-count"></span>
|
||||
<span data-l10n-name="meta" class="result-meta"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="import-separator"></div>
|
||||
<button class="import-done-button primary" data-l10n-id="about-logins-import-dialog-done"></button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="fxaccounts-button-template">
|
||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
|
||||
|
@ -112,14 +112,6 @@ window.addEventListener("AboutLoginsChromeToContent", event => {
|
||||
gElements.loginItem.updateVulnerableLogins(event.detail.value);
|
||||
break;
|
||||
}
|
||||
case "ImportPasswordsDialog": {
|
||||
let dialog = document.querySelector("import-summary-dialog");
|
||||
let options = {
|
||||
logins: event.detail.value,
|
||||
};
|
||||
dialog.show(options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,118 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
inset: 0;
|
||||
/* TODO: this color is used in the about:preferences overlay, but
|
||||
why isn't it declared as a variable? */
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.container {
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 30px auto 170px;
|
||||
grid-template-rows: 30px auto 20px 35px;
|
||||
grid-gap: 5px;
|
||||
align-items: center;
|
||||
width: 580px;
|
||||
height: 290px;
|
||||
padding: 50px 50px 20px;
|
||||
margin: auto;
|
||||
background-color: var(--in-content-page-background);
|
||||
color: var(--in-content-page-color);
|
||||
box-shadow: var(--shadow-30);
|
||||
/* show a border in high contrast mode */
|
||||
outline: 1px solid transparent;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.2em;
|
||||
font-weight: 300;
|
||||
user-select: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding: 16px 32px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.buttons.macosx > .confirm-button {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.buttons > button {
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
.import-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.import-summary {
|
||||
display: grid;
|
||||
grid-template-columns: max-content max-content max-content;
|
||||
}
|
||||
|
||||
.import-summary span,
|
||||
.import-summary b,
|
||||
.import-summary i {
|
||||
margin-block: 0 2px;
|
||||
margin-inline: 0 10px;
|
||||
}
|
||||
|
||||
.import-done-button {
|
||||
width: 170px;
|
||||
height: 30px;
|
||||
grid-column-start: 3;
|
||||
grid-row-start: 4;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
grid-column-start: 2;
|
||||
align-self: baseline;
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.dialog-body {
|
||||
padding-block: 40px 16px;
|
||||
padding-inline: 45px 32px;
|
||||
}
|
||||
|
||||
.import-separator {
|
||||
grid-column: 1 / 4;
|
||||
grid-row-start: 3;
|
||||
border-top: 1px solid var(--in-content-border-color);
|
||||
}
|
||||
|
||||
.import-items-row {
|
||||
grid-column: 1 / 4;
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
}
|
||||
|
||||
.result-count {
|
||||
text-align: end;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.result-meta {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.import-items-errors .result-meta {
|
||||
color: var(--dialog-warning-text-color);
|
||||
}
|
||||
|
@ -1,123 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
import { setKeyboardAccessForNonDialogElements } from "../aboutLoginsUtils.js";
|
||||
|
||||
export default class ImportSummaryDialog extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this._promise = null;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.shadowRoot) {
|
||||
return;
|
||||
}
|
||||
let template = document.querySelector("#import-summary-dialog-template");
|
||||
let shadowRoot = this.attachShadow({ mode: "open" });
|
||||
document.l10n.connectRoot(shadowRoot);
|
||||
shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
|
||||
this._dismissButton = this.shadowRoot.querySelector(".import-done-button");
|
||||
this._overlay = this.shadowRoot.querySelector(".overlay");
|
||||
|
||||
this._added = this.shadowRoot.querySelector(".import-items-added");
|
||||
this._modified = this.shadowRoot.querySelector(".import-items-modified");
|
||||
this._noChange = this.shadowRoot.querySelector(".import-items-no-change");
|
||||
this._error = this.shadowRoot.querySelector(".import-items-errors");
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "keydown":
|
||||
if (event.repeat) {
|
||||
// Prevent repeat keypresses from accidentally confirming the
|
||||
// dialog since the confirmation button is focused by default.
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (event.key === "Escape" && !event.defaultPrevented) {
|
||||
this.onCancel();
|
||||
}
|
||||
break;
|
||||
case "click":
|
||||
if (
|
||||
event.currentTarget.classList.contains("import-done-button") ||
|
||||
event.target.classList.contains("overlay")
|
||||
) {
|
||||
this.onCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hide() {
|
||||
setKeyboardAccessForNonDialogElements(true);
|
||||
this._dismissButton.removeEventListener("click", this);
|
||||
this._overlay.removeEventListener("click", this);
|
||||
window.removeEventListener("keydown", this);
|
||||
|
||||
this.hidden = true;
|
||||
}
|
||||
|
||||
show({ logins }) {
|
||||
const report = {
|
||||
added: 0,
|
||||
modified: 0,
|
||||
no_change: 0,
|
||||
error: 0,
|
||||
};
|
||||
for (let loginRow of logins) {
|
||||
if (loginRow.result.indexOf("error") > -1) {
|
||||
report.error++;
|
||||
} else {
|
||||
report[loginRow.result]++;
|
||||
}
|
||||
}
|
||||
this._updateCount(
|
||||
report.added,
|
||||
this._added,
|
||||
"about-logins-import-dialog-items-added"
|
||||
);
|
||||
this._updateCount(
|
||||
report.modified,
|
||||
this._modified,
|
||||
"about-logins-import-dialog-items-modified"
|
||||
);
|
||||
this._updateCount(
|
||||
report.no_change,
|
||||
this._noChange,
|
||||
"about-logins-import-dialog-items-no-change"
|
||||
);
|
||||
this._updateCount(
|
||||
report.error,
|
||||
this._error,
|
||||
"about-logins-import-dialog-items-error"
|
||||
);
|
||||
setKeyboardAccessForNonDialogElements(false);
|
||||
this.hidden = false;
|
||||
|
||||
this._dismissButton.addEventListener("click", this);
|
||||
this._overlay.addEventListener("click", this);
|
||||
window.addEventListener("keydown", this);
|
||||
|
||||
this._promise = new Promise((resolve, reject) => {
|
||||
this._resolve = resolve;
|
||||
this._reject = reject;
|
||||
});
|
||||
|
||||
return this._promise;
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this._reject();
|
||||
this.hide();
|
||||
}
|
||||
|
||||
_updateCount(count, component, message) {
|
||||
if (count != document.l10n.getAttributes(component).args.count) {
|
||||
document.l10n.setAttributes(component, message, { count });
|
||||
}
|
||||
}
|
||||
}
|
||||
customElements.define("import-summary-dialog", ImportSummaryDialog);
|
@ -71,7 +71,7 @@
|
||||
}
|
||||
|
||||
.menuitem-import-file {
|
||||
background-image: url("chrome://browser/skin/import.svg");
|
||||
background-image: url("chrome://browser/skin/open.svg");
|
||||
}
|
||||
|
||||
.menuitem-export {
|
||||
|
@ -5,8 +5,6 @@
|
||||
browser.jar:
|
||||
content/browser/aboutlogins/components/confirmation-dialog.css (content/components/confirmation-dialog.css)
|
||||
content/browser/aboutlogins/components/confirmation-dialog.js (content/components/confirmation-dialog.js)
|
||||
content/browser/aboutlogins/components/import-summary-dialog.css (content/components/import-summary-dialog.css)
|
||||
content/browser/aboutlogins/components/import-summary-dialog.js (content/components/import-summary-dialog.js)
|
||||
content/browser/aboutlogins/components/fxaccounts-button.css (content/components/fxaccounts-button.css)
|
||||
content/browser/aboutlogins/components/fxaccounts-button.js (content/components/fxaccounts-button.js)
|
||||
content/browser/aboutlogins/components/login-filter.css (content/components/login-filter.css)
|
||||
|
@ -5,22 +5,7 @@ let { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
|
||||
let { MockFilePicker } = SpecialPowers;
|
||||
|
||||
function waitForFilePicker() {
|
||||
return new Promise(resolve => {
|
||||
MockFilePicker.showCallback = () => {
|
||||
MockFilePicker.showCallback = null;
|
||||
ok(true, "Saw the file picker");
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function setup() {
|
||||
MockFilePicker.init(window);
|
||||
MockFilePicker.useAnyFile();
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
await TestUtils.waitForCondition(() => {
|
||||
Services.telemetry.clearEvents();
|
||||
let events = Services.telemetry.snapshotEvents(
|
||||
@ -36,7 +21,6 @@ add_task(async function setup() {
|
||||
});
|
||||
registerCleanupFunction(() => {
|
||||
BrowserTestUtils.removeTab(aboutLoginsTab);
|
||||
MockFilePicker.cleanup();
|
||||
});
|
||||
});
|
||||
|
||||
@ -64,24 +48,6 @@ add_task(async function test_open_import() {
|
||||
let importWindow = await promiseImportWindow;
|
||||
ok(true, "Import opened");
|
||||
|
||||
let filePicker = waitForFilePicker();
|
||||
info("waiting for Import file picker to get opened");
|
||||
await filePicker;
|
||||
ok(true, "Import file picker opened");
|
||||
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
() => {
|
||||
let confirmExportDialog = window.document.querySelector(
|
||||
"import-summary-dialog"
|
||||
);
|
||||
return confirmExportDialog.shadowRoot.querySelector(
|
||||
".import-done-button"
|
||||
);
|
||||
},
|
||||
{},
|
||||
browser
|
||||
);
|
||||
|
||||
// First event is for opening about:logins
|
||||
await LoginTestUtils.telemetry.waitForEventCount(2);
|
||||
TelemetryTestUtils.assertEvents(
|
||||
|
@ -164,9 +164,6 @@ about-logins-confirm-export-dialog-title = Export logins and passwords
|
||||
about-logins-confirm-export-dialog-message = Your passwords will be saved as readable text (e.g., BadP@ssw0rd) so anyone who can open the exported file can view them.
|
||||
about-logins-confirm-export-dialog-confirm-button = Export…
|
||||
|
||||
about-logins-alert-import-title = Import Complete
|
||||
about-logins-alert-import-message = View detailed import summary
|
||||
|
||||
confirm-discard-changes-dialog-title = Discard unsaved changes?
|
||||
confirm-discard-changes-dialog-message = All unsaved changes will be lost.
|
||||
confirm-discard-changes-dialog-confirm-button = Discard
|
||||
@ -230,34 +227,3 @@ about-logins-import-file-picker-csv-filter-title =
|
||||
[macos] CSV Document
|
||||
*[other] CSV File
|
||||
}
|
||||
|
||||
##
|
||||
## Variables:
|
||||
## $count (number) - The number of affected elements
|
||||
|
||||
about-logins-import-dialog-title = Import Complete
|
||||
about-logins-import-dialog-items-added =
|
||||
{ $count ->
|
||||
[one] <span>New login added:</span> <span data-l10n-name="count">{ $count }</span>
|
||||
*[other] <span>New logins added:</span> <span data-l10n-name="count">{ $count }</span>
|
||||
}
|
||||
|
||||
about-logins-import-dialog-items-modified =
|
||||
{ $count ->
|
||||
[one] <span>Existing login updated:</span> <span data-l10n-name="count">{ $count }</span>
|
||||
*[other] <span>Existing logins updated:</span> <span data-l10n-name="count">{ $count }</span>
|
||||
}
|
||||
|
||||
about-logins-import-dialog-items-no-change =
|
||||
{ $count ->
|
||||
[0] Duplicate logins found: <span data-l10n-name="count">{ $count }</span> <span data-l10n-name="meta"></span>
|
||||
[one] Duplicate login found: <span data-l10n-name="count">{ $count }</span> <span data-l10n-name="meta">(not imported)</span>
|
||||
*[other] Duplicate logins found: <span data-l10n-name="count">{ $count }</span> <span data-l10n-name="meta">(not imported)</span>
|
||||
}
|
||||
about-logins-import-dialog-items-error =
|
||||
{ $count ->
|
||||
[0] Errors: <span data-l10n-name="count">{ $count }</span> <span data-l10n-name="meta"></span>
|
||||
[one] Error: <span data-l10n-name="count">{ $count }</span> <span data-l10n-name="meta">(not imported)</span>
|
||||
*[other] Errors: <span data-l10n-name="count">{ $count }</span> <span data-l10n-name="meta">(not imported)</span>
|
||||
}
|
||||
about-logins-import-dialog-done = Done
|
||||
|
@ -147,7 +147,7 @@ class LoginCSVImport {
|
||||
);
|
||||
});
|
||||
|
||||
let summary = await LoginHelper.maybeImportLogins(loginsToImport);
|
||||
await LoginHelper.maybeImportLogins(loginsToImport);
|
||||
|
||||
// Record quantity, jank, and duration telemetry.
|
||||
try {
|
||||
@ -165,6 +165,5 @@ class LoginCSVImport {
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
}
|
||||
|
@ -992,7 +992,6 @@ this.LoginHelper = {
|
||||
* @returns {nsILoginInfo[]} the newly added logins, filtered if no login was added.
|
||||
*/
|
||||
async maybeImportLogins(loginDatas) {
|
||||
let summary = [];
|
||||
let loginsToAdd = [];
|
||||
let loginMap = new Map();
|
||||
for (let rawLoginData of loginDatas) {
|
||||
@ -1000,18 +999,6 @@ this.LoginHelper = {
|
||||
let loginData = ChromeUtils.shallowClone(rawLoginData);
|
||||
loginData.origin = this.getLoginOrigin(loginData.origin);
|
||||
if (!loginData.origin) {
|
||||
summary.push({
|
||||
result: "error_invalid_origin",
|
||||
login: { ...loginData },
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!loginData.password) {
|
||||
summary.push({
|
||||
result: "error_invalid_password",
|
||||
login: { ...loginData },
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1042,21 +1029,8 @@ this.LoginHelper = {
|
||||
// Use a property bag rather than an nsILoginInfo so we don't clobber
|
||||
// properties that the import source doesn't provide.
|
||||
let propBag = this.newPropertyBag(loginData);
|
||||
if (
|
||||
loginData.username !== existingLogin.username ||
|
||||
loginData.password !== existingLogin.password ||
|
||||
loginData.httpRealm !== existingLogin.httpRealm ||
|
||||
loginData.formActionOrigin !== existingLogin.formActionOrigin ||
|
||||
`${loginData.timeCreated}` !== `${existingLogin.timeCreated}` ||
|
||||
`${loginData.timePasswordChanged}` !==
|
||||
`${existingLogin.timePasswordChanged}`
|
||||
) {
|
||||
summary.push({ result: "modified", login: { ...existingLogin } });
|
||||
Services.logins.modifyLogin(existingLogin, propBag);
|
||||
// Updated a login so we're done.
|
||||
} else {
|
||||
summary.push({ result: "no_change", login: { ...existingLogin } });
|
||||
}
|
||||
Services.logins.modifyLogin(existingLogin, propBag);
|
||||
// Updated a login so we're done.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1088,10 +1062,6 @@ this.LoginHelper = {
|
||||
// out from the bulk APIs below us.
|
||||
this.checkLoginValues(login);
|
||||
} catch (e) {
|
||||
summary.push({
|
||||
result: "error",
|
||||
login: { ...loginData },
|
||||
});
|
||||
Cu.reportError(e);
|
||||
continue;
|
||||
}
|
||||
@ -1104,7 +1074,6 @@ this.LoginHelper = {
|
||||
loginMap.set(login.origin, newLogins);
|
||||
} else {
|
||||
if (newLogins.some(l => login.matches(l, false /* ignorePassword */))) {
|
||||
summary.push({ result: "no_change", login });
|
||||
continue;
|
||||
}
|
||||
let foundMatchingNewLogin = false;
|
||||
@ -1125,7 +1094,6 @@ this.LoginHelper = {
|
||||
}
|
||||
|
||||
if (foundMatchingNewLogin) {
|
||||
summary.push({ result: "no_change", login });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1142,7 +1110,6 @@ this.LoginHelper = {
|
||||
if (
|
||||
existingLogins.some(l => login.matches(l, false /* ignorePassword */))
|
||||
) {
|
||||
summary.push({ result: "no_change", login });
|
||||
continue;
|
||||
}
|
||||
// Now check for a login with the same username, where it may be that we have an
|
||||
@ -1166,26 +1133,22 @@ this.LoginHelper = {
|
||||
"timePasswordChanged",
|
||||
login.timePasswordChanged
|
||||
);
|
||||
summary.push({ result: "modified", login: { ...existingLogin } });
|
||||
Services.logins.modifyLogin(existingLogin, propBag);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the new login is an update or is older than an exiting login, don't add it.
|
||||
if (foundMatchingLogin) {
|
||||
summary.push({ result: "no_change", login: { login } });
|
||||
continue;
|
||||
}
|
||||
|
||||
newLogins.push(login);
|
||||
loginsToAdd.push(login);
|
||||
}
|
||||
if (loginsToAdd.length) {
|
||||
let addedLogins = await Services.logins.addLogins(loginsToAdd);
|
||||
for (let addedLogin of addedLogins) {
|
||||
summary.push({ result: "added", login: { ...addedLogin } });
|
||||
}
|
||||
if (!loginsToAdd.length) {
|
||||
return [];
|
||||
}
|
||||
return summary;
|
||||
return Services.logins.addLogins(loginsToAdd);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -10,13 +10,8 @@ const PASS1 = "mypass";
|
||||
const PASS2 = "anotherpass";
|
||||
const PASS3 = "yetanotherpass";
|
||||
|
||||
async function maybeImportLogins(logins) {
|
||||
let summary = await LoginHelper.maybeImportLogins(logins);
|
||||
return summary.filter(ir => ir.result == "added").map(ir => ir.login);
|
||||
}
|
||||
|
||||
add_task(async function test_invalid_logins() {
|
||||
let importedLogins = await maybeImportLogins([
|
||||
let importedLogins = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -55,7 +50,7 @@ add_task(async function test_invalid_logins() {
|
||||
});
|
||||
|
||||
add_task(async function test_new_logins() {
|
||||
let [importedLogin] = await maybeImportLogins([
|
||||
let [importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -71,7 +66,7 @@ add_task(async function test_new_logins() {
|
||||
`There should be 1 login for ${HOST1}`
|
||||
);
|
||||
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -106,7 +101,7 @@ add_task(async function test_new_logins() {
|
||||
});
|
||||
|
||||
add_task(async function test_duplicate_logins() {
|
||||
let [importedLogin] = await maybeImportLogins([
|
||||
let [importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -122,7 +117,7 @@ add_task(async function test_duplicate_logins() {
|
||||
`There should be 1 login for ${HOST1}`
|
||||
);
|
||||
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -144,7 +139,7 @@ add_task(async function test_duplicate_logins() {
|
||||
});
|
||||
|
||||
add_task(async function test_different_passwords() {
|
||||
let [importedLogin] = await maybeImportLogins([
|
||||
let [importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -162,7 +157,7 @@ add_task(async function test_different_passwords() {
|
||||
);
|
||||
|
||||
// This item will be newer, so its password should take precedence.
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS2,
|
||||
@ -188,7 +183,7 @@ add_task(async function test_different_passwords() {
|
||||
);
|
||||
|
||||
// Now try to update with an older password:
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS3,
|
||||
@ -217,7 +212,7 @@ add_task(async function test_different_passwords() {
|
||||
});
|
||||
|
||||
add_task(async function test_different_usernames_without_guid() {
|
||||
let [importedLogin] = await maybeImportLogins([
|
||||
let [importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -233,7 +228,7 @@ add_task(async function test_different_usernames_without_guid() {
|
||||
`There should be 1 login for ${HOST1}`
|
||||
);
|
||||
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER2,
|
||||
password: PASS1,
|
||||
@ -256,7 +251,7 @@ add_task(async function test_different_usernames_without_guid() {
|
||||
});
|
||||
|
||||
add_task(async function test_different_usernames_with_guid() {
|
||||
let [{ login: importedLogin }] = await LoginHelper.maybeImportLogins([
|
||||
let [importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -282,11 +277,7 @@ add_task(async function test_different_usernames_with_guid() {
|
||||
guid: importedLogin.guid,
|
||||
},
|
||||
]);
|
||||
Assert.equal(
|
||||
importedLogins[0].result,
|
||||
"modified",
|
||||
"Return value should indicate an update"
|
||||
);
|
||||
Assert.ok(!importedLogins.length, "Return value should indicate an update");
|
||||
matchingLogins = LoginHelper.searchLoginsWithObject({ origin: HOST2 });
|
||||
Assert.equal(
|
||||
matchingLogins.length,
|
||||
@ -302,7 +293,7 @@ add_task(async function test_different_usernames_with_guid() {
|
||||
});
|
||||
|
||||
add_task(async function test_different_targets() {
|
||||
let [importedLogin] = await maybeImportLogins([
|
||||
let [importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -320,7 +311,7 @@ add_task(async function test_different_targets() {
|
||||
|
||||
// Not passing either a formActionOrigin or a httpRealm should be treated as
|
||||
// the same as the previous login
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
@ -344,7 +335,7 @@ add_task(async function test_different_targets() {
|
||||
"The form submission URL should have been kept."
|
||||
);
|
||||
|
||||
[importedLogin] = await maybeImportLogins([
|
||||
[importedLogin] = await LoginHelper.maybeImportLogins([
|
||||
{
|
||||
username: USER1,
|
||||
password: PASS1,
|
||||
|
@ -437,96 +437,3 @@ add_task(async function test_import_from_chrome_csv() {
|
||||
checkLoginNewlyCreated(a)
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Imports login data summary contains added logins.
|
||||
*/
|
||||
add_task(async function test_import_summary_contains_added_login() {
|
||||
let csvFilePath = await setupCsv([
|
||||
"url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged",
|
||||
"https://added.org,jane@example.com,added_passwordd,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0003},1589617814635,1589710449871,1589617846802",
|
||||
]);
|
||||
|
||||
let [added] = await LoginCSVImport.importFromCSV(csvFilePath);
|
||||
|
||||
equal(added.result, "added", `Check that the login was added`);
|
||||
});
|
||||
|
||||
/**
|
||||
* Imports login data summary contains modified logins.
|
||||
*/
|
||||
add_task(async function test_import_summary_contains_modified_login() {
|
||||
let initialDataFile = await setupCsv([
|
||||
"url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged",
|
||||
"https://modifiedwithguid.org,jane@example.com,initial_password,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0001},1589617814635,1589710449871,1589617846802",
|
||||
"https://modifiedwithoutguid.org,jane@example.com,initial_password,My realm,,,1589617814635,1589710449871,1589617846802",
|
||||
]);
|
||||
await LoginCSVImport.importFromCSV(initialDataFile);
|
||||
|
||||
let csvFile = await LoginTestUtils.file.setupCsvFileWithLines([
|
||||
"url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged",
|
||||
"https://modified.org,jane@example.com,modified_password,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0001},1589617814635,1589710449871,1589617846999",
|
||||
"https://modifiedwithoutguid.org,jane@example.com,modified_password,My realm,,,1589617814635,1589710449871,1589617846999",
|
||||
]);
|
||||
|
||||
let [
|
||||
modifiedWithGuid,
|
||||
modifiedWithoutGuid,
|
||||
] = await LoginCSVImport.importFromCSV(csvFile.path);
|
||||
|
||||
equal(
|
||||
modifiedWithGuid.result,
|
||||
"modified",
|
||||
`Check that the login was modified when it had the same guid`
|
||||
);
|
||||
equal(
|
||||
modifiedWithoutGuid.result,
|
||||
"modified",
|
||||
`Check that the login was modified when there was no guid data`
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Imports login data summary contains unchanged logins.
|
||||
*/
|
||||
add_task(async function test_import_summary_contains_unchanged_login() {
|
||||
let initialDataFile = await setupCsv([
|
||||
"url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged",
|
||||
"https://nochange.org,jane@example.com,nochange_password,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0002},1589617814635,1589710449871,1589617846802",
|
||||
]);
|
||||
await LoginCSVImport.importFromCSV(initialDataFile);
|
||||
|
||||
let csvFile = await LoginTestUtils.file.setupCsvFileWithLines([
|
||||
"url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged",
|
||||
"https://nochange.org,jane@example.com,nochange_password,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0002},1589617814635,1589710449871,1589617846802",
|
||||
]);
|
||||
|
||||
let [noChange] = await LoginCSVImport.importFromCSV(csvFile.path);
|
||||
|
||||
equal(noChange.result, "no_change", `Check that the login was not changed`);
|
||||
});
|
||||
|
||||
/**
|
||||
* Imports login data summary contains logins with errors.
|
||||
*/
|
||||
add_task(async function test_import_summary_contains_logins_with_errors() {
|
||||
let csvFilePath = await setupCsv([
|
||||
"url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged",
|
||||
"https://invalid.password.org,jane@example.com,,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0002},1589617814635,1589710449871,1589617846802",
|
||||
",jane@example.com,invalid_origin,My realm,,{5ec0d12f-e194-4279-ae1b-d7d281bb0002},1589617814635,1589710449871,1589617846802",
|
||||
]);
|
||||
let [invalidPassword, invalidOrigin] = await LoginCSVImport.importFromCSV(
|
||||
csvFilePath
|
||||
);
|
||||
|
||||
equal(
|
||||
invalidPassword.result,
|
||||
"error_invalid_password",
|
||||
`Check that the invalid password error is reported`
|
||||
);
|
||||
equal(
|
||||
invalidOrigin.result,
|
||||
"error_invalid_origin",
|
||||
`Check that the invalid origin error is reported`
|
||||
);
|
||||
});
|
||||
|
@ -52,8 +52,6 @@
|
||||
--in-content-dialog-header-background: #f1f1f1;
|
||||
--in-content-sidebar-width: 240px;
|
||||
|
||||
--dialog-warning-text-color: var(--red-60);
|
||||
|
||||
--panel-border-radius: 2px; /* This is overridden on Windows */
|
||||
|
||||
--blue-40: #45a1ff;
|
||||
@ -80,7 +78,6 @@
|
||||
--green-80: #006504;
|
||||
--green-90: #003706;
|
||||
--orange-50: #ff9400;
|
||||
--red-40: #ff4f5e;
|
||||
--red-50: #ff0039;
|
||||
--red-50-a30: rgba(255, 0, 57, 0.3);
|
||||
--red-60: #d70022;
|
||||
@ -145,8 +142,6 @@
|
||||
|
||||
--card-outline-color: var(--grey-60);
|
||||
|
||||
--dialog-warning-text-color: var(--red-40);
|
||||
|
||||
scrollbar-color: rgba(249,249,250,.4) rgba(20,20,25,.3);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user