78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import type {
|
|
RateLimitedError as NetRateLimitedError,
|
|
Net,
|
|
} from '@signalapp/libsignal-client';
|
|
import {
|
|
ErrorCode as LibSignalErrorCode,
|
|
LibSignalErrorBase,
|
|
} from '@signalapp/libsignal-client';
|
|
import pTimeout from 'p-timeout';
|
|
import type { CDSBaseOptionsType } from './CDSBase';
|
|
import { CDSBase } from './CDSBase';
|
|
import type { CDSRequestOptionsType, CDSResponseType } from './Types';
|
|
import { sleep } from '../../util/sleep';
|
|
import * as durations from '../../util/durations';
|
|
|
|
export type CDSIOptionsType = CDSBaseOptionsType;
|
|
|
|
const REQUEST_TIMEOUT = 10 * durations.SECOND;
|
|
|
|
export class CDSI extends CDSBase<CDSIOptionsType> {
|
|
#retryAfter?: number;
|
|
|
|
constructor(
|
|
private readonly libsignalNet: Net.Net,
|
|
options: CDSIOptionsType
|
|
) {
|
|
super(options);
|
|
}
|
|
|
|
public async request(
|
|
options: CDSRequestOptionsType
|
|
): Promise<CDSResponseType> {
|
|
const log = this.logger;
|
|
|
|
if (this.#retryAfter !== undefined) {
|
|
const delay = Math.max(0, this.#retryAfter - Date.now());
|
|
|
|
log.info(`CDSSocketManager: waiting ${delay}ms before retrying`);
|
|
await sleep(delay);
|
|
}
|
|
|
|
const { acisAndAccessKeys, e164s } = options;
|
|
const auth = await this.getAuth();
|
|
|
|
log.info('CDSSocketManager: making request via libsignal');
|
|
try {
|
|
log.info('CDSSocketManager: starting lookup request');
|
|
|
|
const { timeout = REQUEST_TIMEOUT } = options;
|
|
const response = await pTimeout(
|
|
this.libsignalNet.cdsiLookup(auth, {
|
|
acisAndAccessKeys,
|
|
e164s,
|
|
}),
|
|
timeout
|
|
);
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|