From 646425afffdd8f57c1b93e40af2c0dbf94941cab Mon Sep 17 00:00:00 2001 From: "Jonas_sorgenfrei@yahoo.de" Date: Thu, 14 Aug 2025 01:19:41 -0700 Subject: [PATCH] link_utils: exposing whitelisted protocols to user settings Fixes #1284. Adding config option to set protocols in the config that are whitelisted to be opened directly. The behaviour is documented in docs\howto\customize-link-protocols.md. --- app/common/config-schemata.ts | 1 + app/common/config-util.ts | 23 +++++++++++++++++ app/common/link-util.ts | 8 +++++- docs/howto/customize-link-protocols.md | 35 ++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 docs/howto/customize-link-protocols.md diff --git a/app/common/config-schemata.ts b/app/common/config-schemata.ts index 8d74f2583..8b58b3b8d 100644 --- a/app/common/config-schemata.ts +++ b/app/common/config-schemata.ts @@ -36,6 +36,7 @@ export const configSchemata = { useManualProxy: z.boolean(), useProxy: z.boolean(), useSystemProxy: z.boolean(), + whitelistedProtocols: z.string().array(), }; export type ConfigSchemata = typeof configSchemata; diff --git a/app/common/config-util.ts b/app/common/config-util.ts index 45858f79f..a4d466304 100644 --- a/app/common/config-util.ts +++ b/app/common/config-util.ts @@ -49,6 +49,28 @@ export function getConfigItem( } } +// The function getConfigItem stores the default in settings.json which means that +// if the defaults change in the future, that change will not be propagated +// to anyone having a pre-installed desktop app. We should phase out getConfigItem +// in favour of this function and rename this to getConfigItem when it is done +// for all existing occurences. +export function getConfigItemWithoutSettingDefault( + key: Key, + defaultValue: Config[Key], +): z.output { + if (isConfigItemExists(key)) { + const typedSchemata: { + [Key in keyof Config]: z.ZodType< + z.output, + z.input + >; + } = configSchemata; // https://github.com/colinhacks/zod/issues/5154 + return typedSchemata[key].parse(database.getObject(`/${key}`)); + } + + return defaultValue; +} + // This function returns whether a key exists in the configuration file (settings.json) export function isConfigItemExists(key: string): boolean { try { @@ -86,6 +108,7 @@ function reloadDatabase(): void { app.getPath("userData"), "/config/settings.json", ); + console.log(settingsJsonPath); try { const file = fs.readFileSync(settingsJsonPath, "utf8"); JSON.parse(file); diff --git a/app/common/link-util.ts b/app/common/link-util.ts index 6054fa509..c1848b47e 100644 --- a/app/common/link-util.ts +++ b/app/common/link-util.ts @@ -3,11 +3,17 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import * as ConfigUtil from "./config-util.ts"; import {Html, html} from "./html.ts"; import * as t from "./translation-util.ts"; +const whitelistedProtocols = ConfigUtil.getConfigItemWithoutSettingDefault( + "whitelistedProtocols", + ["http:", "https:", "mailto:", "tel:", "sip:"], +); + export async function openBrowser(url: URL): Promise { - if (["http:", "https:", "mailto:"].includes(url.protocol)) { + if (whitelistedProtocols.includes(url.protocol)) { await shell.openExternal(url.href); } else { // For security, indirect links to non-whitelisted protocols diff --git a/docs/howto/customize-link-protocols.md b/docs/howto/customize-link-protocols.md new file mode 100644 index 000000000..b2b1a90a4 --- /dev/null +++ b/docs/howto/customize-link-protocols.md @@ -0,0 +1,35 @@ +# Customizing link protocols + +The Zulip app supports opening certain link protocols directly in their associated system applications. These are known as **whitelisted protocols**. + +## Default whitelisted protocols + +By default, the following protocols are whitelisted: + +``` +http, https, mailto, tel, sip +``` + +Links using these protocols are opened directly by the system. + +All other protocols are considered potentially unsafe and are therefore opened indirectly—through a local HTML file in your default web browser. + +## Extending the whitelisted protocols + +It is possible to customize the list of whitelisted protocols by editing the `settings.json` file located at: `userdata/Zulip/config/settings.json` + +To modify the list, the `whitelistedProtocols` key can be updated. For example: + +```json +{ + ... + "whitelistedProtocols": [ + "http:", + "https:", + "mailto:" + ] + ... +} +``` + +Note: Each protocol should include the trailing (:), e.g., "mailto:" instead of "mailto".