/* eslint-disable camelcase, node/handle-callback-err, max-len, no-unused-vars, */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let ProjectFileAgent const AuthorizationManager = require('../Authorization/AuthorizationManager') const ProjectLocator = require('../Project/ProjectLocator') const ProjectGetter = require('../Project/ProjectGetter') const DocstoreManager = require('../Docstore/DocstoreManager') const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') const FileStoreHandler = require('../FileStore/FileStoreHandler') const _ = require('underscore') const Settings = require('@overleaf/settings') const LinkedFilesHandler = require('./LinkedFilesHandler') const { BadDataError, AccessDeniedError, BadEntityTypeError, SourceFileNotFoundError, ProjectNotFoundError, V1ProjectNotFoundError, } = require('./LinkedFilesErrors') module.exports = ProjectFileAgent = { createLinkedFile( project_id, linkedFileData, name, parent_folder_id, user_id, callback ) { if (!this._canCreate(linkedFileData)) { return callback(new AccessDeniedError()) } return this._go( project_id, linkedFileData, name, parent_folder_id, user_id, callback ) }, refreshLinkedFile( project_id, linkedFileData, name, parent_folder_id, user_id, callback ) { return this._go( project_id, linkedFileData, name, parent_folder_id, user_id, callback ) }, _prepare(project_id, linkedFileData, user_id, callback) { if (callback == null) { callback = function () {} } return this._checkAuth( project_id, linkedFileData, user_id, (err, allowed) => { if (err != null) { return callback(err) } if (!allowed) { return callback(new AccessDeniedError()) } if (!this._validate(linkedFileData)) { return callback(new BadDataError()) } return callback(null, linkedFileData) } ) }, _go(project_id, linkedFileData, name, parent_folder_id, user_id, callback) { linkedFileData = this._sanitizeData(linkedFileData) return this._prepare( project_id, linkedFileData, user_id, (err, linkedFileData) => { if (err != null) { return callback(err) } if (!this._validate(linkedFileData)) { return callback(new BadDataError()) } return this._getEntity( linkedFileData, user_id, (err, source_project, entity, type) => { if (err != null) { return callback(err) } if (type === 'doc') { return DocstoreManager.getDoc( source_project._id, entity._id, function (err, lines) { if (err != null) { return callback(err) } return LinkedFilesHandler.importContent( project_id, lines.join('\n'), linkedFileData, name, parent_folder_id, user_id, function (err, file) { if (err != null) { return callback(err) } return callback(null, file._id) } ) } ) // Created } else if (type === 'file') { return FileStoreHandler.getFileStream( source_project._id, entity._id, null, function (err, fileStream) { if (err != null) { return callback(err) } return LinkedFilesHandler.importFromStream( project_id, fileStream, linkedFileData, name, parent_folder_id, user_id, function (err, file) { if (err != null) { return callback(err) } return callback(null, file._id) } ) } ) // Created } else { return callback(new BadEntityTypeError()) } } ) } ) }, _getEntity(linkedFileData, current_user_id, callback) { if (callback == null) { callback = function () {} } callback = _.once(callback) const { source_entity_path } = linkedFileData return this._getSourceProject(linkedFileData, function (err, project) { if (err != null) { return callback(err) } const source_project_id = project._id return DocumentUpdaterHandler.flushProjectToMongo( source_project_id, function (err) { if (err != null) { return callback(err) } return ProjectLocator.findElementByPath( { project_id: source_project_id, path: source_entity_path, exactCaseMatch: true, }, function (err, entity, type) { if (err != null) { if (/^not found.*/.test(err.message)) { err = new SourceFileNotFoundError() } return callback(err) } return callback(null, project, entity, type) } ) } ) }) }, _sanitizeData(data) { return _.pick( data, 'provider', 'source_project_id', 'v1_source_doc_id', 'source_entity_path' ) }, _validate(data) { return ( (data.source_project_id != null || data.v1_source_doc_id != null) && data.source_entity_path != null ) }, _canCreate(data) { // Don't allow creation of linked-files with v1 doc ids return data.v1_source_doc_id == null }, _getSourceProject: LinkedFilesHandler.getSourceProject, _checkAuth(project_id, data, current_user_id, callback) { if (callback == null) { callback = function () {} } callback = _.once(callback) if (!ProjectFileAgent._validate(data)) { return callback(new BadDataError()) } return this._getSourceProject(data, function (err, project) { if (err != null) { return callback(err) } return AuthorizationManager.canUserReadProject( current_user_id, project._id, null, function (err, canRead) { if (err != null) { return callback(err) } return callback(null, canRead) } ) }) }, }