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

View file

@ -1,6 +1,12 @@
// Copyright 2021 Signal Messenger, LLC
// 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 pTimeout from 'p-timeout';
@ -19,6 +25,7 @@ import type {
} from './Types.d';
import { RateLimitedError } from './RateLimitedError';
import { connect as connectWebSocket } from '../WebSocket';
import { Environment, getEnvironment } from '../../environment';
const REQUEST_TIMEOUT = 10 * SECOND;
@ -47,6 +54,16 @@ export abstract class CDSSocketManagerBase<
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();
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> {
return connectWebSocket<Socket>({
name: 'CDSSocket',

View file

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