Compare commits

..

13 Commits

Author SHA1 Message Date
Anders Kaseorg
af7272a439 release: New release v5.10.5.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-25 17:02:14 -08:00
Anders Kaseorg
9d08a13e64 Set a restrictive Content-Security-Policy for the app UI.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-25 15:39:05 -08:00
Anders Kaseorg
f98d6d7037 Upgrade dependencies, including Electron 28.2.0.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-25 14:05:37 -08:00
Anders Kaseorg
da1cad9dff autoupdater: Use a separate electron-log instance.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-23 16:09:20 -08:00
Anders Kaseorg
955a2eb6c7 Use process-specific electron-log modules.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-23 16:09:20 -08:00
Anders Kaseorg
1cf822a2b5 Use process-specific @sentry/electron modules.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-23 16:09:20 -08:00
Anders Kaseorg
b9baf140eb release: New release v5.10.4.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-08 17:12:08 -08:00
Anders Kaseorg
727c2335f6 electron-bridge: Fix unicorn/prefer-node-protocol.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-08 17:10:37 -08:00
Anders Kaseorg
e8173919f8 Upgrade dependencies, including Electron 28.1.1.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-08 17:10:37 -08:00
Anders Kaseorg
cf2f4fe9c9 Avoid deprecated ipcRenderer.sendTo.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-08 16:02:14 -08:00
Anders Kaseorg
47cdd5fa8b release: New release v5.10.3.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-29 23:38:26 -07:00
Anders Kaseorg
90e76fab6e Upgrade dependencies, including Electron 25.8.4.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-29 23:38:22 -07:00
Anders Kaseorg
193adb1901 Fix gatemaker TypeError with Electron 25.
This had been breaking our download notifications.  Fixes #1333.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-29 23:25:32 -07:00
20 changed files with 2058 additions and 1839 deletions

View File

@@ -1,7 +1,7 @@
import fs from "node:fs"; import fs from "node:fs";
import path from "node:path"; import path from "node:path";
import * as Sentry from "@sentry/electron"; import * as Sentry from "@sentry/core";
import {JsonDB} from "node-json-db"; import {JsonDB} from "node-json-db";
import {DataError} from "node-json-db/dist/lib/Errors"; import {DataError} from "node-json-db/dist/lib/Errors";
import type {z} from "zod"; import type {z} from "zod";

View File

@@ -2,7 +2,7 @@ import {shell} from "electron/common";
import {app, dialog, session} from "electron/main"; import {app, dialog, session} from "electron/main";
import process from "node:process"; import process from "node:process";
import log from "electron-log"; import log from "electron-log/main";
import type {UpdateDownloadedEvent, UpdateInfo} from "electron-updater"; import type {UpdateDownloadedEvent, UpdateInfo} from "electron-updater";
import {autoUpdater} from "electron-updater"; import {autoUpdater} from "electron-updater";
@@ -31,9 +31,10 @@ export async function appUpdater(updateFromMenu = false): Promise<void> {
let updateAvailable = false; let updateAvailable = false;
// Log what's happening // Log what's happening
log.transports.file.fileName = "updates.log"; const updateLogger = log.create({logId: "updates"});
log.transports.file.level = "info"; updateLogger.transports.file.fileName = "updates.log";
autoUpdater.logger = log; updateLogger.transports.file.level = "info";
autoUpdater.logger = updateLogger;
// Handle auto updates for beta/pre releases // Handle auto updates for beta/pre releases
const isBetaUpdate = ConfigUtil.getConfigItem("betaUpdate", false); const isBetaUpdate = ConfigUtil.getConfigItem("betaUpdate", false);

View File

@@ -1,7 +1,14 @@
import type {Event} from "electron/common"; import type {Event} from "electron/common";
import {clipboard} from "electron/common"; import {clipboard} from "electron/common";
import type {IpcMainEvent, WebContents} from "electron/main"; import type {IpcMainEvent, WebContents} from "electron/main";
import {BrowserWindow, app, dialog, powerMonitor, session} from "electron/main"; import {
BrowserWindow,
app,
dialog,
powerMonitor,
session,
webContents,
} from "electron/main";
import {Buffer} from "node:buffer"; import {Buffer} from "node:buffer";
import crypto from "node:crypto"; import crypto from "node:crypto";
import path from "node:path"; import path from "node:path";
@@ -389,6 +396,21 @@ ${error}`,
}, },
); );
ipcMain.on(
"forward-to",
<Channel extends keyof RendererMessage>(
_event: IpcMainEvent,
webContentsId: number,
listener: Channel,
...parameters: Parameters<RendererMessage[Channel]>
) => {
const contents = webContents.fromId(webContentsId);
if (contents !== undefined) {
send(contents, listener, ...parameters);
}
},
);
ipcMain.on("update-menu", (_event, props: MenuProps) => { ipcMain.on("update-menu", (_event, props: MenuProps) => {
AppMenu.setMenu(props); AppMenu.setMenu(props);
if (props.activeTabIndex !== undefined) { if (props.activeTabIndex !== undefined) {

View File

@@ -6,7 +6,7 @@ import {Readable} from "node:stream";
import {pipeline} from "node:stream/promises"; import {pipeline} from "node:stream/promises";
import type {ReadableStream} from "node:stream/web"; import type {ReadableStream} from "node:stream/web";
import * as Sentry from "@sentry/electron"; import * as Sentry from "@sentry/electron/main";
import {z} from "zod"; import {z} from "zod";
import Logger from "../common/logger-util.js"; import Logger from "../common/logger-util.js";

View File

@@ -1,6 +1,6 @@
import {app} from "electron/main"; import {app} from "electron/main";
import * as Sentry from "@sentry/electron/main"; // eslint-disable-line n/file-extension-in-import import * as Sentry from "@sentry/electron/main";
import {getConfigItem} from "../common/config-util.js"; import {getConfigItem} from "../common/config-util.js";

View File

@@ -33,6 +33,15 @@ export const ipcMain: {
...args: Parameters<RendererMessage[Channel]> ...args: Parameters<RendererMessage[Channel]>
) => void, ) => void,
): void; ): void;
on(
channel: "forward-to",
listener: <Channel extends keyof RendererMessage>(
event: IpcMainEvent,
webContentsId: number,
channel: Channel,
...args: Parameters<RendererMessage[Channel]>
) => void,
): void;
on<Channel extends keyof MainMessage>( on<Channel extends keyof MainMessage>(
channel: Channel, channel: Channel,
listener: MainListener<Channel>, listener: MainListener<Channel>,

View File

@@ -10,7 +10,7 @@ import type {Html} from "../../../common/html.js";
import {html} from "../../../common/html.js"; import {html} from "../../../common/html.js";
import type {RendererMessage} from "../../../common/typed-ipc.js"; import type {RendererMessage} from "../../../common/typed-ipc.js";
import type {TabRole} from "../../../common/types.js"; import type {TabRole} from "../../../common/types.js";
import preloadCss from "../../css/preload.css?raw"; // eslint-disable-line n/file-extension-in-import import preloadCss from "../../css/preload.css?raw";
import {ipcRenderer} from "../typed-ipc-renderer.js"; import {ipcRenderer} from "../typed-ipc-renderer.js";
import * as SystemUtil from "../utils/system-util.js"; import * as SystemUtil from "../utils/system-util.js";
@@ -226,7 +226,7 @@ export default class WebView {
channel: Channel, channel: Channel,
...args: Parameters<RendererMessage[Channel]> ...args: Parameters<RendererMessage[Channel]>
): void { ): void {
ipcRenderer.sendTo(this.webContentsId, channel, ...args); ipcRenderer.send("forward-to", this.webContentsId, channel, ...args);
} }
private registerListeners(): void { private registerListeners(): void {

View File

@@ -1,4 +1,4 @@
import {EventEmitter} from "events"; // eslint-disable-line unicorn/prefer-node-protocol import {EventEmitter} from "node:events";
import type {ClipboardDecrypter} from "./clipboard-decrypter.js"; import type {ClipboardDecrypter} from "./clipboard-decrypter.js";
import {ClipboardDecrypterImpl} from "./clipboard-decrypter.js"; import {ClipboardDecrypterImpl} from "./clipboard-decrypter.js";

View File

@@ -5,7 +5,7 @@ import url from "node:url";
import {Menu, app, dialog, session} from "@electron/remote"; import {Menu, app, dialog, session} from "@electron/remote";
import * as remote from "@electron/remote"; import * as remote from "@electron/remote";
import * as Sentry from "@sentry/electron"; import * as Sentry from "@sentry/electron/renderer";
import type {Config} from "../../common/config-util.js"; import type {Config} from "../../common/config-util.js";
import * as ConfigUtil from "../../common/config-util.js"; import * as ConfigUtil from "../../common/config-util.js";

View File

@@ -356,7 +356,8 @@ export function initGeneralSection({$root}: GeneralSectionProps): void {
const newValue = !ConfigUtil.getConfigItem("silent", true); const newValue = !ConfigUtil.getConfigItem("silent", true);
ConfigUtil.setConfigItem("silent", newValue); ConfigUtil.setConfigItem("silent", newValue);
updateSilentOption(); updateSilentOption();
ipcRenderer.sendTo( ipcRenderer.send(
"forward-to",
currentBrowserWindow.webContents.id, currentBrowserWindow.webContents.id,
"toggle-silent", "toggle-silent",
newValue, newValue,

View File

@@ -138,7 +138,7 @@ function sendAction<Channel extends keyof RendererMessage>(
win.restore(); win.restore();
} }
ipcRenderer.sendTo(win.webContents.id, channel, ...args); ipcRenderer.send("forward-to", win.webContents.id, channel, ...args);
} }
const createTray = function (): void { const createTray = function (): void {

View File

@@ -37,6 +37,12 @@ export const ipcRenderer: {
rendererChannel: Channel, rendererChannel: Channel,
...args: Parameters<RendererMessage[Channel]> ...args: Parameters<RendererMessage[Channel]>
): void; ): void;
send<Channel extends keyof RendererMessage>(
channel: "forward-to",
webContentsId: number,
rendererChannel: Channel,
...args: Parameters<RendererMessage[Channel]>
): void;
send<Channel extends keyof MainMessage>( send<Channel extends keyof MainMessage>(
channel: Channel, channel: Channel,
...args: Parameters<MainMessage[Channel]> ...args: Parameters<MainMessage[Channel]>
@@ -56,11 +62,6 @@ export const ipcRenderer: {
: never, : never,
transfer?: MessagePort[], transfer?: MessagePort[],
): void; ): void;
sendTo<Channel extends keyof RendererMessage>(
webContentsId: number,
channel: Channel,
...args: Parameters<RendererMessage[Channel]>
): void;
sendToHost<Channel extends keyof RendererMessage>( sendToHost<Channel extends keyof RendererMessage>(
channel: Channel, channel: Channel,
...args: Parameters<RendererMessage[Channel]> ...args: Parameters<RendererMessage[Channel]>

View File

@@ -2,7 +2,7 @@ import fs from "node:fs";
import path from "node:path"; import path from "node:path";
import {app, dialog} from "@electron/remote"; import {app, dialog} from "@electron/remote";
import * as Sentry from "@sentry/electron"; import * as Sentry from "@sentry/electron/renderer";
import {JsonDB} from "node-json-db"; import {JsonDB} from "node-json-db";
import {DataError} from "node-json-db/dist/lib/Errors"; import {DataError} from "node-json-db/dist/lib/Errors";
import {z} from "zod"; import {z} from "zod";

View File

@@ -2,6 +2,10 @@
<html lang="en" class="responsive desktop"> <html lang="en" class="responsive desktop">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; connect-src 'self'; font-src 'self'; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'"
/>
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<title>Zulip</title> <title>Zulip</title>
<link rel="stylesheet" href="css/fonts.css" /> <link rel="stylesheet" href="css/fonts.css" />

View File

@@ -2,6 +2,10 @@
<html lang="en" class="responsive desktop"> <html lang="en" class="responsive desktop">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; connect-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'"
/>
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<title>Zulip - Network Troubleshooting</title> <title>Zulip - Network Troubleshooting</title>
<link <link

View File

@@ -2,6 +2,32 @@
All notable changes to the Zulip desktop app are documented in this file. All notable changes to the Zulip desktop app are documented in this file.
### v5.10.5 --2024-01-25
**Dependencies**:
- Upgraded all dependencies, including Electron 28.2.0.
**Enhancements**:
- Improved security hardening by setting a Content-Security-Policy for the app UI.
### v5.10.4 --2024-01-09
**Dependencies**:
- Upgraded all dependencies, including Electron 28.1.1.
### v5.10.3 --2023-09-30
**Fixes**:
- Fixed an error in the third-party `gatemaker` library that broke the display of notifications for completed downloads.
**Dependencies**:
- Upgraded all dependencies, including Electron 25.8.4.
### v5.10.2 --2023-09-14 ### v5.10.2 --2023-09-14
**Dependencies**: **Dependencies**:

3722
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{ {
"name": "zulip", "name": "zulip",
"productName": "Zulip", "productName": "Zulip",
"version": "5.10.2", "version": "5.10.5",
"main": "./dist-electron", "main": "./dist-electron",
"description": "Zulip Desktop App", "description": "Zulip Desktop App",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -143,25 +143,26 @@
"InstantMessaging" "InstantMessaging"
], ],
"dependencies": { "dependencies": {
"gatemaker": "^1.0.0" "gatemaker": "https://github.com/andersk/gatemaker/archive/d31890ae1cb293faabcb1e4e465c673458f6eed2.tar.gz"
}, },
"devDependencies": { "devDependencies": {
"@electron/remote": "^2.0.8", "@electron/remote": "^2.0.8",
"@sentry/core": "^7.94.1",
"@sentry/electron": "^4.1.2", "@sentry/electron": "^4.1.2",
"@types/adm-zip": "^0.5.0", "@types/adm-zip": "^0.5.0",
"@types/auto-launch": "^5.0.2", "@types/auto-launch": "^5.0.2",
"@types/backoff": "^2.5.2", "@types/backoff": "^2.5.2",
"@types/i18n": "^0.13.1", "@types/i18n": "^0.13.1",
"@types/node": "^18.16.5", "@types/node": "~18.17.19",
"@types/requestidlecallback": "^0.3.4", "@types/requestidlecallback": "^0.3.4",
"@types/yaireo__tagify": "^4.3.2", "@types/yaireo__tagify": "^4.3.2",
"@yaireo/tagify": "^4.5.0", "@yaireo/tagify": "^4.5.0",
"adm-zip": "^0.5.5", "adm-zip": "^0.5.5",
"auto-launch": "^5.0.5", "auto-launch": "^5.0.5",
"backoff": "^2.5.0", "backoff": "^2.5.0",
"electron": "^25.8.1", "electron": "^28.1.1",
"electron-builder": "^24.6.4", "electron-builder": "^24.6.4",
"electron-log": "^4.3.5", "electron-log": "^5.0.3",
"electron-updater": "^6.1.4", "electron-updater": "^6.1.4",
"electron-window-state": "^5.0.3", "electron-window-state": "^5.0.3",
"escape-goat": "^4.0.0", "escape-goat": "^4.0.0",
@@ -170,17 +171,17 @@
"iso-639-1": "^3.1.0", "iso-639-1": "^3.1.0",
"medium": "^1.2.0", "medium": "^1.2.0",
"node-json-db": "^1.3.0", "node-json-db": "^1.3.0",
"playwright-core": "^1.30.0-alpha-jan-3-2023", "playwright-core": "^1.41.0-alpha-jan-9-2024",
"pre-commit": "^1.2.2", "pre-commit": "^1.2.2",
"prettier": "^3.0.3", "prettier": "^3.0.3",
"rimraf": "^5.0.0", "rimraf": "^5.0.0",
"semver": "^7.3.5", "semver": "^7.3.5",
"stylelint": "^15.6.1", "stylelint": "^16.1.0",
"stylelint-config-standard": "^34.0.0", "stylelint-config-standard": "^36.0.0",
"tape": "^5.2.2", "tape": "^5.2.2",
"typescript": "^5.0.4", "typescript": "^5.0.4",
"vite": "^4.1.1", "vite": "^5.0.11",
"vite-plugin-electron": "^0.14.1", "vite-plugin-electron": "^0.28.0",
"xo": "^0.56.0", "xo": "^0.56.0",
"zod": "^3.5.1" "zod": "^3.5.1"
}, },
@@ -239,6 +240,10 @@
"error", "error",
{ {
"paths": [ "paths": [
{
"name": "@sentry/electron",
"message": "Use @sentry/electron/main, @sentry/electron/renderer, or @sentry/core."
},
{ {
"name": "electron", "name": "electron",
"message": "Use electron/main, electron/renderer, or electron/common." "message": "Use electron/main, electron/renderer, or electron/common."
@@ -256,6 +261,10 @@
"ipcRenderer" "ipcRenderer"
], ],
"message": "Use typed-ipc-renderer." "message": "Use typed-ipc-renderer."
},
{
"name": "electron-log",
"message": "Use electron-log/main or electron-log/renderer."
} }
] ]
} }

View File

@@ -8,6 +8,6 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"strict": true, "strict": true,
"noImplicitOverride": true, "noImplicitOverride": true,
"types": ["vite/client"] "types": ["vite/client"],
} },
} }

View File

@@ -5,15 +5,6 @@ import * as path from "node:path";
import {defineConfig} from "vite"; import {defineConfig} from "vite";
import electron from "vite-plugin-electron"; import electron from "vite-plugin-electron";
let resolvePreload: () => void;
let resolveRenderer: () => void;
const whenPreload = new Promise<void>((resolve) => {
resolvePreload = resolve;
});
const whenRenderer = new Promise<void>((resolve) => {
resolveRenderer = resolve;
});
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
electron([ electron([
@@ -21,11 +12,6 @@ export default defineConfig({
entry: { entry: {
index: "app/main", index: "app/main",
}, },
async onstart({startup}) {
await whenPreload;
await whenRenderer;
await startup();
},
vite: { vite: {
build: { build: {
sourcemap: true, sourcemap: true,
@@ -48,9 +34,6 @@ export default defineConfig({
entry: { entry: {
preload: "app/renderer/js/preload.ts", preload: "app/renderer/js/preload.ts",
}, },
onstart() {
resolvePreload();
},
vite: { vite: {
build: { build: {
sourcemap: "inline", sourcemap: "inline",
@@ -64,9 +47,6 @@ export default defineConfig({
entry: { entry: {
renderer: "app/renderer/js/main.ts", renderer: "app/renderer/js/main.ts",
}, },
onstart() {
resolveRenderer();
},
vite: { vite: {
build: { build: {
sourcemap: true, sourcemap: true,