зеркало из 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,
|
||||
* 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";
|
||||
|
||||
|
|
|
@ -2,15 +2,13 @@
|
|||
* 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 startBackground, analytics, communication, Raven, catcher, auth, log, browser, getStrings */
|
||||
/* globals startBackground, analytics, communication, catcher, log, browser, getStrings */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.senderror = (function() {
|
||||
const exports = {};
|
||||
|
||||
const manifest = browser.runtime.getManifest();
|
||||
|
||||
// Do not show an error more than every ERROR_TIME_LIMIT milliseconds:
|
||||
const ERROR_TIME_LIMIT = 3000;
|
||||
|
||||
|
@ -101,13 +99,6 @@ this.senderror = (function() {
|
|||
log.error("Telemetry disabled. Not sending critical error:", e);
|
||||
return;
|
||||
}
|
||||
const dsn = auth.getSentryPublicDSN();
|
||||
if (!dsn) {
|
||||
return;
|
||||
}
|
||||
if (!Raven.isSetup()) {
|
||||
Raven.config(dsn, { allowSecretKey: true }).install();
|
||||
}
|
||||
const exception = new Error(e.message);
|
||||
exception.stack = e.multilineStack || e.stack || undefined;
|
||||
|
||||
|
@ -138,13 +129,6 @@ this.senderror = (function() {
|
|||
}
|
||||
}
|
||||
rest.stack = exception.stack;
|
||||
Raven.captureException(exception, {
|
||||
logger: "addon",
|
||||
tags: { category: e.popupMessage },
|
||||
release: manifest.version,
|
||||
message: exception.message,
|
||||
extra: rest,
|
||||
});
|
||||
};
|
||||
|
||||
catcher.registerHandler(errorObj => {
|
||||
|
|
|
@ -51,9 +51,7 @@ this.startBackground = (function() {
|
|||
"blobConverters.js",
|
||||
"background/selectorLoader.js",
|
||||
"background/communication.js",
|
||||
"background/auth.js",
|
||||
"background/senderror.js",
|
||||
"build/raven.js",
|
||||
"build/shot.js",
|
||||
"build/thumbnailGenerator.js",
|
||||
"background/analytics.js",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 browser, communication, getZoomFactor, shot, main, auth, catcher, analytics, blobConverters, thumbnailGenerator */
|
||||
/* globals browser, communication, getZoomFactor, shot, main, catcher, analytics, blobConverters, thumbnailGenerator */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -26,7 +26,6 @@ FINAL_TARGET_FILES.features["screenshots@mozilla.org"] += [
|
|||
|
||||
FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["background"] += [
|
||||
"background/analytics.js",
|
||||
"background/auth.js",
|
||||
"background/communication.js",
|
||||
"background/deviceInfo.js",
|
||||
"background/main.js",
|
||||
|
@ -38,7 +37,6 @@ FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["background"] += [
|
|||
|
||||
FINAL_TARGET_FILES.features["screenshots@mozilla.org"]["build"] += [
|
||||
"build/inlineSelectionCss.js",
|
||||
"build/raven.js",
|
||||
"build/selection.js",
|
||||
"build/shot.js",
|
||||
"build/thumbnailGenerator.js",
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
"use strict";
|
||||
|
||||
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 => {
|
||||
callBackground("reportError", errorObj);
|
||||
});
|
||||
|
@ -32,40 +28,6 @@ this.sitehelper = (function() {
|
|||
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(
|
||||
"delete-everything",
|
||||
catcher.watchFunction(event => {
|
||||
|
@ -73,25 +35,6 @@ this.sitehelper = (function() {
|
|||
}, 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(
|
||||
"copy-to-clipboard",
|
||||
catcher.watchFunction(event => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче