Page MenuHomePhabricator

D8574.diff
No OneTemporary

D8574.diff

diff --git a/keyserver/src/deleters/role-deleters.js b/keyserver/src/deleters/role-deleters.js
--- a/keyserver/src/deleters/role-deleters.js
+++ b/keyserver/src/deleters/role-deleters.js
@@ -1,6 +1,23 @@
// @flow
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import type {
+ RoleDeletionRequest,
+ RoleDeletionResult,
+} from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types-enum.js';
+import { ServerError } from 'lib/utils/errors.js';
+
+import { createUpdates } from '../creators/update-creator.js';
import { dbQuery, SQL } from '../database/database.js';
+import {
+ fetchServerThreadInfos,
+ rawThreadInfosFromServerThreadInfos,
+ fetchThreadInfos,
+} from '../fetchers/thread-fetchers.js';
+import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { updateRole } from '../updaters/thread-updaters.js';
async function deleteOrphanedRoles(): Promise<void> {
await dbQuery(SQL`
@@ -12,4 +29,109 @@
`);
}
-export { deleteOrphanedRoles };
+async function deleteRole(
+ viewer: Viewer,
+ request: RoleDeletionRequest,
+): Promise<RoleDeletionResult> {
+ const hasPermission = await checkThreadPermission(
+ viewer,
+ request.community,
+ threadPermissions.CHANGE_ROLE,
+ );
+ if (!hasPermission) {
+ throw new ServerError('invalid_credentials');
+ }
+
+ const { community, roleID } = request;
+
+ const defaultRoleQuery = SQL`
+ SELECT default_role
+ FROM threads
+ WHERE id = ${community}
+ `;
+
+ const membersWithRoleQuery = SQL`
+ SELECT user
+ FROM memberships
+ WHERE thread = ${community}
+ AND role = ${roleID}
+ `;
+
+ const [[defaultRoleResult], [membersWithRoleResult], { threadInfos }] =
+ await Promise.all([
+ dbQuery(defaultRoleQuery),
+ dbQuery(membersWithRoleQuery),
+ fetchThreadInfos(viewer, {
+ threadID: community,
+ }),
+ ]);
+ const threadInfo = threadInfos[community];
+
+ if (!threadInfo) {
+ throw new ServerError('invalid_parameters');
+ }
+
+ const defaultRoleID = defaultRoleResult[0].default_role.toString();
+ const membersWithRole = membersWithRoleResult.map(result => result.user);
+ const adminRoleID = Object.keys(threadInfo.roles).find(
+ role => threadInfo.roles[role].name === 'Admins',
+ );
+
+ if (roleID === defaultRoleID || roleID === adminRoleID) {
+ throw new ServerError('invalid_parameters');
+ }
+
+ if (membersWithRole.length > 0) {
+ await updateRole(viewer, {
+ threadID: community,
+ memberIDs: membersWithRole,
+ role: defaultRoleID,
+ });
+ }
+
+ const deleteFromRolesQuery = SQL`
+ DELETE FROM roles
+ WHERE id = ${roleID}
+ AND thread = ${community}
+ `;
+
+ await dbQuery(deleteFromRolesQuery);
+
+ const fetchServerThreadInfosResult = await fetchServerThreadInfos({
+ threadID: community,
+ });
+ const { threadInfos: serverThreadInfos } = fetchServerThreadInfosResult;
+ const serverThreadInfo = serverThreadInfos[community];
+
+ const time = Date.now();
+
+ const updateDatas = [];
+ for (const memberInfo of serverThreadInfo.members) {
+ updateDatas.push({
+ type: updateTypes.UPDATE_THREAD,
+ userID: memberInfo.id,
+ time,
+ threadID: community,
+ });
+ }
+
+ const { viewerUpdates } = await createUpdates(updateDatas, {
+ viewer,
+ updatesForCurrentSession: 'return',
+ });
+
+ const { threadInfos: rawThreadInfos } = rawThreadInfosFromServerThreadInfos(
+ viewer,
+ fetchServerThreadInfosResult,
+ );
+ const rawThreadInfo = rawThreadInfos[community];
+
+ return {
+ threadInfo: rawThreadInfo,
+ updatesResult: {
+ newUpdates: viewerUpdates,
+ },
+ };
+}
+
+export { deleteOrphanedRoles, deleteRole };
diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js
--- a/lib/types/thread-types.js
+++ b/lib/types/thread-types.js
@@ -428,6 +428,25 @@
},
};
+export type RoleDeletionRequest = {
+ +community: string,
+ +roleID: string,
+};
+
+export type RoleDeletionResult = {
+ +threadInfo: RawThreadInfo,
+ +updatesResult: {
+ +newUpdates: $ReadOnlyArray<ServerUpdateInfo>,
+ },
+};
+
+export type RoleDeletionPayload = {
+ +threadInfo: RawThreadInfo,
+ +updatesResult: {
+ +newUpdates: $ReadOnlyArray<ClientUpdateInfo>,
+ },
+};
+
// We can show a max of 3 sidebars inline underneath their parent in the chat
// tab. If there are more, we show a button that opens a modal to see the rest
export const maxReadSidebars = 3;

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 2, 5:46 PM (22 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2608449
Default Alt Text
D8574.diff (4 KB)

Event Timeline