diff --git a/keyserver/src/creators/role-creator.js b/keyserver/src/creators/role-creator.js --- a/keyserver/src/creators/role-creator.js +++ b/keyserver/src/creators/role-creator.js @@ -145,6 +145,7 @@ DESCENDANT + threadPermissions.EDIT_PERMISSIONS; const descendantRemoveMembers = DESCENDANT + threadPermissions.REMOVE_MEMBERS; const descendantChangeRole = DESCENDANT + threadPermissions.CHANGE_ROLE; + const descendantManagePins = DESCENDANT + threadPermissions.MANAGE_PINS; const baseAdminPermissions = { [threadPermissions.KNOW_OF]: true, @@ -160,6 +161,7 @@ [threadPermissions.DELETE_THREAD]: true, [threadPermissions.REMOVE_MEMBERS]: true, [threadPermissions.CHANGE_ROLE]: true, + [threadPermissions.MANAGE_PINS]: true, [descendantKnowOf]: true, [descendantVisible]: true, [topLevelDescendantJoinThread]: true, @@ -176,6 +178,7 @@ [descendantEditPermissions]: true, [descendantRemoveMembers]: true, [descendantChangeRole]: true, + [descendantManagePins]: true, }; let adminPermissions; 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 @@ -3,6 +3,7 @@ import fs from 'fs'; import { policyTypes } from 'lib/facts/policies.js'; +import { threadPermissions } from 'lib/types/thread-types.js'; import { dbQuery, SQL } from '../database/database.js'; import { updateRolesAndPermissionsForAllThreads } from '../updaters/thread-permission-updaters.js'; @@ -203,6 +204,39 @@ ); }, ], + [ + 18, + async () => { + const managePinsExtractString = `$.${threadPermissions.MANAGE_PINS}.value`; + const descendantManagePinsExtractString = `$.descendant_${threadPermissions.MANAGE_PINS}.value`; + await dbQuery( + SQL` + CREATE TABLE IF NOT EXISTS pinned_messages ( + messageID bigint(20) NOT NULL, + thread bigint(20) NOT NULL, + pin_time bigint(20) NOT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + ALTER TABLE pinned_messages + ADD INDEX IF NOT EXISTS thread (thread); + + UPDATE roles + SET permissions = JSON_SET( + permissions, ${managePinsExtractString}, TRUE + ) + WHERE name = "Admins"; + + UPDATE roles + SET permissions = JSON_SET( + permissions, ${descendantManagePinsExtractString}, TRUE + ) + WHERE name = "Admins"; + `, + { multipleStatements: true }, + ); + await updateRolesAndPermissionsForAllThreads(); + }, + ], ]); const newDatabaseVersion: number = Math.max(...migrations.keys()); 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 @@ -98,6 +98,7 @@ REMOVE_MEMBERS: 'remove_members', CHANGE_ROLE: 'change_role', LEAVE_THREAD: 'leave_thread', + MANAGE_PINS: 'manage_pins', }); export type ThreadPermission = $Values; export function assertThreadPermissions( @@ -120,7 +121,8 @@ ourThreadPermissions === 'add_members' || ourThreadPermissions === 'remove_members' || ourThreadPermissions === 'change_role' || - ourThreadPermissions === 'leave_thread', + ourThreadPermissions === 'leave_thread' || + ourThreadPermissions === 'manage_pins', 'string is not threadPermissions enum', ); return ourThreadPermissions;