diff --git a/keyserver/src/database/migration-config.js b/keyserver/src/database/migration-config.js --- a/keyserver/src/database/migration-config.js +++ b/keyserver/src/database/migration-config.js @@ -7,9 +7,17 @@ import { policyTypes } from 'lib/facts/policies.js'; import { specialRoles } from 'lib/permissions/special-roles.js'; import { messageTypes } from 'lib/types/message-types-enum.js'; -import { threadPermissions } from 'lib/types/thread-permission-types.js'; +import { + threadPermissions, + userSurfacedPermissions, + type ThreadRolePermissionsBlob, +} from 'lib/types/thread-permission-types.js'; import { threadTypes } from 'lib/types/thread-types-enum.js'; import { permissionsToRemoveInMigration } from 'lib/utils/migration-utils.js'; +import { + userSurfacedPermissionsFromRolePermissions, + toggleUserSurfacedPermission, +} from 'lib/utils/role-utils.js'; import { dbQuery, SQL } from '../database/database.js'; import { processMessagesInDBForSearch } from '../database/search-utils.js'; @@ -836,6 +844,61 @@ [66, updateRolesAndPermissionsForAllThreads], [67, updateRolesAndPermissionsForAllThreads], [68, updateRolesAndPermissionsForAllThreads], + [ + 69, + async () => { + const [result] = await dbQuery(SQL` + SELECT r.id, r.permissions + FROM threads t + LEFT JOIN roles r ON r.thread = t.id + WHERE t.community IS NULL + AND t.type != ${threadTypes.GENESIS} + AND r.special_role != ${specialRoles.ADMIN_ROLE} + `); + + // We accidentally removed ADD_MEMBERS in an earlier migration, + // so we make sure to bring it back here + const rolePermissionsToUpdate = new Map< + string, + ThreadRolePermissionsBlob, + >(); + for (const row of result) { + const { id, permissions: permissionsString } = row; + const permissions = JSON.parse(permissionsString); + const userSurfaced = + userSurfacedPermissionsFromRolePermissions(permissions); + if (userSurfaced.has(userSurfacedPermissions.ADD_MEMBERS)) { + continue; + } + const newPermissions = toggleUserSurfacedPermission( + permissions, + userSurfacedPermissions.ADD_MEMBERS, + ); + rolePermissionsToUpdate.set(id, newPermissions); + } + + if (rolePermissionsToUpdate.size > 0) { + const updateQuery = SQL` + UPDATE roles + SET permissions = CASE id + `; + for (const [id, permissions] of rolePermissionsToUpdate) { + console.log(`updating ${id} to ${JSON.stringify(permissions)}`); + const permissionsBlob = JSON.stringify(permissions); + updateQuery.append(SQL` + WHEN ${id} THEN ${permissionsBlob} + `); + } + updateQuery.append(SQL` + ELSE permissions + END + `); + await dbQuery(updateQuery); + } + + await updateRolesAndPermissionsForAllThreads(); + }, + ], ]); const newDatabaseVersion: number = Math.max(...migrations.keys());