mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
fixup edit profile dialog
This commit is contained in:
parent
b64e8bf610
commit
6c1cac9203
|
@ -19,6 +19,7 @@ import { ConversationController } from '../session/conversations';
|
|||
import { SpacerLG, SpacerMD } from './basic/Text';
|
||||
import autoBind from 'auto-bind';
|
||||
import { editProfileModal } from '../state/ducks/modalDialog';
|
||||
import { uploadOurAvatar } from '../interactions/conversationInteractions';
|
||||
|
||||
interface State {
|
||||
profileName: string;
|
||||
|
@ -317,8 +318,6 @@ export class EditProfileDialog extends React.Component<{}, State> {
|
|||
ConversationTypeEnum.PRIVATE
|
||||
);
|
||||
|
||||
const url: any = null;
|
||||
let profileKey: any = null;
|
||||
if (avatar) {
|
||||
const data = await AttachmentUtil.readFile({ file: avatar });
|
||||
// Ensure that this file is either small enough or is resized to meet our
|
||||
|
@ -342,67 +341,26 @@ export class EditProfileDialog extends React.Component<{}, State> {
|
|||
// others, which means we need to wait for the database response.
|
||||
// To avoid the wait, we create a temporary url for the local image
|
||||
// and use it until we the the response from the server
|
||||
const tempUrl = window.URL.createObjectURL(avatar);
|
||||
await conversation.setLokiProfile({ displayName: newName });
|
||||
conversation.set('avatar', tempUrl);
|
||||
// const tempUrl = window.URL.createObjectURL(avatar);
|
||||
// await conversation.setLokiProfile({ displayName: newName });
|
||||
// conversation.set('avatar', tempUrl);
|
||||
|
||||
// Encrypt with a new key every time
|
||||
profileKey = window.libsignal.crypto.getRandomBytes(32);
|
||||
const encryptedData = await window.textsecure.crypto.encryptProfile(
|
||||
dataResized,
|
||||
profileKey
|
||||
);
|
||||
|
||||
throw new Error('uploadAvatarV1 to move to v2');
|
||||
|
||||
// const avatarPointer = await AttachmentUtils.uploadAvatarV1({
|
||||
// ...dataResized,
|
||||
// data: encryptedData,
|
||||
// size: encryptedData.byteLength,
|
||||
// });
|
||||
|
||||
// url = avatarPointer ? avatarPointer.url : null;
|
||||
// window.storage.put('profileKey', profileKey);
|
||||
// conversation.set('avatarPointer', url);
|
||||
|
||||
// const upgraded = await window.Signal.Migrations.processNewAttachment({
|
||||
// isRaw: true,
|
||||
// data: data.data,
|
||||
// url,
|
||||
// });
|
||||
// newAvatarPath = upgraded.path;
|
||||
// // Replace our temporary image with the attachment pointer from the server:
|
||||
// conversation.set('avatar', null);
|
||||
// await conversation.setLokiProfile({
|
||||
// displayName: newName,
|
||||
// avatar: newAvatarPath,
|
||||
// });
|
||||
|
||||
// await conversation.commit();
|
||||
// UserUtils.setLastProfileUpdateTimestamp(Date.now());
|
||||
// await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
|
||||
await uploadOurAvatar(dataResized);
|
||||
} catch (error) {
|
||||
window.log.error(
|
||||
'showEditProfileDialog Error ensuring that image is properly sized:',
|
||||
error && error.stack ? error.stack : error
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// do not update the avatar if it did not change
|
||||
await conversation.setLokiProfile({
|
||||
displayName: newName,
|
||||
});
|
||||
// might be good to not trigger a sync if the name did not change
|
||||
await conversation.commit();
|
||||
UserUtils.setLastProfileUpdateTimestamp(Date.now());
|
||||
await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
|
||||
}
|
||||
|
||||
if (avatar) {
|
||||
ConversationController.getInstance()
|
||||
.getConversations()
|
||||
.filter(convo => convo.isPublic())
|
||||
.forEach(convo => convo.trigger('ourAvatarChanged', { url, profileKey }));
|
||||
return;
|
||||
}
|
||||
// do not update the avatar if it did not change
|
||||
await conversation.setLokiProfile({
|
||||
displayName: newName,
|
||||
});
|
||||
// might be good to not trigger a sync if the name did not change
|
||||
await conversation.commit();
|
||||
UserUtils.setLastProfileUpdateTimestamp(Date.now());
|
||||
await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ import { SessionNicknameDialog } from './SessionNicknameDialog';
|
|||
import { editProfileModal, onionPathModal } from '../../state/ducks/modalDialog';
|
||||
import { SessionSeedModal } from './SessionSeedModal';
|
||||
import { AdminLeaveClosedGroupDialog } from '../conversation/AdminLeaveClosedGroupDialog';
|
||||
import { uploadOurAvatar } from '../../interactions/conversationInteractions';
|
||||
|
||||
// tslint:disable-next-line: no-import-side-effect no-submodule-imports
|
||||
|
||||
|
@ -239,72 +240,7 @@ const triggerAvatarReUploadIfNeeded = async () => {
|
|||
if (Date.now() - lastTimeStampAvatarUpload > DURATION.DAYS * 14) {
|
||||
window.log.info('Reuploading avatar...');
|
||||
// reupload the avatar
|
||||
const ourConvo = ConversationController.getInstance().get(UserUtils.getOurPubKeyStrFromCache());
|
||||
if (!ourConvo) {
|
||||
window.log.warn('ourConvo not found... This is not a valid case');
|
||||
return;
|
||||
}
|
||||
const profileKey = window.textsecure.storage.get('profileKey');
|
||||
if (!profileKey) {
|
||||
window.log.warn('our profileKey not found... This is not a valid case');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentAttachmentPath = ourConvo.getAvatarPath();
|
||||
|
||||
if (!currentAttachmentPath) {
|
||||
window.log.warn('No attachment currently set for our convo.. Nothing to do.');
|
||||
return;
|
||||
}
|
||||
|
||||
const decryptedAvatarUrl = await getDecryptedMediaUrl(currentAttachmentPath, IMAGE_JPEG);
|
||||
|
||||
if (!decryptedAvatarUrl) {
|
||||
window.log.warn('Could not decrypt avatar stored locally..');
|
||||
return;
|
||||
}
|
||||
const response = await fetch(decryptedAvatarUrl);
|
||||
const blob = await response.blob();
|
||||
const decryptedAvatarData = await blob.arrayBuffer();
|
||||
|
||||
if (!decryptedAvatarData?.byteLength) {
|
||||
window.log.warn('Could not read blob of avatar locally..');
|
||||
return;
|
||||
}
|
||||
|
||||
const encryptedData = await window.textsecure.crypto.encryptProfile(
|
||||
decryptedAvatarData,
|
||||
profileKey
|
||||
);
|
||||
|
||||
const avatarPointer = await FSv2.uploadFileToFsV2(encryptedData);
|
||||
let fileUrl;
|
||||
if (!avatarPointer) {
|
||||
window.log.warn('failed to reupload avatar to fsv2');
|
||||
return;
|
||||
}
|
||||
({ fileUrl } = avatarPointer);
|
||||
|
||||
ourConvo.set('avatarPointer', fileUrl);
|
||||
|
||||
// this encrypts and save the new avatar and returns a new attachment path
|
||||
const upgraded = await window.Signal.Migrations.processNewAttachment({
|
||||
isRaw: true,
|
||||
data: decryptedAvatarData,
|
||||
url: fileUrl,
|
||||
});
|
||||
const newAvatarPath = upgraded.path;
|
||||
// Replace our temporary image with the attachment pointer from the server:
|
||||
ourConvo.set('avatar', null);
|
||||
const existingHash = ourConvo.get('avatarHash');
|
||||
const displayName = ourConvo.get('profileName');
|
||||
// this commits already
|
||||
await ourConvo.setLokiProfile({ avatar: newAvatarPath, displayName, avatarHash: existingHash });
|
||||
const newTimestampReupload = Date.now();
|
||||
await createOrUpdateItem({ id: lastAvatarUploadTimestamp, value: newTimestampReupload });
|
||||
window.log.info(
|
||||
`Reuploading avatar finished at ${newTimestampReupload}, newAttachmentPointer ${fileUrl}`
|
||||
);
|
||||
await uploadOurAvatar();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
openGroupV2ConversationIdRegex,
|
||||
} from '../opengroup/utils/OpenGroupUtils';
|
||||
import { getV2OpenGroupRoom } from '../data/opengroups';
|
||||
import { ToastUtils, UserUtils } from '../session/utils';
|
||||
import { SyncUtils, ToastUtils, UserUtils } from '../session/utils';
|
||||
import {
|
||||
ConversationModel,
|
||||
ConversationNotificationSettingType,
|
||||
|
@ -26,8 +26,16 @@ import {
|
|||
updateInviteContactModal,
|
||||
updateRemoveModeratorsModal,
|
||||
} from '../state/ducks/modalDialog';
|
||||
import { removeAllMessagesInConversation } from '../data/data';
|
||||
import {
|
||||
createOrUpdateItem,
|
||||
lastAvatarUploadTimestamp,
|
||||
removeAllMessagesInConversation,
|
||||
} from '../data/data';
|
||||
import { conversationReset } from '../state/ducks/conversations';
|
||||
import { getDecryptedMediaUrl } from '../session/crypto/DecryptedAttachmentsManager';
|
||||
import { IMAGE_JPEG } from '../types/MIME';
|
||||
import { FSv2 } from '../fileserver';
|
||||
import { fromBase64ToArray, toHex } from '../session/utils/String';
|
||||
|
||||
export const getCompleteUrlForV2ConvoId = async (convoId: string) => {
|
||||
if (convoId.match(openGroupV2ConversationIdRegex)) {
|
||||
|
@ -325,3 +333,98 @@ export async function setDisappearingMessagesByConvoId(
|
|||
await conversation.updateExpirationTimer(seconds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be used for reupload our avatar to the fsv2 or upload a new avatar.
|
||||
*
|
||||
* If this is a reupload, the old profileKey is used, otherwise a new one is generated
|
||||
*/
|
||||
export async function uploadOurAvatar(newAvatarDecrypted?: ArrayBuffer) {
|
||||
const ourConvo = ConversationController.getInstance().get(UserUtils.getOurPubKeyStrFromCache());
|
||||
if (!ourConvo) {
|
||||
window.log.warn('ourConvo not found... This is not a valid case');
|
||||
return;
|
||||
}
|
||||
|
||||
let profileKey;
|
||||
let decryptedAvatarData;
|
||||
if (newAvatarDecrypted) {
|
||||
// Encrypt with a new key every time
|
||||
profileKey = window.libsignal.crypto.getRandomBytes(32);
|
||||
decryptedAvatarData = newAvatarDecrypted;
|
||||
} else {
|
||||
// this is a reupload. no need to generate a new profileKey
|
||||
profileKey = window.textsecure.storage.get('profileKey');
|
||||
if (!profileKey) {
|
||||
window.log.warn('our profileKey not found');
|
||||
return;
|
||||
}
|
||||
const currentAttachmentPath = ourConvo.getAvatarPath();
|
||||
|
||||
if (!currentAttachmentPath) {
|
||||
window.log.warn('No attachment currently set for our convo.. Nothing to do.');
|
||||
return;
|
||||
}
|
||||
|
||||
const decryptedAvatarUrl = await getDecryptedMediaUrl(currentAttachmentPath, IMAGE_JPEG);
|
||||
|
||||
if (!decryptedAvatarUrl) {
|
||||
window.log.warn('Could not decrypt avatar stored locally..');
|
||||
return;
|
||||
}
|
||||
const response = await fetch(decryptedAvatarUrl);
|
||||
const blob = await response.blob();
|
||||
decryptedAvatarData = await blob.arrayBuffer();
|
||||
}
|
||||
|
||||
if (!decryptedAvatarData?.byteLength) {
|
||||
window.log.warn('Could not read content of avatar ...');
|
||||
return;
|
||||
}
|
||||
|
||||
const encryptedData = await window.textsecure.crypto.encryptProfile(
|
||||
decryptedAvatarData,
|
||||
profileKey
|
||||
);
|
||||
|
||||
const avatarPointer = await FSv2.uploadFileToFsV2(encryptedData);
|
||||
let fileUrl;
|
||||
if (!avatarPointer) {
|
||||
window.log.warn('failed to upload avatar to fsv2');
|
||||
return;
|
||||
}
|
||||
({ fileUrl } = avatarPointer);
|
||||
|
||||
ourConvo.set('avatarPointer', fileUrl);
|
||||
|
||||
// this encrypts and save the new avatar and returns a new attachment path
|
||||
const upgraded = await window.Signal.Migrations.processNewAttachment({
|
||||
isRaw: true,
|
||||
data: decryptedAvatarData,
|
||||
url: fileUrl,
|
||||
});
|
||||
// Replace our temporary image with the attachment pointer from the server:
|
||||
ourConvo.set('avatar', null);
|
||||
const displayName = ourConvo.get('profileName');
|
||||
|
||||
// write the profileKey even if it did not change
|
||||
window.storage.put('profileKey', profileKey);
|
||||
ourConvo.set({ profileKey: toHex(profileKey) });
|
||||
// Replace our temporary image with the attachment pointer from the server:
|
||||
// this commits already
|
||||
await ourConvo.setLokiProfile({
|
||||
avatar: upgraded.path,
|
||||
displayName,
|
||||
});
|
||||
const newTimestampReupload = Date.now();
|
||||
await createOrUpdateItem({ id: lastAvatarUploadTimestamp, value: newTimestampReupload });
|
||||
|
||||
if (newAvatarDecrypted) {
|
||||
UserUtils.setLastProfileUpdateTimestamp(Date.now());
|
||||
await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
|
||||
} else {
|
||||
window.log.info(
|
||||
`Reuploading avatar finished at ${newTimestampReupload}, newAttachmentPointer ${fileUrl}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue