Changeset View
Changeset View
Standalone View
Standalone View
keyserver/src/updaters/thread-updaters.js
Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
async function updateRole( | async function updateRole( | ||||
viewer: Viewer, | viewer: Viewer, | ||||
request: RoleChangeRequest, | request: RoleChangeRequest, | ||||
): Promise<ChangeThreadSettingsResult> { | ): Promise<ChangeThreadSettingsResult> { | ||||
if (!viewer.loggedIn) { | if (!viewer.loggedIn) { | ||||
throw new ServerError('not_logged_in'); | throw new ServerError('not_logged_in'); | ||||
} | } | ||||
const [memberIDs, hasPermission] = await Promise.all([ | const [memberIDs, hasPermission, fetchThreadResult] = await Promise.all([ | ||||
verifyUserIDs(request.memberIDs), | verifyUserIDs(request.memberIDs), | ||||
checkThreadPermission( | checkThreadPermission( | ||||
viewer, | viewer, | ||||
request.threadID, | request.threadID, | ||||
threadPermissions.CHANGE_ROLE, | threadPermissions.CHANGE_ROLE, | ||||
), | ), | ||||
fetchThreadInfos(viewer, SQL`t.id = ${request.threadID}`), | |||||
]); | ]); | ||||
if (memberIDs.length === 0) { | if (memberIDs.length === 0) { | ||||
throw new ServerError('invalid_parameters'); | throw new ServerError('invalid_parameters'); | ||||
} | } | ||||
if (!hasPermission) { | if (!hasPermission) { | ||||
throw new ServerError('invalid_credentials'); | throw new ServerError('invalid_credentials'); | ||||
} | } | ||||
const threadInfo = fetchThreadResult.threadInfos[request.threadID]; | |||||
if (!threadInfo) { | |||||
throw new ServerError('invalid_parameters'); | |||||
} | |||||
const adminRoleID = Object.keys(threadInfo.roles).find( | |||||
roleID => threadInfo.roles[roleID].name === 'Admins', | |||||
); | |||||
// Ensure that there will always still be at least one admin in a community | |||||
if (adminRoleID) { | |||||
const memberRoles = memberIDs.map( | |||||
memberID => | |||||
threadInfo.members.find(member => member.id === memberID)?.role, | |||||
); | |||||
const communityAdminsCount = threadInfo.members.filter( | |||||
member => member.role === adminRoleID, | |||||
).length; | |||||
const changedAdminsCount = memberRoles.filter( | |||||
memberRole => memberRole === adminRoleID, | |||||
).length; | |||||
if (changedAdminsCount >= communityAdminsCount) { | |||||
throw new ServerError('invalid_parameters'); | |||||
} | |||||
} | |||||
const query = SQL` | const query = SQL` | ||||
SELECT user, role | SELECT user, role | ||||
FROM memberships | FROM memberships | ||||
WHERE user IN (${memberIDs}) | WHERE user IN (${memberIDs}) | ||||
AND thread = ${request.threadID} | AND thread = ${request.threadID} | ||||
`; | `; | ||||
const [result] = await dbQuery(query); | const [result] = await dbQuery(query); | ||||
▲ Show 20 Lines • Show All 932 Lines • Show Last 20 Lines |