Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3357122
D10913.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D10913.diff
View Options
diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js
--- a/lib/actions/upload-actions.js
+++ b/lib/actions/upload-actions.js
@@ -1,10 +1,14 @@
// @flow
+import invariant from 'invariant';
+import * as React from 'react';
import uuid from 'uuid';
import blobService from '../facts/blob-service.js';
import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js';
import type { CallKeyserverEndpoint } from '../keyserver-conn/keyserver-conn-types.js';
+import { IdentityClientContext } from '../shared/identity-client-context.js';
+import type { AuthMetadata } from '../shared/identity-client-context.js';
import type { UploadMultimediaResult, Dimensions } from '../types/media-types';
import { toBase64URL } from '../utils/base64.js';
import {
@@ -15,7 +19,10 @@
import type { CallSingleKeyserverEndpoint } from '../utils/call-single-keyserver-endpoint.js';
import { getMessageForException } from '../utils/errors.js';
import { useKeyserverCall } from '../utils/keyserver-call.js';
-import { handleHTTPResponseError } from '../utils/services-utils.js';
+import {
+ handleHTTPResponseError,
+ createDefaultHTTPRequestHeaders,
+} from '../utils/services-utils.js';
import { type UploadBlob } from '../utils/upload-blob.js';
export type MultimediaUploadCallbacks = Partial<{
@@ -144,13 +151,17 @@
}) => Promise<BlobServiceUploadResult>;
const blobServiceUpload =
- (callKeyserverEndpoint: CallKeyserverEndpoint): BlobServiceUploadAction =>
+ (
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ authMetadata: AuthMetadata,
+ ): BlobServiceUploadAction =>
async input => {
const { uploadInput, callbacks, keyserverOrThreadID } = input;
const { encryptionKey, loop, dimensions, thumbHash, blobInput } =
uploadInput;
const blobHolder = uuid.v4();
const blobHash = toBase64URL(uploadInput.blobHash);
+ const defaultHeaders = createDefaultHTTPRequestHeaders(authMetadata);
// 1. Assign new holder for blob with given blobHash
let blobAlreadyExists: boolean;
@@ -165,6 +176,7 @@
blob_hash: blobHash,
}),
headers: {
+ ...defaultHeaders,
'content-type': 'application/json',
},
},
@@ -196,6 +208,7 @@
blobHash,
blobInput,
},
+ authMetadata,
{ ...callbacks },
);
} catch (e) {
@@ -240,7 +253,25 @@
};
function useBlobServiceUpload(): BlobServiceUploadAction {
- return useKeyserverCall(blobServiceUpload);
+ const identityContext = React.useContext(IdentityClientContext);
+ invariant(identityContext, 'Identity context should be set');
+ const { getAuthMetadata } = identityContext;
+
+ const blobUploadAction = React.useCallback(
+ (
+ callSingleKeyserverEndpoint: CallSingleKeyserverEndpoint,
+ ): BlobServiceUploadAction =>
+ async input => {
+ const authMetadata = await getAuthMetadata();
+ const authenticatedUploadAction = blobServiceUpload(
+ callSingleKeyserverEndpoint,
+ authMetadata,
+ );
+ return authenticatedUploadAction(input);
+ },
+ [getAuthMetadata],
+ );
+ return useKeyserverCall(blobUploadAction);
}
export {
diff --git a/lib/utils/blob-service-upload.js b/lib/utils/blob-service-upload.js
--- a/lib/utils/blob-service-upload.js
+++ b/lib/utils/blob-service-upload.js
@@ -3,10 +3,12 @@
import invariant from 'invariant';
import _throttle from 'lodash/throttle.js';
+import { createHTTPAuthorizationHeader } from './services-utils.js';
import type {
MultimediaUploadCallbacks,
BlobServiceUploadFile,
} from '../actions/upload-actions.js';
+import type { AuthMetadata } from '../shared/identity-client-context.js';
function blobServiceUploadHandler(
url: string,
@@ -15,6 +17,7 @@
blobHash: string,
blobInput: BlobServiceUploadFile,
},
+ authMetadata: AuthMetadata,
options?: ?MultimediaUploadCallbacks,
): Promise<void> {
if (input.blobInput.type !== 'file') {
@@ -28,6 +31,9 @@
const xhr = new XMLHttpRequest();
xhr.open(method, url);
+ const authHeader = createHTTPAuthorizationHeader(authMetadata);
+ xhr.setRequestHeader('Authorization', authHeader);
+
const { timeout, onProgress, abortHandler } = options ?? {};
if (timeout) {
diff --git a/native/utils/blob-service-upload.js b/native/utils/blob-service-upload.js
--- a/native/utils/blob-service-upload.js
+++ b/native/utils/blob-service-upload.js
@@ -6,11 +6,13 @@
import { pathFromURI } from 'lib/media/file-utils.js';
import type { BlobServiceUploadHandler } from 'lib/utils/blob-service-upload.js';
import { getMessageForException } from 'lib/utils/errors.js';
+import { createDefaultHTTPRequestHeaders } from 'lib/utils/services-utils.js';
const blobServiceUploadHandler: BlobServiceUploadHandler = async (
url,
method,
input,
+ authMetadata,
options,
) => {
if (input.blobInput.type !== 'uri') {
@@ -23,6 +25,7 @@
path = resolvedPath;
}
}
+ const headers = authMetadata && createDefaultHTTPRequestHeaders(authMetadata);
const uploadTask = FileSystem.createUploadTask(
url,
path,
@@ -31,6 +34,7 @@
fieldName: 'blob_data',
httpMethod: method,
parameters: { blob_hash: input.blobHash },
+ headers,
},
uploadProgress => {
if (options?.onProgress) {
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -41,6 +41,8 @@
import commStaffCommunity from 'lib/facts/comm-staff-community.js';
import { getNextLocalUploadID } from 'lib/media/media-utils.js';
import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors.js';
+import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
+import type { IdentityClientContextType } from 'lib/shared/identity-client-context.js';
import {
createMediaMessageInfo,
localIDPrefix,
@@ -95,6 +97,7 @@
} from 'lib/utils/redux-promise-utils.js';
import { useDispatch } from 'lib/utils/redux-utils.js';
import { generateReportID } from 'lib/utils/report-utils.js';
+import { createDefaultHTTPRequestHeaders } from 'lib/utils/services-utils.js';
import {
type BaseInputState,
@@ -151,6 +154,7 @@
+registerSendCallback: (() => mixed) => void,
+unregisterSendCallback: (() => mixed) => void,
+textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
+ +identityContext: ?IdentityClientContextType,
};
type WritableState = {
pendingUploads: {
@@ -867,6 +871,9 @@
const steps = [...upload.steps];
let userTime;
+ const { identityContext } = this.props;
+ invariant(identityContext, 'Identity context should be set');
+
const sendReport = (missionResult: MediaMissionResult) => {
const newThreadID = this.getRealizedOrPendingThreadID(threadID);
const latestUpload = this.state.pendingUploads[newThreadID][localID];
@@ -907,6 +914,7 @@
encryptionKey && blobHash && dimensions,
'incomplete encrypted upload',
);
+
uploadResult = await this.props.blobServiceUpload({
uploadInput: {
blobInput: {
@@ -1011,7 +1019,11 @@
});
if (encryptionKey) {
- const { steps: preloadSteps } = await preloadMediaResource(result.uri);
+ const authMetadata = await identityContext.getAuthMetadata();
+ const { steps: preloadSteps } = await preloadMediaResource(
+ result.uri,
+ authMetadata,
+ );
steps.push(...preloadSteps);
} else {
const { steps: preloadSteps } = await preloadImage(result.uri);
@@ -1202,6 +1214,8 @@
keyserverOrThreadID: threadID,
});
if (isBlobServiceURI(pendingUpload.uri)) {
+ const identityContext = this.props.identityContext;
+ invariant(identityContext, 'Identity context should be set');
invariant(
pendingUpload.blobHolder,
'blob service upload has no holder',
@@ -1209,16 +1223,22 @@
const endpoint = blobService.httpEndpoints.DELETE_BLOB;
const holder = pendingUpload.blobHolder;
const blobHash = blobHashFromBlobServiceURI(pendingUpload.uri);
- void fetch(makeBlobServiceEndpointURL(endpoint), {
- method: endpoint.method,
- body: JSON.stringify({
- holder,
- blob_hash: blobHash,
- }),
- headers: {
- 'content-type': 'application/json',
- },
- });
+ void (async () => {
+ const authMetadata = await identityContext.getAuthMetadata();
+ const defaultHeaders =
+ createDefaultHTTPRequestHeaders(authMetadata);
+ await fetch(makeBlobServiceEndpointURL(endpoint), {
+ method: endpoint.method,
+ body: JSON.stringify({
+ holder,
+ blob_hash: blobHash,
+ }),
+ headers: {
+ ...defaultHeaders,
+ 'content-type': 'application/json',
+ },
+ });
+ })();
}
}
const newPendingUploads = _omit([localUploadID])(currentPendingUploads);
@@ -1656,6 +1676,7 @@
const dispatch = useDispatch();
const dispatchActionPromise = useDispatchActionPromise();
const modalContext = useModalContext();
+ const identityContext = React.useContext(IdentityClientContext);
const [sendCallbacks, setSendCallbacks] = React.useState<
$ReadOnlyArray<() => mixed>,
@@ -1696,6 +1717,7 @@
registerSendCallback={registerSendCallback}
unregisterSendCallback={unregisterSendCallback}
textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
+ identityContext={identityContext}
/>
);
});
diff --git a/web/media/media-utils.js b/web/media/media-utils.js
--- a/web/media/media-utils.js
+++ b/web/media/media-utils.js
@@ -5,13 +5,16 @@
import { thumbHashToDataURL } from 'thumbhash';
import { fetchableMediaURI } from 'lib/media/media-utils.js';
+import type { AuthMetadata } from 'lib/shared/identity-client-context.js';
import type {
MediaType,
Dimensions,
MediaMissionStep,
MediaMissionFailure,
} from 'lib/types/media-types.js';
+import { isBlobServiceURI } from 'lib/utils/blob-service.js';
import { getMessageForException } from 'lib/utils/errors.js';
+import { createDefaultHTTPRequestHeaders } from 'lib/utils/services-utils.js';
import { probeFile } from './blob-utils.js';
import { decryptThumbhashToDataURL } from './encryption-utils.js';
@@ -64,15 +67,23 @@
* @returns Steps and the result of the preload. The preload is successful
* if the HTTP response is OK (20x).
*/
-async function preloadMediaResource(uri: string): Promise<{
+async function preloadMediaResource(
+ uri: string,
+ authMetadata: AuthMetadata,
+): Promise<{
steps: $ReadOnlyArray<MediaMissionStep>,
result: { +success: boolean },
}> {
+ let headers;
+ if (isBlobServiceURI(uri)) {
+ headers = createDefaultHTTPRequestHeaders(authMetadata);
+ }
+
const start = Date.now();
const mediaURI = fetchableMediaURI(uri);
let success, exceptionMessage;
try {
- const response = await fetch(mediaURI);
+ const response = await fetch(mediaURI, { headers });
// we need to read the blob to make sure the browser caches it
await response.blob();
success = response.ok;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 24, 10:33 PM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2577496
Default Alt Text
D10913.diff (11 KB)
Attached To
Mode
D10913: [native][web] Add AuthMetadata to Blob service upload actions
Attached
Detach File
Event Timeline
Log In to Comment