feat: fixed groups migration v34

pull/2971/head
William Grant 2 years ago
parent 4aba2493e5
commit 45cfa6b38b

@ -303,7 +303,7 @@ function getLegacyGroupInfoFromDBValues({
function insertLegacyGroupIntoWrapper(
legacyGroup: Pick<
ConversationAttributes,
'id' | 'priority' | 'displayNameInProfile' | 'lastJoinedTimestamp' | 'expireTimer'
'id' | 'priority' | 'displayNameInProfile' | 'lastJoinedTimestamp'
> & { members: string; groupAdmins: string }, // members and groupAdmins are still stringified here
userGroupConfigWrapper: UserGroupsWrapperNode,
volatileInfoConfigWrapper: ConvoInfoVolatileWrapperNode,
@ -315,7 +315,6 @@ function insertLegacyGroupIntoWrapper(
const {
priority,
id,
// expireTimer,
groupAdmins,
members,
displayNameInProfile,
@ -330,7 +329,6 @@ function insertLegacyGroupIntoWrapper(
const wrapperLegacyGroup = getLegacyGroupInfoFromDBValues({
id,
priority,
// expireTimer, // FIXME WILL add expirationMode here
groupAdmins,
members,
displayNameInProfile,

@ -4,12 +4,25 @@ import {
ContactInfoSet,
ContactsConfigWrapperNode,
DisappearingMessageConversationType,
LegacyGroupInfo,
LegacyGroupMemberInfo,
UserGroupsWrapperNode,
} from 'libsession_util_nodejs';
import { isEmpty, isEqual } from 'lodash';
import { CONVERSATION_PRIORITIES } from '../../../models/conversationAttributes';
import { from_hex } from 'libsodium-wrappers-sumo';
import {
CONVERSATION_PRIORITIES,
ConversationAttributes,
} from '../../../models/conversationAttributes';
import { fromHexToArray } from '../../../session/utils/String';
import { checkTargetMigration, hasDebugEnvVariable } from '../utils';
import { ConfigDumpRow, CONFIG_DUMP_TABLE } from '../../../types/sqlSharedTypes';
import {
ConfigDumpRow,
CONFIG_DUMP_TABLE,
maybeArrayJSONtoArray,
} from '../../../types/sqlSharedTypes';
import { HexKeyPair } from '../../../receiver/keypairs';
import { sqlNode } from '../../sql';
const targetVersion = 34;
@ -187,8 +200,120 @@ function updateContactInContactWrapper(
}
}
function getLegacyGroupInfoFromDBValues({
id,
priority,
members: maybeMembers,
displayNameInProfile,
expirationType,
expireTimer,
encPubkeyHex,
encSeckeyHex,
groupAdmins: maybeAdmins,
lastJoinedTimestamp,
}: Pick<
ConversationAttributes,
| 'id'
| 'priority'
| 'displayNameInProfile'
| 'lastJoinedTimestamp'
| 'expirationType'
| 'expireTimer'
> & {
encPubkeyHex: string;
encSeckeyHex: string;
members: string | Array<string>;
groupAdmins: string | Array<string>;
}) {
const admins: Array<string> = maybeArrayJSONtoArray(maybeAdmins);
const members: Array<string> = maybeArrayJSONtoArray(maybeMembers);
const wrappedMembers: Array<LegacyGroupMemberInfo> = (members || []).map(m => {
return {
isAdmin: admins.includes(m),
pubkeyHex: m,
};
});
const legacyGroup: LegacyGroupInfo = {
pubkeyHex: id,
disappearingTimerSeconds:
expirationType &&
(expirationType as DisappearingMessageConversationType) !== 'off' &&
!!expireTimer &&
expireTimer > 0
? expireTimer
: 0,
name: displayNameInProfile || '',
priority: priority || 0,
members: wrappedMembers,
encPubkey: !isEmpty(encPubkeyHex) ? from_hex(encPubkeyHex) : new Uint8Array(),
encSeckey: !isEmpty(encSeckeyHex) ? from_hex(encSeckeyHex) : new Uint8Array(),
joinedAtSeconds: Math.floor(lastJoinedTimestamp / 1000),
};
return legacyGroup;
}
function updateLegacyGroupInWrapper(
legacyGroup: Pick<
ConversationAttributes,
| 'id'
| 'priority'
| 'displayNameInProfile'
| 'lastJoinedTimestamp'
| 'expirationType'
| 'expireTimer'
> & { members: string; groupAdmins: string }, // members and groupAdmins are still stringified here
userGroupConfigWrapper: UserGroupsWrapperNode,
db: BetterSqlite3.Database,
version: number
) {
checkTargetMigration(version, targetVersion);
const {
priority,
id,
expirationType,
expireTimer,
groupAdmins,
members,
displayNameInProfile,
lastJoinedTimestamp,
} = legacyGroup;
const latestEncryptionKeyPairHex = sqlNode.getLatestClosedGroupEncryptionKeyPair(
legacyGroup.id,
db
) as HexKeyPair | undefined;
const wrapperLegacyGroup = getLegacyGroupInfoFromDBValues({
id,
priority,
expirationType,
expireTimer,
groupAdmins,
members,
displayNameInProfile,
encPubkeyHex: latestEncryptionKeyPairHex?.publicHex || '',
encSeckeyHex: latestEncryptionKeyPairHex?.privateHex || '',
lastJoinedTimestamp,
});
try {
hasDebugEnvVariable &&
console.info('Inserting legacy group into wrapper: ', wrapperLegacyGroup);
const success = userGroupConfigWrapper.setLegacyGroup(wrapperLegacyGroup);
hasDebugEnvVariable && console.info('legacy group into wrapper success: ', success);
} catch (e) {
console.error(
`userGroupConfigWrapper.set during migration failed with ${e.message} for legacyGroup.id: "${legacyGroup.id}". Skipping that legacy group entirely`
);
}
}
export const V34 = {
fetchConfigDumps,
writeConfigDumps,
updateContactInContactWrapper,
updateLegacyGroupInWrapper,
};

@ -1736,6 +1736,7 @@ function updateToSessionSchemaVersion34(currentVersion: number, db: BetterSqlite
);
}
}
// endregion
// region Disappearing Messages Private Conversations
@ -1806,7 +1807,7 @@ function updateToSessionSchemaVersion34(currentVersion: number, db: BetterSqlite
);
} else {
console.log(
'===================== contacts config config wrapper dump found ======================='
'===================== contacts config wrapper dump not found ======================='
);
}
}
@ -1815,11 +1816,76 @@ function updateToSessionSchemaVersion34(currentVersion: number, db: BetterSqlite
// endregion
// region Disappearing Messages Groups
db.prepare(
`UPDATE ${CONVERSATIONS_TABLE} SET
const groupConversationsInfo = db
.prepare(
`UPDATE ${CONVERSATIONS_TABLE} SET
expirationType = $expirationType
WHERE type = 'group' AND id LIKE '05%' AND expireTimer > 0;`
).run({ expirationType: 'deleteAfterSend' });
)
.run({ expirationType: 'deleteAfterSend' });
if (groupConversationsInfo.changes) {
// this filter is based on the `isLegacyGroupToStoreInWrapper` function. Note, it has been expanded to check if disappearing messages is on
const legacyGroupsToWriteInWrapper = db
.prepare(
`SELECT * FROM ${CONVERSATIONS_TABLE} WHERE type = 'group' AND active_at > 0 AND id LIKE '05%' AND NOT isKickedFromGroup AND NOT left AND expirationType = 'deleteAfterSend' AND expireTimer > 0;`
)
.all({});
if (isArray(legacyGroupsToWriteInWrapper) && legacyGroupsToWriteInWrapper.length) {
// Get existing config wrapper dumps and update them
const userGroupsConfigWrapperDump = MIGRATION_HELPERS.V34.fetchConfigDumps(
db,
targetVersion,
publicKeyHex,
'UserGroupsConfig'
);
if (userGroupsConfigWrapperDump) {
const userGroupsConfigData = userGroupsConfigWrapperDump.data;
const userGroupsConfigWrapper = new UserGroupsWrapperNode(
privateEd25519,
userGroupsConfigData
);
console.info(
`===================== Starting legacy group wrapper update length: ${legacyGroupsToWriteInWrapper?.length} =======================`
);
legacyGroupsToWriteInWrapper.forEach(legacyGroup => {
try {
hasDebugEnvVariable &&
console.info('Updating legacy group: ', JSON.stringify(legacyGroup));
MIGRATION_HELPERS.V34.updateLegacyGroupInWrapper(
legacyGroup,
userGroupsConfigWrapper,
db,
targetVersion
);
} catch (e) {
console.info(`failed to insert legacy group with ${e.message}`, legacyGroup);
}
});
// dump the wrapper content and save it to the DB
MIGRATION_HELPERS.V34.writeConfigDumps(
db,
targetVersion,
publicKeyHex,
'UserGroupsConfig',
userGroupsConfigWrapper.dump()
);
console.info(
'===================== Done with legacy group inserting ======================='
);
} else {
console.log(
'===================== user groups config wrapper dump found ======================='
);
}
}
}
// endregion

Loading…
Cancel
Save