@xwiki/cristal-electron-main 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/index.cjs +42 -21
- package/package.json +10 -11
- package/src/index.ts +9 -2
- package/src/mainWindow.ts +3 -0
- package/src/menu.ts +73 -0
- package/src/security-restrictions.ts +20 -5
- package/tsconfig.json +2 -0
- package/tsdoc.json +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xwiki/cristal-electron-main",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"license": "LGPL 2.1",
|
|
5
5
|
"author": "XWiki Org Community <contact@xwiki.org>",
|
|
6
6
|
"homepage": "https://cristal.xwiki.org/",
|
|
@@ -13,21 +13,20 @@
|
|
|
13
13
|
"url": "https://jira.xwiki.org/projects/CRISTAL/"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"electron": "
|
|
17
|
-
"@xwiki/cristal-browser-electron": "0.
|
|
18
|
-
"@xwiki/cristal-electron-
|
|
19
|
-
"@xwiki/cristal-electron-storage": "0.
|
|
16
|
+
"electron": "34.0.0",
|
|
17
|
+
"@xwiki/cristal-browser-electron": "0.14.0",
|
|
18
|
+
"@xwiki/cristal-configuration-electron-main": "0.14.0",
|
|
19
|
+
"@xwiki/cristal-electron-storage": "0.14.0",
|
|
20
|
+
"@xwiki/cristal-electron-authentication-xwiki-main": "0.14.0"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"@types/node": "22.
|
|
23
|
-
"
|
|
23
|
+
"@types/node": "22.10.7",
|
|
24
|
+
"typescript": "5.7.3",
|
|
25
|
+
"vite": "6.0.11"
|
|
24
26
|
},
|
|
25
27
|
"scripts": {
|
|
26
28
|
"build": "tsc --project tsconfig.json && vite build",
|
|
27
29
|
"clean": "rimraf dist",
|
|
28
|
-
"
|
|
29
|
-
"lint": "eslint \"./src/**/*.{ts,tsx}\" --max-warnings=0",
|
|
30
|
-
"linux": "echo 'no task'",
|
|
31
|
-
"package": "echo 'no task'"
|
|
30
|
+
"lint": "eslint \"./src/**/*.{ts,tsx,vue}\" --max-warnings=0"
|
|
32
31
|
}
|
|
33
32
|
}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { loadFile } from "./reload";
|
|
|
23
23
|
import "./security-restrictions";
|
|
24
24
|
// @ts-expect-error shouldn't happen, but we need to generate the types for the whole project once.
|
|
25
25
|
import loadBrowser from "@xwiki/cristal-browser-electron/main";
|
|
26
|
+
import { load as loadConfiguration } from "@xwiki/cristal-configuration-electron-main";
|
|
26
27
|
import { load as loadAuthentication } from "@xwiki/cristal-electron-authentication-xwiki-main";
|
|
27
28
|
// @ts-expect-error shouldn't happen, but we need to generate the types for the whole project once.
|
|
28
29
|
import load from "@xwiki/cristal-electron-storage/main";
|
|
@@ -53,16 +54,22 @@ app.on("window-all-closed", () => {
|
|
|
53
54
|
}
|
|
54
55
|
});
|
|
55
56
|
|
|
57
|
+
if (process.env.NODE_ENV !== "development") {
|
|
58
|
+
// Deactivate debug logs when the environment is not explicitly in development mode.
|
|
59
|
+
console.debug = () => {};
|
|
60
|
+
}
|
|
61
|
+
|
|
56
62
|
/**
|
|
57
63
|
* Create the application window when the background process is ready.
|
|
58
64
|
*/
|
|
59
65
|
app
|
|
60
66
|
.whenReady()
|
|
61
|
-
.then(() => {
|
|
62
|
-
load();
|
|
67
|
+
.then(async () => {
|
|
68
|
+
await load();
|
|
63
69
|
restoreOrCreateWindow().then((w) => {
|
|
64
70
|
loadBrowser(w);
|
|
65
71
|
loadAuthentication(w, loadFile);
|
|
72
|
+
loadConfiguration();
|
|
66
73
|
});
|
|
67
74
|
/**
|
|
68
75
|
* @see https://www.electronjs.org/docs/latest/api/app#event-activate-macos Event: 'activate'.
|
package/src/mainWindow.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { initializeMenu } from "./menu";
|
|
21
22
|
import { loadFile } from "./reload";
|
|
22
23
|
import { BrowserWindow, app, shell } from "electron";
|
|
23
24
|
import { join } from "node:path";
|
|
@@ -35,6 +36,8 @@ async function createWindow() {
|
|
|
35
36
|
},
|
|
36
37
|
});
|
|
37
38
|
|
|
39
|
+
initializeMenu(browserWindow);
|
|
40
|
+
|
|
38
41
|
// Uncomment to start electron debugger at startup.
|
|
39
42
|
// browserWindow.webContents.openDevTools();
|
|
40
43
|
|
package/src/menu.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* See the LICENSE file distributed with this work for additional
|
|
3
|
+
* information regarding copyright ownership.
|
|
4
|
+
*
|
|
5
|
+
* This is free software; you can redistribute it and/or modify it
|
|
6
|
+
* under the terms of the GNU Lesser General Public License as
|
|
7
|
+
* published by the Free Software Foundation; either version 2.1 of
|
|
8
|
+
* the License, or (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This software is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Lesser General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
* License along with this software; if not, write to the Free
|
|
17
|
+
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
18
|
+
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { BrowserWindow, Menu } from "electron";
|
|
22
|
+
import type { MenuItem } from "electron";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Scan recursively the menus and sub-menus to find the interesting items.
|
|
26
|
+
*
|
|
27
|
+
* @param items - the item of the current menu
|
|
28
|
+
* @param actions - the action we are interested to keep
|
|
29
|
+
* @param newMenu - the new menu built from interesting actions
|
|
30
|
+
* @since 0.13
|
|
31
|
+
*/
|
|
32
|
+
function scan(items: MenuItem[], actions: string[], newMenu: Menu): void {
|
|
33
|
+
for (const item of items) {
|
|
34
|
+
if (actions.includes(`${item.role}`)) {
|
|
35
|
+
newMenu.insert(0, item);
|
|
36
|
+
} else {
|
|
37
|
+
if (item.submenu != undefined) {
|
|
38
|
+
scan(item.submenu.items, actions, newMenu);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Initialize the menu for the provided browser window. The menu is hidden, and we only keep entries with useful
|
|
46
|
+
* keyboard shortcuts.
|
|
47
|
+
* @param browserWindow - the provided browser window.
|
|
48
|
+
* @since 0.13
|
|
49
|
+
*/
|
|
50
|
+
function initializeMenu(browserWindow: BrowserWindow) {
|
|
51
|
+
const menu = Menu.getApplicationMenu();
|
|
52
|
+
const newMenu = new Menu();
|
|
53
|
+
|
|
54
|
+
// The list of actions we wish to preserve from the default application menu.
|
|
55
|
+
const actions = [
|
|
56
|
+
"toggledevtools",
|
|
57
|
+
"resetzoom",
|
|
58
|
+
"zoomin",
|
|
59
|
+
"zoomout",
|
|
60
|
+
"togglefullscreen",
|
|
61
|
+
];
|
|
62
|
+
if (menu?.items) {
|
|
63
|
+
scan(menu?.items, actions, newMenu);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Sets the menu on windows and linux.
|
|
67
|
+
browserWindow.setMenu(newMenu);
|
|
68
|
+
// Set the menu on MacOS.
|
|
69
|
+
Menu.setApplicationMenu(menu);
|
|
70
|
+
browserWindow.setMenuBarVisibility(false);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { initializeMenu };
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { readConfiguration } from "@xwiki/cristal-configuration-electron-main";
|
|
21
22
|
import { app, shell } from "electron";
|
|
22
23
|
import { URL } from "node:url";
|
|
23
24
|
import type { Session } from "electron";
|
|
@@ -32,7 +33,8 @@ type Permission = Parameters<
|
|
|
32
33
|
/**
|
|
33
34
|
* A list of origins that you allow open INSIDE the application and permissions for them.
|
|
34
35
|
*
|
|
35
|
-
* In development mode you need allow open `VITE_DEV_SERVER_URL`.
|
|
36
|
+
* In development mode, you need allow open `VITE_DEV_SERVER_URL`.
|
|
37
|
+
* @deprecated the allowed origins and permissions should be derived from the configuration.
|
|
36
38
|
*/
|
|
37
39
|
const ALLOWED_ORIGINS_AND_PERMISSIONS: Map<string, Set<Permission>> = new Map<
|
|
38
40
|
string,
|
|
@@ -69,9 +71,20 @@ app.on("web-contents-created", (_, contents) => {
|
|
|
69
71
|
*
|
|
70
72
|
* @see https://www.electronjs.org/docs/latest/tutorial/security#13-disable-or-limit-navigation
|
|
71
73
|
*/
|
|
74
|
+
const configuration = readConfiguration();
|
|
72
75
|
contents.on("will-navigate", (event, url) => {
|
|
73
76
|
const { origin } = new URL(url);
|
|
74
|
-
|
|
77
|
+
const isAllowedOrigin = Object.values(configuration).some(
|
|
78
|
+
(configuration) => {
|
|
79
|
+
const baseURL = configuration.baseURL;
|
|
80
|
+
if (!baseURL) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return new URL(baseURL).origin == origin;
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (isAllowedOrigin) {
|
|
75
88
|
return;
|
|
76
89
|
}
|
|
77
90
|
|
|
@@ -93,6 +106,8 @@ app.on("web-contents-created", (_, contents) => {
|
|
|
93
106
|
(webContents, permission, callback) => {
|
|
94
107
|
const { origin } = new URL(webContents.getURL());
|
|
95
108
|
|
|
109
|
+
// FIXME: this control is currently based on a fixed set of URLs, but seems also unused. We need to check more
|
|
110
|
+
// closely if this check is needed.
|
|
96
111
|
const permissionGranted =
|
|
97
112
|
!!ALLOWED_ORIGINS_AND_PERMISSIONS.get(origin)?.has(permission);
|
|
98
113
|
callback(permissionGranted);
|
|
@@ -108,9 +123,9 @@ app.on("web-contents-created", (_, contents) => {
|
|
|
108
123
|
/**
|
|
109
124
|
* Hyperlinks leading to allowed sites are opened in the default browser.
|
|
110
125
|
*
|
|
111
|
-
* The creation of new `webContents` is a common attack vector. Attackers attempt to convince the app to create new
|
|
112
|
-
* frames, or other renderer processes with more privileges than they had before; or with pages opened that
|
|
113
|
-
* You should deny any unexpected window creation.
|
|
126
|
+
* The creation of new `webContents` is a common attack vector. Attackers attempt to convince the app to create new
|
|
127
|
+
* windows, frames, or other renderer processes with more privileges than they had before; or with pages opened that
|
|
128
|
+
* they couldn't open before. You should deny any unexpected window creation.
|
|
114
129
|
*
|
|
115
130
|
* @see https://www.electronjs.org/docs/latest/tutorial/security#14-disable-or-limit-creation-of-new-windows
|
|
116
131
|
* @see https://www.electronjs.org/docs/latest/tutorial/security#15-do-not-use-openexternal-with-untrusted-content
|
package/tsconfig.json
CHANGED
package/tsdoc.json
ADDED