mirror of
https://github.com/finos/SymphonyElectron.git
synced 2026-10-24 13:57:39 -05:00
SDA-3919 Upgrade to Electron 21
This commit is contained in:
1 parent
7f50ec17d3
commit
a8eddbac60
8 files changed
+163
-530
No files matched your search
Generated
+153
-9
@@ -23,10 +23,10 @@
|
||||
"lazy-brush": "^1.0.1",
|
||||
"react": "16.13.0",
|
||||
"react-dom": "16.13.0",
|
||||
"ref-napi": "^3.0.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"save-svg-as-png": "^1.4.17",
|
||||
"shell-path": "^3.0.0"
|
||||
"shell-path": "^3.0.0",
|
||||
"win32-api": "^20.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cheerio": "^0.22.22",
|
||||
@@ -41,7 +41,7 @@
|
||||
"builder-util-runtime": "^9.0.3",
|
||||
"cross-env": "5.2.0",
|
||||
"del": "3.0.0",
|
||||
"electron": "^20.1.4",
|
||||
"electron": "^21.3.0",
|
||||
"electron-builder": "23.0.9",
|
||||
"electron-builder-squirrel-windows": "20.38.3",
|
||||
"electron-icon-maker": "0.0.4",
|
||||
@@ -7128,9 +7128,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "20.1.4",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/electron/-/electron-20.1.4.tgz",
|
||||
"integrity": "sha1-0ltUnxQ3b5mgojnifWfvhRW0paA=",
|
||||
"version": "21.3.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/electron/-/electron-21.3.0.tgz",
|
||||
"integrity": "sha1-6ZBeJArdlQRD3BFbS+E9NhYvCgU=",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
@@ -17370,6 +17370,33 @@
|
||||
"integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ref-union-di": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/ref-union-di/-/ref-union-di-1.0.1.tgz",
|
||||
"integrity": "sha1-5KJ4Ncgmbn67ypkyzp6NlQAWtXY=",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"debug": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ref-union-di/node_modules/debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o=",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ref-union-di/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/reflect.ownkeys": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
|
||||
@@ -21089,6 +21116,67 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/win32-api": {
|
||||
"version": "20.1.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/win32-api/-/win32-api-20.1.0.tgz",
|
||||
"integrity": "sha1-EdJLUuiCqcLuMhutzg2mzvCOTwI=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"win32-def": "^20.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.15.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ffi-napi": "^4.0.3",
|
||||
"ref-napi": "^3.0.3",
|
||||
"ref-struct-di": "^1.1.1",
|
||||
"ref-union-di": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/win32-def": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/win32-def/-/win32-def-20.0.0.tgz",
|
||||
"integrity": "sha1-XRXUR2B3r3WyN9dCa+V00kIS3GE=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@waiting/shared-types": "^20.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.15.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ref-napi": "^3.0.3",
|
||||
"ref-struct-di": "^1.1.1",
|
||||
"ref-union-di": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/win32-def/node_modules/@waiting/shared-types": {
|
||||
"version": "20.5.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/@waiting/shared-types/-/shared-types-20.5.0.tgz",
|
||||
"integrity": "sha1-4P8jrsbOvOoVy4aP/WkPr7kRp9w=",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.16.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/win32-def/node_modules/typescript": {
|
||||
"version": "4.9.3",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/typescript/-/typescript-4.9.3.tgz",
|
||||
"integrity": "sha1-OuowfBdGuMOEQ12Kw2uKLlgNhds=",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/window-size": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/window-size/-/window-size-0.2.0.tgz",
|
||||
@@ -26788,9 +26876,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"electron": {
|
||||
"version": "20.1.4",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/electron/-/electron-20.1.4.tgz",
|
||||
"integrity": "sha1-0ltUnxQ3b5mgojnifWfvhRW0paA=",
|
||||
"version": "21.3.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/electron/-/electron-21.3.0.tgz",
|
||||
"integrity": "sha1-6ZBeJArdlQRD3BFbS+E9NhYvCgU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^1.14.1",
|
||||
@@ -34339,6 +34427,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ref-union-di": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/ref-union-di/-/ref-union-di-1.0.1.tgz",
|
||||
"integrity": "sha1-5KJ4Ncgmbn67ypkyzp6NlQAWtXY=",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"debug": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o=",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"reflect.ownkeys": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
|
||||
@@ -37136,6 +37250,36 @@
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
|
||||
"dev": true
|
||||
},
|
||||
"win32-api": {
|
||||
"version": "20.1.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/win32-api/-/win32-api-20.1.0.tgz",
|
||||
"integrity": "sha1-EdJLUuiCqcLuMhutzg2mzvCOTwI=",
|
||||
"requires": {
|
||||
"win32-def": "^20.0.0"
|
||||
}
|
||||
},
|
||||
"win32-def": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/win32-def/-/win32-def-20.0.0.tgz",
|
||||
"integrity": "sha1-XRXUR2B3r3WyN9dCa+V00kIS3GE=",
|
||||
"requires": {
|
||||
"@waiting/shared-types": "^20.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@waiting/shared-types": {
|
||||
"version": "20.5.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/@waiting/shared-types/-/shared-types-20.5.0.tgz",
|
||||
"integrity": "sha1-4P8jrsbOvOoVy4aP/WkPr7kRp9w=",
|
||||
"requires": {}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.9.3",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/typescript/-/typescript-4.9.3.tgz",
|
||||
"integrity": "sha1-OuowfBdGuMOEQ12Kw2uKLlgNhds=",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"window-size": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/window-size/-/window-size-0.2.0.tgz",
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "symphony",
|
||||
"productName": "Symphony",
|
||||
"version": "20.0.0",
|
||||
"version": "21.0.0",
|
||||
"clientVersion": "2.0.1",
|
||||
"buildNumber": "0",
|
||||
"searchAPIVersion": "1.55.3",
|
||||
@@ -171,7 +171,7 @@
|
||||
"builder-util-runtime": "^9.0.3",
|
||||
"cross-env": "5.2.0",
|
||||
"del": "3.0.0",
|
||||
"electron": "^20.1.4",
|
||||
"electron": "^21.3.0",
|
||||
"electron-builder": "23.0.9",
|
||||
"electron-builder-squirrel-windows": "20.38.3",
|
||||
"electron-icon-maker": "0.0.4",
|
||||
@@ -213,10 +213,10 @@
|
||||
"lazy-brush": "^1.0.1",
|
||||
"react": "16.13.0",
|
||||
"react-dom": "16.13.0",
|
||||
"ref-napi": "^3.0.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"save-svg-as-png": "^1.4.17",
|
||||
"shell-path": "^3.0.0"
|
||||
"shell-path": "^3.0.0",
|
||||
"win32-api": "^20.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@symphony/symphony-c9-shell": "3.14.99-37",
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
import { getContentWindowHandle } from '../src/app/hwnd-handler';
|
||||
|
||||
jest.mock('../src/common/env', () => {
|
||||
return {
|
||||
isWindowsOS: true,
|
||||
isLinux: false,
|
||||
isMac: false,
|
||||
};
|
||||
});
|
||||
|
||||
const mockFindWindowExA = jest.fn();
|
||||
const mockGetWindowRect = jest.fn();
|
||||
|
||||
jest.mock('ffi-napi', () => {
|
||||
return {
|
||||
Library: jest.fn(() => {
|
||||
return {
|
||||
FindWindowExA: mockFindWindowExA,
|
||||
GetWindowRect: mockGetWindowRect,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
function writeRect(
|
||||
buffer: Buffer,
|
||||
left: number,
|
||||
top: number,
|
||||
right: number,
|
||||
bottom: number,
|
||||
) {
|
||||
buffer.writeInt32LE(left, 0);
|
||||
buffer.writeInt32LE(top, 4);
|
||||
buffer.writeInt32LE(right, 8);
|
||||
buffer.writeInt32LE(bottom, 12);
|
||||
}
|
||||
|
||||
describe('hwnd handler', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks().resetModules();
|
||||
|
||||
mockGetWindowRect.mockImplementation((_hwnd: bigint, _rect: Buffer) => {
|
||||
return 0;
|
||||
});
|
||||
mockFindWindowExA.mockImplementation(() => {
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
|
||||
it('not using windows', () => {
|
||||
jest.mock('../src/common/env', () => {
|
||||
return {
|
||||
isWindowsOS: false,
|
||||
isLinux: true,
|
||||
isMac: false,
|
||||
};
|
||||
});
|
||||
const { getContentWindowHandle } = require('../src/app/hwnd-handler');
|
||||
const parent = Buffer.from('hwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
expect(hwnd).toBe(parent);
|
||||
});
|
||||
|
||||
it('unexpected buffer size', () => {
|
||||
const parent = Buffer.from('hwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
expect(hwnd).toBe(parent);
|
||||
});
|
||||
|
||||
it('no child window found', () => {
|
||||
const parent = Buffer.from('validhwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
|
||||
expect(mockGetWindowRect).toBeCalledTimes(0);
|
||||
expect(mockFindWindowExA).toBeCalledTimes(1);
|
||||
expect(hwnd).toBe(parent);
|
||||
});
|
||||
|
||||
it('no rect found for child window', () => {
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 4711;
|
||||
});
|
||||
|
||||
const parent = Buffer.from('validhwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
|
||||
expect(mockGetWindowRect).toBeCalledTimes(1);
|
||||
expect(mockFindWindowExA).toBeCalledTimes(2);
|
||||
expect(hwnd).toBe(parent);
|
||||
});
|
||||
|
||||
it('no rect found for second child window', () => {
|
||||
mockGetWindowRect.mockImplementationOnce((_hwnd, rect) => {
|
||||
writeRect(rect, 10, 10, 100, 10);
|
||||
return 1;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 4711;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 42;
|
||||
});
|
||||
|
||||
const parent = Buffer.from('validhwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
|
||||
expect(mockGetWindowRect).toBeCalledTimes(2);
|
||||
expect(mockFindWindowExA).toBeCalledTimes(3);
|
||||
expect(hwnd).toBe(parent);
|
||||
});
|
||||
|
||||
it('matching child window found', () => {
|
||||
mockGetWindowRect.mockImplementationOnce((_hwnd, rect) => {
|
||||
writeRect(rect, 10, 20, 100, 100);
|
||||
return 1;
|
||||
});
|
||||
mockGetWindowRect.mockImplementationOnce((_hwnd, rect) => {
|
||||
writeRect(rect, 10, 10, 100, 10);
|
||||
return 1;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 4711;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 42;
|
||||
});
|
||||
|
||||
const parent = Buffer.from('validhwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
|
||||
expect(mockGetWindowRect).toBeCalledTimes(2);
|
||||
expect(mockFindWindowExA).toBeCalledTimes(3);
|
||||
expect(hwnd.readInt32LE(0)).toBe(4711);
|
||||
});
|
||||
|
||||
it('matching child window found second', () => {
|
||||
mockGetWindowRect.mockImplementationOnce((_hwnd, rect) => {
|
||||
writeRect(rect, 10, 10, 100, 10);
|
||||
return 1;
|
||||
});
|
||||
mockGetWindowRect.mockImplementationOnce((_hwnd, rect) => {
|
||||
writeRect(rect, 10, 20, 100, 100);
|
||||
return 1;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 4711;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 42;
|
||||
});
|
||||
|
||||
const parent = Buffer.from('validhwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
|
||||
expect(mockGetWindowRect).toBeCalledTimes(2);
|
||||
expect(mockFindWindowExA).toBeCalledTimes(3);
|
||||
expect(hwnd.readInt32LE(0)).toBe(42);
|
||||
});
|
||||
|
||||
it('no matching child window found', () => {
|
||||
mockGetWindowRect.mockImplementationOnce((_hwnd, rect) => {
|
||||
writeRect(rect, 10, 10, 100, 100);
|
||||
return 1;
|
||||
});
|
||||
mockFindWindowExA.mockImplementationOnce(() => {
|
||||
return 4711;
|
||||
});
|
||||
|
||||
const parent = Buffer.from('validhwnd', 'utf8');
|
||||
const hwnd = getContentWindowHandle(parent);
|
||||
|
||||
expect(mockGetWindowRect).toBeCalledTimes(1);
|
||||
expect(mockFindWindowExA).toBeCalledTimes(2);
|
||||
expect(hwnd).toBe(parent);
|
||||
});
|
||||
});
|
||||
@@ -1,212 +0,0 @@
|
||||
import { app } from 'electron';
|
||||
import { Library } from 'ffi-napi';
|
||||
import * as path from 'path';
|
||||
import { refType, types } from 'ref-napi';
|
||||
|
||||
const execPath = path.dirname(app.getPath('exe'));
|
||||
import { isDevEnv, isMac } from '../common/env';
|
||||
import { logger } from '../common/logger';
|
||||
|
||||
const TAG_LENGTH = 16;
|
||||
const arch = process.arch === 'ia32';
|
||||
const winLibraryPath = isDevEnv
|
||||
? path.join(__dirname, '..', '..', 'library')
|
||||
: path.join(execPath, 'library');
|
||||
const macLibraryPath = isDevEnv
|
||||
? path.join(__dirname, '..', '..', '..', 'library')
|
||||
: path.join(execPath, '..', 'library');
|
||||
|
||||
const cryptoLibPath = isMac
|
||||
? path.join(macLibraryPath, 'cryptoLib.dylib')
|
||||
: arch
|
||||
? path.join(winLibraryPath, 'libsymphonysearch-x86.dll')
|
||||
: path.join(winLibraryPath, 'libsymphonysearch-x64.dll');
|
||||
|
||||
const library = new Library(cryptoLibPath, {
|
||||
AESEncryptGCM: [
|
||||
types.int32,
|
||||
[
|
||||
refType(types.uchar),
|
||||
types.int32,
|
||||
refType(types.uchar),
|
||||
types.int32,
|
||||
refType(types.uchar),
|
||||
refType(types.uchar),
|
||||
types.uint32,
|
||||
refType(types.uchar),
|
||||
refType(types.uchar),
|
||||
types.uint32,
|
||||
],
|
||||
],
|
||||
|
||||
AESDecryptGCM: [
|
||||
types.int32,
|
||||
[
|
||||
refType(types.uchar),
|
||||
types.int32,
|
||||
refType(types.uchar),
|
||||
types.int32,
|
||||
refType(types.uchar),
|
||||
types.uint32,
|
||||
refType(types.uchar),
|
||||
refType(types.uchar),
|
||||
types.uint32,
|
||||
refType(types.uchar),
|
||||
],
|
||||
],
|
||||
|
||||
getVersion: [types.CString, []],
|
||||
});
|
||||
|
||||
interface ICryptoLib {
|
||||
AESGCMEncrypt: (
|
||||
name: string,
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
) => string | null;
|
||||
AESGCMDecrypt: (
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
) => string | null;
|
||||
}
|
||||
|
||||
class CryptoLibrary implements ICryptoLib {
|
||||
/**
|
||||
* Encrypt / Decrypt
|
||||
*
|
||||
* @param name {string} Method name to execute
|
||||
* @param base64IV {string}
|
||||
* @param base64AAD {string}
|
||||
* @param base64Key {string}
|
||||
* @param base64In {string}
|
||||
* @constructor
|
||||
*/
|
||||
public static EncryptDecrypt(
|
||||
name: string,
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
): string | null {
|
||||
let base64Input = base64In;
|
||||
|
||||
if (!base64Input) {
|
||||
base64Input = '';
|
||||
}
|
||||
|
||||
const IV: Buffer = Buffer.from(base64IV, 'base64');
|
||||
const AAD: Buffer = Buffer.from(base64AAD, 'base64');
|
||||
const KEY: Buffer = Buffer.from(base64Key, 'base64');
|
||||
const IN: Buffer = Buffer.from(base64Input, 'base64');
|
||||
|
||||
if (name === 'AESGCMEncrypt') {
|
||||
const outPtr: Buffer = Buffer.alloc(IN.length);
|
||||
const TAG: Buffer = Buffer.alloc(TAG_LENGTH);
|
||||
|
||||
const resultCode = library.AESEncryptGCM(
|
||||
IN,
|
||||
IN.length,
|
||||
AAD,
|
||||
AAD.length,
|
||||
KEY,
|
||||
IV,
|
||||
IV.length,
|
||||
outPtr,
|
||||
TAG,
|
||||
TAG_LENGTH,
|
||||
);
|
||||
|
||||
if (resultCode < 0) {
|
||||
logger.error(
|
||||
`AESEncryptGCM, Failed to encrypt with exit code ${resultCode}`,
|
||||
);
|
||||
}
|
||||
const bufferArray = [outPtr, TAG];
|
||||
return Buffer.concat(bufferArray).toString('base64');
|
||||
}
|
||||
|
||||
if (name === 'AESGCMDecrypt') {
|
||||
const cipherTextLen = IN.length - TAG_LENGTH;
|
||||
const TAG = Buffer.from(IN.slice(IN.length - 16, IN.length));
|
||||
const outPtr = Buffer.alloc(IN.length - TAG_LENGTH);
|
||||
|
||||
const resultCode = library.AESDecryptGCM(
|
||||
IN,
|
||||
cipherTextLen,
|
||||
AAD,
|
||||
AAD.length,
|
||||
TAG,
|
||||
TAG_LENGTH,
|
||||
KEY,
|
||||
IV,
|
||||
IV.length,
|
||||
outPtr,
|
||||
);
|
||||
|
||||
if (resultCode < 0) {
|
||||
logger.error(
|
||||
`AESDecryptGCM, Failed to decrypt with exit code ${resultCode}`,
|
||||
);
|
||||
}
|
||||
return outPtr.toString('base64');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the given data
|
||||
*
|
||||
* @param base64IV {string}
|
||||
* @param base64AAD {string}
|
||||
* @param base64Key {string}
|
||||
* @param base64In {string}
|
||||
* @constructor
|
||||
*/
|
||||
public AESGCMEncrypt(
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
): string | null {
|
||||
return CryptoLibrary.EncryptDecrypt(
|
||||
'AESGCMEncrypt',
|
||||
base64IV,
|
||||
base64AAD,
|
||||
base64Key,
|
||||
base64In,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the give data
|
||||
*
|
||||
* @param base64IV {string}
|
||||
* @param base64AAD {string}
|
||||
* @param base64Key {string}
|
||||
* @param base64In {string}
|
||||
* @constructor
|
||||
*/
|
||||
public AESGCMDecrypt(
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
): string | null {
|
||||
return CryptoLibrary.EncryptDecrypt(
|
||||
'AESGCMDecrypt',
|
||||
base64IV,
|
||||
base64AAD,
|
||||
base64Key,
|
||||
base64In,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const cryptoLibrary = new CryptoLibrary();
|
||||
|
||||
export { cryptoLibrary };
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Library } from 'ffi-napi';
|
||||
import { isWindowsOS } from '../common/env';
|
||||
|
||||
/**
|
||||
@@ -12,72 +11,5 @@ export const getContentWindowHandle = (nativeWindowHandle: Buffer): Buffer => {
|
||||
if (!isWindowsOS) {
|
||||
return nativeWindowHandle;
|
||||
}
|
||||
if (nativeWindowHandle.byteLength < 8) {
|
||||
return nativeWindowHandle;
|
||||
}
|
||||
|
||||
const user32 = Library('user32.dll', {
|
||||
FindWindowExA: ['int', ['int', 'int', 'string', 'string']],
|
||||
GetWindowRect: ['int', ['int', 'pointer']],
|
||||
});
|
||||
|
||||
const getWindowRect = (hwnd: bigint) => {
|
||||
const rect = Buffer.alloc(16);
|
||||
|
||||
const ret = user32.GetWindowRect(hwnd.toString(), rect);
|
||||
if (ret) {
|
||||
return {
|
||||
left: rect.readInt32LE(0),
|
||||
top: rect.readInt32LE(4),
|
||||
right: rect.readInt32LE(8),
|
||||
bottom: rect.readInt32LE(12),
|
||||
};
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const parentHwnd = nativeWindowHandle.readBigUInt64LE();
|
||||
const children = new Map();
|
||||
let titleChild;
|
||||
|
||||
let child = user32.FindWindowExA(
|
||||
parentHwnd.toString(),
|
||||
0,
|
||||
'Chrome_RenderWidgetHostHWND',
|
||||
null,
|
||||
);
|
||||
while (child !== 0) {
|
||||
const rect = getWindowRect(child);
|
||||
if (rect) {
|
||||
children.set(child, rect);
|
||||
|
||||
// The titlebar child is the one that is the least tall
|
||||
if (!titleChild) {
|
||||
titleChild = child;
|
||||
} else {
|
||||
const curTitleRect = children.get(titleChild)!;
|
||||
if (rect.bottom - rect.top < curTitleRect.bottom - curTitleRect.top) {
|
||||
titleChild = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
child = user32.FindWindowExA(
|
||||
parentHwnd.toString(),
|
||||
child,
|
||||
'Chrome_RenderWidgetHostHWND',
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
// Return the first child window that isn't the title bar
|
||||
for (const hwnd of children.keys()) {
|
||||
if (hwnd !== titleChild) {
|
||||
const ret = Buffer.alloc(8);
|
||||
ret.writeBigUInt64LE(BigInt(hwnd));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return nativeWindowHandle;
|
||||
};
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
NOTIFICATION_WINDOW_TITLE,
|
||||
NotificationActions,
|
||||
} from '../common/api-interface';
|
||||
import { isMac } from '../common/env';
|
||||
import { logger } from '../common/logger';
|
||||
import NotificationHandler from './notification-handler';
|
||||
|
||||
@@ -609,7 +610,7 @@ class Notification extends NotificationHandler {
|
||||
* notification window opts
|
||||
*/
|
||||
private getNotificationOpts(): Electron.BrowserWindowConstructorOptions {
|
||||
return {
|
||||
const toastNotificationOpts: Electron.BrowserWindowConstructorOptions = {
|
||||
width: CONTAINER_WIDTH,
|
||||
height: CONTAINER_HEIGHT,
|
||||
alwaysOnTop: true,
|
||||
@@ -628,6 +629,10 @@ class Notification extends NotificationHandler {
|
||||
disableBlinkFeatures: AUX_CLICK,
|
||||
},
|
||||
};
|
||||
if (isMac) {
|
||||
toastNotificationOpts.type = 'panel';
|
||||
}
|
||||
return toastNotificationOpts;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,6 @@ if (ssfWindow.ssf) {
|
||||
// For Mana to communicate with SDA
|
||||
contextBridge.exposeInMainWorld('manaSSF', {
|
||||
setIsMana: ssfWindow.ssf.setIsMana,
|
||||
CryptoLib: ssfWindow.ssf.CryptoLib,
|
||||
Search: ssfWindow.ssf.Search,
|
||||
Notification: ssfWindow.ssf.Notification,
|
||||
getMediaSource: ssfWindow.ssf.getMediaSource,
|
||||
activate: ssfWindow.ssf.activate,
|
||||
|
||||
@@ -40,22 +40,6 @@ const MAIN_WINDOW_NAME = 'main';
|
||||
let isAltKey: boolean = false;
|
||||
let isMenuOpen: boolean = false;
|
||||
|
||||
interface ICryptoLib {
|
||||
AESGCMEncrypt: (
|
||||
name: string,
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
) => string | null;
|
||||
AESGCMDecrypt: (
|
||||
base64IV: string,
|
||||
base64AAD: string,
|
||||
base64Key: string,
|
||||
base64In: string,
|
||||
) => string | null;
|
||||
}
|
||||
|
||||
export interface ILocalObject {
|
||||
ipcRenderer;
|
||||
logger?: (msg: ILogMsg, logLevel: LogLevel, showInConsole: boolean) => void;
|
||||
@@ -171,51 +155,9 @@ const throttledSetZoomLevel = throttle((zoomLevel) => {
|
||||
});
|
||||
}, DEFAULT_THROTTLE);
|
||||
|
||||
let cryptoLib: ICryptoLib | null;
|
||||
try {
|
||||
// cryptoLib = remote.require('../app/crypto-handler.js').cryptoLibrary;
|
||||
} catch (e) {
|
||||
cryptoLib = null;
|
||||
// tslint:disable-next-line
|
||||
console.warn(
|
||||
"Failed to initialize Crypto Lib. You'll need to include the Crypto library. Contact the developers for more details",
|
||||
);
|
||||
}
|
||||
|
||||
let swiftSearch: any;
|
||||
try {
|
||||
// swiftSearch = remote.require('swift-search').Search;
|
||||
} catch (e) {
|
||||
swiftSearch = null;
|
||||
// tslint:disable-next-line
|
||||
console.warn(
|
||||
"Failed to initialize swift search. You'll need to include the search dependency. Contact the developers for more details",
|
||||
);
|
||||
}
|
||||
|
||||
let swiftSearchUtils: any;
|
||||
try {
|
||||
// swiftSearchUtils = remote.require('swift-search').SearchUtils;
|
||||
} catch (e) {
|
||||
swiftSearchUtils = null;
|
||||
// tslint:disable-next-line
|
||||
console.warn(
|
||||
"Failed to initialize swift search utils. You'll need to include the search dependency. Contact the developers for more details",
|
||||
);
|
||||
}
|
||||
|
||||
let nextIndicatorId = 0;
|
||||
|
||||
export class SSFApi {
|
||||
/**
|
||||
* Native encryption and decryption.
|
||||
*/
|
||||
public CryptoLib: ICryptoLib | null = cryptoLib; // tslint:disable-line
|
||||
|
||||
public Search: any = swiftSearch; // tslint:disable-line
|
||||
|
||||
public SearchUtils: any = swiftSearchUtils; // tslint:disable-line
|
||||
|
||||
public Notification = SSFNotificationHandler; // tslint:disable-line
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user