1
- import { Server , WebSocket } from "ws" ;
1
+ import { Server } from "ws" ;
2
2
import path from "path" ;
3
3
import fs from "fs" ;
4
4
import net from "net" ;
5
5
import merge from "lodash/merge" ;
6
- import { toAccountRaw } from "@ledgerhq/live-common/account/index" ;
6
+
7
7
import { NavigatorName } from "../../src/const" ;
8
8
import { Subject } from "rxjs" ;
9
9
import { BleState , DeviceLike } from "../../src/reducers/types" ;
@@ -12,12 +12,10 @@ import { DeviceUSB, nanoSP_USB, nanoS_USB, nanoX_USB } from "../models/devices";
12
12
import { MessageData , MockDeviceEvent , ServerData } from "./types" ;
13
13
import { getDeviceModel } from "@ledgerhq/devices" ;
14
14
import { SettingsSetOverriddenFeatureFlagsPlayload } from "~/actions/types" ;
15
+ import { log as detoxLog } from "detox" ;
15
16
16
17
export const e2eBridgeServer = new Subject < ServerData > ( ) ;
17
-
18
- let wss : Server ;
19
- let webSocket : WebSocket ;
20
- const lastMessages : { [ id : string ] : MessageData } = { } ; // Store the last messages not sent
18
+ let lastMessages : { [ id : string ] : MessageData } = { } ; // Store the last messages not sent
21
19
let clientResponse : ( data : string ) => void ;
22
20
const RESPONSE_TIMEOUT = 10000 ;
23
21
@@ -52,16 +50,20 @@ function uniqueId(): string {
52
50
return timestamp + randomString ; // Concatenate timestamp and random string
53
51
}
54
52
55
- // eslint-disable-next-line @typescript-eslint/no-empty-function
56
- export function init ( port = 8099 , onConnection = ( ) => { } ) {
57
- wss = new Server ( { port } ) ;
53
+ export function init ( port = 8099 , onConnection ?: ( ) => void ) {
54
+ webSocket . wss = new Server ( { port } ) ;
58
55
log ( `Start listening on localhost:${ port } ` ) ;
59
56
60
- wss . on ( "connection" , ws => {
57
+ webSocket . wss . on ( "connection" , ws => {
61
58
log ( `Client connected` ) ;
62
- onConnection ( ) ;
63
- webSocket = ws ;
59
+ onConnection && onConnection ( ) ;
60
+ webSocket . ws ?. close ( ) ;
61
+ webSocket . ws = ws ;
64
62
ws . on ( "message" , onMessage ) ;
63
+ ws . on ( "close" , ( ) => {
64
+ log ( "Client disconnected" ) ;
65
+ webSocket . ws = undefined ; // Free memory
66
+ } ) ;
65
67
if ( Object . keys ( lastMessages ) . length !== 0 ) {
66
68
log ( `Sending unsent messages` ) ;
67
69
Object . values ( lastMessages ) . forEach ( message => {
@@ -72,8 +74,24 @@ export function init(port = 8099, onConnection = () => {}) {
72
74
}
73
75
74
76
export function close ( ) {
75
- webSocket ?. close ( ) ;
76
- wss ?. close ( ) ;
77
+ if ( webSocket . ws ) {
78
+ webSocket . ws . removeAllListeners ( ) ;
79
+ webSocket . ws . close ( ) ;
80
+ webSocket . ws = undefined ;
81
+ }
82
+
83
+ if ( webSocket . wss ) {
84
+ webSocket . wss . clients . forEach ( client => {
85
+ client . removeAllListeners ( ) ;
86
+ client . terminate ( ) ;
87
+ } ) ;
88
+
89
+ webSocket . wss . close ( ( ) => {
90
+ log ( "WebSocket server closed" ) ;
91
+ webSocket . wss = undefined ;
92
+ } ) ;
93
+ }
94
+ lastMessages = { } ;
77
95
}
78
96
79
97
export async function loadConfig ( fileName : string , agreed : true = true ) : Promise < void > {
@@ -86,12 +104,12 @@ export async function loadConfig(fileName: string, agreed: true = true): Promise
86
104
const { data } = JSON . parse ( f . toString ( ) ) ;
87
105
88
106
const defaultSettings = { shareAnalytics : true , hasSeenAnalyticsOptInPrompt : true } ;
89
- const settings = merge ( defaultSettings , data . settings ) ;
107
+ const settings = merge ( defaultSettings , data . settings || { } ) ;
90
108
await postMessage ( { type : "importSettings" , id : uniqueId ( ) , payload : settings } ) ;
91
109
92
110
navigate ( NavigatorName . Base ) ;
93
111
94
- if ( data . accounts . length ) {
112
+ if ( data . accounts ? .length ) {
95
113
await postMessage ( { type : "importAccounts" , id : uniqueId ( ) , payload : data . accounts } ) ;
96
114
}
97
115
}
@@ -118,6 +136,8 @@ export async function loadAccountsRaw(
118
136
}
119
137
120
138
export async function loadAccounts ( accounts : Account [ ] ) {
139
+ delete require . cache [ require . resolve ( "@ledgerhq/live-common/account/index" ) ] ; // Clear cache
140
+ const toAccountRaw = require ( "@ledgerhq/live-common/account/index" ) . toAccountRaw ;
121
141
await postMessage ( {
122
142
type : "importAccounts" ,
123
143
id : uniqueId ( ) ,
@@ -244,8 +264,7 @@ function onMessage(messageStr: string) {
244
264
}
245
265
246
266
function log ( message : string ) {
247
- // eslint-disable-next-line no-console
248
- console . log ( `[E2E Bridge Server]: ${ message } ` ) ;
267
+ detoxLog . info ( `[E2E Bridge Server]: ${ message } ` ) ;
249
268
}
250
269
251
270
async function acceptTerms ( ) {
@@ -256,8 +275,8 @@ async function postMessage(message: MessageData) {
256
275
log ( `Message sending ${ message . type } : ${ message . id } ` ) ;
257
276
try {
258
277
lastMessages [ message . id ] = message ;
259
- if ( webSocket ) {
260
- webSocket . send ( JSON . stringify ( message ) ) ;
278
+ if ( webSocket . ws ) {
279
+ webSocket . ws . send ( JSON . stringify ( message ) ) ;
261
280
} else {
262
281
log ( "WebSocket connection is not open. Message not sent." ) ;
263
282
}
0 commit comments