Page MenuHomePhorge

D15534.1765033523.diff
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

D15534.1765033523.diff

diff --git a/native/avatars/avatar-hooks.js b/native/avatars/avatar-hooks.js
--- a/native/avatars/avatar-hooks.js
+++ b/native/avatars/avatar-hooks.js
@@ -10,7 +10,10 @@
import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js';
import { EditUserAvatarContext } from 'lib/components/edit-user-avatar-provider.react.js';
-import { useBlobServiceUpload } from 'lib/hooks/upload-hooks.js';
+import {
+ useBlobServiceUpload,
+ usePlaintextMediaUpload,
+} from 'lib/hooks/upload-hooks.js';
import {
extensionFromFilename,
filenameFromPathOrURI,
@@ -37,7 +40,10 @@
import { useSelector } from '../redux/redux-utils.js';
import { useStyles } from '../themes/colors.js';
import Alert from '../utils/alert.js';
-import { blobServiceUploadHandler } from '../utils/blob-service-upload.js';
+import {
+ blobServiceUploadHandler,
+ plaintextMediaUploadHandler,
+} from '../utils/blob-service-upload.js';
import { useStaffCanSee } from '../utils/staff-utils.js';
function displayAvatarUpdateFailureAlert(): void {
@@ -52,10 +58,47 @@
function useUploadProcessedMedia(): (
media: MediaResult,
metadataUploadLocation: 'keyserver' | 'none',
+ supportsEncryption?: boolean,
) => Promise<?UpdateUserAvatarRequest> {
const callBlobServiceUpload = useBlobServiceUpload();
+ const callPlaintextMediaUpload = usePlaintextMediaUpload();
+
return React.useCallback(
- async (processedMedia, metadataUploadLocation) => {
+ async (
+ processedMedia,
+ metadataUploadLocation,
+ supportsEncryption = true,
+ ) => {
+ if (!supportsEncryption) {
+ invariant(processedMedia.success, 'processedMedia must be successful');
+ invariant(
+ processedMedia.mediaType === 'photo',
+ 'Avatar must be a photo',
+ );
+
+ const uploadResult = await callPlaintextMediaUpload({
+ mediaInput: {
+ uploadInput: {
+ type: 'uri',
+ uri: processedMedia.uploadURI,
+ filename: processedMedia.filename,
+ mimeType: processedMedia.mime,
+ },
+ dimensions: processedMedia.dimensions,
+ loop: false,
+ thumbHash: null,
+ },
+ callbacks: { plaintextMediaUploadHandler },
+ });
+
+ return {
+ type: 'non_keyserver_image',
+ blobURI: uploadResult.uri,
+ thumbHash: null,
+ encryptionKey: '',
+ };
+ }
+
const { result: encryptionResult } = await encryptMedia(processedMedia);
if (!encryptionResult.success) {
throw new Error('Avatar media encryption failed.');
@@ -107,7 +150,7 @@
}
return { type: 'encrypted_image', uploadID: id };
},
- [callBlobServiceUpload],
+ [callBlobServiceUpload, callPlaintextMediaUpload],
);
}
@@ -178,12 +221,17 @@
): (
selection: NativeMediaSelection,
metadataUploadLocation: 'keyserver' | 'none',
+ supportsEncryption?: boolean,
) => Promise<?UpdateUserAvatarRequest> {
const processSelectedMedia = useProcessSelectedMedia();
const uploadProcessedMedia = useUploadProcessedMedia();
return React.useCallback(
- async (selection: NativeMediaSelection, metadataUploadLocation) => {
+ async (
+ selection: NativeMediaSelection,
+ metadataUploadLocation,
+ supportsEncryption = true,
+ ) => {
setProcessingOrUploadInProgress?.(true);
const urisToBeDisposed: Set<string> = new Set([selection.uri]);
@@ -218,6 +266,7 @@
uploadedMedia = await uploadProcessedMedia(
processedMedia,
metadataUploadLocation,
+ supportsEncryption,
);
urisToBeDisposed.forEach(filesystem.unlink);
setProcessingOrUploadInProgress?.(false);
@@ -400,13 +449,14 @@
selection: NativeMediaSelection,
threadInfo: ThreadInfo | RawThreadInfo,
): Promise<void> => {
- const metadataUploadLocation = threadSpecs[threadInfo.type].protocol()
- .uploadMultimediaMetadataToKeyserver
- ? 'keyserver'
- : 'none';
+ const protocol = threadSpecs[threadInfo.type].protocol();
+ const metadataUploadLocation =
+ protocol.uploadMultimediaMetadataToKeyserver ? 'keyserver' : 'none';
+ const supportsEncryption = protocol.supportsEncryptedMultimedia;
const imageAvatarUpdateRequest = await uploadSelectedMedia(
selection,
metadataUploadLocation,
+ supportsEncryption,
);
if (!imageAvatarUpdateRequest) {
return;
diff --git a/web/avatars/avatar-hooks.react.js b/web/avatars/avatar-hooks.react.js
--- a/web/avatars/avatar-hooks.react.js
+++ b/web/avatars/avatar-hooks.react.js
@@ -2,7 +2,10 @@
import * as React from 'react';
-import { useBlobServiceUpload } from 'lib/hooks/upload-hooks.js';
+import {
+ useBlobServiceUpload,
+ usePlaintextMediaUpload,
+} from 'lib/hooks/upload-hooks.js';
import type { UpdateUserAvatarRequest } from 'lib/types/avatar-types.js';
import { authoritativeKeyserverID } from '../authoritative-keyserver.js';
@@ -12,14 +15,18 @@
type AvatarMediaUploadOptions = {
+uploadMetadataToKeyserver?: boolean,
+ +supportsEncryption?: boolean,
};
function useUploadAvatarMedia(
options: AvatarMediaUploadOptions = {},
): File => Promise<UpdateUserAvatarRequest> {
- const { uploadMetadataToKeyserver = true } = options;
+ const { uploadMetadataToKeyserver = true, supportsEncryption = true } =
+ options;
const callBlobServiceUpload = useBlobServiceUpload();
+ const callPlaintextMediaUpload = usePlaintextMediaUpload();
+
const uploadAvatarMedia = React.useCallback(
async (file: File): Promise<UpdateUserAvatarRequest> => {
const validatedFile = await validateFile(file);
@@ -29,6 +36,25 @@
}
const { file: fixedFile, dimensions } = result;
+ if (!supportsEncryption) {
+ const uploadResult = await callPlaintextMediaUpload({
+ mediaInput: {
+ uploadInput: { type: 'file', file: fixedFile },
+ dimensions,
+ loop: false,
+ thumbHash: null,
+ },
+ callbacks: {},
+ });
+
+ return {
+ type: 'non_keyserver_image',
+ blobURI: uploadResult.uri,
+ thumbHash: null,
+ encryptionKey: '',
+ };
+ }
+
const encryptionResponse = await encryptFile(fixedFile);
const { result: encryptionResult } = encryptionResponse;
if (!encryptionResult.success) {
@@ -77,7 +103,12 @@
encryptionKey,
};
},
- [callBlobServiceUpload, uploadMetadataToKeyserver],
+ [
+ callBlobServiceUpload,
+ callPlaintextMediaUpload,
+ uploadMetadataToKeyserver,
+ supportsEncryption,
+ ],
);
return uploadAvatarMedia;
}
diff --git a/web/avatars/edit-thread-avatar-menu.react.js b/web/avatars/edit-thread-avatar-menu.react.js
--- a/web/avatars/edit-thread-avatar-menu.react.js
+++ b/web/avatars/edit-thread-avatar-menu.react.js
@@ -75,6 +75,8 @@
uploadMetadataToKeyserver:
threadSpecs[threadInfo.type].protocol()
.uploadMultimediaMetadataToKeyserver,
+ supportsEncryption:
+ threadSpecs[threadInfo.type].protocol().supportsEncryptedMultimedia,
});
const onImageSelected = React.useCallback(
async (event: SyntheticEvent<HTMLInputElement>) => {

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 3:05 PM (13 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5838893
Default Alt Text
D15534.1765033523.diff (7 KB)

Event Timeline