Send support for Sender Key

This commit is contained in:
Scott Nonnenberg 2021-05-25 15:40:04 -07:00 committed by GitHub
parent d8417e562b
commit e6f1ec2b6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 2290 additions and 911 deletions

View file

@ -26,6 +26,7 @@ import { pki } from 'node-forge';
import is from '@sindresorhus/is';
import PQueue from 'p-queue';
import { v4 as getGuid } from 'uuid';
import { z } from 'zod';
import { Long } from '../window.d';
import { getUserAgent } from '../util/getUserAgent';
@ -351,6 +352,49 @@ type ArrayBufferWithDetailsType = {
response: Response;
};
export const multiRecipient200ResponseSchema = z
.object({
uuids404: z.array(z.string()).optional(),
needsSync: z.boolean().optional(),
})
.passthrough();
export type MultiRecipient200ResponseType = z.infer<
typeof multiRecipient200ResponseSchema
>;
export const multiRecipient409ResponseSchema = z.array(
z
.object({
uuid: z.string(),
devices: z
.object({
missingDevices: z.array(z.number()).optional(),
extraDevices: z.array(z.number()).optional(),
})
.passthrough(),
})
.passthrough()
);
export type MultiRecipient409ResponseType = z.infer<
typeof multiRecipient409ResponseSchema
>;
export const multiRecipient410ResponseSchema = z.array(
z
.object({
uuid: z.string(),
devices: z
.object({
staleDevices: z.array(z.number()).optional(),
})
.passthrough(),
})
.passthrough()
);
export type MultiRecipient410ResponseType = z.infer<
typeof multiRecipient410ResponseSchema
>;
function isSuccess(status: number): boolean {
return status >= 0 && status < 400;
}
@ -685,6 +729,7 @@ const URL_CALLS = {
groupToken: 'v1/groups/token',
keys: 'v2/keys',
messages: 'v1/messages',
multiRecipient: 'v1/messages/multi_recipient',
profile: 'v1/profile',
registerCapabilities: 'v1/devices/capabilities',
removeSignalingKey: 'v1/accounts/signaling_key',
@ -728,6 +773,7 @@ type AjaxOptionsType = {
call: keyof typeof URL_CALLS;
contentType?: string;
data?: ArrayBuffer | Buffer | string;
headers?: HeaderListType;
host?: string;
httpType: HTTPCodeType;
jsonData?: any;
@ -749,10 +795,12 @@ export type WebAPIConnectType = {
export type CapabilitiesType = {
gv2: boolean;
'gv1-migration': boolean;
senderKey: boolean;
};
export type CapabilitiesUploadType = {
'gv2-3': boolean;
'gv1-migration': boolean;
senderKey: boolean;
};
type StickerPackManifestType = any;
@ -895,6 +943,12 @@ export type WebAPIType = {
online?: boolean,
options?: { accessKey?: string }
) => Promise<void>;
sendWithSenderKey: (
payload: ArrayBuffer,
accessKeys: ArrayBuffer,
timestamp: number,
online?: boolean
) => Promise<MultiRecipient200ResponseType>;
setSignedPreKey: (signedPreKey: SignedPreKeyType) => Promise<void>;
updateDeviceName: (deviceName: string) => Promise<void>;
uploadGroupAvatar: (
@ -1065,6 +1119,7 @@ export function initialize({
requestVerificationVoice,
sendMessages,
sendMessagesUnauth,
sendWithSenderKey,
setSignedPreKey,
updateDeviceName,
uploadGroupAvatar,
@ -1082,6 +1137,7 @@ export function initialize({
certificateAuthority,
contentType: param.contentType || 'application/json; charset=utf-8',
data: param.data || (param.jsonData && _jsonThing(param.jsonData)),
headers: param.headers,
host: param.host || url,
password: param.password || password,
path: URL_CALLS[param.call] + param.urlParameters,
@ -1375,6 +1431,7 @@ export function initialize({
const capabilities: CapabilitiesUploadType = {
'gv2-3': true,
'gv1-migration': true,
senderKey: false,
};
const { accessKey } = options;
@ -1661,6 +1718,25 @@ export function initialize({
});
}
async function sendWithSenderKey(
data: ArrayBuffer,
accessKeys: ArrayBuffer,
timestamp: number,
online?: boolean
): Promise<MultiRecipient200ResponseType> {
return _ajax({
call: 'multiRecipient',
httpType: 'PUT',
contentType: 'application/vnd.signal-messenger.mrm',
data,
urlParameters: `?ts=${timestamp}&online=${online ? 'true' : 'false'}`,
responseType: 'json',
headers: {
'Unidentified-Access-Key': arrayBufferToBase64(accessKeys),
},
});
}
function redactStickerUrl(stickerUrl: string) {
return stickerUrl.replace(
/(\/stickers\/)([^/]+)(\/)/,