diff --git a/keyserver/src/scripts/add-edit-thread-detailed-permissions.js b/keyserver/src/scripts/add-edit-thread-detailed-permissions.js deleted file mode 100644 --- a/keyserver/src/scripts/add-edit-thread-detailed-permissions.js +++ /dev/null @@ -1,52 +0,0 @@ -// @flow - -import bots from 'lib/facts/bots.js'; -import { assertThreadType } from 'lib/types/thread-types-enum.js'; - -import { main } from './utils.js'; -import { dbQuery, SQL } from '../database/database.js'; -import { createScriptViewer } from '../session/scripts.js'; -import { updateRoles } from '../updaters/role-updaters.js'; -import { - recalculateThreadPermissions, - commitMembershipChangeset, -} from '../updaters/thread-permission-updaters.js'; -import RelationshipChangeset from '../utils/relationship-changeset.js'; - -async function addEditThreadDetailedPermissions() { - const batchSize = 10; - - const fetchThreads = SQL`SELECT id, type FROM threads`; - const [result] = await dbQuery(fetchThreads); - const threads = result.map(row => { - return { id: row.id.toString(), type: assertThreadType(row.type) }; - }); - - const viewer = createScriptViewer(bots.commbot.userID); - - while (threads.length > 0) { - const batch = threads.splice(0, batchSize); - const membershipRows = []; - const relationshipChangeset = new RelationshipChangeset(); - await Promise.all( - batch.map(async thread => { - console.log(`updating roles for ${thread.id}`); - await updateRoles(viewer, thread.id, thread.type); - console.log(`recalculating permissions for ${thread.id}`); - const { - membershipRows: threadMembershipRows, - relationshipChangeset: threadRelationshipChangeset, - } = await recalculateThreadPermissions(thread.id); - membershipRows.push(...threadMembershipRows); - relationshipChangeset.addAll(threadRelationshipChangeset); - }), - ); - console.log(`committing batch ${JSON.stringify(batch)}`); - await commitMembershipChangeset(viewer, { - membershipRows, - relationshipChangeset, - }); - } -} - -main([addEditThreadDetailedPermissions]); diff --git a/keyserver/src/scripts/fix-new-thread-types.js b/keyserver/src/scripts/fix-new-thread-types.js deleted file mode 100644 --- a/keyserver/src/scripts/fix-new-thread-types.js +++ /dev/null @@ -1,119 +0,0 @@ -// @flow - -import bots from 'lib/facts/bots.js'; -import { threadTypes, assertThreadType } from 'lib/types/thread-types-enum.js'; - -import { main } from './utils.js'; -import { dbQuery, SQL } from '../database/database.js'; -import { createScriptViewer } from '../session/scripts.js'; -import { updateThread } from '../updaters/thread-updaters.js'; - -const batchSize = 10; -const updateThreadOptions = { forceUpdateRoot: true }; -const threadObjectComparator = (a, b) => a.id - b.id; - -// When we introduced threadTypes.PERSONAL and threadTypes.PRIVATE, we made some -// mistakes in how we converted existing threads into the new thread types: -// (1) For both PRIVATE and PERSONAL, we didn't handle converting threads that -// had multiple roles properly. updateRoles was written to handle this, but -// we missed it and wrote some code that just converted all roles to the new -// role type instead of deleting extra roles and migrating those members -// over to the new single role. -// (2) We allowed multiple threads per user to be converted into PRIVATE -// threads. -// (3) We allowed threads with a parent to be converted into PRIVATE threads. -// (4) We forgot to include EDIT_ENTRIES permissions for PRIVATE threads. -async function fixNewThreadTypes() { - const fetchBrokenThreads = SQL` - SELECT t.id, t.type, t.parent_thread_id, MIN(m.user) AS user - FROM threads t - LEFT JOIN memberships m ON m.thread = t.id - WHERE t.type IN (${[threadTypes.PERSONAL, threadTypes.PRIVATE]}) - GROUP BY t.id - `; - const [result] = await dbQuery(fetchBrokenThreads); - - const forceUpdatePersonalThreadIDs = new Set(); - const privateThreadsByUser = new Map(); - for (const row of result) { - const id = row.id.toString(); - const threadType = assertThreadType(row.type); - if (threadType === threadTypes.PERSONAL) { - forceUpdatePersonalThreadIDs.add(id); - continue; - } - const user = row.user.toString(); - const parentThreadID = row.parent_thread_id - ? row.parent_thread_id.toString() - : null; - let userPrivateThreads = privateThreadsByUser.get(user); - if (!userPrivateThreads) { - userPrivateThreads = new Set(); - privateThreadsByUser.set(user, userPrivateThreads); - } - userPrivateThreads.add({ id, parentThreadID }); - } - - const forceUpdatePrivateThreadIDs = new Set(); - const unsetPrivateThreads = new Set(); - for (const userPrivateThreads of privateThreadsByUser.values()) { - const sortedPrivateThreads = [...userPrivateThreads].sort( - threadObjectComparator, - ); - while (sortedPrivateThreads.length > 0) { - const privateThread = sortedPrivateThreads.shift(); - if (!privateThread.parentThreadID) { - forceUpdatePrivateThreadIDs.add(privateThread.id); - break; - } - unsetPrivateThreads.add(privateThread.id); - } - for (const privateThread of sortedPrivateThreads) { - unsetPrivateThreads.add(privateThread.id); - } - } - - const updateThreadRequests = []; - for (const threadID of forceUpdatePersonalThreadIDs) { - updateThreadRequests.push({ - threadID, - changes: { - type: threadTypes.PERSONAL, - }, - }); - } - for (const threadID of forceUpdatePrivateThreadIDs) { - updateThreadRequests.push({ - threadID, - changes: { - type: threadTypes.PRIVATE, - }, - }); - } - for (const threadID of unsetPrivateThreads) { - updateThreadRequests.push({ - threadID, - changes: { - type: threadTypes.COMMUNITY_SECRET_SUBTHREAD, - description: '', - }, - }); - } - - const viewer = createScriptViewer(bots.commbot.userID); - while (updateThreadRequests.length > 0) { - const batch = updateThreadRequests.splice(0, batchSize); - await Promise.all( - batch.map(async updateThreadRequest => { - console.log(`updating ${JSON.stringify(updateThreadRequest)}`); - return await updateThread( - viewer, - updateThreadRequest, - updateThreadOptions, - ); - }), - ); - } -} - -main([fixNewThreadTypes]); diff --git a/keyserver/src/scripts/rescind-notifs.js b/keyserver/src/scripts/rescind-notifs.js deleted file mode 100644 --- a/keyserver/src/scripts/rescind-notifs.js +++ /dev/null @@ -1,44 +0,0 @@ -// @flow - -import { threadTypes } from 'lib/types/thread-types-enum.js'; - -import { main } from './utils.js'; -import { dbQuery, SQL } from '../database/database.js'; -import { createScriptViewer } from '../session/scripts.js'; -import { activityUpdater } from '../updaters/activity-updaters.js'; - -async function rescindNotifs() { - const fetchRescindThreadInfo = SQL` - SELECT m.user, m.thread, m.last_message - FROM users u - INNER JOIN memberships m - ON m.user = u.id - INNER JOIN threads t - ON t.id = m.thread - WHERE t.type IN (${[threadTypes.PERSONAL, threadTypes.PRIVATE]}) - `; - const [result] = await dbQuery(fetchRescindThreadInfo); - - const usersToActivityUpdates = new Map(); - for (const row of result) { - const user = row.user.toString(); - let activityUpdates = usersToActivityUpdates.get(user); - if (!activityUpdates) { - activityUpdates = []; - usersToActivityUpdates.set(user, activityUpdates); - } - activityUpdates.push({ - focus: false, - threadID: row.thread.toString(), - latestMessage: row.last_message.toString(), - }); - } - - for (const [user, activityUpdates] of usersToActivityUpdates) { - await activityUpdater(createScriptViewer(user), { - updates: activityUpdates, - }); - } -} - -main([rescindNotifs]); diff --git a/keyserver/src/scripts/sidebar-know-of-migration.js b/keyserver/src/scripts/sidebar-know-of-migration.js deleted file mode 100644 --- a/keyserver/src/scripts/sidebar-know-of-migration.js +++ /dev/null @@ -1,68 +0,0 @@ -// @flow - -import bots from 'lib/facts/bots.js'; -import { threadTypes, type ThreadType } from 'lib/types/thread-types-enum.js'; - -import { main } from './utils.js'; -import { dbQuery, SQL } from '../database/database.js'; -import { createScriptViewer } from '../session/scripts.js'; -import { updateRoles } from '../updaters/role-updaters.js'; -import { - recalculateThreadPermissions, - commitMembershipChangeset, -} from '../updaters/thread-permission-updaters.js'; -import RelationshipChangeset from '../utils/relationship-changeset.js'; - -async function updatePrivateThreads() { - console.log('updating private threads'); - await updateThreads(threadTypes.PRIVATE); -} - -async function updateSidebars() { - console.log('updating sidebars'); - await updateThreads(threadTypes.SIDEBAR); -} - -const batchSize = 10; - -async function updateThreads(threadType: ThreadType) { - const fetchThreads = SQL` - SELECT id FROM threads WHERE type = ${threadType} - `; - const [result] = await dbQuery(fetchThreads); - const threadIDs = result.map(row => row.id.toString()); - - const viewer = createScriptViewer(bots.commbot.userID); - while (threadIDs.length > 0) { - const batch = threadIDs.splice(0, batchSize); - const membershipRows = []; - const relationshipChangeset = new RelationshipChangeset(); - await Promise.all( - batch.map(async threadID => { - console.log(`updating roles for ${threadID}`); - await updateRoles(viewer, threadID, threadType); - console.log(`recalculating permissions for ${threadID}`); - const { - membershipRows: threadMembershipRows, - relationshipChangeset: threadRelationshipChangeset, - } = await recalculateThreadPermissions(threadID); - membershipRows.push(...threadMembershipRows); - relationshipChangeset.addAll(threadRelationshipChangeset); - }), - ); - console.log(`committing batch ${JSON.stringify(batch)}`); - await commitMembershipChangeset(viewer, { - membershipRows, - relationshipChangeset, - }); - } -} - -// This migration is supposed to update the database to reflect -// https://phabricator.ashoat.com/D1020. There are two changes there: -// (1) Changes to SIDEBAR so membership no longer automatically confers KNOW_OF -// (2) Changes to PRIVATE so all of its children have KNOW_OF -// We want to apply the changes to PRIVATE first so that when we recalculate -// the permissions for any of a PRIVATE thread's SIDEBARs, the parent has -// already been updated. -main([updatePrivateThreads, updateSidebars]);