Use new attachments API endpoint

This commit is contained in:
Fedor Indutny 2023-05-04 13:58:53 -07:00 committed by Josh Perez
parent d7bd4eb156
commit f1624705a7
3 changed files with 51 additions and 29 deletions

View file

@ -472,7 +472,7 @@ function makeHTTPError(
const URL_CALLS = {
accounts: 'v1/accounts',
accountExistence: 'v1/accounts/account',
attachmentId: 'v2/attachments/form/upload',
attachmentId: 'v3/attachments/form/upload',
attestation: 'v1/attestation',
batchIdentityCheck: 'v1/profile/identity_check/batch',
boostBadges: 'v1/subscription/boost/badges',
@ -841,6 +841,15 @@ const artAuthZod = z.object({
export type ArtAuthType = z.infer<typeof artAuthZod>;
const attachmentV3Response = z.object({
cdn: z.literal(2),
key: z.string(),
headers: z.record(z.string()),
signedUploadLocation: z.string(),
});
export type AttachmentV3ResponseType = z.infer<typeof attachmentV3Response>;
export type WebAPIType = {
startRegistration(): unknown;
finishRegistration(baton: unknown): void;
@ -2334,7 +2343,7 @@ export function initialize({
);
}
type ServerAttachmentType = {
type ServerV2AttachmentType = {
key: string;
credential: string;
acl: string;
@ -2353,7 +2362,7 @@ export function initialize({
date,
policy,
signature,
}: ServerAttachmentType,
}: ServerV2AttachmentType,
encryptedBin: Uint8Array
) {
// Note: when using the boundary string in the POST body, it needs to be prefixed by
@ -2416,8 +2425,8 @@ export function initialize({
urlParameters: `/${encryptedStickers.length}`,
})) as {
packId: string;
manifest: ServerAttachmentType;
stickers: ReadonlyArray<ServerAttachmentType>;
manifest: ServerV2AttachmentType;
stickers: ReadonlyArray<ServerV2AttachmentType>;
};
// Upload manifest
@ -2439,7 +2448,7 @@ export function initialize({
throwOnTimeout: true,
});
await Promise.all(
stickers.map(async (sticker: ServerAttachmentType, index: number) => {
stickers.map(async (sticker: ServerV2AttachmentType, index: number) => {
const stickerParams = makePutParams(
sticker,
encryptedStickers[index]
@ -2503,32 +2512,48 @@ export function initialize({
}
}
type PutAttachmentResponseType = ServerAttachmentType & {
attachmentIdString: string;
};
async function putEncryptedAttachment(encryptedBin: Uint8Array) {
const response = (await _ajax({
call: 'attachmentId',
httpType: 'GET',
responseType: 'json',
})) as PutAttachmentResponseType;
const response = attachmentV3Response.parse(
await _ajax({
call: 'attachmentId',
httpType: 'GET',
responseType: 'json',
})
);
const { attachmentIdString } = response;
const params = makePutParams(response, encryptedBin);
const { signedUploadLocation, key: cdnKey, headers } = response;
// This is going to the CDN, not the service, so we use _outerAjax
await _outerAjax(`${cdnUrlObject['0']}/attachments/`, {
...params,
const { response: uploadResponse } = await _outerAjax(
signedUploadLocation,
{
responseType: 'byteswithdetails',
certificateAuthority,
proxyUrl,
timeout: 0,
type: 'POST',
version,
headers,
}
);
const uploadLocation = uploadResponse.headers.get('location');
strictAssert(
uploadLocation,
'attachment v3 response header has no location'
);
// This is going to the CDN, not the service, so we use _outerAjax
await _outerAjax(uploadLocation, {
certificateAuthority,
proxyUrl,
timeout: 0,
type: 'POST',
type: 'PUT',
version,
data: encryptedBin,
});
return attachmentIdString;
return cdnKey;
}
function getHeaderPadding() {

View file

@ -88,7 +88,7 @@ export type AttachmentType = {
export type UploadedAttachmentType = Proto.IAttachmentPointer &
Readonly<{
// Required fields
cdnId: Long;
cdnKey: string;
key: Uint8Array;
size: number;
digest: Uint8Array;

View file

@ -1,8 +1,6 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import Long from 'long';
import type {
AttachmentWithHydratedData,
UploadedAttachmentType,
@ -20,12 +18,11 @@ export async function uploadAttachment(
const { server } = window.textsecure;
strictAssert(server, 'WebAPI must be initialized');
const attachmentIdString = await server.putEncryptedAttachment(
encrypted.ciphertext
);
const cdnKey = await server.putEncryptedAttachment(encrypted.ciphertext);
return {
cdnId: Long.fromString(attachmentIdString),
cdnKey,
cdnNumber: 2,
key: keys,
size: attachment.data.byteLength,
digest: encrypted.digest,