mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-13 21:53:43 +01:00
[web] Add another partial fix for fix_malformed_filetree: use _id instead of path to locate data (#24101)
* Fix `fix_malformed_filetree`'s `fixName` * Fix findUniqueName with missing names in siblings * Add test showcasing another bug: shifted arrays in filetree folder * Update `removeNulls` to use `_id` * Update services/web/app/src/Features/Project/ProjectLocator.js Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com> * Add FIXME about file names uniqueness * Rename `obj` to `project` --------- Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com> GitOrigin-RevId: 3ed795ae0621800603395f7b50626ac89c39199d
This commit is contained in:
committed by
Copybot
co-authored by
Jakob Ackermann
parent
359b41ef57
commit
4d265f862b
@@ -8,7 +8,9 @@
|
||||
*/
|
||||
import mongodb from 'mongodb-legacy'
|
||||
import { db } from '../app/src/infrastructure/mongodb.js'
|
||||
import ProjectLocator from '../app/src/Features/Project/ProjectLocator.js'
|
||||
import ProjectLocator, {
|
||||
findDeep,
|
||||
} from '../app/src/Features/Project/ProjectLocator.js'
|
||||
import minimist from 'minimist'
|
||||
import readline from 'node:readline'
|
||||
import fs from 'node:fs'
|
||||
@@ -72,7 +74,7 @@ async function processBadPath(projectId, mongoPath, _id) {
|
||||
if (isRootFolder(mongoPath)) {
|
||||
modifiedCount = await fixRootFolder(projectId)
|
||||
} else if (isArrayElement(mongoPath)) {
|
||||
modifiedCount = await removeNulls(projectId, parentPath(mongoPath))
|
||||
modifiedCount = await removeNulls(projectId, _id)
|
||||
} else if (isArray(mongoPath)) {
|
||||
modifiedCount = await fixArray(projectId, mongoPath)
|
||||
} else if (isFolderId(mongoPath)) {
|
||||
@@ -83,7 +85,7 @@ async function processBadPath(projectId, mongoPath, _id) {
|
||||
parentPath(parentPath(mongoPath))
|
||||
)
|
||||
} else if (isName(mongoPath)) {
|
||||
modifiedCount = await fixName(projectId, mongoPath)
|
||||
modifiedCount = await fixName(projectId, _id)
|
||||
} else if (isHash(mongoPath)) {
|
||||
console.error(`Missing file hash: ${projectId}/${_id} (${mongoPath})`)
|
||||
console.error('SaaS: likely needs filestore restore')
|
||||
@@ -164,10 +166,26 @@ async function fixRootFolder(projectId) {
|
||||
/**
|
||||
* Remove all nulls from the given docs/files/folders array
|
||||
*/
|
||||
async function removeNulls(projectId, path) {
|
||||
async function removeNulls(projectId, _id) {
|
||||
if (!_id) {
|
||||
throw new Error('missing _id')
|
||||
}
|
||||
const project = await db.projects.findOne(
|
||||
{ _id: new ObjectId(projectId) },
|
||||
{ projection: { rootFolder: 1 } }
|
||||
)
|
||||
const foundResult = findDeep(project, obj => obj?._id?.toString() === _id)
|
||||
if (!foundResult) return
|
||||
const { path } = foundResult
|
||||
const result = await db.projects.updateOne(
|
||||
{ _id: new ObjectId(projectId), [path]: { $type: 'array' } },
|
||||
{ $pull: { [path]: null } }
|
||||
{ _id: new ObjectId(projectId) },
|
||||
{
|
||||
$pull: {
|
||||
[`${path}.folders`]: null,
|
||||
[`${path}.docs`]: null,
|
||||
[`${path}.fileRefs`]: null,
|
||||
},
|
||||
}
|
||||
)
|
||||
return result.modifiedCount
|
||||
}
|
||||
@@ -208,19 +226,26 @@ async function removeElementsWithoutIds(projectId, path) {
|
||||
/**
|
||||
* Give a name to a file/doc/folder that doesn't have one
|
||||
*/
|
||||
async function fixName(projectId, path) {
|
||||
async function fixName(projectId, _id) {
|
||||
if (!_id) {
|
||||
throw new Error('missing _id')
|
||||
}
|
||||
const project = await db.projects.findOne(
|
||||
{ _id: new ObjectId(projectId) },
|
||||
{ projection: { rootFolder: 1 } }
|
||||
)
|
||||
const arrayPath = parentPath(parentPath(path))
|
||||
const array = ProjectLocator.findElementByMongoPath(project, arrayPath)
|
||||
const existingNames = new Set(array.map(x => x.name))
|
||||
const foundResult = findDeep(project, obj => obj?._id?.toString() === _id)
|
||||
if (!foundResult) return
|
||||
const { path } = foundResult
|
||||
const array = ProjectLocator.findElementByMongoPath(project, parentPath(path))
|
||||
const name =
|
||||
path === 'rootFolder.0.name' ? 'rootFolder' : findUniqueName(existingNames)
|
||||
path === 'rootFolder.0'
|
||||
? 'rootFolder'
|
||||
: findUniqueName(new Set(array.map(x => x?.name)))
|
||||
const pathToName = `${path}.name`
|
||||
const result = await db.projects.updateOne(
|
||||
{ _id: new ObjectId(projectId), [path]: { $in: [null, ''] } },
|
||||
{ $set: { [path]: name } }
|
||||
{ _id: new ObjectId(projectId), [pathToName]: { $in: [null, ''] } },
|
||||
{ $set: { [pathToName]: name } }
|
||||
)
|
||||
return result.modifiedCount
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user