@proton-app/main 0.1.4 → 0.1.6

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.
@@ -1,8 +1,7 @@
1
- import { type IpcRenderer } from "electron";
2
1
  import Storage from "electron-store";
3
2
  export declare function setupAppIpc<T extends Record<string, any>>(storage: Storage<T>): void;
4
3
  export type IpcSchema = Record<string, {
5
- input?: unknown;
4
+ input: unknown;
6
5
  result: unknown;
7
6
  }>;
8
7
  type Input<S extends IpcSchema, K extends keyof S> = S[K] extends {
@@ -36,17 +35,13 @@ export interface AppBridge {
36
35
  setValue: <T>(key: string, value: T) => T;
37
36
  syncAuth: (accessToken: string) => void;
38
37
  }
39
- type IpcClient = Pick<IpcRenderer, "send" | "invoke">;
40
- /**
41
- * Creates the standard application controls exposed by an Electron preload.
42
- */
43
- export declare function createAppBridge(ipc: IpcClient): AppBridge;
44
- export type IpcApi<T> = {
45
- [Namespace in keyof T]: {
46
- [Handler in keyof T[Namespace]]: T[Namespace][Handler] extends {
47
- input: infer Input;
48
- result: infer Result;
49
- } ? (input: Input) => Promise<Result> : never;
50
- };
38
+ type KebabToCamel<S extends string> = S extends `${infer A}-${infer B}` ? `${A}${Capitalize<KebabToCamel<B>>}` : S;
39
+ type NamespaceApi<S extends IpcSchema> = {
40
+ [K in keyof S & string as KebabToCamel<K>]: (input: S[K]["input"]) => Promise<S[K]["result"]>;
51
41
  };
42
+ type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
43
+ export type IpcApi<S extends Record<string, IpcSchema>> = UnionToIntersection<{
44
+ [N in keyof S]: NamespaceApi<S[N]>;
45
+ }[keyof S]>;
46
+ export declare function createIpcManager<S extends Record<string, IpcSchema>>(): <N extends keyof S & string>(namespace: N) => IpcManager<S[N]>;
52
47
  export {};
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.APP_CHANNELS = exports.IpcManager = void 0;
4
4
  exports.setupAppIpc = setupAppIpc;
5
- exports.createAppBridge = createAppBridge;
5
+ exports.createIpcManager = createIpcManager;
6
6
  const electron_1 = require("electron");
7
7
  const files_1 = require("./files");
8
8
  function setupAppIpc(storage) {
@@ -64,31 +64,6 @@ exports.APP_CHANNELS = {
64
64
  setValue: "app:set-value",
65
65
  syncAuth: "app:sync-auth"
66
66
  };
67
- /**
68
- * Creates the standard application controls exposed by an Electron preload.
69
- */
70
- function createAppBridge(ipc) {
71
- return {
72
- minimize: () => {
73
- ipc.send(exports.APP_CHANNELS.minimize);
74
- },
75
- close: () => {
76
- ipc.send(exports.APP_CHANNELS.close);
77
- },
78
- choosePath: () => {
79
- return ipc.invoke(exports.APP_CHANNELS.choosePath);
80
- },
81
- openLink: (url) => {
82
- ipc.send(exports.APP_CHANNELS.openLink, url);
83
- },
84
- getValue: (key) => {
85
- return ipc.invoke(exports.APP_CHANNELS.getValue, key);
86
- },
87
- setValue: (key, value) => {
88
- return ipc.invoke(exports.APP_CHANNELS.setValue, key, value);
89
- },
90
- syncAuth: (accessToken) => {
91
- return ipc.send(exports.APP_CHANNELS.syncAuth, accessToken);
92
- }
93
- };
67
+ function createIpcManager() {
68
+ return (namespace) => new IpcManager(namespace);
94
69
  }
package/dist/csp.d.ts CHANGED
@@ -1,17 +1,3 @@
1
- /**
2
- * Content Security Policies.
3
- *
4
- * Production:
5
- * - Restrict all resources to the app bundle (`'self'`) by default.
6
- * - Allow network access only to Supabase.
7
- * - Enable safe playback of audio/media via `blob:` and `data:` URLs.
8
- * - Explicitly disable dangerous features such as plugins and framing.
9
- *
10
- * Development:
11
- * - Relax restrictions to support hot reload, devtools, and local servers.
12
- * - Allow inline scripts and eval (required by some bundlers/dev servers).
13
- * - Permit WebSocket connections to localhost.
14
- **/
15
- export declare const csp: string;
16
- export declare const devCsp: string;
17
- export declare const setupCspPolicy: () => void;
1
+ export declare const buildCsp: (connectSrc?: string[]) => string;
2
+ export declare const buildDevCsp: (connectSrc?: string[]) => string;
3
+ export declare const setupCspPolicy: (connectSrc?: string[]) => void;
package/dist/csp.js CHANGED
@@ -1,50 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setupCspPolicy = exports.devCsp = exports.csp = void 0;
3
+ exports.setupCspPolicy = exports.buildDevCsp = exports.buildCsp = void 0;
4
4
  const electron_1 = require("electron");
5
- const ts_1 = require("@bouko/ts");
6
- /**
7
- * Content Security Policies.
8
- *
9
- * Production:
10
- * - Restrict all resources to the app bundle (`'self'`) by default.
11
- * - Allow network access only to Supabase.
12
- * - Enable safe playback of audio/media via `blob:` and `data:` URLs.
13
- * - Explicitly disable dangerous features such as plugins and framing.
14
- *
15
- * Development:
16
- * - Relax restrictions to support hot reload, devtools, and local servers.
17
- * - Allow inline scripts and eval (required by some bundlers/dev servers).
18
- * - Permit WebSocket connections to localhost.
19
- **/
20
- exports.csp = "default-src 'self'; " +
5
+ const buildCsp = (connectSrc = []) => "default-src 'self'; " +
21
6
  "script-src 'self'; " +
22
7
  "style-src 'self'; " +
23
8
  "img-src 'self' data: https:; " +
24
9
  "font-src 'self' data:; " +
25
- `connect-src 'self' blob: ${(0, ts_1.getEnv)("BASE_URL")} ${(0, ts_1.getEnv)("DB_URL")}; ` +
10
+ `connect-src ${["'self'", "blob:", ...connectSrc].join(" ")}; ` +
26
11
  "media-src 'self' blob: data:; " +
27
12
  "worker-src 'self' blob:; " +
28
13
  "object-src 'none'; " +
29
14
  "base-uri 'self'; " +
30
15
  "frame-ancestors 'none';";
31
- exports.devCsp = "default-src 'self' http://localhost:* blob: data:; " +
16
+ exports.buildCsp = buildCsp;
17
+ const buildDevCsp = (connectSrc = []) => "default-src 'self' http://localhost:* blob: data:; " +
32
18
  "script-src 'self' 'unsafe-eval' 'unsafe-inline' http://localhost:*; " +
33
19
  "style-src 'self' 'unsafe-inline' http://localhost:*; " +
34
20
  "img-src 'self' data: blob: http://localhost:* https:; " +
35
21
  "media-src 'self' blob: data:; " +
36
22
  "worker-src 'self' blob: http://localhost:*; " +
37
- `connect-src 'self' blob: http://localhost:* ws://localhost:* ${(0, ts_1.getEnv)("BASE_URL")} ${(0, ts_1.getEnv)("DB_URL")};`;
38
- const setupCspPolicy = () => electron_1.session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
39
- if (details.url.startsWith("file://") || details.url.startsWith("http://localhost")) {
40
- callback({
41
- responseHeaders: {
42
- ...details.responseHeaders,
43
- "Content-Security-Policy": [!electron_1.app.isPackaged ? exports.devCsp : exports.csp],
44
- },
45
- });
46
- return;
47
- }
48
- callback({ responseHeaders: details.responseHeaders });
49
- });
23
+ `connect-src ${["'self'", "blob:", "http://localhost:*", "ws://localhost:*", ...connectSrc].join(" ")};`;
24
+ exports.buildDevCsp = buildDevCsp;
25
+ const setupCspPolicy = (connectSrc = []) => {
26
+ const policy = electron_1.app.isPackaged ? (0, exports.buildCsp)(connectSrc) : (0, exports.buildDevCsp)(connectSrc);
27
+ electron_1.session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
28
+ if (details.url.startsWith("file://") || details.url.startsWith("http://localhost")) {
29
+ callback({
30
+ responseHeaders: {
31
+ ...details.responseHeaders,
32
+ "Content-Security-Policy": [policy],
33
+ },
34
+ });
35
+ return;
36
+ }
37
+ callback({ responseHeaders: details.responseHeaders });
38
+ });
39
+ };
50
40
  exports.setupCspPolicy = setupCspPolicy;
package/dist/setup.d.ts CHANGED
@@ -2,5 +2,6 @@ import Storage from "electron-store";
2
2
  export type Options = {
3
3
  width: number;
4
4
  height: number;
5
+ connectSrc?: string[];
5
6
  };
6
7
  export declare function setupApp<T extends Record<string, any>>(app: Electron.App, storage: Storage<T>, opts: Options): void;
package/dist/setup.js CHANGED
@@ -28,8 +28,8 @@ function setupApp(app, storage, opts) {
28
28
  return mainWindow;
29
29
  }
30
30
  app.on("ready", () => {
31
+ (0, csp_1.setupCspPolicy)(opts.connectSrc);
31
32
  createWindow();
32
- (0, csp_1.setupCspPolicy)();
33
33
  });
34
34
  app.on("activate", () => {
35
35
  if (electron_1.BrowserWindow.getAllWindows().length === 0)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
 
3
3
  "name": "@proton-app/main",
4
- "version": "0.1.4",
4
+ "version": "0.1.6",
5
5
  "description": "",
6
6
  "keywords": [],
7
7
  "author": "",