From 451ee56c929614ff20c478201414cfced9938ce2 Mon Sep 17 00:00:00 2001 From: trevor-signal <131492920+trevor-signal@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:25:43 -0400 Subject: [PATCH] Use v4/attachments endpoint for attachment upload forms --- ts/services/backups/api.ts | 4 ++-- ts/textsecure/WebAPI.ts | 30 ++++++++++++++++-------------- ts/util/uploadAttachment.ts | 6 +++--- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/ts/services/backups/api.ts b/ts/services/backups/api.ts index f122dbf3bd3..8e6bcb1a3d3 100644 --- a/ts/services/backups/api.ts +++ b/ts/services/backups/api.ts @@ -4,7 +4,7 @@ import { strictAssert } from '../../util/assert'; import type { WebAPIType, - AttachmentV3ResponseType, + AttachmentUploadFormResponseType, GetBackupInfoResponseType, BackupMediaItemType, BackupMediaBatchResponseType, @@ -66,7 +66,7 @@ export class BackupAPI { }); } - public async getMediaUploadForm(): Promise { + public async getMediaUploadForm(): Promise { return this.server.getBackupMediaUploadForm( await this.credentials.getHeadersForToday() ); diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index 7553766d164..88752cee4e7 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -537,7 +537,7 @@ function makeHTTPError( const URL_CALLS = { accountExistence: 'v1/accounts/account', - attachmentUploadForm: 'v3/attachments/form/upload', + attachmentUploadForm: 'v4/attachments/form/upload', attestation: 'v1/attestation', batchIdentityCheck: 'v1/profile/identity_check/batch', challenge: 'v1/challenge', @@ -982,14 +982,16 @@ export type ReportMessageOptionsType = Readonly<{ token?: string; }>; -const attachmentV3Response = z.object({ +const attachmentUploadFormResponse = z.object({ cdn: z.literal(2).or(z.literal(3)), key: z.string(), headers: z.record(z.string()), signedUploadLocation: z.string(), }); -export type AttachmentV3ResponseType = z.infer; +export type AttachmentUploadFormResponseType = z.infer< + typeof attachmentUploadFormResponse +>; export type ServerKeyCountType = { count: number; @@ -1214,7 +1216,7 @@ export type WebAPIType = { timeout?: number; }; }) => Promise; - getAttachmentUploadForm: () => Promise; + getAttachmentUploadForm: () => Promise; getAvatar: (path: string) => Promise; getHasSubscription: (subscriberId: Uint8Array) => Promise; getGroup: (options: GroupCredentialsType) => Promise; @@ -1304,7 +1306,7 @@ export type WebAPIType = { ) => Promise; putEncryptedAttachment: ( encryptedBin: Uint8Array | (() => Readable), - uploadForm: AttachmentV3ResponseType + uploadForm: AttachmentUploadFormResponseType ) => Promise; putProfile: ( jsonData: ProfileRequestDataType @@ -1368,17 +1370,17 @@ export type WebAPIType = { } ) => Promise; createFetchForAttachmentUpload( - attachment: AttachmentV3ResponseType + attachment: AttachmentUploadFormResponseType ): FetchFunctionType; getBackupInfo: ( headers: BackupPresentationHeadersType ) => Promise; getBackupUploadForm: ( headers: BackupPresentationHeadersType - ) => Promise; + ) => Promise; getBackupMediaUploadForm: ( headers: BackupPresentationHeadersType - ) => Promise; + ) => Promise; refreshBackup: (headers: BackupPresentationHeadersType) => Promise; getBackupCredentials: ( options: GetBackupCredentialsOptionsType @@ -2769,14 +2771,14 @@ export function initialize({ responseType: 'json', }); - return attachmentV3Response.parse(res); + return attachmentUploadFormResponse.parse(res); } function createFetchForAttachmentUpload({ signedUploadLocation, headers: uploadHeaders, cdn, - }: AttachmentV3ResponseType): FetchFunctionType { + }: AttachmentUploadFormResponseType): FetchFunctionType { strictAssert(cdn === 3, 'Fetch can only be created for CDN 3'); const { origin: expectedOrigin } = new URL(signedUploadLocation); @@ -2820,7 +2822,7 @@ export function initialize({ responseType: 'json', }); - return attachmentV3Response.parse(res); + return attachmentUploadFormResponse.parse(res); } async function refreshBackup(headers: BackupPresentationHeadersType) { @@ -3520,7 +3522,7 @@ export function initialize({ } async function getAttachmentUploadForm() { - return attachmentV3Response.parse( + return attachmentUploadFormResponse.parse( await _ajax({ call: 'attachmentUploadForm', httpType: 'GET', @@ -3531,7 +3533,7 @@ export function initialize({ async function putEncryptedAttachment( encryptedBin: Uint8Array | (() => Readable), - uploadForm: AttachmentV3ResponseType + uploadForm: AttachmentUploadFormResponseType ) { const { signedUploadLocation, headers } = uploadForm; @@ -3558,7 +3560,7 @@ export function initialize({ const uploadLocation = uploadResponse.headers.get('location'); strictAssert( uploadLocation, - 'attachment v3 response header has no location' + 'attachment upload form header has no location' ); // This is going to the CDN, not the service, so we use _outerAjax diff --git a/ts/util/uploadAttachment.ts b/ts/util/uploadAttachment.ts index 4e0808c0fc8..b92b9d590bb 100644 --- a/ts/util/uploadAttachment.ts +++ b/ts/util/uploadAttachment.ts @@ -11,7 +11,7 @@ import { strictAssert } from './assert'; import { backupsService } from '../services/backups'; import { tusUpload } from './uploads/tusProtocol'; import { defaultFileReader } from './uploads/uploads'; -import type { AttachmentV3ResponseType } from '../textsecure/WebAPI'; +import type { AttachmentUploadFormResponseType } from '../textsecure/WebAPI'; import { type EncryptedAttachmentV2, encryptAttachmentV2ToDisk, @@ -79,7 +79,7 @@ export async function encryptAndUploadAttachment({ const { server } = window.textsecure; strictAssert(server, 'WebAPI must be initialized'); - let uploadForm: AttachmentV3ResponseType; + let uploadForm: AttachmentUploadFormResponseType; let absoluteCiphertextPath: string | undefined; try { @@ -129,7 +129,7 @@ export async function uploadFile({ }: { absoluteCiphertextPath: string; ciphertextFileSize: number; - uploadForm: AttachmentV3ResponseType; + uploadForm: AttachmentUploadFormResponseType; }): Promise { const { server } = window.textsecure; strictAssert(server, 'WebAPI must be initialized');