зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1705745 - Remove authentication code from screenshots r=sfoster
Differential Revision: https://phabricator.services.mozilla.com/D141918
This commit is contained in:
Родитель
dfd75c103a
Коммит
cf4d1e50b4
|
@ -1,209 +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/. */
|
|
||||||
|
|
||||||
/* globals log */
|
|
||||||
/* globals main, deviceInfo, catcher, communication, browser */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
this.auth = (function() {
|
|
||||||
const exports = {};
|
|
||||||
|
|
||||||
let registrationInfo;
|
|
||||||
let initialized = false;
|
|
||||||
let authHeader = null;
|
|
||||||
let sentryPublicDSN = null;
|
|
||||||
let abTests = {};
|
|
||||||
let accountId = null;
|
|
||||||
|
|
||||||
const fetchStoredInfo = catcher.watchPromise(
|
|
||||||
browser.storage.local.get(["registrationInfo", "abTests"]).then(result => {
|
|
||||||
if (result.abTests) {
|
|
||||||
abTests = result.abTests;
|
|
||||||
}
|
|
||||||
if (result.registrationInfo) {
|
|
||||||
registrationInfo = result.registrationInfo;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
function generateRegistrationInfo() {
|
|
||||||
const info = {
|
|
||||||
secret: crypto.randomUUID(),
|
|
||||||
registered: false,
|
|
||||||
};
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
function register() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const registerUrl = main.getBackend() + "/api/register";
|
|
||||||
// TODO: replace xhr with Fetch #2261
|
|
||||||
const req = new XMLHttpRequest();
|
|
||||||
req.open("POST", registerUrl);
|
|
||||||
req.setRequestHeader("content-type", "application/json");
|
|
||||||
req.onload = catcher.watchFunction(() => {
|
|
||||||
if (req.status === 200) {
|
|
||||||
log.info("Registered login");
|
|
||||||
initialized = true;
|
|
||||||
saveAuthInfo(JSON.parse(req.responseText));
|
|
||||||
resolve(true);
|
|
||||||
} else {
|
|
||||||
log.warn("Error in response:", req.responseText);
|
|
||||||
const exc = new Error("Bad response: " + req.status);
|
|
||||||
exc.popupMessage = "LOGIN_ERROR";
|
|
||||||
reject(exc);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
req.onerror = catcher.watchFunction(() => {
|
|
||||||
const exc = new Error("Error contacting server");
|
|
||||||
exc.popupMessage = "LOGIN_CONNECTION_ERROR";
|
|
||||||
reject(exc);
|
|
||||||
});
|
|
||||||
req.send(
|
|
||||||
JSON.stringify({
|
|
||||||
secret: registrationInfo.secret,
|
|
||||||
deviceInfo: JSON.stringify(deviceInfo()),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function login(options) {
|
|
||||||
const { ownershipCheck, noRegister } = options || {};
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
return fetchStoredInfo.then(() => {
|
|
||||||
if (!registrationInfo) {
|
|
||||||
registrationInfo = generateRegistrationInfo();
|
|
||||||
log.info("Generating new device authentication ID", registrationInfo);
|
|
||||||
browser.storage.local.set({ registrationInfo });
|
|
||||||
}
|
|
||||||
const loginUrl = main.getBackend() + "/api/login";
|
|
||||||
// TODO: replace xhr with Fetch #2261
|
|
||||||
const req = new XMLHttpRequest();
|
|
||||||
req.open("POST", loginUrl);
|
|
||||||
req.onload = catcher.watchFunction(() => {
|
|
||||||
if (req.status === 404) {
|
|
||||||
if (noRegister) {
|
|
||||||
resolve(false);
|
|
||||||
} else {
|
|
||||||
resolve(register());
|
|
||||||
}
|
|
||||||
} else if (req.status >= 300) {
|
|
||||||
log.warn("Error in response:", req.responseText);
|
|
||||||
const exc = new Error("Could not log in: " + req.status);
|
|
||||||
exc.popupMessage = "LOGIN_ERROR";
|
|
||||||
reject(exc);
|
|
||||||
} else if (req.status === 0) {
|
|
||||||
const error = new Error("Could not log in, server unavailable");
|
|
||||||
error.popupMessage = "LOGIN_CONNECTION_ERROR";
|
|
||||||
reject(error);
|
|
||||||
} else {
|
|
||||||
initialized = true;
|
|
||||||
const jsonResponse = JSON.parse(req.responseText);
|
|
||||||
log.info("Screenshots logged in");
|
|
||||||
saveAuthInfo(jsonResponse);
|
|
||||||
if (ownershipCheck) {
|
|
||||||
resolve({ isOwner: jsonResponse.isOwner });
|
|
||||||
} else {
|
|
||||||
resolve(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
req.onerror = catcher.watchFunction(() => {
|
|
||||||
const exc = new Error("Connection failed");
|
|
||||||
exc.url = loginUrl;
|
|
||||||
exc.popupMessage = "CONNECTION_ERROR";
|
|
||||||
reject(exc);
|
|
||||||
});
|
|
||||||
req.setRequestHeader("content-type", "application/json");
|
|
||||||
req.send(
|
|
||||||
JSON.stringify({
|
|
||||||
secret: registrationInfo.secret,
|
|
||||||
deviceInfo: JSON.stringify(deviceInfo()),
|
|
||||||
ownershipCheck,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveAuthInfo(responseJson) {
|
|
||||||
accountId = responseJson.accountId;
|
|
||||||
if (responseJson.sentryPublicDSN) {
|
|
||||||
sentryPublicDSN = responseJson.sentryPublicDSN;
|
|
||||||
}
|
|
||||||
if (responseJson.authHeader) {
|
|
||||||
authHeader = responseJson.authHeader;
|
|
||||||
if (!registrationInfo.registered) {
|
|
||||||
registrationInfo.registered = true;
|
|
||||||
catcher.watchPromise(browser.storage.local.set({ registrationInfo }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (responseJson.abTests) {
|
|
||||||
abTests = responseJson.abTests;
|
|
||||||
catcher.watchPromise(browser.storage.local.set({ abTests }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.maybeLogin = function() {
|
|
||||||
if (!registrationInfo) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
return exports.authHeaders();
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.authHeaders = function() {
|
|
||||||
let initPromise = Promise.resolve();
|
|
||||||
if (!initialized) {
|
|
||||||
initPromise = login();
|
|
||||||
}
|
|
||||||
return initPromise.then(() => {
|
|
||||||
if (authHeader) {
|
|
||||||
return { "x-screenshots-auth": authHeader };
|
|
||||||
}
|
|
||||||
log.warn("No auth header available");
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getSentryPublicDSN = function() {
|
|
||||||
return sentryPublicDSN;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getAbTests = function() {
|
|
||||||
return abTests;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.isRegistered = function() {
|
|
||||||
return registrationInfo && registrationInfo.registered;
|
|
||||||
};
|
|
||||||
|
|
||||||
communication.register("getAuthInfo", (sender, ownershipCheck) => {
|
|
||||||
return fetchStoredInfo.then(() => {
|
|
||||||
// If a device id was never generated, report back accordingly.
|
|
||||||
if (!registrationInfo) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return exports.authHeaders().then(authHeaders => {
|
|
||||||
let info = registrationInfo;
|
|
||||||
if (info.registered) {
|
|
||||||
return login({ ownershipCheck }).then(result => {
|
|
||||||
return {
|
|
||||||
isOwner: result && result.isOwner,
|
|
||||||
accountId,
|
|
||||||
authHeaders,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
info = Object.assign({ authHeaders }, info);
|
|
||||||
return info;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return exports;
|
|
||||||
})();
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/* globals browser, getStrings, selectorLoader, analytics, communication, catcher, log, auth, senderror, startBackground, blobConverters, startSelectionWithOnboarding */
|
/* globals browser, getStrings, selectorLoader, analytics, communication, catcher, log, senderror, startBackground, blobConverters, startSelectionWithOnboarding */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,13 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/* globals startBackground, analytics, communication, Raven, catcher, auth, log, browser, getStrings */
|
/* globals startBackground, analytics, communication, catcher, log, browser, getStrings */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
this.senderror = (function() {
|
this.senderror = (function() {
|
||||||
const exports = {};
|
const exports = {};
|
||||||
|
|
||||||
const manifest = browser.runtime.getManifest();
|
|
||||||
|
|
||||||
// Do not show an error more than every ERROR_TIME_LIMIT milliseconds:
|
// Do not show an error more than every ERROR_TIME_LIMIT milliseconds:
|
||||||
const ERROR_TIME_LIMIT = 3000;
|
const ERROR_TIME_LIMIT = 3000;
|
||||||
|
|
||||||
|
@ -101,13 +99,6 @@ this.senderror = (function() {
|
||||||
log.error("Telemetry disabled. Not sending critical error:", e);
|
log.error("Telemetry disabled. Not sending critical error:", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dsn = auth.getSentryPublicDSN();
|
|
||||||
if (!dsn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!Raven.isSetup()) {
|
|
||||||
Raven.config(dsn, { allowSecretKey: true }).install();
|
|
||||||
}
|
|
||||||
const exception = new Error(e.message);
|
const exception = new Error(e.message);
|
||||||
exception.stack = e.multilineStack || e.stack || undefined;
|
exception.stack = e.multilineStack || e.stack || undefined;
|
||||||
|
|
||||||
|
@ -138,13 +129,6 @@ this.senderror = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rest.stack = exception.stack;
|
rest.stack = exception.stack;
|
||||||
Raven.captureException(exception, {
|
|
||||||
logger: "addon",
|
|
||||||
tags: { category: e.popupMessage },
|
|
||||||
release: manifest.version,
|
|
||||||
message: exception.message,
|
|
||||||
extra: rest,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
catcher.registerHandler(errorObj => {
|
catcher.registerHandler(errorObj => {
|
||||||
|
|
|
@ -51,9 +51,7 @@ this.startBackground = (function() {
|
||||||
"blobConverters.js",
|
"blobConverters.js",
|
||||||
"background/selectorLoader.js",
|
"background/selectorLoader.js",
|
||||||
"background/communication.js",
|
"background/communication.js",
|
||||||
"background/auth.js",
|
|
||||||
"background/senderror.js",
|
"background/senderror.js",
|
||||||
"build/raven.js",
|
|
||||||
"build/shot.js",
|
"build/shot.js",
|
||||||
"build/thumbnailGenerator.js",
|
"build/thumbnailGenerator.js",
|
||||||
"background/analytics.js",
|
"background/analytics.js",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/* globals browser, communication, getZoomFactor, shot, main, auth, catcher, analytics, blobConverters, thumbnailGenerator */
|
/* globals browser, communication, getZoomFactor, shot, main, catcher, analytics, blobConverters, thumbnailGenerator */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -26,7 +26,6 @@ FINAL_TARGET_FILES.features["screenshots@mozilla.org"] += [
|
||||||
|
|
||||||
FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["background"] += [
|
FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["background"] += [
|
||||||
"background/analytics.js",
|
"background/analytics.js",
|
||||||
"background/auth.js",
|
|
||||||
"background/communication.js",
|
"background/communication.js",
|
||||||
"background/deviceInfo.js",
|
"background/deviceInfo.js",
|
||||||
"background/main.js",
|
"background/main.js",
|
||||||
|
@ -38,7 +37,6 @@ FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["background"] += [
|
||||||
|
|
||||||
FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["build"] += [
|
FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["build"] += [
|
||||||
"build/inlineSelectionCss.js",
|
"build/inlineSelectionCss.js",
|
||||||
"build/raven.js",
|
|
||||||
"build/selection.js",
|
"build/selection.js",
|
||||||
"build/shot.js",
|
"build/shot.js",
|
||||||
"build/thumbnailGenerator.js",
|
"build/thumbnailGenerator.js",
|
||||||
|
|
|
@ -9,10 +9,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
this.sitehelper = (function() {
|
this.sitehelper = (function() {
|
||||||
// This gives us the content's copy of XMLHttpRequest, instead of the wrapped
|
|
||||||
// copy that this content script gets:
|
|
||||||
const ContentXMLHttpRequest = content.XMLHttpRequest;
|
|
||||||
|
|
||||||
catcher.registerHandler(errorObj => {
|
catcher.registerHandler(errorObj => {
|
||||||
callBackground("reportError", errorObj);
|
callBackground("reportError", errorObj);
|
||||||
});
|
});
|
||||||
|
@ -32,40 +28,6 @@ this.sitehelper = (function() {
|
||||||
document.dispatchEvent(new CustomEvent(name, { detail }));
|
document.dispatchEvent(new CustomEvent(name, { detail }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the cookie, even if third-party cookies are disabled in this browser
|
|
||||||
(when they are disabled, login from the background page won't set cookies) */
|
|
||||||
function sendBackupCookieRequest(authHeaders) {
|
|
||||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1295660
|
|
||||||
// This bug would allow us to access window.content.XMLHttpRequest, and get
|
|
||||||
// a safer (not overridable by content) version of the object.
|
|
||||||
|
|
||||||
// This is a very minimal attempt to verify that the XMLHttpRequest object we got
|
|
||||||
// is legitimate. It is not a good test.
|
|
||||||
if (
|
|
||||||
Object.toString.apply(ContentXMLHttpRequest) !==
|
|
||||||
"function XMLHttpRequest() {\n [native code]\n}"
|
|
||||||
) {
|
|
||||||
console.warn("Insecure copy of XMLHttpRequest");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const req = new ContentXMLHttpRequest();
|
|
||||||
req.open("POST", "/api/set-login-cookie");
|
|
||||||
for (const name in authHeaders) {
|
|
||||||
req.setRequestHeader(name, authHeaders[name]);
|
|
||||||
}
|
|
||||||
req.send("");
|
|
||||||
req.onload = () => {
|
|
||||||
if (req.status !== 200) {
|
|
||||||
console.warn(
|
|
||||||
"Attempt to set Screenshots cookie via /api/set-login-cookie failed:",
|
|
||||||
req.status,
|
|
||||||
req.statusText,
|
|
||||||
req.responseText
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
registerListener(
|
registerListener(
|
||||||
"delete-everything",
|
"delete-everything",
|
||||||
catcher.watchFunction(event => {
|
catcher.watchFunction(event => {
|
||||||
|
@ -73,25 +35,6 @@ this.sitehelper = (function() {
|
||||||
}, false)
|
}, false)
|
||||||
);
|
);
|
||||||
|
|
||||||
registerListener(
|
|
||||||
"request-login",
|
|
||||||
catcher.watchFunction(event => {
|
|
||||||
const shotId = event.detail;
|
|
||||||
catcher.watchPromise(
|
|
||||||
callBackground("getAuthInfo", shotId || null).then(info => {
|
|
||||||
if (info) {
|
|
||||||
sendBackupCookieRequest(info.authHeaders);
|
|
||||||
sendCustomEvent("login-successful", {
|
|
||||||
accountId: info.accountId,
|
|
||||||
isOwner: info.isOwner,
|
|
||||||
backupCookieRequest: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
registerListener(
|
registerListener(
|
||||||
"copy-to-clipboard",
|
"copy-to-clipboard",
|
||||||
catcher.watchFunction(event => {
|
catcher.watchFunction(event => {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче