Always refetch profile key credential if expired

This commit is contained in:
Fedor Indutny 2022-07-18 13:05:41 -07:00 committed by GitHub
parent 2f252b8e26
commit a4cf2e0948
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 37 deletions

View file

@ -818,7 +818,7 @@ export async function startApp(): Promise<void> {
await window.Signal.Data.clearAllErrorStickerPackAttempts(); await window.Signal.Data.clearAllErrorStickerPackAttempts();
} }
if (window.isBeforeVersion(lastVersion, 'v5.50.0-alpha.1')) { if (window.isBeforeVersion(lastVersion, 'v5.51.0-beta.2')) {
await window.storage.put('groupCredentials', []); await window.storage.put('groupCredentials', []);
await window.Signal.Data.removeAllProfileKeyCredentials(); await window.Signal.Data.removeAllProfileKeyCredentials();
} }

View file

@ -60,6 +60,7 @@ import type {
GroupCredentialsType, GroupCredentialsType,
GroupLogResponseType, GroupLogResponseType,
} from './textsecure/WebAPI'; } from './textsecure/WebAPI';
import { HTTPError } from './textsecure/Errors';
import type MessageSender from './textsecure/SendMessage'; import type MessageSender from './textsecure/SendMessage';
import { CURRENT_SCHEMA_VERSION as MAX_MESSAGE_SCHEMA } from './types/Message2'; import { CURRENT_SCHEMA_VERSION as MAX_MESSAGE_SCHEMA } from './types/Message2';
import type { ConversationModel } from './models/conversations'; import type { ConversationModel } from './models/conversations';
@ -1491,13 +1492,6 @@ export async function modifyGroupV2({
log.info(`modifyGroupV2/${logId}: Fetching profiles for ${logIds}`); log.info(`modifyGroupV2/${logId}: Fetching profiles for ${logIds}`);
} }
for (const member of membersMissingCredentials) {
member.set({
profileKeyCredential: null,
profileKeyCredentialExpiration: null,
});
}
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
await Promise.all( await Promise.all(
membersMissingCredentials.map(member => member.getProfiles()) membersMissingCredentials.map(member => member.getProfiles())
@ -1735,19 +1729,25 @@ export async function fetchMembershipProof({
// Creating a group // Creating a group
export async function createGroupV2({ export async function createGroupV2(
name, options: Readonly<{
avatar, name: string;
expireTimer, avatar: undefined | Uint8Array;
conversationIds, expireTimer: undefined | number;
avatars, conversationIds: Array<string>;
}: Readonly<{ avatars?: Array<AvatarDataType>;
name: string; refreshedCredentials?: boolean;
avatar: undefined | Uint8Array; }>
expireTimer: undefined | number; ): Promise<ConversationModel> {
conversationIds: Array<string>; const {
avatars?: Array<AvatarDataType>; name,
}>): Promise<ConversationModel> { avatar,
expireTimer,
conversationIds,
avatars,
refreshedCredentials = false,
} = options;
// Ensure we have the credentials we need before attempting GroupsV2 operations // Ensure we have the credentials we need before attempting GroupsV2 operations
await maybeFetchNewCredentials(); await maybeFetchNewCredentials();
@ -1770,10 +1770,6 @@ export async function createGroupV2({
window.ConversationController.getOurConversationOrThrow(); window.ConversationController.getOurConversationOrThrow();
if (ourConversation.hasProfileKeyCredentialExpired()) { if (ourConversation.hasProfileKeyCredentialExpired()) {
log.info(`createGroupV2/${logId}: fetching our own credentials`); log.info(`createGroupV2/${logId}: fetching our own credentials`);
ourConversation.set({
profileKeyCredential: null,
profileKeyCredentialExpiration: null,
});
await ourConversation.getProfiles(); await ourConversation.getProfiles();
} }
@ -1869,12 +1865,45 @@ export async function createGroupV2({
...protoAndConversationAttributes, ...protoAndConversationAttributes,
}); });
await makeRequestWithTemporalRetry({ try {
logId: `createGroupV2/${logId}`, await makeRequestWithTemporalRetry({
publicParams, logId: `createGroupV2/${logId}`,
secretParams, publicParams,
request: (sender, options) => sender.createGroup(groupProto, options), secretParams,
}); request: (sender, requestOptions) =>
sender.createGroup(groupProto, requestOptions),
});
} catch (error) {
if (!(error instanceof HTTPError)) {
throw error;
}
if (error.code !== 400 || refreshedCredentials) {
throw error;
}
const logIds = conversationIds.map(conversationId => {
const contact = window.ConversationController.get(conversationId);
if (!contact) {
return;
}
contact.set({
profileKeyCredential: null,
profileKeyCredentialExpiration: null,
});
return contact.idForLogging();
});
log.warn(
`createGroupV2/${logId}: Profile key credentials were not ` +
`up-to-date. Updating profiles for ${logIds} and retrying`
);
return createGroupV2({
...options,
refreshedCredentials: true,
});
}
let avatarAttribute: ConversationAttributesType['avatar']; let avatarAttribute: ConversationAttributesType['avatar'];
if (uploadedAvatar) { if (uploadedAvatar) {

View file

@ -196,10 +196,6 @@ function* getFilteredConversations(
(conversation.id === ourConversationId || (conversation.id === ourConversationId ||
!conversationIdsSeen.has(conversation.id)) !conversationIdsSeen.has(conversation.id))
) { ) {
conversation.set({
profileKeyCredential: null,
profileKeyCredentialExpiration: null,
});
conversationIdsSeen.add(conversation.id); conversationIdsSeen.add(conversation.id);
yield conversation; yield conversation;
break; break;

View file

@ -230,7 +230,6 @@ async function doGetProfile(c: ConversationModel): Promise<void> {
const profileKey = c.get('profileKey'); const profileKey = c.get('profileKey');
const profileKeyVersion = c.deriveProfileKeyVersion(); const profileKeyVersion = c.deriveProfileKeyVersion();
const uuid = c.getCheckedUuid('getProfile'); const uuid = c.getCheckedUuid('getProfile');
const existingProfileKeyCredential = c.get('profileKeyCredential');
const lastProfile = c.get('lastProfile'); const lastProfile = c.get('lastProfile');
let profileCredentialRequestContext: let profileCredentialRequestContext:
@ -246,7 +245,7 @@ async function doGetProfile(c: ConversationModel): Promise<void> {
'profileKeyVersion and accessKey are derived from profileKey' 'profileKeyVersion and accessKey are derived from profileKey'
); );
if (existingProfileKeyCredential) { if (!c.hasProfileKeyCredentialExpired()) {
getProfileOptions = { getProfileOptions = {
accessKey, accessKey,
profileKeyVersion, profileKeyVersion,