Enable file uploader component
This commit is contained in:
parent
8714ab79f1
commit
f629e6f3bd
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
.idea
|
.idea
|
||||||
.idea/*
|
.idea/*
|
||||||
|
uploads/*
|
||||||
### Node ###
|
### Node ###
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
@ -95,4 +95,4 @@ www/**
|
|||||||
|
|
||||||
### VScode stuff ###
|
### VScode stuff ###
|
||||||
.vscode*
|
.vscode*
|
||||||
.vscode/**
|
.vscode/**
|
||||||
|
137
app/controllers/api/v1/File.controller.js
Normal file
137
app/controllers/api/v1/File.controller.js
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
const Controller = require('libflitter/controller/Controller')
|
||||||
|
const Page = require('../../../models/api/Page.model')
|
||||||
|
const Node = require('../../../models/api/Node.model')
|
||||||
|
const FileGroup = require('../../../models/api/FileGroup.model')
|
||||||
|
const { ObjectId } = require('mongodb')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File Controller
|
||||||
|
* -------------------------------------------------------------
|
||||||
|
* Put some description here!
|
||||||
|
*/
|
||||||
|
class File extends Controller {
|
||||||
|
static get services() {
|
||||||
|
return [...super.services, 'models']
|
||||||
|
}
|
||||||
|
|
||||||
|
async create_config(req, res) {
|
||||||
|
const PageId = req.params.PageId
|
||||||
|
|
||||||
|
let page = await Page.findOne({UUID: PageId})
|
||||||
|
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
|
||||||
|
if ( !page.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
const NodeId = req.params.NodeId
|
||||||
|
|
||||||
|
let node = await Node.findOne({UUID: NodeId})
|
||||||
|
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
|
||||||
|
|
||||||
|
const group = new FileGroup({
|
||||||
|
NodeId: node.UUID,
|
||||||
|
PageId: page.UUID,
|
||||||
|
FileIds: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
await group.save()
|
||||||
|
req.user.allow(`files:${group.UUID}`)
|
||||||
|
await req.user.save()
|
||||||
|
|
||||||
|
return res.api(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_config(req, res) {
|
||||||
|
const PageId = req.params.PageId
|
||||||
|
|
||||||
|
let page = await Page.findOne({UUID: PageId})
|
||||||
|
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
|
||||||
|
if ( !page.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
const NodeId = req.params.NodeId
|
||||||
|
|
||||||
|
let node = await Node.findOne({UUID: NodeId})
|
||||||
|
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
|
||||||
|
|
||||||
|
const group = await FileGroup.findOne({UUID: req.params.FilesId})
|
||||||
|
if ( !group ) return res.status(404).message('Invalid file group.').api({})
|
||||||
|
if ( !group.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
const File = this.models.get('upload::File')
|
||||||
|
const files = await File.find({_id: {$in: group.FileIds.map(x => ObjectId(x))}})
|
||||||
|
group.files = files
|
||||||
|
|
||||||
|
return res.api(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
async save_upload(req, res) {
|
||||||
|
const PageId = req.params.PageId
|
||||||
|
|
||||||
|
let page = await Page.findOne({UUID: PageId})
|
||||||
|
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
|
||||||
|
if ( !page.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
const NodeId = req.params.NodeId
|
||||||
|
|
||||||
|
let node = await Node.findOne({UUID: NodeId})
|
||||||
|
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
|
||||||
|
|
||||||
|
const group = await FileGroup.findOne({UUID: req.params.FilesId})
|
||||||
|
if ( !group ) return res.status(404).message('Invalid file group.').api({})
|
||||||
|
if ( !group.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
if ( req.uploads.uploaded_file ) {
|
||||||
|
group.FileIds.push(req.uploads.uploaded_file.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
await group.save()
|
||||||
|
return res.redirect('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
async download(req, res) {
|
||||||
|
const PageId = req.params.PageId
|
||||||
|
|
||||||
|
let page = await Page.findOne({UUID: PageId})
|
||||||
|
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
|
||||||
|
if ( !page.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
const NodeId = req.params.NodeId
|
||||||
|
|
||||||
|
let node = await Node.findOne({UUID: NodeId})
|
||||||
|
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
|
||||||
|
|
||||||
|
const group = await FileGroup.findOne({UUID: req.params.FilesId})
|
||||||
|
if ( !group ) return res.status(404).message('Invalid file group.').api({})
|
||||||
|
if ( !group.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
if ( !group.FileIds.includes(req.params.FileId) ) {
|
||||||
|
return req.security.deny()
|
||||||
|
}
|
||||||
|
|
||||||
|
const File = this.models.get('upload::File')
|
||||||
|
const file = await File.findOne({_id: ObjectId(req.params.FileId)})
|
||||||
|
if ( !file ) return res.status(404).api({})
|
||||||
|
|
||||||
|
return file.send(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete_group(req, res) {
|
||||||
|
const PageId = req.params.PageId
|
||||||
|
|
||||||
|
let page = await Page.findOne({UUID: PageId})
|
||||||
|
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
|
||||||
|
if ( !page.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
const NodeId = req.params.NodeId
|
||||||
|
|
||||||
|
let node = await Node.findOne({UUID: NodeId})
|
||||||
|
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
|
||||||
|
|
||||||
|
const group = await FileGroup.findOne({UUID: req.params.FilesId})
|
||||||
|
if ( !group ) return res.status(404).message('Invalid file group.').api({})
|
||||||
|
if ( !group.accessible_by(req.user) ) return req.security.deny()
|
||||||
|
|
||||||
|
await group.delete()
|
||||||
|
return res.api({})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = File
|
27
app/models/api/FileGroup.model.js
Normal file
27
app/models/api/FileGroup.model.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const Model = require('flitter-orm/src/model/Model')
|
||||||
|
const uuid = require('uuid/v4')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FileGroup Model
|
||||||
|
* -------------------------------------------------------------
|
||||||
|
* Put some description here!
|
||||||
|
*/
|
||||||
|
class FileGroup extends Model {
|
||||||
|
static get schema() {
|
||||||
|
// Return a flitter-orm schema here.
|
||||||
|
return {
|
||||||
|
NodeId: String,
|
||||||
|
PageId: String,
|
||||||
|
FileIds: [String],
|
||||||
|
UUID: {type: String, default: () => uuid()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accessible_by(user, mode = 'view') {
|
||||||
|
return user.can(`files:${this.UUID}:${mode}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static and instance methods can go here
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = FileGroup
|
12
app/routing/middleware/upload/UploadFile.middleware.js
Normal file
12
app/routing/middleware/upload/UploadFile.middleware.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const Middleware = require('flitter-upload/middleware/UploadFile')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Middleware to upload the files included in the request
|
||||||
|
* to the default file store backend. Stores instances of
|
||||||
|
* the "upload::File" model in "request.uploads".
|
||||||
|
*/
|
||||||
|
class UploadFile extends Middleware {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = UploadFile
|
@ -36,6 +36,9 @@ const index = {
|
|||||||
* or middleware that are applied in order.
|
* or middleware that are applied in order.
|
||||||
*/
|
*/
|
||||||
get: {
|
get: {
|
||||||
|
'/files/:PageId/:NodeId/get/:FilesId': ['controller::api:v1:File.get_config'],
|
||||||
|
'/files/:PageId/:NodeId/get/:FilesId/:FileId': ['controller::api:v1:File.download'],
|
||||||
|
|
||||||
'/hello_world': ['controller::api:v1:Misc.hello_world'],
|
'/hello_world': ['controller::api:v1:Misc.hello_world'],
|
||||||
'/page/:PageId': ['controller::api:v1:Page.get_page'],
|
'/page/:PageId': ['controller::api:v1:Page.get_page'],
|
||||||
'/page/:PageId/nodes': ['controller::api:v1:Page.get_nodes'],
|
'/page/:PageId/nodes': ['controller::api:v1:Page.get_nodes'],
|
||||||
@ -49,6 +52,11 @@ const index = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
post: {
|
post: {
|
||||||
|
'/file/upload/:PageId/:NodeId/:FilesId': ['middleware::upload:UploadFile', 'controller::api:v1:File.save_upload'],
|
||||||
|
'/files/:PageId/:NodeId/create': ['controller::api:v1:File.create_config'],
|
||||||
|
'/files/:PageId/:NodeId/delete/:FilesId': ['controller::api:v1:File.delete_group'],
|
||||||
|
|
||||||
|
|
||||||
'/page/:PageId/save': ['controller::api:v1:Page.save_page'],
|
'/page/:PageId/save': ['controller::api:v1:Page.save_page'],
|
||||||
'/page/:PageId/nodes/save': ['controller::api:v1:Page.save_nodes'],
|
'/page/:PageId/nodes/save': ['controller::api:v1:Page.save_nodes'],
|
||||||
'/page/create': ['controller::api:v1:Page.create_top_level'],
|
'/page/create': ['controller::api:v1:Page.create_top_level'],
|
||||||
|
@ -34,6 +34,7 @@ const server_config = {
|
|||||||
|
|
||||||
uploads: {
|
uploads: {
|
||||||
|
|
||||||
|
enable: true,
|
||||||
/*
|
/*
|
||||||
* Used by flitter-upload. Path for uploaded files.
|
* Used by flitter-upload. Path for uploaded files.
|
||||||
* Should be relative to the application root.
|
* Should be relative to the application root.
|
||||||
@ -58,4 +59,4 @@ const server_config = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = server_config
|
module.exports = server_config
|
||||||
|
36
config/upload.config.js
Normal file
36
config/upload.config.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* flitter-upload configuration
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
* Specifies the configuration for various uploader aspects. Mainly,
|
||||||
|
* contains the configuration for the different file upload backends.
|
||||||
|
*/
|
||||||
|
const upload_config = {
|
||||||
|
/*
|
||||||
|
* The name of the upload backend to use by default.
|
||||||
|
*/
|
||||||
|
default_store: 'flitter',
|
||||||
|
enabled: true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stores available to the uploader.
|
||||||
|
*/
|
||||||
|
stores: {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example of the basic, filesystem-backed uploader.
|
||||||
|
* The name of the store is arbitrary. Here, it's called 'flitter'.
|
||||||
|
*/
|
||||||
|
flitter: {
|
||||||
|
enabled: true,
|
||||||
|
|
||||||
|
// This is a filesystem backed 'FlitterStore'
|
||||||
|
type: 'FlitterStore',
|
||||||
|
|
||||||
|
// Destination for uploaded files. Will be relative to the root
|
||||||
|
// path of the application.
|
||||||
|
destination: './uploads',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = upload_config
|
Loading…
Reference in New Issue
Block a user