Source code

Revision control

Copy as Markdown

Other Tools

/* 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 { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
// Maximum length of the string properties sent to the API endpoint.
const MAX_STRING_LENGTH = 255;
const AMO_SUPPORTED_ADDON_TYPES = [
"extension",
"theme",
"sitepermission",
// TODO(Bug 1789718): Remove after the deprecated XPIProvider-based implementation is also removed.
"sitepermission-deprecated",
"dictionary",
];
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
});
/**
* A singleton used to manage abuse reports for add-ons.
*/
export const AbuseReporter = {
getAMOFormURL({ addonId }) {
return Services.urlFormatter
.formatURLPref("extensions.abuseReport.amoFormURL")
.replace(/%addonID%/g, addonId);
},
isSupportedAddonType(addonType) {
return AMO_SUPPORTED_ADDON_TYPES.includes(addonType);
},
/**
* Helper function that retrieves from an addon object all the data to send
* as part of the submission request, besides the `reason`, `message` which are
* going to be received from the submit method of the report object returned
* by `createAbuseReport`.
*
* @param {AddonWrapper} addon
* The addon object to collect the detail from.
*
* @return {object}
* An object that contains the collected details.
*/
async getReportData(addon) {
const truncateString = text =>
typeof text == "string" ? text.slice(0, MAX_STRING_LENGTH) : text;
// Normalize addon_install_source and addon_install_method values
// as expected by the server API endpoint. Returns null if the
// value is not a string.
const normalizeValue = text =>
typeof text == "string"
? text.toLowerCase().replace(/[- :]/g, "_")
: null;
const installInfo = addon.installTelemetryInfo || {};
const data = {
addon: addon.id,
addon_version: addon.version,
addon_name: truncateString(addon.name),
addon_summary: truncateString(addon.description),
addon_install_origin:
addon.sourceURI && truncateString(addon.sourceURI.spec),
install_date: addon.installDate && addon.installDate.toISOString(),
addon_install_source: normalizeValue(installInfo.source),
addon_install_source_url:
installInfo.sourceURL && truncateString(installInfo.sourceURL),
addon_install_method: normalizeValue(installInfo.method),
};
switch (addon.signedState) {
case lazy.AddonManager.SIGNEDSTATE_BROKEN:
data.addon_signature = "broken";
break;
case lazy.AddonManager.SIGNEDSTATE_UNKNOWN:
data.addon_signature = "unknown";
break;
case lazy.AddonManager.SIGNEDSTATE_MISSING:
data.addon_signature = "missing";
break;
case lazy.AddonManager.SIGNEDSTATE_PRELIMINARY:
data.addon_signature = "preliminary";
break;
case lazy.AddonManager.SIGNEDSTATE_SIGNED:
data.addon_signature = "signed";
break;
case lazy.AddonManager.SIGNEDSTATE_SYSTEM:
data.addon_signature = "system";
break;
case lazy.AddonManager.SIGNEDSTATE_PRIVILEGED:
data.addon_signature = "privileged";
break;
default:
data.addon_signature = `unknown: ${addon.signedState}`;
}
// Set "curated" as addon_signature on recommended addons
// (addon.isRecommended internally checks that the addon is also
// signed correctly).
if (addon.isRecommended) {
data.addon_signature = "curated";
}
data.client_id = await lazy.ClientID.getClientIdHash();
data.app = Services.appinfo.name.toLowerCase();
data.appversion = Services.appinfo.version;
data.lang = Services.locale.appLocaleAsBCP47;
data.operating_system = AppConstants.platform;
data.operating_system_version = Services.sysinfo.getProperty("version");
return data;
},
};