Prevent logging lots of "Browser unsupported" lines (#32647)
* Store the result of getBrowserSupport * Add supported_environment data * Refactor * Ensure have a cache opt-out * docstring * Use memoizeOne
This commit is contained in:
@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import browserlist from "browserslist";
|
import browserlist from "browserslist";
|
||||||
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";
|
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
|
||||||
import { DeviceType, parseUserAgent } from "./utils/device/parseUserAgent";
|
import { DeviceType, parseUserAgent } from "./utils/device/parseUserAgent";
|
||||||
import ToastStore from "./stores/ToastStore";
|
import ToastStore from "./stores/ToastStore";
|
||||||
@@ -40,11 +41,7 @@ function getBrowserNameVersion(browser: string): [name: string, version: number]
|
|||||||
return [browserNameLc, parseInt(browserVersion, 10)];
|
return [browserNameLc, parseInt(browserVersion, 10)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function calculateBrowserSupport(): boolean {
|
||||||
* Function to check if the current browser is considered supported by our support policy.
|
|
||||||
* Based on user agent parsing so may be inaccurate if the user has fingerprint prevention turned up to 11.
|
|
||||||
*/
|
|
||||||
export function getBrowserSupport(): boolean {
|
|
||||||
const browsers = browserlist(SUPPORTED_BROWSER_QUERY).sort();
|
const browsers = browserlist(SUPPORTED_BROWSER_QUERY).sort();
|
||||||
const minimumBrowserVersions = new Map<string, number>();
|
const minimumBrowserVersions = new Map<string, number>();
|
||||||
for (const browser of browsers) {
|
for (const browser of browsers) {
|
||||||
@@ -56,34 +53,41 @@ export function getBrowserSupport(): boolean {
|
|||||||
|
|
||||||
const details = parseUserAgent(navigator.userAgent);
|
const details = parseUserAgent(navigator.userAgent);
|
||||||
|
|
||||||
let supported = true;
|
if (!details.client) {
|
||||||
|
logger.warn("Browser unsupported, unknown client", navigator.userAgent);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SUPPORTED_DEVICE_TYPES.includes(details.deviceType)) {
|
if (!SUPPORTED_DEVICE_TYPES.includes(details.deviceType)) {
|
||||||
logger.warn("Browser unsupported, unsupported device type", details.deviceType);
|
logger.warn("Browser unsupported, unsupported device type", details.deviceType);
|
||||||
supported = false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details.client) {
|
// We don't care about the browser version for desktop devices
|
||||||
// We don't care about the browser version for desktop devices
|
// We ship our own browser (electron) for desktop devices
|
||||||
// We ship our own browser (electron) for desktop devices
|
if (details.deviceType === DeviceType.Desktop) {
|
||||||
if (details.deviceType === DeviceType.Desktop) {
|
return true;
|
||||||
return supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [browserName, browserVersion] = getBrowserNameVersion(details.client);
|
|
||||||
const minimumVersion = minimumBrowserVersions.get(browserName);
|
|
||||||
// Check both with the sub-version cut off and without as some browsers have less granular versioning e.g. Safari
|
|
||||||
if (!minimumVersion || browserVersion < minimumVersion) {
|
|
||||||
logger.warn("Browser unsupported, unsupported user agent", details.client);
|
|
||||||
supported = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.warn("Browser unsupported, unknown client", navigator.userAgent);
|
|
||||||
supported = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return supported;
|
const [browserName, browserVersion] = getBrowserNameVersion(details.client);
|
||||||
|
const minimumVersion = minimumBrowserVersions.get(browserName);
|
||||||
|
// Check both with the sub-version cut off and without as some browsers have less granular versioning e.g. Safari
|
||||||
|
if (!minimumVersion || browserVersion < minimumVersion) {
|
||||||
|
logger.warn("Browser unsupported, unsupported user agent", details.client);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to check if the current browser is considered supported by our support policy.
|
||||||
|
* Based on user agent parsing so may be inaccurate if the user has fingerprint prevention turned up to 11.
|
||||||
|
* This is calculated once and stored for the lifetime of the session to prevent logspam.
|
||||||
|
*
|
||||||
|
* @returns `true` if the browser is supported by us, or `false` if *any* of the checks fail.
|
||||||
|
*/
|
||||||
|
export const getBrowserSupport = memoizeOne(calculateBrowserSupport);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a user warning toast if the user's browser is not supported.
|
* Shows a user warning toast if the user's browser is not supported.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import SdkConfig from "../SdkConfig";
|
|||||||
import { getServerVersionFromFederationApi } from "../components/views/dialogs/devtools/ServerInfo";
|
import { getServerVersionFromFederationApi } from "../components/views/dialogs/devtools/ServerInfo";
|
||||||
import type * as Tar from "tar-js";
|
import type * as Tar from "tar-js";
|
||||||
import { BugReportEndpointURLLocal } from "../IConfigOptions";
|
import { BugReportEndpointURLLocal } from "../IConfigOptions";
|
||||||
|
import { getBrowserSupport } from "../SupportedBrowser";
|
||||||
|
|
||||||
interface IOpts {
|
interface IOpts {
|
||||||
labels?: string[];
|
labels?: string[];
|
||||||
@@ -118,6 +119,7 @@ async function collectBaseInformation(body: FormData, opts: IOpts): Promise<void
|
|||||||
body.append("app", opts.customApp || "element-web");
|
body.append("app", opts.customApp || "element-web");
|
||||||
body.append("version", version ?? "UNKNOWN");
|
body.append("version", version ?? "UNKNOWN");
|
||||||
body.append("user_agent", userAgent);
|
body.append("user_agent", userAgent);
|
||||||
|
body.append("supported_environment", getBrowserSupport().toString());
|
||||||
body.append("installed_pwa", installedPWA);
|
body.append("installed_pwa", installedPWA);
|
||||||
body.append("touch_input", touchInput);
|
body.append("touch_input", touchInput);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
|
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import { checkBrowserSupport, LOCAL_STORAGE_KEY } from "../../src/SupportedBrowser";
|
import { getBrowserSupport, checkBrowserSupport, LOCAL_STORAGE_KEY } from "../../src/SupportedBrowser";
|
||||||
import ToastStore from "../../src/stores/ToastStore";
|
import ToastStore from "../../src/stores/ToastStore";
|
||||||
import GenericToast from "../../src/components/views/toasts/GenericToast";
|
import GenericToast from "../../src/components/views/toasts/GenericToast";
|
||||||
|
|
||||||
@@ -18,6 +18,7 @@ describe("SupportedBrowser", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
getBrowserSupport.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
const testUserAgentFactory =
|
const testUserAgentFactory =
|
||||||
@@ -109,6 +110,7 @@ describe("SupportedBrowser", () => {
|
|||||||
toastSpy.mockClear();
|
toastSpy.mockClear();
|
||||||
warnLogSpy.mockClear();
|
warnLogSpy.mockClear();
|
||||||
|
|
||||||
|
getBrowserSupport.clear();
|
||||||
checkBrowserSupport();
|
checkBrowserSupport();
|
||||||
expect(warnLogSpy).toHaveBeenCalledWith("Browser unsupported, but user has previously accepted");
|
expect(warnLogSpy).toHaveBeenCalledWith("Browser unsupported, but user has previously accepted");
|
||||||
expect(toastSpy).not.toHaveBeenCalled();
|
expect(toastSpy).not.toHaveBeenCalled();
|
||||||
|
|||||||
Reference in New Issue
Block a user