70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { protocol, App } from 'electron';
|
|
|
|
import { PROTOCOL_NAME, isValidEventType } from 'shared/enclave/utils';
|
|
import { EnclaveMethods, EnclaveMethodParams, EnclaveResponse } from 'shared/enclave/types';
|
|
import handlers from './handlers';
|
|
|
|
export function registerServer(app: App) {
|
|
// Register protocol scheme
|
|
protocol.registerStandardSchemes([PROTOCOL_NAME]);
|
|
|
|
app.on('ready', () => {
|
|
// Register custom protocol behavior
|
|
protocol.registerStringProtocol(PROTOCOL_NAME, async (req, cb) => {
|
|
let res: EnclaveResponse;
|
|
|
|
try {
|
|
const method = getMethod(req);
|
|
const params = getParams(method, req);
|
|
const data = await handlers[method](params);
|
|
res = { data };
|
|
} catch (err) {
|
|
console.error(`Request to '${req.url}' failed with error:`, err);
|
|
res = {
|
|
error: {
|
|
code: 500,
|
|
type: err.name,
|
|
message: err.message
|
|
}
|
|
};
|
|
}
|
|
|
|
cb(JSON.stringify(res));
|
|
});
|
|
});
|
|
}
|
|
|
|
function getMethod(req: Electron.RegisterStringProtocolRequest): EnclaveMethods {
|
|
const urlSplit = req.url.split(`${PROTOCOL_NAME}://`);
|
|
|
|
if (!urlSplit[1]) {
|
|
throw new Error('No method provided');
|
|
}
|
|
|
|
const method = urlSplit[1].replace('/', '');
|
|
if (!isValidEventType(method)) {
|
|
throw new Error(`Invalid or unknown method '${method}'`);
|
|
}
|
|
|
|
return method;
|
|
}
|
|
|
|
function getParams(
|
|
method: EnclaveMethods,
|
|
req: Electron.RegisterStringProtocolRequest
|
|
): EnclaveMethodParams {
|
|
const data = req.uploadData.find(d => !!d.bytes);
|
|
|
|
if (!data) {
|
|
throw new Error(`No data provided for '${method}'`);
|
|
}
|
|
|
|
try {
|
|
// TODO: Validate params based on provided method
|
|
const params = JSON.parse(data.bytes.toString());
|
|
return params as EnclaveMethodParams;
|
|
} catch (err) {
|
|
throw new Error(`Invalid JSON blob provided for '${method}': ${err.message}`);
|
|
}
|
|
}
|