11import { spawn } from 'node:child_process'
22import { promises as fs } from 'node:fs'
3+ import * as os from 'node:os'
34import * as path from 'node:path'
45import { app } from 'electron'
56import { ExtensionSender } from '../../router'
@@ -22,26 +23,35 @@ function isValidConfig(config: any): config is NativeConfig {
2223 typeof config . name === 'string' &&
2324 typeof config . description === 'string' &&
2425 typeof config . path === 'string' &&
25- config . stdio === 'stdio' &&
26+ config . type === 'stdio' &&
2627 Array . isArray ( config . allowed_origins )
2728 )
2829}
2930
30- async function readNativeMessagingHostConfig (
31- application : string ,
32- ) : Promise < NativeConfig | undefined > {
31+ async function getConfigSearchPaths ( application : string ) {
32+ const appJson = `${ application } .json`
3333 let searchPaths : string [ ]
3434 switch ( process . platform ) {
3535 case 'darwin' :
3636 searchPaths = [
37- path . join ( app . getPath ( 'userData' ) , 'NativeMessagingHosts' , `${ application } .json` ) ,
38- path . join ( '/Library/Google/Chrome/NativeMessagingHosts' , `${ application } .json` ) ,
37+ path . join ( '/Library/Google/Chrome/NativeMessagingHosts' , appJson ) ,
38+ // Also look under Chrome's directory since some apps only install their
39+ // config there
40+ path . join (
41+ os . homedir ( ) ,
42+ 'Library' ,
43+ 'Application Support' ,
44+ 'Google/Chrome/NativeMessagingHosts' ,
45+ appJson ,
46+ ) ,
47+ path . join ( app . getPath ( 'userData' ) , 'NativeMessagingHosts' , appJson ) ,
3948 ]
4049 break
4150 case 'linux' :
4251 searchPaths = [
43- path . join ( app . getPath ( 'userData' ) , 'NativeMessagingHosts' , `${ application } .json` ) ,
44- path . join ( '/etc/opt/chrome/native-messaging-hosts/' , `${ application } .json` ) ,
52+ path . join ( '/etc/opt/chrome/native-messaging-hosts/' , appJson ) ,
53+ path . join ( os . homedir ( ) , '.config/google-chrome/NativeMessagingHosts/' , appJson ) ,
54+ path . join ( app . getPath ( 'userData' ) , 'NativeMessagingHosts' , appJson ) ,
4555 ]
4656 break
4757 case 'win32' : {
@@ -58,14 +68,29 @@ async function readNativeMessagingHostConfig(
5868 default :
5969 throw new Error ( 'Unsupported platform' )
6070 }
71+ return searchPaths
72+ }
6173
74+ async function readNativeMessagingHostConfig (
75+ application : string ,
76+ ) : Promise < NativeConfig | undefined > {
77+ const searchPaths = await getConfigSearchPaths ( application )
6278 for ( const filePath of searchPaths ) {
6379 try {
6480 const data = await fs . readFile ( filePath )
6581 const config = JSON . parse ( data . toString ( ) )
66- if ( isValidConfig ( config ) ) return config
82+ if ( isValidConfig ( config ) ) {
83+ d ( 'read config in %s' , filePath , config )
84+ return config
85+ } else {
86+ d ( '%s contained invalid config' , filePath , config )
87+ }
6788 } catch ( error ) {
68- d ( 'readNativeMessagingHostConfig: unable to read %s' , filePath , error )
89+ if ( ( error as NodeJS . ErrnoException ) ?. code === 'ENOENT' ) {
90+ d ( 'unable to read %s' , filePath )
91+ } else {
92+ d ( 'unknown error' , error )
93+ }
6994 continue
7095 }
7196 }
0 commit comments