Support endorsements for group 1:1 sends
Co-authored-by: trevor-signal <131492920+trevor-signal@users.noreply.github.com>
This commit is contained in:
parent
76a77a9b7f
commit
e617981e59
26 changed files with 1296 additions and 796 deletions
|
@ -74,6 +74,10 @@ import { isStagingServer } from '../util/isStagingServer';
|
|||
import type { IWebSocketResource } from './WebsocketResources';
|
||||
import type { GroupSendToken } from '../types/GroupSendEndorsements';
|
||||
import { parseUnknown, safeParseUnknown } from '../util/schemas';
|
||||
import type {
|
||||
ProfileFetchAuthRequestOptions,
|
||||
ProfileFetchUnauthRequestOptions,
|
||||
} from '../services/profiles';
|
||||
|
||||
// Note: this will break some code that expects to be able to use err.response when a
|
||||
// web request fails, because it will force it to text. But it is very useful for
|
||||
|
@ -91,7 +95,7 @@ function resolveLibsignalNetEnvironment(url: string): Net.Environment {
|
|||
}
|
||||
|
||||
function _createRedactor(
|
||||
...toReplace: ReadonlyArray<string | undefined>
|
||||
...toReplace: ReadonlyArray<string | undefined | null>
|
||||
): RedactUrl {
|
||||
// NOTE: It would be nice to remove this cast, but TypeScript doesn't support
|
||||
// it. However, there is [an issue][0] that discusses this in more detail.
|
||||
|
@ -898,31 +902,6 @@ export type CdsLookupOptionsType = Readonly<{
|
|||
useLibsignal?: boolean;
|
||||
}>;
|
||||
|
||||
type GetProfileCommonOptionsType = Readonly<
|
||||
{
|
||||
userLanguages: ReadonlyArray<string>;
|
||||
} & (
|
||||
| {
|
||||
profileKeyVersion?: undefined;
|
||||
profileKeyCredentialRequest?: undefined;
|
||||
}
|
||||
| {
|
||||
profileKeyVersion: string;
|
||||
profileKeyCredentialRequest?: string;
|
||||
}
|
||||
)
|
||||
>;
|
||||
|
||||
export type GetProfileOptionsType = GetProfileCommonOptionsType &
|
||||
Readonly<{
|
||||
accessKey?: undefined;
|
||||
}>;
|
||||
|
||||
export type GetProfileUnauthOptionsType = GetProfileCommonOptionsType &
|
||||
Readonly<{
|
||||
accessKey: string;
|
||||
}>;
|
||||
|
||||
export type GetGroupCredentialsOptionsType = Readonly<{
|
||||
startDayInMs: number;
|
||||
endDayInMs: number;
|
||||
|
@ -1311,14 +1290,14 @@ export type WebAPIType = {
|
|||
}>;
|
||||
getProfile: (
|
||||
serviceId: ServiceIdString,
|
||||
options: GetProfileOptionsType
|
||||
options: ProfileFetchAuthRequestOptions
|
||||
) => Promise<ProfileType>;
|
||||
getAccountForUsername: (
|
||||
options: GetAccountForUsernameOptionsType
|
||||
) => Promise<GetAccountForUsernameResultType>;
|
||||
getProfileUnauth: (
|
||||
serviceId: ServiceIdString,
|
||||
options: GetProfileUnauthOptionsType
|
||||
options: ProfileFetchUnauthRequestOptions
|
||||
) => Promise<ProfileType>;
|
||||
getBadgeImageFile: (imageUrl: string) => Promise<Uint8Array>;
|
||||
getSubscriptionConfiguration: (
|
||||
|
@ -1413,7 +1392,8 @@ export type WebAPIType = {
|
|||
messageArray: ReadonlyArray<MessageType>,
|
||||
timestamp: number,
|
||||
options: {
|
||||
accessKey?: string;
|
||||
accessKey: string | null;
|
||||
groupSendToken: GroupSendToken | null;
|
||||
online?: boolean;
|
||||
story?: boolean;
|
||||
urgent?: boolean;
|
||||
|
@ -1421,8 +1401,8 @@ export type WebAPIType = {
|
|||
) => Promise<void>;
|
||||
sendWithSenderKey: (
|
||||
payload: Uint8Array,
|
||||
accessKeys: Uint8Array | undefined,
|
||||
groupSendToken: GroupSendToken | undefined,
|
||||
accessKeys: Uint8Array | null,
|
||||
groupSendToken: GroupSendToken | null,
|
||||
timestamp: number,
|
||||
options: {
|
||||
online?: boolean;
|
||||
|
@ -2177,19 +2157,19 @@ export function initialize({
|
|||
{
|
||||
profileKeyVersion,
|
||||
profileKeyCredentialRequest,
|
||||
}: GetProfileCommonOptionsType
|
||||
}: ProfileFetchAuthRequestOptions | ProfileFetchUnauthRequestOptions
|
||||
) {
|
||||
let profileUrl = `/${serviceId}`;
|
||||
if (profileKeyVersion !== undefined) {
|
||||
if (profileKeyVersion != null) {
|
||||
profileUrl += `/${profileKeyVersion}`;
|
||||
if (profileKeyCredentialRequest !== undefined) {
|
||||
if (profileKeyCredentialRequest != null) {
|
||||
profileUrl +=
|
||||
`/${profileKeyCredentialRequest}` +
|
||||
'?credentialType=expiringProfileKey';
|
||||
}
|
||||
} else {
|
||||
strictAssert(
|
||||
profileKeyCredentialRequest === undefined,
|
||||
profileKeyCredentialRequest == null,
|
||||
'getProfileUrl called without version, but with request'
|
||||
);
|
||||
}
|
||||
|
@ -2199,7 +2179,7 @@ export function initialize({
|
|||
|
||||
async function getProfile(
|
||||
serviceId: ServiceIdString,
|
||||
options: GetProfileOptionsType
|
||||
options: ProfileFetchAuthRequestOptions
|
||||
) {
|
||||
const { profileKeyVersion, profileKeyCredentialRequest, userLanguages } =
|
||||
options;
|
||||
|
@ -2258,15 +2238,25 @@ export function initialize({
|
|||
|
||||
async function getProfileUnauth(
|
||||
serviceId: ServiceIdString,
|
||||
options: GetProfileUnauthOptionsType
|
||||
options: ProfileFetchUnauthRequestOptions
|
||||
) {
|
||||
const {
|
||||
accessKey,
|
||||
groupSendToken,
|
||||
profileKeyVersion,
|
||||
profileKeyCredentialRequest,
|
||||
userLanguages,
|
||||
} = options;
|
||||
|
||||
if (profileKeyVersion != null || profileKeyCredentialRequest != null) {
|
||||
// Without an up-to-date profile key, we won't be able to read the
|
||||
// profile anyways so there's no point in falling back to endorsements.
|
||||
strictAssert(
|
||||
groupSendToken == null,
|
||||
'Should not use endorsements for fetching a versioned profile'
|
||||
);
|
||||
}
|
||||
|
||||
return (await _ajax({
|
||||
call: 'profile',
|
||||
httpType: 'GET',
|
||||
|
@ -2276,8 +2266,8 @@ export function initialize({
|
|||
},
|
||||
responseType: 'json',
|
||||
unauthenticated: true,
|
||||
accessKey,
|
||||
groupSendToken: undefined,
|
||||
accessKey: accessKey ?? undefined,
|
||||
groupSendToken: groupSendToken ?? undefined,
|
||||
redactUrl: _createRedactor(
|
||||
serviceId,
|
||||
profileKeyVersion,
|
||||
|
@ -3273,11 +3263,13 @@ export function initialize({
|
|||
timestamp: number,
|
||||
{
|
||||
accessKey,
|
||||
groupSendToken,
|
||||
online,
|
||||
urgent = true,
|
||||
story = false,
|
||||
}: {
|
||||
accessKey?: string;
|
||||
accessKey: string | null;
|
||||
groupSendToken: GroupSendToken | null;
|
||||
online?: boolean;
|
||||
story?: boolean;
|
||||
urgent?: boolean;
|
||||
|
@ -3297,8 +3289,8 @@ export function initialize({
|
|||
jsonData,
|
||||
responseType: 'json',
|
||||
unauthenticated: true,
|
||||
accessKey,
|
||||
groupSendToken: undefined,
|
||||
accessKey: accessKey ?? undefined,
|
||||
groupSendToken: groupSendToken ?? undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3334,8 +3326,8 @@ export function initialize({
|
|||
|
||||
async function sendWithSenderKey(
|
||||
data: Uint8Array,
|
||||
accessKeys: Uint8Array | undefined,
|
||||
groupSendToken: GroupSendToken | undefined,
|
||||
accessKeys: Uint8Array | null,
|
||||
groupSendToken: GroupSendToken | null,
|
||||
timestamp: number,
|
||||
{
|
||||
online,
|
||||
|
@ -3360,7 +3352,7 @@ export function initialize({
|
|||
responseType: 'json',
|
||||
unauthenticated: true,
|
||||
accessKey: accessKeys != null ? Bytes.toBase64(accessKeys) : undefined,
|
||||
groupSendToken,
|
||||
groupSendToken: groupSendToken ?? undefined,
|
||||
});
|
||||
const parseResult = safeParseUnknown(
|
||||
multiRecipient200ResponseSchema,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue