1+ /**
2+ * IPC handlers for electronFSAPI
3+ * Preload location: contextBridge.exposeInMainWorld('electronFSAPI', { ... })
4+ *
5+ * NOTE: This file is copied from phoenix-fs library. Do not modify without
6+ * updating the source library. Only add new Phoenix-specific handlers to main-window-ipc.js.
7+ */
8+
19const { ipcMain, dialog, BrowserWindow } = require ( 'electron' ) ;
210const path = require ( 'path' ) ;
311const fsp = require ( 'fs/promises' ) ;
412const os = require ( 'os' ) ;
5- const { identifier : APP_IDENTIFIER } = require ( './package.json' ) ;
13+ const { identifier : APP_IDENTIFIER } = require ( './config' ) ;
14+ const { assertTrusted } = require ( './ipc-security' ) ;
615
716// Electron IPC only preserves Error.message when errors cross the IPC boundary (see
817// https://github.com/electron/electron/issues/24427). To preserve error.code for FS
@@ -39,25 +48,32 @@ function getAppDataDir() {
3948
4049function registerFsIpcHandlers ( ) {
4150 // Directory APIs
42- ipcMain . handle ( 'get-documents-dir' , ( ) => {
51+ ipcMain . handle ( 'get-documents-dir' , ( event ) => {
52+ assertTrusted ( event ) ;
4353 // Match Tauri's documentDir which ends with a trailing slash
4454 return path . join ( os . homedir ( ) , 'Documents' ) + path . sep ;
4555 } ) ;
4656
47- ipcMain . handle ( 'get-home-dir' , ( ) => {
57+ ipcMain . handle ( 'get-home-dir' , ( event ) => {
58+ assertTrusted ( event ) ;
4859 // Match Tauri's homeDir which ends with a trailing slash
4960 const home = os . homedir ( ) ;
5061 return home . endsWith ( path . sep ) ? home : home + path . sep ;
5162 } ) ;
5263
53- ipcMain . handle ( 'get-temp-dir' , ( ) => {
64+ ipcMain . handle ( 'get-temp-dir' , ( event ) => {
65+ assertTrusted ( event ) ;
5466 return os . tmpdir ( ) ;
5567 } ) ;
5668
57- ipcMain . handle ( 'get-app-data-dir' , ( ) => getAppDataDir ( ) ) ;
69+ ipcMain . handle ( 'get-app-data-dir' , ( event ) => {
70+ assertTrusted ( event ) ;
71+ return getAppDataDir ( ) ;
72+ } ) ;
5873
5974 // Get Windows drive letters (returns null on non-Windows platforms)
60- ipcMain . handle ( 'get-windows-drives' , async ( ) => {
75+ ipcMain . handle ( 'get-windows-drives' , async ( event ) => {
76+ assertTrusted ( event ) ;
6177 if ( process . platform !== 'win32' ) {
6278 return null ;
6379 }
@@ -78,26 +94,30 @@ function registerFsIpcHandlers() {
7894
7995 // Dialogs
8096 ipcMain . handle ( 'show-open-dialog' , async ( event , options ) => {
97+ assertTrusted ( event ) ;
8198 const win = BrowserWindow . fromWebContents ( event . sender ) ;
8299 const result = await dialog . showOpenDialog ( win , options ) ;
83100 return result . filePaths ;
84101 } ) ;
85102
86103 ipcMain . handle ( 'show-save-dialog' , async ( event , options ) => {
104+ assertTrusted ( event ) ;
87105 const win = BrowserWindow . fromWebContents ( event . sender ) ;
88106 const result = await dialog . showSaveDialog ( win , options ) ;
89107 return result . filePath ;
90108 } ) ;
91109
92110 // FS operations
93111 ipcMain . handle ( 'fs-readdir' , async ( event , dirPath ) => {
112+ assertTrusted ( event ) ;
94113 return fsResult (
95114 fsp . readdir ( dirPath , { withFileTypes : true } )
96115 . then ( entries => entries . map ( e => ( { name : e . name , isDirectory : e . isDirectory ( ) } ) ) )
97116 ) ;
98117 } ) ;
99118
100119 ipcMain . handle ( 'fs-stat' , async ( event , filePath ) => {
120+ assertTrusted ( event ) ;
101121 return fsResult (
102122 fsp . stat ( filePath ) . then ( stats => ( {
103123 isFile : stats . isFile ( ) ,
@@ -114,12 +134,30 @@ function registerFsIpcHandlers() {
114134 ) ;
115135 } ) ;
116136
117- ipcMain . handle ( 'fs-mkdir' , ( event , dirPath , options ) => fsResult ( fsp . mkdir ( dirPath , options ) ) ) ;
118- ipcMain . handle ( 'fs-unlink' , ( event , filePath ) => fsResult ( fsp . unlink ( filePath ) ) ) ;
119- ipcMain . handle ( 'fs-rmdir' , ( event , dirPath , options ) => fsResult ( fsp . rm ( dirPath , options ) ) ) ;
120- ipcMain . handle ( 'fs-rename' , ( event , oldPath , newPath ) => fsResult ( fsp . rename ( oldPath , newPath ) ) ) ;
121- ipcMain . handle ( 'fs-read-file' , ( event , filePath ) => fsResult ( fsp . readFile ( filePath ) ) ) ;
122- ipcMain . handle ( 'fs-write-file' , ( event , filePath , data ) => fsResult ( fsp . writeFile ( filePath , Buffer . from ( data ) ) ) ) ;
137+ ipcMain . handle ( 'fs-mkdir' , ( event , dirPath , options ) => {
138+ assertTrusted ( event ) ;
139+ return fsResult ( fsp . mkdir ( dirPath , options ) ) ;
140+ } ) ;
141+ ipcMain . handle ( 'fs-unlink' , ( event , filePath ) => {
142+ assertTrusted ( event ) ;
143+ return fsResult ( fsp . unlink ( filePath ) ) ;
144+ } ) ;
145+ ipcMain . handle ( 'fs-rmdir' , ( event , dirPath , options ) => {
146+ assertTrusted ( event ) ;
147+ return fsResult ( fsp . rm ( dirPath , options ) ) ;
148+ } ) ;
149+ ipcMain . handle ( 'fs-rename' , ( event , oldPath , newPath ) => {
150+ assertTrusted ( event ) ;
151+ return fsResult ( fsp . rename ( oldPath , newPath ) ) ;
152+ } ) ;
153+ ipcMain . handle ( 'fs-read-file' , ( event , filePath ) => {
154+ assertTrusted ( event ) ;
155+ return fsResult ( fsp . readFile ( filePath ) ) ;
156+ } ) ;
157+ ipcMain . handle ( 'fs-write-file' , ( event , filePath , data ) => {
158+ assertTrusted ( event ) ;
159+ return fsResult ( fsp . writeFile ( filePath , Buffer . from ( data ) ) ) ;
160+ } ) ;
123161}
124162
125163module . exports = {
0 commit comments