diff --git a/keyserver/src/fetchers/role-fetchers.js b/keyserver/src/fetchers/role-fetchers.js index a56d2b3c3..eb9848c72 100644 --- a/keyserver/src/fetchers/role-fetchers.js +++ b/keyserver/src/fetchers/role-fetchers.js @@ -1,29 +1,30 @@ // @flow import { specialRoles } from 'lib/permissions/special-roles.js'; -import type { ClientLegacyRoleInfo } from 'lib/types/thread-types.js'; +import type { ServerLegacyRoleInfo } from 'lib/types/thread-types.js'; import { dbQuery, SQL } from '../database/database.js'; -async function fetchRoles(threadID: string): Promise { +async function fetchRoles(threadID: string): Promise { const query = SQL` - SELECT id, name, permissions, + SELECT id, name, permissions, special_role, special_role = ${specialRoles.DEFAULT_ROLE} AS is_default FROM roles WHERE thread = ${threadID} `; const [result] = await dbQuery(query); - const roles: Array = []; + const roles: Array = []; for (const row of result) { roles.push({ id: row.id.toString(), name: row.name, permissions: JSON.parse(row.permissions), isDefault: Boolean(row.is_default), + specialRole: row.special_role, }); } return roles; } export { fetchRoles }; diff --git a/keyserver/src/updaters/role-updaters.js b/keyserver/src/updaters/role-updaters.js index 5b5b03c8e..c9fb31a8f 100644 --- a/keyserver/src/updaters/role-updaters.js +++ b/keyserver/src/updaters/role-updaters.js @@ -1,116 +1,118 @@ // @flow import invariant from 'invariant'; import _isEqual from 'lodash/fp/isEqual.js'; import { getRolePermissionBlobs } from 'lib/permissions/thread-permissions.js'; import type { ThreadRolePermissionsBlob } from 'lib/types/thread-permission-types.js'; import type { ThreadType } from 'lib/types/thread-types-enum.js'; +import type { ServerLegacyRoleInfo } from 'lib/types/thread-types.js'; import createIDs from '../creators/id-creator.js'; import { dbQuery, SQL } from '../database/database.js'; import { fetchRoles } from '../fetchers/role-fetchers.js'; import type { Viewer } from '../session/viewer.js'; async function updateRoles( viewer: Viewer, threadID: string, threadType: ThreadType, ): Promise { - const currentRoles = await fetchRoles(threadID); + const currentRoles: $ReadOnlyArray = + await fetchRoles(threadID); const currentRolePermissions: { [string]: ThreadRolePermissionsBlob } = {}; const currentRoleIDs: { [string]: string } = {}; for (const roleInfo of currentRoles) { currentRolePermissions[roleInfo.name] = roleInfo.permissions; currentRoleIDs[roleInfo.name] = roleInfo.id; } const rolePermissions = getRolePermissionBlobs(threadType); if (_isEqual(rolePermissions)(currentRolePermissions)) { return; } const promises = []; if (rolePermissions.Admins && !currentRolePermissions.Admins) { const [id] = await createIDs('roles', 1); const newRow = [ id, threadID, 'Admins', JSON.stringify(rolePermissions.Admins), Date.now(), ]; const insertQuery = SQL` INSERT INTO roles (id, thread, name, permissions, creation_time) VALUES ${[newRow]} `; promises.push(dbQuery(insertQuery)); const setAdminQuery = SQL` UPDATE memberships SET role = ${id} WHERE thread = ${threadID} AND user = ${viewer.userID} AND role > 0 `; promises.push(dbQuery(setAdminQuery)); } else if (!rolePermissions.Admins && currentRolePermissions.Admins) { invariant( currentRoleIDs.Admins && currentRoleIDs.Members, 'ids should exist for both Admins and Members roles', ); const id = currentRoleIDs.Admins; const deleteQuery = SQL` DELETE r, i FROM roles r LEFT JOIN ids i ON i.id = r.id WHERE r.id = ${id} `; promises.push(dbQuery(deleteQuery)); const updateMembershipsQuery = SQL` UPDATE memberships SET role = ${currentRoleIDs.Members} WHERE thread = ${threadID} AND role > 0 `; promises.push(dbQuery(updateMembershipsQuery)); } const updatePermissions: { [string]: ThreadRolePermissionsBlob } = {}; for (const name in currentRoleIDs) { const currentPermissions = currentRolePermissions[name]; const permissions = rolePermissions[name]; if ( !permissions || !currentPermissions || _isEqual(permissions)(currentPermissions) ) { continue; } const id = currentRoleIDs[name]; updatePermissions[id] = permissions; } if (Object.values(updatePermissions).length > 0) { const updateQuery = SQL` UPDATE roles SET permissions = CASE id `; for (const id in updatePermissions) { const permissionsBlob = JSON.stringify(updatePermissions[id]); updateQuery.append(SQL` WHEN ${id} THEN ${permissionsBlob} `); } updateQuery.append(SQL` ELSE permissions END WHERE thread = ${threadID} `); promises.push(dbQuery(updateQuery)); } await Promise.all(promises); } export { updateRoles };