diff --git a/sticker-creator/preload.js b/sticker-creator/preload.js index 265702e6a144..a238a2d3f80a 100644 --- a/sticker-creator/preload.js +++ b/sticker-creator/preload.js @@ -212,7 +212,7 @@ window.encryptAndUpload = async ( const server = WebAPI.connect({ username: username || oldUsername, password, - disableWebSockets: true, + useWebSocket: false, }); const uniqueStickers = uniqBy( diff --git a/ts/background.ts b/ts/background.ts index c9a0aaa546b3..2d63b2713ce2 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -636,7 +636,7 @@ export async function startApp(): Promise { 'WebAPI should be initialized together with MessageReceiver' ); server.unregisterRequestHandler(messageReceiver); - await messageReceiver.stopProcessing(); + messageReceiver.stopProcessing(); await window.waitForAllBatchers(); } @@ -3334,18 +3334,23 @@ export async function startApp(): Promise { ): Promise { window.Whisper.events.trigger('unauthorized'); + window.log.warn( + 'unlinkAndDisconnect: Client is no longer authorized; ' + + 'deleting local configuration' + ); + if (messageReceiver) { + window.log.info('unlinkAndDisconnect: logging out'); strictAssert(server !== undefined, 'WebAPI not initialized'); server.unregisterRequestHandler(messageReceiver); - await messageReceiver.stopProcessing(); + messageReceiver.stopProcessing(); + + await server.logout(); await window.waitForAllBatchers(); } onEmpty(); - window.log.warn( - 'Client is no longer authorized; deleting local configuration' - ); window.Signal.Util.Registration.remove(); const NUMBER_ID_KEY = 'number_id'; @@ -3364,6 +3369,7 @@ export async function startApp(): Promise { ); try { + window.log.info('unlinkAndDisconnect: removing configuration'); await window.textsecure.storage.protocol.removeAllConfiguration(mode); // This was already done in the database with removeAllConfiguration; this does it @@ -3398,10 +3404,13 @@ export async function startApp(): Promise { } await window.textsecure.storage.put(VERSION_KEY, window.getVersion()); - window.log.info('Successfully cleared local configuration'); + window.log.info( + 'unlinkAndDisconnect: Successfully cleared local configuration' + ); } catch (eraseError) { window.log.error( - 'Something went wrong clearing local configuration', + 'unlinkAndDisconnect: Something went wrong clearing ' + + 'local configuration', eraseError && eraseError.stack ? eraseError.stack : eraseError ); } finally { diff --git a/ts/textsecure/SocketManager.ts b/ts/textsecure/SocketManager.ts index 8531769073e9..6fe4d93a801c 100644 --- a/ts/textsecure/SocketManager.ts +++ b/ts/textsecure/SocketManager.ts @@ -187,14 +187,18 @@ export class SocketManager extends EventListener { authenticated = await process.getResult(); this.status = SocketStatus.OPEN; } catch (error) { - strictAssert(this.authenticated === process, 'Someone stole our socket'); - this.dropAuthenticated(process); - window.log.warn( 'SocketManager: authenticated socket connection failed with ' + `error: ${Errors.toLogFormat(error)}` ); + // The socket was deliberately closed, don't follow up + if (this.authenticated !== process) { + return; + } + + this.dropAuthenticated(process); + if (error instanceof HTTPError) { const { code } = error; @@ -389,6 +393,16 @@ export class SocketManager extends EventListener { } } + public async logout(): Promise { + const { authenticated } = this; + if (authenticated) { + authenticated.abort(); + this.dropAuthenticated(authenticated); + } + + this.credentials = undefined; + } + // // Private // diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index ddfa8e1bed56..da8d1f1708d8 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -755,7 +755,7 @@ type AjaxOptionsType = { }; export type WebAPIConnectOptionsType = WebAPICredentials & { - disableWebSockets?: boolean; + useWebSocket?: boolean; }; export type WebAPIConnectType = { @@ -964,6 +964,7 @@ export type WebAPIType = { Array<{ name: string; enabled: boolean; value: string | null }> >; authenticate: (credentials: WebAPICredentials) => Promise; + logout: () => Promise; getSocketStatus: () => SocketStatus; registerRequestHandler: (handler: IRequestHandler) => void; unregisterRequestHandler: (handler: IRequestHandler) => void; @@ -1078,7 +1079,7 @@ export function initialize({ function connect({ username: initialUsername, password: initialPassword, - disableWebSockets = false, + useWebSocket = true, }: WebAPIConnectOptionsType) { let username = initialUsername; let password = initialPassword; @@ -1096,7 +1097,7 @@ export function initialize({ window.Whisper.events.trigger('unlinkAndDisconnect'); }); - if (!disableWebSockets) { + if (useWebSocket) { socketManager.authenticate({ username, password }); } @@ -1109,6 +1110,7 @@ export function initialize({ registerRequestHandler, unregisterRequestHandler, authenticate, + logout, confirmCode, createGroup, fetchLinkPreviewImage, @@ -1166,11 +1168,11 @@ export function initialize({ param.urlParameters = ''; } - const useWebSocket = - !disableWebSockets && WEBSOCKET_CALLS.has(param.call); + const useWebSocketForEndpoint = + useWebSocket && WEBSOCKET_CALLS.has(param.call); return _outerAjax(null, { - socketManager: useWebSocket ? socketManager : undefined, + socketManager: useWebSocketForEndpoint ? socketManager : undefined, basicAuth: param.basicAuth, certificateAuthority, contentType: param.contentType || 'application/json; charset=utf-8', @@ -1221,11 +1223,20 @@ export function initialize({ username = newUsername; password = newPassword; - if (!disableWebSockets) { + if (useWebSocket) { await socketManager.authenticate({ username, password }); } } + async function logout() { + username = ''; + password = ''; + + if (useWebSocket) { + await socketManager.logout(); + } + } + function getSocketStatus(): SocketStatus { return socketManager.getStatus(); } @@ -1530,10 +1541,7 @@ export function initialize({ // Reset old websocket credentials and disconnect. // AccountManager is our only caller and it will trigger // `registration_done` which will update credentials. - await socketManager.authenticate({ - username: '', - password: '', - }); + await logout(); // Update REST credentials, though. We need them for the call below username = number; diff --git a/ts/textsecure/WebsocketResources.ts b/ts/textsecure/WebsocketResources.ts index a5eaa8cb2a00..f3842077b853 100644 --- a/ts/textsecure/WebsocketResources.ts +++ b/ts/textsecure/WebsocketResources.ts @@ -307,7 +307,7 @@ export default class WebSocketResource extends EventTarget { ); if (this.shuttingDown) { - incomingRequest.respond(500, 'Shutting down'); + incomingRequest.respond(-1, 'Shutting down'); return; } @@ -343,7 +343,7 @@ export default class WebSocketResource extends EventTarget { for (const resolve of outgoing.values()) { resolve({ - status: 500, + status: -1, message: 'Connection closed', response: undefined, headers: [],