starting upload poc
This commit is contained in:
parent
09bc78c068
commit
fe1ea5678c
|
@ -43,6 +43,7 @@ class Encryption {
|
|||
handshake: Function;
|
||||
decrypt: Function;
|
||||
encrypt: Function;
|
||||
encryptText: Function;
|
||||
encryptFile: Function;
|
||||
decryptFile: Function;
|
||||
encryptUpload: Function;
|
||||
|
@ -446,6 +447,11 @@ class Encryption {
|
|||
};
|
||||
};
|
||||
|
||||
encryptText = async (rid: string, text: string) => {
|
||||
const roomE2E = await this.getRoomInstance(rid);
|
||||
return roomE2E.encryptText(text);
|
||||
};
|
||||
|
||||
// Encrypt a message
|
||||
encryptMessage = async (message: IMessage | IUpload) => {
|
||||
const { rid } = message;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
|
||||
import RNFetchBlob, { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
|
||||
import { Alert } from 'react-native';
|
||||
|
||||
import { Encryption } from '../encryption';
|
||||
|
@ -51,13 +51,14 @@ export function sendFileMessage(
|
|||
tmid: string | undefined,
|
||||
server: string,
|
||||
user: Partial<Pick<IUser, 'id' | 'token'>>,
|
||||
isForceTryAgain?: boolean
|
||||
isForceTryAgain?: boolean,
|
||||
getContent?: Function
|
||||
): Promise<FetchBlobResponse | void> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const { id, token } = user;
|
||||
|
||||
const uploadUrl = `${server}/api/v1/rooms.upload/${rid}`;
|
||||
const uploadUrl = `${server}/api/v1/rooms.media/${rid}`;
|
||||
|
||||
fileInfo.rid = rid;
|
||||
|
||||
|
@ -89,7 +90,7 @@ export function sendFileMessage(
|
|||
}
|
||||
}
|
||||
|
||||
const encryptedFileInfo = await Encryption.encryptMessage(fileInfo);
|
||||
// const encryptedFileInfo = await Encryption.encryptMessage(fileInfo);
|
||||
|
||||
const formData: IFileUpload[] = [];
|
||||
formData.push({
|
||||
|
@ -99,38 +100,38 @@ export function sendFileMessage(
|
|||
uri: fileInfo.path
|
||||
});
|
||||
|
||||
if (fileInfo.description) {
|
||||
formData.push({
|
||||
name: 'description',
|
||||
data: encryptedFileInfo.description
|
||||
});
|
||||
}
|
||||
// if (fileInfo.description) {
|
||||
// formData.push({
|
||||
// name: 'description',
|
||||
// data: encryptedFileInfo.description
|
||||
// });
|
||||
// }
|
||||
|
||||
if (fileInfo.msg) {
|
||||
formData.push({
|
||||
name: 'msg',
|
||||
data: fileInfo.msg
|
||||
});
|
||||
}
|
||||
// if (fileInfo.msg) {
|
||||
// formData.push({
|
||||
// name: 'msg',
|
||||
// data: fileInfo.msg
|
||||
// });
|
||||
// }
|
||||
|
||||
if (tmid) {
|
||||
formData.push({
|
||||
name: 'tmid',
|
||||
data: tmid
|
||||
});
|
||||
}
|
||||
// if (tmid) {
|
||||
// formData.push({
|
||||
// name: 'tmid',
|
||||
// data: tmid
|
||||
// });
|
||||
// }
|
||||
|
||||
const { version: serverVersion } = store.getState().server;
|
||||
if (encryptedFileInfo.t === E2E_MESSAGE_TYPE && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.8.0')) {
|
||||
formData.push({
|
||||
name: 't',
|
||||
data: encryptedFileInfo.t
|
||||
});
|
||||
formData.push({
|
||||
name: 'e2e',
|
||||
data: encryptedFileInfo.e2e
|
||||
});
|
||||
}
|
||||
// const { version: serverVersion } = store.getState().server;
|
||||
// if (encryptedFileInfo.t === E2E_MESSAGE_TYPE && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.8.0')) {
|
||||
// formData.push({
|
||||
// name: 't',
|
||||
// data: encryptedFileInfo.t
|
||||
// });
|
||||
// formData.push({
|
||||
// name: 'e2e',
|
||||
// data: encryptedFileInfo.e2e
|
||||
// });
|
||||
// }
|
||||
|
||||
const headers = {
|
||||
...RocketChatSettings.customHeaders,
|
||||
|
@ -139,61 +140,110 @@ export function sendFileMessage(
|
|||
'X-User-Id': id
|
||||
};
|
||||
|
||||
uploadQueue[uploadPath] = FileUpload.fetch('POST', uploadUrl, headers, formData);
|
||||
|
||||
uploadQueue[uploadPath].uploadProgress(async (loaded: number, total: number) => {
|
||||
try {
|
||||
await db.write(async () => {
|
||||
await uploadRecord.update(u => {
|
||||
u.progress = Math.floor((loaded / total) * 100);
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
});
|
||||
|
||||
uploadQueue[uploadPath].then(async response => {
|
||||
if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
||||
// If response is all good...
|
||||
try {
|
||||
await db.write(async () => {
|
||||
await uploadRecord.destroyPermanently();
|
||||
});
|
||||
resolve(response);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
try {
|
||||
const data = formData.map(item => {
|
||||
if (item.uri) {
|
||||
return {
|
||||
name: item.name,
|
||||
type: item.type,
|
||||
filename: item.filename,
|
||||
data: RNFetchBlob.wrap(decodeURI(item.uri))
|
||||
};
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
await db.write(async () => {
|
||||
await uploadRecord.update(u => {
|
||||
u.error = true;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
try {
|
||||
reject(response);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
return item;
|
||||
});
|
||||
console.log('🚀 ~ data ~ data:', data);
|
||||
const response = await RNFetchBlob.fetch('POST', uploadUrl, headers, data);
|
||||
console.log(response);
|
||||
|
||||
uploadQueue[uploadPath].catch(async error => {
|
||||
try {
|
||||
await db.write(async () => {
|
||||
await uploadRecord.update(u => {
|
||||
u.error = true;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
const json = response.json();
|
||||
console.log('🚀 ~ returnnewPromise ~ json:', json);
|
||||
|
||||
console.log('🚀 ~ returnnewPromise ~ getContent:', getContent);
|
||||
let content;
|
||||
if (getContent) {
|
||||
content = await getContent(json.file._id, json.file.url);
|
||||
console.log('🚀 ~ returnnewPromise ~ content:', content);
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
|
||||
const mediaConfirm = await fetch(`${server}/api/v1/rooms.mediaConfirm/${rid}/${json.file._id}`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
msg: fileInfo.msg,
|
||||
tmid: fileInfo.tmid,
|
||||
description: fileInfo.description,
|
||||
t: fileInfo.t,
|
||||
content
|
||||
})
|
||||
});
|
||||
console.log('🚀 ~ returnnewPromise ~ mediaConfirm :', mediaConfirm);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// uploadQueue[uploadPath] = FileUpload.fetch('POST', uploadUrl, headers, formData);
|
||||
|
||||
// uploadQueue[uploadPath].uploadProgress(async (loaded: number, total: number) => {
|
||||
// try {
|
||||
// await db.write(async () => {
|
||||
// await uploadRecord.update(u => {
|
||||
// u.progress = Math.floor((loaded / total) * 100);
|
||||
// });
|
||||
// });
|
||||
// } catch (e) {
|
||||
// log(e);
|
||||
// }
|
||||
// });
|
||||
|
||||
// uploadQueue[uploadPath].then(async response => {
|
||||
// // If response is all good...
|
||||
// if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
||||
// try {
|
||||
// console.log('🚀 ~ returnnewPromise ~ response:', response);
|
||||
// console.log('🚀 ~ returnnewPromise ~ response:', response.data);
|
||||
// // if (getContent) {
|
||||
// // const content = getContent(response.json().file._id, response.json().file.url);
|
||||
// // console.log('🚀 ~ returnnewPromise ~ content:', content);
|
||||
// // }
|
||||
|
||||
// await db.write(async () => {
|
||||
// await uploadRecord.destroyPermanently();
|
||||
// });
|
||||
// resolve(response);
|
||||
// } catch (e) {
|
||||
// log(e);
|
||||
// }
|
||||
// } else {
|
||||
// try {
|
||||
// await db.write(async () => {
|
||||
// await uploadRecord.update(u => {
|
||||
// u.error = true;
|
||||
// });
|
||||
// });
|
||||
// } catch (e) {
|
||||
// log(e);
|
||||
// }
|
||||
// try {
|
||||
// reject(response);
|
||||
// } catch (e) {
|
||||
// reject(e);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// uploadQueue[uploadPath].catch(async error => {
|
||||
// try {
|
||||
// await db.write(async () => {
|
||||
// await uploadRecord.update(u => {
|
||||
// u.error = true;
|
||||
// });
|
||||
// });
|
||||
// } catch (e) {
|
||||
// log(e);
|
||||
// }
|
||||
// reject(error);
|
||||
// });
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { connect } from 'react-redux';
|
|||
import ShareExtension from 'rn-extensions-share';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import SimpleCrypto from 'react-native-simple-crypto';
|
||||
import EJSON from 'ejson';
|
||||
|
||||
import { IMessageComposerRef, MessageComposerContainer } from '../../containers/MessageComposer';
|
||||
import { InsideStackParamList } from '../../stacks/types';
|
||||
|
@ -37,7 +38,15 @@ import { sendFileMessage, sendMessage } from '../../lib/methods';
|
|||
import { hasPermission, isAndroid, canUploadFile, isReadOnly, isBlocked } from '../../lib/methods/helpers';
|
||||
import { RoomContext } from '../RoomView/context';
|
||||
import { Encryption } from '../../lib/encryption';
|
||||
import { b64URIToBuffer, decryptAESCTR, encryptAESCTR, exportAESCTR, generateAESCTRKey } from '../../lib/encryption/utils';
|
||||
import {
|
||||
Base64,
|
||||
b64URIToBuffer,
|
||||
bufferToB64,
|
||||
decryptAESCTR,
|
||||
encryptAESCTR,
|
||||
exportAESCTR,
|
||||
generateAESCTRKey
|
||||
} from '../../lib/encryption/utils';
|
||||
|
||||
interface IShareViewState {
|
||||
selected: IShareAttachment;
|
||||
|
@ -252,64 +261,101 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
|
|||
}
|
||||
|
||||
try {
|
||||
const { path } = attachments[0];
|
||||
const vector = await SimpleCrypto.utils.randomBytes(16);
|
||||
const key = await generateAESCTRKey();
|
||||
// Send attachment
|
||||
if (attachments.length) {
|
||||
console.log('🚀 ~ ShareView ~ send= ~ attachments:', attachments);
|
||||
await Promise.all(
|
||||
attachments.map(async ({ filename: name, mime: type, description, size, canUpload }) => {
|
||||
if (!canUpload) {
|
||||
return Promise.resolve(); // Resolve immediately if upload is not allowed
|
||||
}
|
||||
|
||||
const exportedKey = exportAESCTR(key);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ exportedKey:', exportedKey, exportedKey.k);
|
||||
try {
|
||||
const { path } = attachments[0]; // Consider if you need a specific attachment or iterate over each
|
||||
const vector = await SimpleCrypto.utils.randomBytes(16);
|
||||
const key = await generateAESCTRKey();
|
||||
|
||||
const exportedKeyArrayBuffer = b64URIToBuffer(exportedKey.k);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ exportedKeyArrayBuffer:', exportedKeyArrayBuffer);
|
||||
const exportedKey = await exportAESCTR(key);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ exportedKey:', exportedKey, exportedKey.k);
|
||||
|
||||
const encryptedFile = await encryptAESCTR(path, exportedKeyArrayBuffer, vector);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ encryptedFile:', encryptedFile);
|
||||
const exportedKeyArrayBuffer = b64URIToBuffer(exportedKey.k);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ exportedKeyArrayBuffer:', exportedKeyArrayBuffer);
|
||||
|
||||
const decryptedFile = await decryptAESCTR(encryptedFile, exportedKeyArrayBuffer, vector);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ decryptedFile:', decryptedFile);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const encryptedFile = await encryptAESCTR(path, exportedKeyArrayBuffer, vector);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ encryptedFile:', encryptedFile);
|
||||
|
||||
const decryptedFile = await decryptAESCTR(encryptedFile, exportedKeyArrayBuffer, vector);
|
||||
console.log('🚀 ~ ShareView ~ send= ~ decryptedFile:', decryptedFile);
|
||||
|
||||
const getContent = async (_id: string, fileUrl: string) => {
|
||||
console.log('🚀 ~ ShareView ~ getContent ~ _id:', _id, fileUrl);
|
||||
const attachments = [];
|
||||
console.log('🚀 ~ ShareView ~ getContent ~ attachment.encryption.exportedKey:', vector, exportedKey);
|
||||
|
||||
const attachment = {
|
||||
title: name,
|
||||
type: 'file',
|
||||
description,
|
||||
// title_link: fileUrl,
|
||||
// title_link_download: true,
|
||||
encryption: {
|
||||
key: exportedKey,
|
||||
iv: bufferToB64(vector)
|
||||
},
|
||||
image_url: fileUrl,
|
||||
image_type: type,
|
||||
image_size: size
|
||||
};
|
||||
attachments.push(attachment);
|
||||
|
||||
const data = EJSON.stringify({
|
||||
attachments
|
||||
});
|
||||
console.log('🚀 ~ ShareView ~ getContent ~ attachments:', attachments, data);
|
||||
|
||||
return {
|
||||
algorithm: 'rc.v1.aes-sha2',
|
||||
ciphertext: await Encryption.encryptText(room.rid, data)
|
||||
};
|
||||
};
|
||||
|
||||
// Send the file message with the encrypted path
|
||||
return sendFileMessage(
|
||||
room.rid,
|
||||
{
|
||||
rid: room.rid,
|
||||
// name,
|
||||
description,
|
||||
size,
|
||||
type: 'file',
|
||||
path: encryptedFile,
|
||||
store: 'Uploads',
|
||||
msg
|
||||
},
|
||||
thread?.id,
|
||||
server,
|
||||
{ id: user.id, token: user.token },
|
||||
undefined,
|
||||
getContent
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return Promise.reject(e); // Ensure that errors are propagated
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Send text message
|
||||
} else if (text.length) {
|
||||
await sendMessage(room.rid, text, thread?.id, { id: user.id, token: user.token } as IUser);
|
||||
}
|
||||
} catch {
|
||||
if (!this.isShareExtension) {
|
||||
const text = this.messageComposerRef.current?.getText();
|
||||
this.finishShareView(text, this.state.selectedMessages);
|
||||
}
|
||||
}
|
||||
|
||||
// try {
|
||||
// // Send attachment
|
||||
// if (attachments.length) {
|
||||
// console.log('🚀 ~ ShareView ~ send= ~ attachments:', attachments);
|
||||
// await Promise.all(
|
||||
// attachments.map(async ({ filename: name, mime: type, description, size, path, canUpload }) => {
|
||||
// if (canUpload) {
|
||||
// return sendFileMessage(
|
||||
// room.rid,
|
||||
// {
|
||||
// rid: room.rid,
|
||||
// name,
|
||||
// description,
|
||||
// size,
|
||||
// type,
|
||||
// path,
|
||||
// store: 'Uploads',
|
||||
// msg
|
||||
// },
|
||||
// thread?.id,
|
||||
// server,
|
||||
// { id: user.id, token: user.token }
|
||||
// );
|
||||
// }
|
||||
// return Promise.resolve();
|
||||
// })
|
||||
// );
|
||||
|
||||
// // Send text message
|
||||
// } else if (text.length) {
|
||||
// await sendMessage(room.rid, text, thread?.id, { id: user.id, token: user.token } as IUser);
|
||||
// }
|
||||
// } catch {
|
||||
// if (!this.isShareExtension) {
|
||||
// const text = this.messageComposerRef.current?.getText();
|
||||
// this.finishShareView(text, this.state.selectedMessages);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if it's share extension this should close
|
||||
if (this.isShareExtension) {
|
||||
sendLoadingEvent({ visible: false });
|
||||
|
|
Loading…
Reference in New Issue