SDA-3919 Upgrade to Electron 21

This commit is contained in:
sbenmoussati authored and Salah Benmoussati committed 2022-11-22 15:24:02 +01:00
1 parent 7f50ec17d3
commit a8eddbac60
8 files changed
+163 -530

No files matched your search

+153 -9
View File
@@ -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
View File
@@ -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",
-176
View File
@@ -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);
});
});
-212
View File
@@ -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 };
-68
View File
@@ -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;
};
+6 -1
View File
@@ -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;
}
}
-2
View File
@@ -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,
-58
View File
@@ -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
/**