mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
style: run prettier
This commit is contained in:
@@ -11,10 +11,7 @@ const addPortableToPortableExecutableFileName = () => {
|
||||
for (const file of files) {
|
||||
if (file.endsWith('.exe') && !file.match('Setup')) {
|
||||
const filePath = path.resolve(distFolderPath, file);
|
||||
const renamedFilePath = path.resolve(
|
||||
distFolderPath,
|
||||
file.replace('plebchan', 'plebchan Portable')
|
||||
);
|
||||
const renamedFilePath = path.resolve(distFolderPath, file.replace('plebchan', 'plebchan Portable'));
|
||||
fs.moveSync(filePath, renamedFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
+123
-144
@@ -1,52 +1,40 @@
|
||||
require('./log')
|
||||
const {
|
||||
app,
|
||||
BrowserWindow,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Tray,
|
||||
screen: electronScreen,
|
||||
shell,
|
||||
dialog
|
||||
} = require('electron')
|
||||
const isDev = require('electron-is-dev')
|
||||
const path = require('path')
|
||||
const startIpfs = require('./start-ipfs')
|
||||
const startPlebbitRpcServer = require('./start-plebbit-rpc')
|
||||
const { URL } = require('node:url')
|
||||
const tcpPortUsed = require('tcp-port-used')
|
||||
require('./log');
|
||||
const { app, BrowserWindow, Menu, MenuItem, Tray, screen: electronScreen, shell, dialog } = require('electron');
|
||||
const isDev = require('electron-is-dev');
|
||||
const path = require('path');
|
||||
const startIpfs = require('./start-ipfs');
|
||||
const startPlebbitRpcServer = require('./start-plebbit-rpc');
|
||||
const { URL } = require('node:url');
|
||||
const tcpPortUsed = require('tcp-port-used');
|
||||
|
||||
// retry starting ipfs every 10 second,
|
||||
// retry starting ipfs every 10 second,
|
||||
// in case it was started by another client that shut down and shut down ipfs with it
|
||||
let startIpfsError
|
||||
let startIpfsError;
|
||||
setInterval(async () => {
|
||||
try {
|
||||
const started = await tcpPortUsed.check(5001, '127.0.0.1')
|
||||
const started = await tcpPortUsed.check(5001, '127.0.0.1');
|
||||
if (started) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
await startIpfs()
|
||||
await startIpfs();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
startIpfsError = e;
|
||||
dialog.showErrorBox('IPFS error', startIpfsError.message);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e)
|
||||
startIpfsError = e
|
||||
dialog.showErrorBox('IPFS error', startIpfsError.message)
|
||||
}
|
||||
}, 10000)
|
||||
}, 10000);
|
||||
|
||||
// use common user agent instead of electron so img, video, audio, iframe elements don't get blocked
|
||||
// https://www.whatismybrowser.com/guides/the-latest-version/chrome
|
||||
// https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome
|
||||
// NOTE: eventually should probably fake sec-ch-ua header as well
|
||||
let fakeUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
|
||||
if (process.platform === 'darwin')
|
||||
fakeUserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
|
||||
if (process.platform === 'linux')
|
||||
fakeUserAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
|
||||
const realUserAgent = `plebchan/${require('../package.json').version}`
|
||||
let fakeUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36';
|
||||
if (process.platform === 'darwin') fakeUserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36';
|
||||
if (process.platform === 'linux') fakeUserAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36';
|
||||
const realUserAgent = `plebchan/${require('../package.json').version}`;
|
||||
|
||||
// add right click menu
|
||||
const contextMenu = require('electron-context-menu')
|
||||
const contextMenu = require('electron-context-menu');
|
||||
contextMenu({
|
||||
// prepend custom buttons to top
|
||||
prepend: (defaultActions, parameters, browserWindow) => [
|
||||
@@ -76,7 +64,7 @@ contextMenu({
|
||||
showInspectElement: true,
|
||||
showServices: false,
|
||||
showSearchWithGoogle: false,
|
||||
})
|
||||
});
|
||||
|
||||
const createMainWindow = () => {
|
||||
let mainWindow = new BrowserWindow({
|
||||
@@ -91,199 +79,192 @@ const createMainWindow = () => {
|
||||
devTools: true, // TODO: change to isDev when no bugs left
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
// set fake user agent
|
||||
mainWindow.webContents.userAgent = fakeUserAgent
|
||||
mainWindow.webContents.userAgent = fakeUserAgent;
|
||||
|
||||
// set custom user agent and other headers for window.fetch requests to prevent origin errors
|
||||
mainWindow.webContents.session.webRequest.onBeforeSendHeaders({urls: ['*://*/*']}, (details, callback) => {
|
||||
const isIframe = !!details.frame?.parent
|
||||
mainWindow.webContents.session.webRequest.onBeforeSendHeaders({ urls: ['*://*/*'] }, (details, callback) => {
|
||||
const isIframe = !!details.frame?.parent;
|
||||
// if not a fetch request (or fetch request is from within iframe), do nothing, filtering webRequest by types doesn't seem to work
|
||||
if (details.resourceType !== 'xhr' || isIframe) {
|
||||
return callback({requestHeaders: details.requestHeaders})
|
||||
return callback({ requestHeaders: details.requestHeaders });
|
||||
}
|
||||
// add privacy
|
||||
details.requestHeaders['User-Agent'] = realUserAgent
|
||||
details.requestHeaders['sec-ch-ua'] = undefined
|
||||
details.requestHeaders['sec-ch-ua-platform'] = undefined
|
||||
details.requestHeaders['sec-ch-ua-mobile'] = undefined
|
||||
details.requestHeaders['Sec-Fetch-Dest'] = undefined
|
||||
details.requestHeaders['Sec-Fetch-Mode'] = undefined
|
||||
details.requestHeaders['Sec-Fetch-Site'] = undefined
|
||||
details.requestHeaders['User-Agent'] = realUserAgent;
|
||||
details.requestHeaders['sec-ch-ua'] = undefined;
|
||||
details.requestHeaders['sec-ch-ua-platform'] = undefined;
|
||||
details.requestHeaders['sec-ch-ua-mobile'] = undefined;
|
||||
details.requestHeaders['Sec-Fetch-Dest'] = undefined;
|
||||
details.requestHeaders['Sec-Fetch-Mode'] = undefined;
|
||||
details.requestHeaders['Sec-Fetch-Site'] = undefined;
|
||||
// prevent origin errors
|
||||
details.requestHeaders['Origin'] = undefined
|
||||
callback({requestHeaders: details.requestHeaders})
|
||||
})
|
||||
details.requestHeaders['Origin'] = undefined;
|
||||
callback({ requestHeaders: details.requestHeaders });
|
||||
});
|
||||
|
||||
// fix cors errors for window.fetch. must not be enabled for iframe or can cause remote code execution
|
||||
mainWindow.webContents.session.webRequest.onHeadersReceived({urls: ['*://*/*']}, (details, callback) => {
|
||||
const isIframe = !!details.frame?.parent
|
||||
mainWindow.webContents.session.webRequest.onHeadersReceived({ urls: ['*://*/*'] }, (details, callback) => {
|
||||
const isIframe = !!details.frame?.parent;
|
||||
// if not a fetch request (or fetch request is from within iframe), do nothing, filtering webRequest by types doesn't seem to work
|
||||
if (details.resourceType !== 'xhr' || isIframe) {
|
||||
return callback({responseHeaders: details.responseHeaders})
|
||||
return callback({ responseHeaders: details.responseHeaders });
|
||||
}
|
||||
// must delete lower case headers or both '*, *' could get added
|
||||
delete details.responseHeaders['access-control-allow-origin']
|
||||
delete details.responseHeaders['access-control-allow-headers']
|
||||
delete details.responseHeaders['access-control-allow-methods']
|
||||
delete details.responseHeaders['access-control-expose-headers']
|
||||
details.responseHeaders['Access-Control-Allow-Origin'] = '*'
|
||||
details.responseHeaders['Access-Control-Allow-Headers'] = '*'
|
||||
details.responseHeaders['Access-Control-Allow-Methods'] = '*'
|
||||
details.responseHeaders['Access-Control-Expose-Headers'] = '*'
|
||||
callback({responseHeaders: details.responseHeaders})
|
||||
})
|
||||
delete details.responseHeaders['access-control-allow-origin'];
|
||||
delete details.responseHeaders['access-control-allow-headers'];
|
||||
delete details.responseHeaders['access-control-allow-methods'];
|
||||
delete details.responseHeaders['access-control-expose-headers'];
|
||||
details.responseHeaders['Access-Control-Allow-Origin'] = '*';
|
||||
details.responseHeaders['Access-Control-Allow-Headers'] = '*';
|
||||
details.responseHeaders['Access-Control-Allow-Methods'] = '*';
|
||||
details.responseHeaders['Access-Control-Expose-Headers'] = '*';
|
||||
callback({ responseHeaders: details.responseHeaders });
|
||||
});
|
||||
|
||||
const startURL = isDev
|
||||
? 'http://localhost:3000'
|
||||
: `file://${path.join(__dirname, '../build/index.html')}`
|
||||
const startURL = isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`;
|
||||
|
||||
mainWindow.loadURL(startURL)
|
||||
mainWindow.loadURL(startURL);
|
||||
|
||||
mainWindow.once('ready-to-show', async () => {
|
||||
// make sure back button is disabled on launch
|
||||
mainWindow.webContents.clearHistory()
|
||||
mainWindow.webContents.clearHistory();
|
||||
|
||||
mainWindow.show()
|
||||
mainWindow.show();
|
||||
|
||||
if (isDev) {
|
||||
mainWindow.openDevTools()
|
||||
mainWindow.openDevTools();
|
||||
}
|
||||
|
||||
if (startIpfsError) {
|
||||
dialog.showErrorBox('IPFS error', startIpfsError.message)
|
||||
dialog.showErrorBox('IPFS error', startIpfsError.message);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
mainWindow = null;
|
||||
});
|
||||
|
||||
// don't open new windows
|
||||
mainWindow.webContents.on('new-window', (event, url) => {
|
||||
event.preventDefault()
|
||||
mainWindow.loadURL(url)
|
||||
})
|
||||
event.preventDefault();
|
||||
mainWindow.loadURL(url);
|
||||
});
|
||||
|
||||
// open links in external browser
|
||||
// do not open links in plebchan or will lead to remote execution
|
||||
mainWindow.webContents.on('will-navigate', (e, originalUrl) => {
|
||||
if (originalUrl != mainWindow.webContents.getURL()) {
|
||||
e.preventDefault()
|
||||
e.preventDefault();
|
||||
try {
|
||||
// do not let the user open any url with shell.openExternal
|
||||
// or it will lead to remote execution https://benjamin-altpeter.de/shell-openexternal-dangers/
|
||||
|
||||
// only open valid https urls to prevent remote execution
|
||||
// will throw if url isn't valid
|
||||
const validatedUrl = new URL(originalUrl)
|
||||
let serializedUrl = ''
|
||||
const validatedUrl = new URL(originalUrl);
|
||||
let serializedUrl = '';
|
||||
|
||||
// make an exception for ipfs stats
|
||||
if (validatedUrl.toString() === 'http://localhost:5001/webui/') {
|
||||
serializedUrl = validatedUrl.toString()
|
||||
serializedUrl = validatedUrl.toString();
|
||||
} else if (validatedUrl.protocol === 'https:') {
|
||||
// open serialized url to prevent remote execution
|
||||
serializedUrl = validatedUrl.toString()
|
||||
serializedUrl = validatedUrl.toString();
|
||||
} else {
|
||||
throw Error(`can't open url '${originalUrl}', it's not https and not the allowed http exception`)
|
||||
throw Error(`can't open url '${originalUrl}', it's not https and not the allowed http exception`);
|
||||
}
|
||||
|
||||
shell.openExternal(serializedUrl)
|
||||
shell.openExternal(serializedUrl);
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// open links (with target="_blank") in external browser
|
||||
// do not open links in plebchan or will lead to remote execution
|
||||
mainWindow.webContents.setWindowOpenHandler(({url}) => {
|
||||
const originalUrl = url
|
||||
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
const originalUrl = url;
|
||||
try {
|
||||
// do not let the user open any url with shell.openExternal
|
||||
// or it will lead to remote execution https://benjamin-altpeter.de/shell-openexternal-dangers/
|
||||
|
||||
// only open valid https urls to prevent remote execution
|
||||
// will throw if url isn't valid
|
||||
const validatedUrl = new URL(originalUrl)
|
||||
let serializedUrl = ''
|
||||
const validatedUrl = new URL(originalUrl);
|
||||
let serializedUrl = '';
|
||||
|
||||
// make an exception for ipfs stats
|
||||
if (validatedUrl.toString() === 'http://localhost:5001/webui/') {
|
||||
serializedUrl = validatedUrl.toString()
|
||||
serializedUrl = validatedUrl.toString();
|
||||
} else if (validatedUrl.protocol === 'https:') {
|
||||
// open serialized url to prevent remote execution
|
||||
serializedUrl = validatedUrl.toString()
|
||||
serializedUrl = validatedUrl.toString();
|
||||
} else {
|
||||
throw Error(`can't open url '${originalUrl}', it's not https and not the allowed http exception`)
|
||||
throw Error(`can't open url '${originalUrl}', it's not https and not the allowed http exception`);
|
||||
}
|
||||
|
||||
shell.openExternal(serializedUrl)
|
||||
shell.openExternal(serializedUrl);
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
console.warn(e);
|
||||
}
|
||||
return {action: 'deny'}
|
||||
})
|
||||
return { action: 'deny' };
|
||||
});
|
||||
|
||||
// deny permissions like location, notifications, etc https://www.electronjs.org/docs/latest/tutorial/security#5-handle-session-permission-requests-from-remote-content
|
||||
mainWindow.webContents.session.setPermissionRequestHandler((webContents, permission, callback) => {
|
||||
// deny all permissions
|
||||
return callback(false)
|
||||
})
|
||||
return callback(false);
|
||||
});
|
||||
|
||||
// deny attaching webview https://www.electronjs.org/docs/latest/tutorial/security#12-verify-webview-options-before-creation
|
||||
mainWindow.webContents.on('will-attach-webview', (e, webPreferences, params) => {
|
||||
// deny all
|
||||
e.preventDefault()
|
||||
})
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
if (process.platform !== 'darwin') {
|
||||
// tray
|
||||
const trayIconPath = path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
isDev ? 'public' : 'build',
|
||||
'electron-tray-icon.png'
|
||||
)
|
||||
const tray = new Tray(trayIconPath)
|
||||
tray.setToolTip('plebchan')
|
||||
const trayIconPath = path.join(__dirname, '..', isDev ? 'public' : 'build', 'electron-tray-icon.png');
|
||||
const tray = new Tray(trayIconPath);
|
||||
tray.setToolTip('plebchan');
|
||||
const trayMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'Open plebchan',
|
||||
click: () => {
|
||||
mainWindow.show()
|
||||
mainWindow.show();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Quit plebchan',
|
||||
click: () => {
|
||||
mainWindow.destroy()
|
||||
app.quit()
|
||||
mainWindow.destroy();
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
])
|
||||
tray.setContextMenu(trayMenu)
|
||||
]);
|
||||
tray.setContextMenu(trayMenu);
|
||||
|
||||
// show/hide on tray right click
|
||||
tray.on('right-click', () => {
|
||||
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()
|
||||
})
|
||||
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
|
||||
});
|
||||
|
||||
// close to tray
|
||||
if (!isDev) {
|
||||
let isQuiting = false
|
||||
let isQuiting = false;
|
||||
app.on('before-quit', () => {
|
||||
isQuiting = true
|
||||
})
|
||||
isQuiting = true;
|
||||
});
|
||||
mainWindow.on('close', (event) => {
|
||||
if (!isQuiting) {
|
||||
event.preventDefault()
|
||||
mainWindow.hide()
|
||||
event.returnValue = false
|
||||
event.preventDefault();
|
||||
mainWindow.hide();
|
||||
event.returnValue = false;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,48 +272,46 @@ const createMainWindow = () => {
|
||||
label: '←',
|
||||
enabled: mainWindow?.webContents?.canGoBack(),
|
||||
click: () => mainWindow?.webContents?.goBack(),
|
||||
})
|
||||
});
|
||||
const appMenuForward = new MenuItem({
|
||||
label: '→',
|
||||
enabled: mainWindow?.webContents?.canGoForward(),
|
||||
click: () => mainWindow?.webContents?.goForward(),
|
||||
})
|
||||
});
|
||||
const appMenuReload = new MenuItem({
|
||||
label: '⟳',
|
||||
role: 'reload',
|
||||
click: () => mainWindow?.webContents?.reload(),
|
||||
})
|
||||
});
|
||||
|
||||
// application menu
|
||||
// hide useless electron help menu
|
||||
if (process.platform === 'darwin') {
|
||||
const appMenu = Menu.getApplicationMenu()
|
||||
appMenu.insert(1, appMenuBack)
|
||||
appMenu.insert(2, appMenuForward)
|
||||
appMenu.insert(3, appMenuReload)
|
||||
Menu.setApplicationMenu(appMenu)
|
||||
const appMenu = Menu.getApplicationMenu();
|
||||
appMenu.insert(1, appMenuBack);
|
||||
appMenu.insert(2, appMenuForward);
|
||||
appMenu.insert(3, appMenuReload);
|
||||
Menu.setApplicationMenu(appMenu);
|
||||
} else {
|
||||
// Other platforms
|
||||
const originalAppMenuWithoutHelp = Menu.getApplicationMenu()?.items.filter(
|
||||
(item) => item.role !== 'help'
|
||||
)
|
||||
const appMenu = [appMenuBack, appMenuForward, appMenuReload, ...originalAppMenuWithoutHelp]
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(appMenu))
|
||||
const originalAppMenuWithoutHelp = Menu.getApplicationMenu()?.items.filter((item) => item.role !== 'help');
|
||||
const appMenu = [appMenuBack, appMenuForward, appMenuReload, ...originalAppMenuWithoutHelp];
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(appMenu));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createMainWindow()
|
||||
createMainWindow();
|
||||
|
||||
app.on('activate', () => {
|
||||
if (!BrowserWindow.getAllWindows().length) {
|
||||
createMainWindow()
|
||||
createMainWindow();
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
app.quit();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
+6
-6
@@ -1,16 +1,16 @@
|
||||
const { contextBridge } = require('electron')
|
||||
const { contextBridge } = require('electron');
|
||||
|
||||
// dev uses http://localhost, prod uses file://...index.html
|
||||
const isDev = window.location.protocol === 'http:'
|
||||
const isDev = window.location.protocol === 'http:';
|
||||
|
||||
const defaultPlebbitOptions = {
|
||||
plebbitRpcClientsOptions: ['ws://localhost:9138']
|
||||
}
|
||||
plebbitRpcClientsOptions: ['ws://localhost:9138'],
|
||||
};
|
||||
|
||||
contextBridge.exposeInMainWorld('defaultPlebbitOptions', defaultPlebbitOptions)
|
||||
contextBridge.exposeInMainWorld('defaultPlebbitOptions', defaultPlebbitOptions);
|
||||
|
||||
// expose a flag to indicate that we are running in electron
|
||||
contextBridge.exposeInMainWorld('electron', { isElectron: true })
|
||||
contextBridge.exposeInMainWorld('electron', { isElectron: true });
|
||||
|
||||
// uncomment for logs
|
||||
// localStorage.debug = 'plebbit-js:*,plebbit-react-hooks:*,plebchan:*'
|
||||
|
||||
+3
-12
@@ -13,12 +13,7 @@ const spawnAsync = (...args) =>
|
||||
const spawedProcess = spawn(...args);
|
||||
spawedProcess.on('exit', (exitCode, signal) => {
|
||||
if (exitCode === 0) resolve();
|
||||
else
|
||||
reject(
|
||||
Error(
|
||||
`spawnAsync process '${spawedProcess.pid}' exited with code '${exitCode}' signal '${signal}'`
|
||||
)
|
||||
);
|
||||
else reject(Error(`spawnAsync process '${spawedProcess.pid}' exited with code '${exitCode}' signal '${signal}'`));
|
||||
});
|
||||
spawedProcess.stderr.on('data', (data) => console.error(data.toString()));
|
||||
spawedProcess.stdin.on('data', (data) => console.log(data.toString()));
|
||||
@@ -59,7 +54,7 @@ const startIpfs = async () => {
|
||||
} catch (e) {}
|
||||
|
||||
// dont use 8080 port because it's too common
|
||||
await spawnAsync(ipfsPath, ['config', '--json', 'Addresses.Gateway', "null"], {
|
||||
await spawnAsync(ipfsPath, ['config', '--json', 'Addresses.Gateway', 'null'], {
|
||||
env,
|
||||
hideWindows: true,
|
||||
});
|
||||
@@ -73,11 +68,7 @@ const startIpfs = async () => {
|
||||
await spawnAsync(ipfsPath, ['config', 'Addresses.API', apiAddress], { env, hideWindows: true });
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
const ipfsProcess = spawn(
|
||||
ipfsPath,
|
||||
['daemon', '--migrate', '--enable-pubsub-experiment', '--enable-namesys-pubsub'],
|
||||
{ env, hideWindows: true }
|
||||
);
|
||||
const ipfsProcess = spawn(ipfsPath, ['daemon', '--migrate', '--enable-pubsub-experiment', '--enable-namesys-pubsub'], { env, hideWindows: true });
|
||||
console.log(`ipfs daemon process started with pid ${ipfsProcess.pid}`);
|
||||
let lastError;
|
||||
ipfsProcess.stderr.on('data', (data) => {
|
||||
|
||||
@@ -1,69 +1,67 @@
|
||||
const tcpPortUsed = require('tcp-port-used')
|
||||
const {PlebbitWsServer} = require('@plebbit/plebbit-js/rpc')
|
||||
const path = require('path')
|
||||
const envPaths = require('env-paths').default('plebbit', { suffix: false })
|
||||
const {randomBytes} = require('crypto')
|
||||
const fs = require('fs-extra')
|
||||
const tcpPortUsed = require('tcp-port-used');
|
||||
const { PlebbitWsServer } = require('@plebbit/plebbit-js/rpc');
|
||||
const path = require('path');
|
||||
const envPaths = require('env-paths').default('plebbit', { suffix: false });
|
||||
const { randomBytes } = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
let isDev = true
|
||||
let isDev = true;
|
||||
try {
|
||||
isDev = require('electron-is-dev')
|
||||
isDev = require('electron-is-dev');
|
||||
} catch (e) {}
|
||||
|
||||
// PLEB, always run plebbit rpc on this port so all clients can use it
|
||||
const port = 9138
|
||||
const port = 9138;
|
||||
const defaultPlebbitOptions = {
|
||||
// find the user's OS data path
|
||||
dataPath: !isDev ? envPaths.data : path.join(__dirname, '..', '.plebbit'),
|
||||
ipfsHttpClientsOptions: ['http://localhost:5001/api/v0'],
|
||||
// TODO: having to define pubsubHttpClientsOptions and ipfsHttpClientsOptions is a bug with plebbit-js
|
||||
pubsubHttpClientsOptions: ['http://localhost:5001/api/v0'],
|
||||
}
|
||||
};
|
||||
|
||||
// generate plebbit rpc auth key if doesn't exist
|
||||
const plebbitRpcAuthKeyPath = path.join(defaultPlebbitOptions.dataPath, 'auth-key')
|
||||
let plebbitRpcAuthKey
|
||||
const plebbitRpcAuthKeyPath = path.join(defaultPlebbitOptions.dataPath, 'auth-key');
|
||||
let plebbitRpcAuthKey;
|
||||
try {
|
||||
plebbitRpcAuthKey = fs.readFileSync(plebbitRpcAuthKeyPath, 'utf8')
|
||||
}
|
||||
catch (e) {
|
||||
plebbitRpcAuthKey = randomBytes(32).toString('base64').replace(/[/+=]/g, '').substring(0, 40)
|
||||
fs.ensureFileSync(plebbitRpcAuthKeyPath)
|
||||
fs.writeFileSync(plebbitRpcAuthKeyPath, plebbitRpcAuthKey)
|
||||
plebbitRpcAuthKey = fs.readFileSync(plebbitRpcAuthKeyPath, 'utf8');
|
||||
} catch (e) {
|
||||
plebbitRpcAuthKey = randomBytes(32).toString('base64').replace(/[/+=]/g, '').substring(0, 40);
|
||||
fs.ensureFileSync(plebbitRpcAuthKeyPath);
|
||||
fs.writeFileSync(plebbitRpcAuthKeyPath, plebbitRpcAuthKey);
|
||||
}
|
||||
|
||||
let pendingStart = false
|
||||
let pendingStart = false;
|
||||
const start = async () => {
|
||||
if (pendingStart) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
pendingStart = true
|
||||
pendingStart = true;
|
||||
try {
|
||||
const started = await tcpPortUsed.check(port, '127.0.0.1')
|
||||
const started = await tcpPortUsed.check(port, '127.0.0.1');
|
||||
if (started) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
const plebbitWebSocketServer = await PlebbitWsServer({port, plebbitOptions: defaultPlebbitOptions, authKey: plebbitRpcAuthKey})
|
||||
const plebbitWebSocketServer = await PlebbitWsServer({ port, plebbitOptions: defaultPlebbitOptions, authKey: plebbitRpcAuthKey });
|
||||
|
||||
console.log(`plebbit rpc: listening on ws://localhost:${port} (local connections only)`)
|
||||
console.log(`plebbit rpc: listening on ws://localhost:${port}/${plebbitRpcAuthKey} (secret auth key for remote connections)`)
|
||||
console.log(`plebbit rpc: listening on ws://localhost:${port} (local connections only)`);
|
||||
console.log(`plebbit rpc: listening on ws://localhost:${port}/${plebbitRpcAuthKey} (secret auth key for remote connections)`);
|
||||
plebbitWebSocketServer.ws.on('connection', (socket, request) => {
|
||||
console.log('plebbit rpc: new connection')
|
||||
console.log('plebbit rpc: new connection');
|
||||
// debug raw JSON RPC messages in console
|
||||
if (isDev) {
|
||||
socket.on('message', (message) => console.log(`plebbit rpc: ${message.toString()}`))
|
||||
socket.on('message', (message) => console.log(`plebbit rpc: ${message.toString()}`));
|
||||
}
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('failed starting plebbit rpc server', e);
|
||||
}
|
||||
catch (e) {
|
||||
console.log('failed starting plebbit rpc server', e)
|
||||
}
|
||||
pendingStart = false
|
||||
}
|
||||
pendingStart = false;
|
||||
};
|
||||
|
||||
// retry starting the plebbit rpc server every 1 second,
|
||||
// retry starting the plebbit rpc server every 1 second,
|
||||
// in case it was started by another client that shut down and shut down the server with it
|
||||
start()
|
||||
start();
|
||||
setInterval(() => {
|
||||
start()
|
||||
}, 1000)
|
||||
start();
|
||||
}, 1000);
|
||||
|
||||
Reference in New Issue
Block a user