From 40979213c13e8f9c8708a68fb2c4eb8c5d4fefb2 Mon Sep 17 00:00:00 2001 From: trickypr <23250792+trickypr@users.noreply.github.com> Date: Tue, 2 Jan 2024 18:19:41 +1100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Implement=20`nsIAboutModule`=20(#45?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/content/webpack.config.js | 1 - apps/misc/static/defaults/pref/prefs.js | 4 + apps/modules/lib/AboutRedirector.sys.mjs | 108 +++++++++++++++++++++++ docs/about-pages.md | 4 + libs/shared/src/utilities/svelte.ts | 1 - 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 apps/modules/lib/AboutRedirector.sys.mjs create mode 100644 docs/about-pages.md diff --git a/apps/content/webpack.config.js b/apps/content/webpack.config.js index 1edcfa0..6e79dd4 100644 --- a/apps/content/webpack.config.js +++ b/apps/content/webpack.config.js @@ -13,7 +13,6 @@ import WebpackLicensePlugin from 'webpack-license-plugin' const HTML_TEMPLATE_FILE = './src/index.html' -const getDistFile = (file) => resolve('dist', file) const absolutePackage = (file) => resolve('node_modules', file) /** diff --git a/apps/misc/static/defaults/pref/prefs.js b/apps/misc/static/defaults/pref/prefs.js index 08bbfde..69cba5b 100644 --- a/apps/misc/static/defaults/pref/prefs.js +++ b/apps/misc/static/defaults/pref/prefs.js @@ -108,6 +108,10 @@ pref('browser.download.clearHistoryOnDelete', 0); // We do this because we want page actions etc. to have color schemes pref('svg.context-properties.content.enabled', true); +// Security page preferences +// This requires our own testing server, which we don't have +pref('security.certerrors.mitm.priming.enabled', true); + // ============================================================================= // Multithreading diff --git a/apps/modules/lib/AboutRedirector.sys.mjs b/apps/modules/lib/AboutRedirector.sys.mjs new file mode 100644 index 0000000..f69e28e --- /dev/null +++ b/apps/modules/lib/AboutRedirector.sys.mjs @@ -0,0 +1,108 @@ +/* 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/. */ + +// @ts-check +/// + +/** + * Based on Thunderbird's module with the same name + * {@link https://searchfox.org/comm-central/source/mail/components/AboutRedirector.jsm} + */ +export class AboutRedirector { + QueryInterface = ChromeUtils.generateQI(['nsIAboutModule']) + + /** + * @type {Record} + * @private + */ + redirectMap = { + certerror: { + url: 'chrome://global/content/aboutNetError.xhtml', + flags: + Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT | + Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD | + Ci.nsIAboutModule.ALLOW_SCRIPT | + Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT, + }, + tests: { + url: 'chrome://browser/content/tests/index.html', + flags: Ci.nsIAboutModule.ALLOW_SCRIPT, + }, + } + + /** + * Filters out hashes and query strings from the about url, returning just the name + * @private + * @param {nsIURIType} uri + * @returns {string} + */ + getRedirectName({ pathQueryRef }) { + const [name] = /[^?#]+/.exec(pathQueryRef) || ['invalid'] + return name.toLowerCase() + } + + /** + * @private + * @param {string} name The name of the missing page + * @returns {never} + */ + notRegistered(name) { + throw new Error(`about:${name} was not registered with AboutRedirector`) + } + + /** + * @param {nsIURIType} uri + * @param {nsILoadInfoType} loadInfo + * @returns {nsIChannelType} + */ + newChannel(uri, loadInfo) { + const redirectName = this.getRedirectName(uri) + const redirect = this.redirectMap[redirectName] + if (!redirect) this.notRegistered(redirectName) + + const redirectUri = Services.io.newURI(redirect.url) + const channel = Services.io.newChannelFromURIWithLoadInfo( + redirectUri, + loadInfo, + ) + channel.originalURI = uri + + const safeForUntrustedContent = + redirect.flags & Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT + if (safeForUntrustedContent) { + channel.owner = Services.scriptSecurityManager.createContentPrincipal( + uri, + {}, + ) + } + + return channel + } + + /** + * Fetches some combination of flags for some `about:` url + * @param {nsIURIType} uri The url to get flags for + * @returns {number} The assigned flags + */ + getURIFlags(uri) { + const redirectName = this.getRedirectName(uri) + const redirect = this.redirectMap[redirectName] + if (!redirect) this.notRegistered(redirectName) + + return redirect.flags + } + + /** + * Finds the uri for a paticular `about:` about + * @param {nsIURIType} uri The url to match + * @returns {nsIURIType} The page to redirect to + */ + getChromeURI(uri) { + const redirectName = this.getRedirectName(uri) + const redirect = this.redirectMap[redirectName] + if (!redirect) this.notRegistered(redirectName) + + return Services.io.newURI(redirect.url) + } +} diff --git a/docs/about-pages.md b/docs/about-pages.md new file mode 100644 index 0000000..66714f2 --- /dev/null +++ b/docs/about-pages.md @@ -0,0 +1,4 @@ +# Custom about pages + +1. You need to update the [runtime](https://github.com/pulse-browser/experiment-runtime/blob/main/src/quark-runtime/components/components.conf) component to include the contract `@mozilla.org/network/protocol/about;1?what=`. You will need to wait for CI to build or use `rt:slink` +2. Add your page to `redirectMap` inside of `AboutRedirector.sys.mjs` diff --git a/libs/shared/src/utilities/svelte.ts b/libs/shared/src/utilities/svelte.ts index c224fc6..d11a303 100644 --- a/libs/shared/src/utilities/svelte.ts +++ b/libs/shared/src/utilities/svelte.ts @@ -113,7 +113,6 @@ export function resolverStore( export const dynamicStringPref = (processor: (value: string) => T) => (pref: string): Readable => { - console.log('dynamicStringPref', pref) return readable( processor(Services.prefs.getStringPref(pref, '')), (set) => {