Integrate libsignal-net CDSI lookup and make it accessible in debug builds

This commit is contained in:
Alex Konradi 2024-01-17 16:57:03 -05:00 committed by GitHub
parent a9df5923a3
commit 6dfef6e70d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 81 additions and 11 deletions

View file

@ -766,6 +766,7 @@ export type CdsLookupOptionsType = Readonly<{
e164s: ReadonlyArray<string>; e164s: ReadonlyArray<string>;
acisAndAccessKeys?: ReadonlyArray<{ aci: AciString; accessKey: string }>; acisAndAccessKeys?: ReadonlyArray<{ aci: AciString; accessKey: string }>;
returnAcisWithoutUaks?: boolean; returnAcisWithoutUaks?: boolean;
useLibsignal?: boolean;
}>; }>;
type GetProfileCommonOptionsType = Readonly< type GetProfileCommonOptionsType = Readonly<
@ -3485,11 +3486,13 @@ export function initialize({
e164s, e164s,
acisAndAccessKeys = [], acisAndAccessKeys = [],
returnAcisWithoutUaks, returnAcisWithoutUaks,
useLibsignal,
}: CdsLookupOptionsType): Promise<CDSResponseType> { }: CdsLookupOptionsType): Promise<CDSResponseType> {
return cds.request({ return cds.request({
e164s, e164s,
acisAndAccessKeys, acisAndAccessKeys,
returnAcisWithoutUaks, returnAcisWithoutUaks,
useLibsignal,
}); });
} }

View file

@ -1,6 +1,12 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { RateLimitedError as NetRateLimitedError } from '@signalapp/libsignal-client';
import {
Net,
ErrorCode as LibSignalErrorCode,
LibSignalErrorBase,
} from '@signalapp/libsignal-client';
import type { connection as WebSocket } from 'websocket'; import type { connection as WebSocket } from 'websocket';
import pTimeout from 'p-timeout'; import pTimeout from 'p-timeout';
@ -19,6 +25,7 @@ import type {
} from './Types.d'; } from './Types.d';
import { RateLimitedError } from './RateLimitedError'; import { RateLimitedError } from './RateLimitedError';
import { connect as connectWebSocket } from '../WebSocket'; import { connect as connectWebSocket } from '../WebSocket';
import { Environment, getEnvironment } from '../../environment';
const REQUEST_TIMEOUT = 10 * SECOND; const REQUEST_TIMEOUT = 10 * SECOND;
@ -47,6 +54,16 @@ export abstract class CDSSocketManagerBase<
await sleep(delay); await sleep(delay);
} }
if (options.useLibsignal) {
return this.requestViaLibsignal(options);
}
return this.requestViaNativeSocket(options);
}
private async requestViaNativeSocket(
options: CDSRequestOptionsType
): Promise<CDSResponseType> {
const log = this.logger;
const auth = await this.getAuth(); const auth = await this.getAuth();
log.info('CDSSocketManager: connecting socket'); log.info('CDSSocketManager: connecting socket');
@ -85,6 +102,59 @@ export abstract class CDSSocketManagerBase<
} }
} }
private async requestViaLibsignal(
options: CDSRequestOptionsType
): Promise<CDSResponseType> {
const log = this.logger;
const {
acisAndAccessKeys,
e164s,
timeout = REQUEST_TIMEOUT,
returnAcisWithoutUaks = false,
} = options;
const auth = await this.getAuth();
log.info('CDSSocketManager: making request via libsignal');
const net = new Net.Net(this.libsignalNetEnvironment());
try {
log.info('CDSSocketManager: starting lookup request');
const response = await net.cdsiLookup(auth, {
acisAndAccessKeys,
e164s,
timeout,
returnAcisWithoutUaks,
});
log.info('CDSSocketManager: lookup request finished');
return response as CDSResponseType;
} catch (error) {
if (
error instanceof LibSignalErrorBase &&
error.code === LibSignalErrorCode.RateLimitedError
) {
const retryError = error as NetRateLimitedError;
this.retryAfter = Math.max(
this.retryAfter ?? Date.now(),
Date.now() + retryError.retryAfterSecs * durations.SECOND
);
}
throw error;
}
}
private libsignalNetEnvironment(): Net.Environment {
const env = getEnvironment();
switch (env) {
case Environment.Production:
return Net.Environment.Production;
case Environment.Development:
case Environment.Test:
case Environment.Staging:
default:
return Net.Environment.Staging;
}
}
private connect(auth: CDSAuthType): AbortableProcess<Socket> { private connect(auth: CDSAuthType): AbortableProcess<Socket> {
return connectWebSocket<Socket>({ return connectWebSocket<Socket>({
name: 'CDSSocket', name: 'CDSSocket',

View file

@ -1,23 +1,20 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { Net } from '@signalapp/libsignal-client';
import type { AciString, PniString } from '../../types/ServiceId'; import type { AciString, PniString } from '../../types/ServiceId';
export type CDSAuthType = Readonly<{ export type CDSAuthType = Net.CDSAuthType;
username: string; export type CDSResponseEntryType = Net.CDSResponseEntryType<
password: string; AciString,
}>; PniString
>;
export type CDSResponseEntryType = Readonly<{ export type CDSResponseType = Net.CDSResponseType<AciString, PniString>;
aci: AciString | undefined;
pni: PniString | undefined;
}>;
export type CDSResponseType = ReadonlyMap<string, CDSResponseEntryType>;
export type CDSRequestOptionsType = Readonly<{ export type CDSRequestOptionsType = Readonly<{
e164s: ReadonlyArray<string>; e164s: ReadonlyArray<string>;
acisAndAccessKeys: ReadonlyArray<{ aci: AciString; accessKey: string }>; acisAndAccessKeys: ReadonlyArray<{ aci: AciString; accessKey: string }>;
returnAcisWithoutUaks?: boolean; returnAcisWithoutUaks?: boolean;
timeout?: number; timeout?: number;
useLibsignal?: boolean;
}>; }>;