Page MenuHomePhabricator

D10912.id36777.diff
No OneTemporary

D10912.id36777.diff

diff --git a/web/media/encrypted-multimedia.react.js b/web/media/encrypted-multimedia.react.js
--- a/web/media/encrypted-multimedia.react.js
+++ b/web/media/encrypted-multimedia.react.js
@@ -7,7 +7,7 @@
import type { EncryptedMediaType } from 'lib/types/media-types.js';
-import { fetchAndDecryptMedia } from './encryption-utils.js';
+import { useFetchAndDecryptMedia } from './encryption-utils.js';
import LoadableVideo from './loadable-video.react.js';
import css from './media.css';
import LoadingIndicator from '../loading-indicator.react.js';
@@ -43,6 +43,8 @@
const [source, setSource] = React.useState<?Source>(null);
const videoRef = React.useRef<?HTMLVideoElement>(null);
+ const fetchAndDecryptMedia = useFetchAndDecryptMedia();
+
React.useEffect(() => {
let isMounted = true,
uriToDispose;
@@ -71,7 +73,7 @@
URL.revokeObjectURL(uriToDispose);
}
};
- }, [blobURI, encryptionKey]);
+ }, [blobURI, encryptionKey, fetchAndDecryptMedia]);
// we need to update the video source when the source changes
// because re-rendering the <source> element wouldn't reload parent <video>
diff --git a/web/media/encryption-utils.js b/web/media/encryption-utils.js
--- a/web/media/encryption-utils.js
+++ b/web/media/encryption-utils.js
@@ -1,18 +1,23 @@
// @flow
import invariant from 'invariant';
+import * as React from 'react';
import { thumbHashToDataURL } from 'thumbhash';
import * as AES from 'lib/media/aes-crypto-utils-common.js';
import { hexToUintArray, uintArrayToHexString } from 'lib/media/data-utils.js';
import { fileInfoFromData } from 'lib/media/file-utils.js';
import { fetchableMediaURI } from 'lib/media/media-utils.js';
+import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
+import type { AuthMetadata } from 'lib/shared/identity-client-context.js';
import type {
MediaMissionFailure,
MediaMissionStep,
} from 'lib/types/media-types.js';
+import { isBlobServiceURI } from 'lib/utils/blob-service.js';
import { getMessageForException } from 'lib/utils/errors.js';
import { calculatePaddedLength, pad, unpad } from 'lib/utils/pkcs7-padding.js';
+import { createDefaultHTTPRequestHeaders } from 'lib/utils/services-utils.js';
import { base64DecodeBuffer } from '../utils/base64-utils.js';
@@ -131,6 +136,11 @@
+reason: 'decrypt_data_failed' | 'save_blob_failed',
};
+type FetchAndDecryptMediaOutput = {
+ steps: $ReadOnlyArray<DecryptFileStep>,
+ result: { success: true, uri: string } | DecryptionFailure,
+};
+
/**
* Fetches the encrypted media for given {@link blobURI}, decrypts it,
* and stores it in a blob. Returns the object URL of the blob.
@@ -140,20 +150,23 @@
async function fetchAndDecryptMedia(
blobURI: string,
encryptionKey: string,
-): Promise<{
- steps: $ReadOnlyArray<DecryptFileStep>,
- result: { success: true, uri: string } | DecryptionFailure,
-}> {
+ authMetadata: AuthMetadata,
+): Promise<FetchAndDecryptMediaOutput> {
let success = true;
let exceptionMessage;
const steps: DecryptFileStep[] = [];
// Step 1 - Fetch the encrypted media and convert it to a Uint8Array
+ let headers;
+ if (isBlobServiceURI(blobURI)) {
+ headers = createDefaultHTTPRequestHeaders(authMetadata);
+ }
+
let data;
const fetchStartTime = Date.now();
const url = fetchableMediaURI(blobURI);
try {
- const response = await fetch(url);
+ const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`HTTP error ${response.status}: ${response.statusText}`);
}
@@ -238,6 +251,23 @@
return { steps, result: { success: true, uri: objectURL } };
}
+function useFetchAndDecryptMedia(): (
+ blobURI: string,
+ encryptionKey: string,
+) => Promise<FetchAndDecryptMediaOutput> {
+ const identityContext = React.useContext(IdentityClientContext);
+ invariant(identityContext, 'Identity context should be set');
+ const { getAuthMetadata } = identityContext;
+
+ return React.useCallback(
+ async (blobURI, encryptionKey) => {
+ const authMetadata = await getAuthMetadata();
+ return fetchAndDecryptMedia(blobURI, encryptionKey, authMetadata);
+ },
+ [getAuthMetadata],
+ );
+}
+
async function decryptThumbhashToDataURL(
encryptedThumbHash: string,
keyHex: string,
@@ -251,4 +281,9 @@
return thumbHashToDataURL(thumbhashBytes);
}
-export { encryptFile, fetchAndDecryptMedia, decryptThumbhashToDataURL };
+export {
+ encryptFile,
+ fetchAndDecryptMedia,
+ useFetchAndDecryptMedia,
+ decryptThumbhashToDataURL,
+};
diff --git a/web/media/loadable-video.react.js b/web/media/loadable-video.react.js
--- a/web/media/loadable-video.react.js
+++ b/web/media/loadable-video.react.js
@@ -3,7 +3,7 @@
import invariant from 'invariant';
import * as React from 'react';
-import { fetchAndDecryptMedia } from './encryption-utils.js';
+import { useFetchAndDecryptMedia } from './encryption-utils.js';
import { preloadImage } from './media-utils.js';
import type { CSSStyle } from '../types/styles';
@@ -36,6 +36,8 @@
const [thumbnailImage, setThumbnailImage] = React.useState<?string>(null);
+ const fetchAndDecryptMedia = useFetchAndDecryptMedia();
+
React.useEffect(() => {
let isMounted = true,
uriToDispose;
@@ -70,7 +72,12 @@
URL.revokeObjectURL(uriToDispose);
}
};
- }, [thumbnailURI, thumbnailBlobURI, thumbnailEncryptionKey]);
+ }, [
+ thumbnailURI,
+ thumbnailBlobURI,
+ thumbnailEncryptionKey,
+ fetchAndDecryptMedia,
+ ]);
let videoSource;
if (uri) {

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 9, 11:53 AM (17 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2451947
Default Alt Text
D10912.id36777.diff (5 KB)

Event Timeline