diff --git a/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs b/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs index 84d37c802f..c74c720df9 100644 --- a/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs +++ b/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs @@ -238,28 +238,6 @@ function personalAndGroupSubscriptions(userId) { } } -function oldDebugProjects(userId) { - return { - key: `old-debug-projects-${userId}`, - async create(userId) { - return await NotificationsHandler.promises.createNotification( - userId, - this.key, - 'notification_old_debug_projects', - {}, - null, - true - ) - }, - async read() { - return await NotificationsHandler.promises.markAsReadWithKey( - userId, - this.key - ) - }, - } -} - const NotificationsBuilder = { // Note: notification keys should be url-safe dropboxUnlinkedDueToLapsedReconfirmation(userId) { @@ -301,7 +279,6 @@ NotificationsBuilder.promises = { projectInvite, personalAndGroupSubscriptions, tpdsFileLimit, - oldDebugProjects, } export default NotificationsBuilder diff --git a/services/web/app/src/Features/Project/ProjectController.mjs b/services/web/app/src/Features/Project/ProjectController.mjs index 32029b81a7..ded4afd98c 100644 --- a/services/web/app/src/Features/Project/ProjectController.mjs +++ b/services/web/app/src/Features/Project/ProjectController.mjs @@ -259,8 +259,8 @@ const _ProjectController = { res.setTimeout(5 * 60 * 1000) // allow extra time for the copy to complete metrics.inc('cloned-project') const projectId = req.params.Project_id - const { projectName, isDebugCopy, tags } = req.body - logger.debug({ projectId, projectName, isDebugCopy }, 'cloning project') + const { projectName, tags } = req.body + logger.debug({ projectId, projectName }, 'cloning project') if (!SessionManager.isUserLoggedIn(req.session)) { return res.json({ redir: '/register' }) } @@ -271,8 +271,7 @@ const _ProjectController = { currentUser, projectId, projectName, - tags, - isDebugCopy + tags ) ProjectAuditLogHandler.addEntryIfManagedInBackground( projectId, diff --git a/services/web/app/src/Features/Project/ProjectCreationHandler.mjs b/services/web/app/src/Features/Project/ProjectCreationHandler.mjs index 095fe12391..55df89bcc2 100644 --- a/services/web/app/src/Features/Project/ProjectCreationHandler.mjs +++ b/services/web/app/src/Features/Project/ProjectCreationHandler.mjs @@ -196,11 +196,6 @@ async function _createBlankProject( if (historyRangesSupportAssignment.variant === 'enabled') { project.overleaf.history.rangesSupportEnabled = true } - - if (attributes.isDebugCopyOf) { - project.overleaf.isDebugCopyOf = new ObjectId(attributes.isDebugCopyOf) - } - await project.save() if (!skipCreatingInTPDS) { await TpdsUpdateSender.promises.createProject({ diff --git a/services/web/app/src/Features/Project/ProjectDuplicator.mjs b/services/web/app/src/Features/Project/ProjectDuplicator.mjs index fdada472b0..c189db966f 100644 --- a/services/web/app/src/Features/Project/ProjectDuplicator.mjs +++ b/services/web/app/src/Features/Project/ProjectDuplicator.mjs @@ -22,9 +22,6 @@ import TagsHandler from '../Tags/TagsHandler.mjs' import ClsiCacheManager from '../Compile/ClsiCacheManager.mjs' import Modules from '../../infrastructure/Modules.mjs' -const TAG_COLOR_RED = '#f04343' -const DEBUG_TAG_NAME = 'Debug' - export default { duplicate: callbackify(duplicate), promises: { @@ -32,13 +29,7 @@ export default { }, } -async function duplicate( - owner, - originalProjectId, - newProjectName, - tags = [], - isDebugCopy -) { +async function duplicate(owner, originalProjectId, newProjectName, tags = []) { await DocumentUpdaterHandler.promises.flushProjectToMongo(originalProjectId) const originalProject = await ProjectGetter.promises.getProject( originalProjectId, @@ -67,18 +58,6 @@ async function duplicate( originalEntries, }) - const attributes = {} - if (isDebugCopy) { - attributes.isDebugCopyOf = originalProjectId - // - Create new tag on owner._id if it doesn't already exist - const debugTag = await TagsHandler.promises.createTag( - owner._id, - DEBUG_TAG_NAME, - TAG_COLOR_RED, - { truncate: true } - ) - tags.push(debugTag) - } // Pass template ID as analytics segmentation if duplicating project from a template const segmentation = _.pick(originalProject, [ 'fromV1TemplateId', @@ -93,9 +72,6 @@ async function duplicate( originalProject._id ) segmentation['updated-tags'] = tags.length - attributes.segmentation = segmentation - - attributes.segmentation = segmentation // remove any leading or trailing spaces newProjectName = newProjectName.trim() @@ -104,7 +80,7 @@ async function duplicate( const newProject = await ProjectCreationHandler.promises.createBlankProject( owner._id, newProjectName, - attributes + { segmentation } ) let prepareClsiCacheInBackground = Promise.resolve() diff --git a/services/web/app/src/Features/Project/ProjectGetter.mjs b/services/web/app/src/Features/Project/ProjectGetter.mjs index 9e2727a9cf..a44e93645e 100644 --- a/services/web/app/src/Features/Project/ProjectGetter.mjs +++ b/services/web/app/src/Features/Project/ProjectGetter.mjs @@ -132,30 +132,6 @@ const ProjectGetter = { return filteredProjects }, - async existUsersDebugProjectsOlderThan(userId, days) { - const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000) - - const exists = await Project.exists({ - owner_ref: userId, - 'overleaf.isDebugCopyOf': { $type: 'objectId' }, - lastUpdated: { $lt: cutoffDate }, - }) - - return Boolean(exists) - }, - - async findAllDebugProjects(fields) { - return Project.find( - { - 'overleaf.isDebugCopyOf': { $type: 'objectId' }, - }, - fields - ) - .limit(500) - .populate('owner_ref', ['email', 'name']) - .exec() - }, - /** * Return all projects with the given name that belong to the given user. * diff --git a/services/web/app/src/Features/Project/ProjectListController.mjs b/services/web/app/src/Features/Project/ProjectListController.mjs index 8b48a51e8c..d1d04f6cc7 100644 --- a/services/web/app/src/Features/Project/ProjectListController.mjs +++ b/services/web/app/src/Features/Project/ProjectListController.mjs @@ -164,10 +164,9 @@ async function projectListPage(req, res, next) { logger.err({ err, userId }, 'projects listing in background failed') return undefined }) - const user = await User.findById( userId, - `email isAdmin emails features alphaProgram betaProgram lastPrimaryEmailCheck lastActive signUpDate ace refProviders${ + `email emails features alphaProgram betaProgram lastPrimaryEmailCheck lastActive signUpDate ace refProviders${ isSaas ? ' enrollment writefull completedTutorials aiErrorAssistant' : '' }` ) @@ -188,8 +187,6 @@ async function projectListPage(req, res, next) { let role if (isSaas) { - if (user.isAdmin) await _checkForOldDebugProjects(userId) - await SplitTestSessionHandler.promises.sessionMaintenance(req, user) try { @@ -598,20 +595,6 @@ async function getProjectsJson(req, res) { res.json(projectsPage) } -/** - * @param {string} userId - * @private - */ -async function _checkForOldDebugProjects(userId) { - const exists = await ProjectGetter.promises.existUsersDebugProjectsOlderThan( - userId, - 7 - ) - if (exists) { - await NotificationsBuilder.promises.oldDebugProjects(userId).create(userId) - } -} - /** * @param {string} userId * @param {Filters} filters diff --git a/services/web/app/src/Features/ServerAdmin/AdminController.mjs b/services/web/app/src/Features/ServerAdmin/AdminController.mjs index 76bf71143e..c42520570d 100644 --- a/services/web/app/src/Features/ServerAdmin/AdminController.mjs +++ b/services/web/app/src/Features/ServerAdmin/AdminController.mjs @@ -6,10 +6,7 @@ import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs' import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs' import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs' import SystemMessageManager from '../SystemMessages/SystemMessageManager.mjs' -import ProjectGetter from '../Project/ProjectGetter.mjs' import Modules from '../../infrastructure/Modules.mjs' -import Features from '../../infrastructure/Features.mjs' -import { expressify } from '@overleaf/promise-utils' const AdminController = { _sendDisconnectAllUsersMessage: delay => { @@ -19,7 +16,7 @@ const AdminController = { delay ) }, - index: expressify(async (req, res, next) => { + index: (req, res, next) => { let url const openSockets = {} for (url in http.globalAgent.sockets) { @@ -34,30 +31,24 @@ const AdminController = { ) } - const systemMessages = - await SystemMessageManager.promises.getMessagesFromDB() - - const privilegesMatrixResults = await Modules.promises.hooks.fire( - 'getPrivilegesMatrix' + SystemMessageManager.getMessagesFromDB( + async function (error, systemMessages) { + if (error) { + return next(error) + } + const privilegesMatrixResults = await Modules.promises.hooks.fire( + 'getPrivilegesMatrix' + ) + const privilegesMatrix = privilegesMatrixResults[0] || null + res.render('admin/index', { + title: 'System Admin', + openSockets, + systemMessages, + privilegesMatrix, + }) + } ) - - const privilegesMatrix = privilegesMatrixResults[0] || null - - const toRender = { - title: 'System Admin', - openSockets, - systemMessages, - privilegesMatrix, - } - - if (Features.hasFeature('saas')) { - const debugProjects = await ProjectGetter.promises.findAllDebugProjects( - 'name lastUpdated owner_ref' - ) - toRender.debugProjects = debugProjects - } - res.render('admin/index', toRender) - }), + }, disconnectAllUsers: (req, res) => { logger.warn('disconecting everyone') diff --git a/services/web/app/views/admin/index.pug b/services/web/app/views/admin/index.pug index 71d85a7bcb..88199a2474 100644 --- a/services/web/app/views/admin/index.pug +++ b/services/web/app/views/admin/index.pug @@ -19,7 +19,6 @@ block content +bookmarkable-tabset-header('privileges-matrix', 'Privileges Matrix') if hasFeature('saas') +bookmarkable-tabset-header('tpds', 'TPDS/Dropbox Management') - +bookmarkable-tabset-header('debug-projects', 'Debug Projects') .tab-content .tab-pane.active(role='tabpanel' id='system-messages') @@ -134,20 +133,3 @@ block content input.form-control(name='user_id' id='user-id' type='text' required) .form-group button.btn-primary.btn(type='submit') Poll - - .tab-pane(role='tabpanel' id='debug-projects') - if debugProjects.length - table.table.table-striped - thead - tr - th Owner - th Project Name - th Last updated - tbody - each project in debugProjects - tr - td= project.owner_ref.email - td= project.name - td= moment(project.lastUpdated.toUTCString()).format('Do MMM YYYY, h:mm a') + ' UTC' - else - p.text-muted No debug projects found diff --git a/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx b/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx index d4f6a3f368..a8e0ab2800 100644 --- a/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx +++ b/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx @@ -287,12 +287,6 @@ function CommonNotification({ notification }: CommonNotificationProps) { /> } /> - ) : templateKey === 'notification_old_debug_projects' ? ( - id && handleDismiss(id)} - content={html} - /> ) : ( Please note that features in this program are still being tested and actively developed. This means that they might <0>change, be <0>removed or <0>become part of a premium plan", "notification": "Notification", "notification_features_upgraded_by_affiliation": "Good news! Your affiliated organization __institutionName__ has an Overleaf subscription, and you now have access to all of Overleaf’s Professional features.", - "notification_old_debug_projects": "You have some old debug projects that you should delete, if you no longer need them.", "notification_personal_and_group_subscriptions": "We’ve spotted that you’ve got <0>more than one active __appName__ subscription. To avoid paying more than you need to, <1>review your subscriptions.", "notification_personal_subscription_not_required_due_to_affiliation": " Good news! Your affiliated organization __institutionName__ has an Overleaf subscription, and you now have access to Overleaf’s Professional features through your affiliation. You can cancel your individual subscription without losing access to any features.", "notification_project_invite_accepted_message": "You’ve joined __projectName__", diff --git a/services/web/test/unit/src/Project/ProjectGetter.test.mjs b/services/web/test/unit/src/Project/ProjectGetter.test.mjs index 676c4e0dda..d8c27a0c50 100644 --- a/services/web/test/unit/src/Project/ProjectGetter.test.mjs +++ b/services/web/test/unit/src/Project/ProjectGetter.test.mjs @@ -20,13 +20,10 @@ describe('ProjectGetter', function () { ctx.Project = { find: sinon.stub().returns({ exec: sinon.stub().resolves(), - populate: sinon.stub().returnsThis(), - limit: sinon.stub().returnsThis(), }), findOne: sinon.stub().returns({ exec: sinon.stub().resolves(ctx.project), }), - exists: sinon.stub().returns({ exec: sinon.stub().resolves(true) }), } ctx.CollaboratorsGetter = { promises: { @@ -461,39 +458,4 @@ describe('ProjectGetter', function () { expect(docs).to.deep.equal([ctx.deletedProject]) }) }) - - describe('findAllDebugProjects', function () { - it('should find all projects with overleaf.isDebugCopyOf of type objectId', async function (ctx) { - await ctx.ProjectGetter.promises.findAllDebugProjects('fields') - sinon.assert.calledWith(ctx.Project.find, { - 'overleaf.isDebugCopyOf': { $type: 'objectId' }, - }) - sinon.assert.calledWith(ctx.Project.find().populate, 'owner_ref', [ - 'email', - 'name', - ]) - sinon.assert.calledOnce(ctx.Project.find().exec) - }) - }) - - describe('existUsersDebugProjectsOlderThan', function () { - it('should check for existence of debug projects older than given days', async function (ctx) { - const days = 10 - const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000) - - const exists = - await ctx.ProjectGetter.promises.existUsersDebugProjectsOlderThan( - ctx.userId, - days - ) - - sinon.assert.calledWith(ctx.Project.exists, { - owner_ref: ctx.userId, - 'overleaf.isDebugCopyOf': { $type: 'objectId' }, - lastUpdated: { $lt: cutoffDate }, - }) - - expect(exists).to.equal(true) - }) - }) })