diff --git a/app/controllers/api/v1/Page.controller.js b/app/controllers/api/v1/Page.controller.js index 1297393..b4de4d2 100644 --- a/app/controllers/api/v1/Page.controller.js +++ b/app/controllers/api/v1/Page.controller.js @@ -12,6 +12,38 @@ class Page extends Controller { return [...super.services, 'models'] } + async revert_version(req, res, next) { + const PageId = req.params.PageId + const user = req.user + + let page = await PageModel.findOne({UUID: PageId}) + if ( !page ) return res.status(404).message('Page not found with that ID.').api({}) + + if ( !(await page.is_accessible_by(user)) ) return req.security.deny() + const level = await page.access_level_for(req.user) + + if ( !req.body.version_num ) { + return res.status(400) + .message('Missing required field: version_num') + .api() + } + + if ( !page.has_version(req.body.version_num) ) { + return res.status(400) + .message('Invalid version_num') + .api() + } + + const reverted_page = await page.revert_to_version(req.body.version_num, req.user.id) + await reverted_page.save() + + const data = reverted_page.toJSON() + delete data.version_archive + data.level = level + data._id = reverted_page.id + return res.api(data) + } + async get_page_versions(req, res, next) { const User = this.models.get('auth:User') const PageId = req.params.PageId diff --git a/app/models/VersionedModel.js b/app/models/VersionedModel.js index 911773a..7509942 100644 --- a/app/models/VersionedModel.js +++ b/app/models/VersionedModel.js @@ -98,11 +98,23 @@ class VersionedModel extends Model { async as_version(version_num = undefined) { const data = await this.get_version_data(version_num) - console.log('as version data', data, version_num) const inst = new this.constructor(data) inst.__initialize_version(this, data) return inst } + + async revert_to_version(version_num, user_id = undefined) { + const inst = await this.as_version(version_num) + inst.version_archive = this.version_archive + inst._id = this._id + inst.__is_version_instantation = false + inst.__version_base = undefined + inst.__version_data = undefined + inst.version_num = this.version_num + await inst.new_version(`Revert to version ${version_num}`, user_id) + await inst.save() + return inst + } } module.exports = exports = VersionedModel diff --git a/app/models/api/Node.model.js b/app/models/api/Node.model.js index fb6a01e..fd1b305 100644 --- a/app/models/api/Node.model.js +++ b/app/models/api/Node.model.js @@ -85,6 +85,36 @@ class Node extends VersionedModel { return data } + + async revert_to_version(version_num, user_id = undefined) { + const reverted = await super.revert_to_version(version_num, user_id) + const data = await this.get_version_data(version_num) + + if ( !data.associated_type_version_num ) return reverted + + // If supported, revert the version of the node item + if ( this.Type === 'code_ref' && this.Value?.Value ) { + const Codium = this.models.get('api:Codium') + const code = await Codium.findOne({ UUID: this.Value?.Value, Active: true }) + if ( code ) { + await code.revert_to_version(data.associated_type_version_num) + } + } else if ( this.Type === 'file_ref' && this.Value?.Value ) { + const FileGroup = this.models.get('api:FileGroup') + const group = await FileGroup.findOne({ UUID: this.Value?.Value }) + if ( group ) { + await group.revert_to_version(data.associated_type_version_num) + } + } else if ( this.Type === 'database_ref' && this.Value?.Value ) { + const Database = this.models.get('api:db:Database') + const db = await Database.findOne({ Active: true, UUID: this.Value?.Value }) + if ( db ) { + await db.revert_to_version(data.associated_type_version_num) + } + } + + return reverted + } } module.exports = exports = Node; diff --git a/app/models/api/Page.model.js b/app/models/api/Page.model.js index 521d5e3..585d3ba 100644 --- a/app/models/api/Page.model.js +++ b/app/models/api/Page.model.js @@ -308,6 +308,24 @@ class Page extends VersionedModel { data.node_version_nums = node_version_nums return data } + + async revert_to_version(version_num, user_id = undefined) { + const Node = this.models.get('api:Node') + const reverted = await super.revert_to_version(version_num, user_id) + const data = await this.get_version_data(version_num) + + // Revert the nodes to the given versions + for ( const node_data of data.node_version_nums ) { + const node = await Node.findOne({ UUID: node_data.NodeId }) + if ( node ) { + const reverted_node = await node.revert_to_version(node_data.version_num) + await reverted_node.save() + } + } + + await reverted.save() + return reverted + } } module.exports = exports = Page; diff --git a/app/routing/routers/api/v1.routes.js b/app/routing/routers/api/v1.routes.js index bbc1f12..6545333 100644 --- a/app/routing/routers/api/v1.routes.js +++ b/app/routing/routers/api/v1.routes.js @@ -67,6 +67,9 @@ const index = { // Save the data for the specified page '/page/:PageId/save': ['controller::api:v1:Page.save_page'], + // Revert the page to a previous version + '/page/:PageId/versions/revert': ['controller::api:v1:Page.revert_version'], + // Save the node data for the specified page '/page/:PageId/nodes/save': ['controller::api:v1:Page.save_nodes'],