fixup edit profile dialog

This commit is contained in:
Audric Ackermann 2021-06-21 11:42:25 +10:00
parent b64e8bf610
commit 6c1cac9203
No known key found for this signature in database
GPG key ID: 999F434D76324AD4
3 changed files with 121 additions and 124 deletions

View file

@ -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);
}
}

View file

@ -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();
}
};

View file

@ -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}`
);
}
}