Use X-Signal-Receive-Stories header

This commit is contained in:
Fedor Indutny 2022-10-04 17:48:25 -07:00 committed by GitHub
parent c52fe3f377
commit ebafc933b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 12 deletions

View File

@ -165,6 +165,7 @@ window.encryptAndUpload = async (
username, username,
password, password,
useWebSocket: false, useWebSocket: false,
hasStoriesDisabled: true,
}); });
const manifestProto = new Proto.StickerPack(); const manifestProto = new Proto.StickerPack();

View File

@ -221,9 +221,10 @@ export async function startApp(): Promise<void> {
let routineProfileRefresher: RoutineProfileRefresher | undefined; let routineProfileRefresher: RoutineProfileRefresher | undefined;
window.storage.onready(() => { window.storage.onready(() => {
server = window.WebAPI.connect( server = window.WebAPI.connect({
window.textsecure.storage.user.getWebAPICredentials() ...window.textsecure.storage.user.getWebAPICredentials(),
); hasStoriesDisabled: window.storage.get('hasStoriesDisabled', false),
});
window.textsecure.server = server; window.textsecure.server = server;
initializeAllJobQueues({ initializeAllJobQueues({
@ -1722,9 +1723,7 @@ export async function startApp(): Promise<void> {
} }
log.info('reconnectToWebSocket starting...'); log.info('reconnectToWebSocket starting...');
await server.onOffline(); await server.reconnect();
await server.onOnline();
log.info('reconnectToWebSocket complete.');
}); });
}; };

View File

@ -1256,7 +1256,11 @@ export async function mergeAccountRecord(
window.storage.put('displayBadgesOnProfile', Boolean(displayBadgesOnProfile)); window.storage.put('displayBadgesOnProfile', Boolean(displayBadgesOnProfile));
window.storage.put('keepMutedChatsArchived', Boolean(keepMutedChatsArchived)); window.storage.put('keepMutedChatsArchived', Boolean(keepMutedChatsArchived));
window.storage.put('hasSetMyStoriesPrivacy', Boolean(hasSetMyStoriesPrivacy)); window.storage.put('hasSetMyStoriesPrivacy', Boolean(hasSetMyStoriesPrivacy));
window.storage.put('hasStoriesDisabled', Boolean(storiesDisabled)); {
const hasStoriesDisabled = Boolean(storiesDisabled);
window.storage.put('hasStoriesDisabled', hasStoriesDisabled);
window.textsecure.server?.onHasStoriesDisabledChange(hasStoriesDisabled);
}
const ourID = window.ConversationController.getOurConversationId(); const ourID = window.ConversationController.getOurConversationId();

View File

@ -37,6 +37,7 @@ export type SocketManagerOptions = Readonly<{
certificateAuthority: string; certificateAuthority: string;
version: string; version: string;
proxyUrl?: string; proxyUrl?: string;
hasStoriesDisabled: boolean;
}>; }>;
// This class manages two websocket resources: // This class manages two websocket resources:
@ -76,12 +77,16 @@ export class SocketManager extends EventListener {
private isOffline = false; private isOffline = false;
private hasStoriesDisabled: boolean;
constructor(private readonly options: SocketManagerOptions) { constructor(private readonly options: SocketManagerOptions) {
super(); super();
if (options.proxyUrl) { if (options.proxyUrl) {
this.proxyAgent = new ProxyAgent(options.proxyUrl); this.proxyAgent = new ProxyAgent(options.proxyUrl);
} }
this.hasStoriesDisabled = options.hasStoriesDisabled;
} }
public getStatus(): SocketStatus { public getStatus(): SocketStatus {
@ -124,7 +129,10 @@ export class SocketManager extends EventListener {
this.credentials = credentials; this.credentials = credentials;
log.info('SocketManager: connecting authenticated socket'); log.info(
'SocketManager: connecting authenticated socket ' +
`(hasStoriesDisabled=${this.hasStoriesDisabled})`
);
this.setStatus(SocketStatus.CONNECTING); this.setStatus(SocketStatus.CONNECTING);
@ -138,6 +146,9 @@ export class SocketManager extends EventListener {
this.queueOrHandleRequest(req); this.queueOrHandleRequest(req);
}, },
}, },
extraHeaders: {
'X-Signal-Receive-Stories': String(!this.hasStoriesDisabled),
},
}); });
// Cancel previous connect attempt or close socket // Cancel previous connect attempt or close socket
@ -348,6 +359,25 @@ export class SocketManager extends EventListener {
this.requestHandlers.delete(handler); this.requestHandlers.delete(handler);
} }
public async onHasStoriesDisabledChange(newValue: boolean): Promise<void> {
if (this.hasStoriesDisabled === newValue) {
return;
}
this.hasStoriesDisabled = newValue;
log.info(
`SocketManager: reconnecting after setting hasStoriesDisabled=${newValue}`
);
await this.reconnect();
}
public async reconnect(): Promise<void> {
log.info('SocketManager.reconnect: starting...');
this.onOffline();
await this.onOnline();
log.info('SocketManager.reconnect: complete.');
}
// Force keep-alive checks on WebSocketResources // Force keep-alive checks on WebSocketResources
public async check(): Promise<void> { public async check(): Promise<void> {
if (this.isOffline) { if (this.isOffline) {
@ -374,7 +404,7 @@ export class SocketManager extends EventListener {
// Puts SocketManager into "offline" state and gracefully disconnects both // Puts SocketManager into "offline" state and gracefully disconnects both
// unauthenticated and authenticated resources. // unauthenticated and authenticated resources.
public async onOffline(): Promise<void> { public onOffline(): void {
log.info('SocketManager.onOffline'); log.info('SocketManager.onOffline');
this.isOffline = true; this.isOffline = true;
@ -471,11 +501,13 @@ export class SocketManager extends EventListener {
path, path,
resourceOptions, resourceOptions,
query = {}, query = {},
extraHeaders = {},
}: { }: {
name: string; name: string;
path: string; path: string;
resourceOptions: WebSocketResourceOptions; resourceOptions: WebSocketResourceOptions;
query?: Record<string, string>; query?: Record<string, string>;
extraHeaders?: Record<string, string>;
}): AbortableProcess<WebSocketResource> { }): AbortableProcess<WebSocketResource> {
const queryWithDefaults = { const queryWithDefaults = {
agent: 'OWD', agent: 'OWD',
@ -492,6 +524,8 @@ export class SocketManager extends EventListener {
version: this.options.version, version: this.options.version,
proxyAgent: this.proxyAgent, proxyAgent: this.proxyAgent,
extraHeaders,
createResource(socket: WebSocket): WebSocketResource { createResource(socket: WebSocket): WebSocketResource {
return new WebSocketResource(socket, resourceOptions); return new WebSocketResource(socket, resourceOptions);
}, },

View File

@ -612,6 +612,7 @@ type AjaxOptionsType = {
export type WebAPIConnectOptionsType = WebAPICredentials & { export type WebAPIConnectOptionsType = WebAPICredentials & {
useWebSocket?: boolean; useWebSocket?: boolean;
hasStoriesDisabled: boolean;
}; };
export type WebAPIConnectType = { export type WebAPIConnectType = {
@ -962,9 +963,11 @@ export type WebAPIType = {
getSocketStatus: () => SocketStatus; getSocketStatus: () => SocketStatus;
registerRequestHandler: (handler: IRequestHandler) => void; registerRequestHandler: (handler: IRequestHandler) => void;
unregisterRequestHandler: (handler: IRequestHandler) => void; unregisterRequestHandler: (handler: IRequestHandler) => void;
onHasStoriesDisabledChange: (newValue: boolean) => void;
checkSockets: () => void; checkSockets: () => void;
onOnline: () => Promise<void>; onOnline: () => Promise<void>;
onOffline: () => Promise<void>; onOffline: () => void;
reconnect: () => Promise<void>;
}; };
export type SignedPreKeyType = { export type SignedPreKeyType = {
@ -1074,6 +1077,7 @@ export function initialize({
username: initialUsername, username: initialUsername,
password: initialPassword, password: initialPassword,
useWebSocket = true, useWebSocket = true,
hasStoriesDisabled,
}: WebAPIConnectOptionsType) { }: WebAPIConnectOptionsType) {
let username = initialUsername; let username = initialUsername;
let password = initialPassword; let password = initialPassword;
@ -1088,6 +1092,7 @@ export function initialize({
certificateAuthority, certificateAuthority,
version, version,
proxyUrl, proxyUrl,
hasStoriesDisabled,
}); });
socketManager.on('statusChange', () => { socketManager.on('statusChange', () => {
@ -1228,8 +1233,10 @@ export function initialize({
checkSockets, checkSockets,
onOnline, onOnline,
onOffline, onOffline,
reconnect,
registerRequestHandler, registerRequestHandler,
unregisterRequestHandler, unregisterRequestHandler,
onHasStoriesDisabledChange,
authenticate, authenticate,
logout, logout,
cdsLookup, cdsLookup,
@ -1430,8 +1437,12 @@ export function initialize({
await socketManager.onOnline(); await socketManager.onOnline();
} }
async function onOffline(): Promise<void> { function onOffline(): void {
await socketManager.onOffline(); socketManager.onOffline();
}
async function reconnect(): Promise<void> {
await socketManager.reconnect();
} }
function registerRequestHandler(handler: IRequestHandler): void { function registerRequestHandler(handler: IRequestHandler): void {
@ -1442,6 +1453,10 @@ export function initialize({
socketManager.unregisterRequestHandler(handler); socketManager.unregisterRequestHandler(handler);
} }
function onHasStoriesDisabledChange(newValue: boolean): void {
socketManager.onHasStoriesDisabledChange(newValue);
}
async function getConfig() { async function getConfig() {
type ResType = { type ResType = {
config: Array<{ name: string; enabled: boolean; value: string | null }>; config: Array<{ name: string; enabled: boolean; value: string | null }>;

View File

@ -184,6 +184,7 @@ export function createIPCEvents(
await window.storage.put('hasStoriesDisabled', value); await window.storage.put('hasStoriesDisabled', value);
const account = window.ConversationController.getOurConversationOrThrow(); const account = window.ConversationController.getOurConversationOrThrow();
account.captureChange('hasStoriesDisabled'); account.captureChange('hasStoriesDisabled');
window.textsecure.server?.onHasStoriesDisabledChange(value);
}, },
getPreferredAudioInputDevice: () => getPreferredAudioInputDevice: () =>