414 lines
18 KiB
JavaScript
Executable File
414 lines
18 KiB
JavaScript
Executable File
const express = require( 'express' );
|
||
const fs = require( 'fs-extra' );
|
||
const path = require( 'path' );
|
||
const glob = require('glob');
|
||
const conf = require(`${process.env.dirtown}/conf.json`);
|
||
|
||
// Classes
|
||
const Tribes = require( '../models/Tribes.js' );
|
||
// Middlewares
|
||
const checkHeaders = require( '../middlewares/checkHeaders' );
|
||
const isAuthenticated = require( '../middlewares/isAuthenticated' );
|
||
const router = express.Router();
|
||
|
||
/**
|
||
* @api {get} /tribes/www/:tribeId - tribe list
|
||
* @apiName getlisttrib
|
||
* @apiDescription Get list of www object (space web)
|
||
* @apiGroup Tribes
|
||
*
|
||
* @apiParam {String} tribeId it identify an existing tribe*
|
||
* @apiSuccess (object) listwww contains folder name in www for tribeId
|
||
* @apiSuccessExample {json} listwww
|
||
* HTTP/1.1 200 OK
|
||
* {status:200,ref:"Tribes",msg:"listwww",data:{listwww}}
|
||
*/
|
||
router.get('www', checkHeaders,isAuthenticated,(req,res)=>{
|
||
let listwww=[]
|
||
glob.sync(`${conf.dirtown}/tribes/${req.params.tribeId}/www/*`).forEach(d=>{
|
||
listwww.push(d.split("/").pop())
|
||
})
|
||
res.status(200).json({status:200,ref:"Tribes",msg:"listwww",data:{listwww}})
|
||
})
|
||
|
||
//router.post('www/') to create a webspace
|
||
|
||
//router.put('www/:app') to update
|
||
|
||
//router.delete('www/:tribeId/:app)
|
||
|
||
router.post('/actionanonyme',checkHeaders,(req,res)=>{
|
||
if (!fs.existsSync(`${conf.dirtown}/tribes/${req.session.header.xtribe}/actions/${req.body.action}.js`)){
|
||
res.status(403).send({status:403,msg:"actionmissing",ref:"Tribes", data:{action:req.body.action,tribe:req.session.header.xtribe}})
|
||
}
|
||
const action = require(`${conf.dirtown}/tribes/${req.session.header.xtribe}/actions/${req.body.action}.js`)
|
||
const resaction= action.run(req.body,req.session.header);
|
||
res.status(resaction.status).send(resaction);
|
||
})
|
||
|
||
router.post('/action',checkHeaders,isAuthenticated,(req,res)=>{
|
||
|
||
})
|
||
|
||
|
||
router.get( '/clientconf/:tribeid', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
/*
|
||
get a clientconf.json for a tribeid depending of user accessright
|
||
if tribeid == all and user is admin of apxtrib => get /tmp/clientconfglob.json
|
||
req.session.header.accessrights, req.session.header.apixpaganid
|
||
*/
|
||
console.log( `Tribes/clientconf for tribeid:${req.params.tribeid}` )
|
||
if( req.params.tribeid == "all" && req.session.header.accessrights.data.apxtrib && req.session.header.accessrights.data.apxtrib.tribeid && req.session.header.accessrights.data.apxtrib.tribeid.includes( 'R' ) ) {
|
||
res.status( 200 )
|
||
.send( { moreinfo: fs.readJsonSync( `${config.tmp}/clientconfglob.json`, 'utf-8' ) } );
|
||
return;
|
||
}
|
||
if( req.session.header.accessrights.data[ req.params.tribeid ] &&
|
||
req.session.header.accessrights.data[ req.params.tribeid ].tribeid &&
|
||
req.session.header.accessrights.data[ req.params.tribeid ].tribeid.includes( 'R' ) &&
|
||
fs.existsSync( `${config.tribes}/${req.params.tribeid}/clientconf.json` ) ) {
|
||
// const conftribeid = { moreinfo: {} }
|
||
// conftribeid.moreinfo[ req.params.tribeid ] = fs.readJsonSync( `${config.tribes}/${req.params.tribeid}/clientconf.json`, 'utf-8' );
|
||
res.status( 200 )
|
||
.send( { moreinfo: [ fs.readJsonSync( `${config.tribes}/${req.params.tribeid}/clientconf.json`, 'utf-8' ) ] } );
|
||
return;
|
||
}
|
||
// if not authorized or dos not exist return empty
|
||
// no specific message is send for security reason (check only log)
|
||
res.status( 403 )
|
||
.send( { info: [ 'forbidenAccess' ], models: 'Tribes' } )
|
||
.end();
|
||
} )
|
||
router.put( '/', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
console.log( 'Create a new tribeid, with a useradmin' )
|
||
console.log( ' send data = clientconf.json with all parameter.' )
|
||
// !!!!! check for security any ; \n or so because data can be used into shell
|
||
const add = Tribes.create( req.body );
|
||
res.status( add.status )
|
||
.send( add.payload )
|
||
} )
|
||
router.delete( '/archivetribeid/:tribeid', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
console.log( "request archive tribeid" )
|
||
const archive = Tribes.archive( req.params.tribeid );
|
||
res.status( archive.status )
|
||
.send( archive.payload )
|
||
} );
|
||
router.post( '/spaceweb', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
// !!!!! check for security any ; \n or so because data can be used into shell
|
||
console.log( 'Create a new webapp for xworkon ' )
|
||
req.body.tribeid = req.session.header.xworkon;
|
||
const add = Tribes.addspaceweb( req.body )
|
||
res.status( add.status )
|
||
.send( add.payload )
|
||
} )
|
||
router.get( '/spaceweb/components/:tribeid/:website/:key', checkHeaders, ( req, res ) => {
|
||
// check if key is valid before continue
|
||
// exemple: get Tribes/spaceweb/components/ndda/mesa/123?rep=appmesatable/appsimpletable.mustache
|
||
const file = `${config.tribes}/${req.params.tribeid}/spacedev/${req.params.website}/src/ctatic/components/${req.query.path}`
|
||
console.log( `Request components file from ${file}` )
|
||
if( fs.existsSync( file ) ) {
|
||
res.sendFile( file );
|
||
} else {
|
||
res.send( `console.error("Missing components file in ${req.params.tribeid}/spacedev/${req.params.website}/src/ctatic/components/${req.query.path}");` );
|
||
}
|
||
} )
|
||
router.get( '/plugins/:tribeid/:pluginname/:key/:filename', ( req, res ) => {
|
||
// No accessright possible cause it is load on the fly
|
||
// @todo Check key to authorize access to the plugin (key comme from user ACCESSRIGHTS[tribeid plugin owner:pluginname]).key
|
||
// return a file into /:tribeid owner of plugin/plugins/:pluginname/components/:filename
|
||
// if not exist or invalid key then return console.error
|
||
const file = `${config.tribes}/${req.params.tribeid}/plugins/${req.params.pluginname}/components/${req.params.filename}`
|
||
console.log( 'Tribes/plugins/ ', file )
|
||
if( fs.existsSync( file ) ) {
|
||
res.sendFile( file );
|
||
} else {
|
||
res.send( `console.error("Missing plugin file in ${req.params.tribeid}/plugins/${req.params.pluginname}/components/${req.params.filename}");` );
|
||
}
|
||
} );
|
||
|
||
router.get( '/dirls', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
// url /Tribes/dirls?rep=referentials/dataManagement
|
||
// request information about a req.query.rep from header xworkon/
|
||
// return
|
||
// {file:[{}],dir:[{}]}
|
||
// @todo check if isAuthorized and exist
|
||
|
||
console.log( 'request dirls', `${config.tribes}/${req.session.header.xworkon}/${req.query.rep}` );
|
||
if( !fs.existsSync( `${config.tribes}/${req.session.header.xworkon}/${req.query.rep}` ) ) {
|
||
res.status( 404 )
|
||
.send( { 'info': [ 'dirnotexist' ], model: 'Tribes' } );
|
||
}
|
||
const info = Tribes.dirls( req.session.header.xworkon, req.query.rep );
|
||
console.log( info )
|
||
res.status( info.status )
|
||
.send( info.payload );
|
||
} )
|
||
router.delete( '/ls', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
// check Accessright with D or O on each
|
||
// url /Tribes/ls
|
||
// req.body.files=[listfiles file to delete ]
|
||
const authfiles = Tribes.checkaccessfiles( req.body, 'D', req.session.header.accessrights, req.session.header.apixpaganid );
|
||
authfiles.ok.forEach( f => { fs.remove( `${config.tribes}/${f}` ); } )
|
||
res.status( 200 )
|
||
.send( { 'info': [ 'fileauthdeleted' ], models: 'Tribes', moreinfo: authfiles } )
|
||
} );
|
||
router.put( '/sendjson', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
//req.body = {object:spacedev, path:website/src/data/tpldataname_lg.json, data:{...}}
|
||
//console.log( req.body )
|
||
const dest = `${config.tribes}/${req.session.header.xworkon}/${req.body.object}/${req.body.path}`;
|
||
console.log( `Send json to saved to ${dest}` );
|
||
if( !( req.body.object && fs.existsSync( `${config.tribes}/${req.session.header.xworkon}/${req.body.object}` ) ) ) {
|
||
res.status( '404' )
|
||
.send( { info: [ 'objectmissiong' ], models: 'Tribes', moreinfo: `object: ${req.body.object} does not exist req.body must {object, data, path} into data ${req.session.header.xworkon}/${req.body.object}` } )
|
||
} else {
|
||
if( fs.existsSync( `${config.tribes}/${req.session.header.xworkon}/${req.body.object}/${req.body.path}` ) ) {
|
||
// exist so can be update check accessright update on this
|
||
//A REVOIR hasAccessrighton( req.body.object, "U" );
|
||
} else {
|
||
// AREVOIRhasAccessrighton( req.body.object, "C" );
|
||
}
|
||
fs.outputJsonSync( dest, req.body.data );
|
||
res.status( 200 )
|
||
.send( { info: [ 'filesaved' ], models: 'Tribes' } )
|
||
}
|
||
} );
|
||
router.post( '/downloadls', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
// midlleware hasAccessrighton.js is not apply here only to access/update/create information inside an object
|
||
// to get file a user need accessrights to data: object: R or to Own it
|
||
// or if exist a .info.json into folder get shared as R in uuid
|
||
|
||
//req.body contain list of path file or folder if only 1 file then download it, otherwise zip list and send zip file
|
||
|
||
const authfiles = Tribes.checkaccessfiles( req.body.files, 'R', req.session.header.accessrights, req.session.header.xpaganid );
|
||
if( authfiles.ok.length == 1 ) {
|
||
// bidouille en attendnat de faire un .zip binaire propre
|
||
if( !authfiles.ok[ 0 ].includes( '.xml' ) ) {
|
||
res.status( 200 )
|
||
.download( `${config.tribes}/${authfiles.ok[0]}`, authfiles.ok[ 0 ] );
|
||
} else {
|
||
fs.copySync( `${config.tribes}/${authfiles.ok[0]}`, `${config.tribes}/${config.mayorId}/www/app/webapp/static/tmp/${authfiles.ok[ 0 ]}` )
|
||
}
|
||
} else if( authfiles.ok.length > 1 ) {
|
||
// on zip et on envoie
|
||
//res.status( 200 )
|
||
// .download( `${config.tribes}/${authfiles.ok[0]}`, authfiles.ok[ 0 ])
|
||
res.status( 200 )
|
||
.attachment( `${config.tribes}/${authfiles.ok[0]}` );
|
||
|
||
} else {
|
||
req.body.filepon
|
||
res.status( 403 )
|
||
.send( 'Forbidden access' )
|
||
}
|
||
} );
|
||
router.post( '/upfilepond', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
console.log( 'post /Tribes/uploadfilepond' );
|
||
// Store file and return a unique id to save button
|
||
// that provide folder where to store it
|
||
const formidable = require( 'formidable' );
|
||
const form = formidable( { multiples: false } );
|
||
form.parse( req, ( err, fields, files ) => {
|
||
if( err ) { next( err ); return; }
|
||
//console.log( 'fields',fields);
|
||
// fileMetadaObject send
|
||
let context = JSON.parse( fields.filepond );
|
||
let idfile = files.filepond.path;
|
||
let name = files.filepond.name;
|
||
let subfolder = context.subfolder;
|
||
name = name.replace( /[ ,'"’]/g, "_" );
|
||
//console.log( 'files.filepond:', files.filepond );
|
||
console.log( idfile, `${config.tribes}/${req.session.header.xworkon}/www/${subfolder}/${name}` )
|
||
// On le supprime s'il existe deja
|
||
fs.removeSync( `${config.tribes}/${req.session.header.xworkon}/www/${subfolder}/${name}` );
|
||
// mv tmp
|
||
fs.moveSync( idfile, `${config.tribes}/${req.session.header.xworkon}/www/${subfolder}/${name}` );
|
||
//res.status(200).send({models:"Tribes",info:["Savedsuccess"],moreinfo:{id:file.filepond.path}})
|
||
//return for filepond
|
||
res.writeHead( 200, { 'Content-Type': 'text/plain' } );
|
||
res.end( idfile );
|
||
} )
|
||
} );
|
||
router.delete( '/file', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
//src = objectfolder with accessright/...
|
||
//hasAccessrighton( "www", "D" ),
|
||
if( !req.query.src ) {
|
||
res.status( 404 )
|
||
.send( { info: [ 'deleteerror' ], models: "Tribes", moreinfo: "your del req need a src" } )
|
||
return;
|
||
};
|
||
// A REVOIR hasAccessrighton( req.query.src.split( '/' )[ 0 ], "D" );
|
||
console.log( 'Remove file', `${config.tribes}/${req.session.header.xworkon}/${req.query.src}` )
|
||
console.log( req.body )
|
||
fs.removeSync( `${config.tribes}/${req.session.header.xworkon}/${req.query.src}` );
|
||
res.status( 200 )
|
||
.send( { info: [ 'Successfullremove' ], models: "Tribes" } )
|
||
} );
|
||
router.post( '/uploadfile', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
console.log( 'upload a file ' )
|
||
/* Authentification is needed to get a TOKEN
|
||
curl -X POST -H "xtribe: apxtrib" -H "xworkon: pvmsaveurs" -H "xlang: fr" -H "xpaganid: 1" -H "xauth: 1" -H "xapp: pvmsaveurs:pvmsaveurs" -H "Content-Type: application/json" -d '{"LOGIN":"adminapxtrib","PASSWORD":"Trze3aze!"}' http://pvmsaveurs.pvmsaveurs.fr/app/users/login
|
||
if exist replace xpaganidTOKEN with payload.TOKEN value
|
||
|
||
curl -H "xtribe: pvmsaveurs" -H "xworkon: pvmsaveurs" -H "xlang: fr" -H "xpaganid: adminapxtrib" -H "xauth: xpressuuisToken" -H "xapp: pvmsaveurs:pvmsaveurs" -F 'data=@filename.xx' http://pvmsaveurs.pvmsaveurs.fr/app/Tribes/uploadfile
|
||
*/
|
||
const formidable = require( 'formidable' );
|
||
const form = formidable( { multiples: false } );
|
||
form.parse( req, function ( err, fields, files ) {
|
||
//console.log( files.data )
|
||
var oldPath = files.data.path;
|
||
var newPath = `${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[files.data.name].dest}`;
|
||
console.log( 'oldPath', oldPath )
|
||
console.log( 'newPath', newPath )
|
||
var rawData = fs.readFileSync( oldPath )
|
||
fs.outputFile( newPath, rawData, function ( err ) {
|
||
if( err ) {
|
||
console.log( err );
|
||
return res.status( 405 )
|
||
.send( { info: [ 'savederror' ], models: "Tribes", moreinfo: "your file was not able to be saved into the server" } )
|
||
} else {
|
||
return res.status( 200 )
|
||
.send( {
|
||
info: [ "successfullsent" ],
|
||
models: "Tribes"
|
||
} );
|
||
}
|
||
} )
|
||
} );
|
||
} );
|
||
router.post( '/uploadzip', checkHeaders, ( req, res ) => {
|
||
console.log( 'uploadzip a file ' )
|
||
|
||
/* no authentification to upload a zip filename into /tribes/${xworkon}/${clientconf.uploadzip[filename].dest}
|
||
unzip it using the password ${clientconf.uploadzip[filename].psw
|
||
if no error then run the callback ${clientconf.uploadzip[filename].callback
|
||
but a password to unzip
|
||
in clientconf.json need to be set
|
||
"uploadzip": {
|
||
"articlesTribespvm.zip": {
|
||
"comment": "unzip with overwrite if same name",
|
||
"psw": "azPI1209qtrse",
|
||
"dest": "importexport/tmp",
|
||
"unzipoption": "-aoa",
|
||
"callback": "importexport/integrationitem.js"
|
||
}
|
||
},
|
||
Example:
|
||
cd where zip file is stored
|
||
curl -H "xtribe: pvmsaveurs" -H "xworkon: pvmsaveurs" -H "xlang: fr" -H "xpaganid: adminapxtrib" -H "xauth: 1" -H "xapp: pvmsaveurs:pvmsaveurs" -F 'data=@articlesTribespvm.zip' http://pvmsaveurs.pvmsaveurs.fr/app/Tribes/uploadzip
|
||
|
||
*/
|
||
const clientconf = fs.readJSONSync( `${config.tribes}/${req.session.header.xworkon}/clientconf.json` )
|
||
if( !clientconf.uploadzip ) {
|
||
return res.status( '404' )
|
||
.send( { info: [ "missconf" ], models: "Tribes", moreinfo: `no uploadzip in clientconf for ${req.session.header.xworkon} please contact apxtrib admin ` } );
|
||
};
|
||
const uploadzip = clientconf.uploadzip;
|
||
const formidable = require( 'formidable' );
|
||
const form = formidable( { multiples: false } );
|
||
form.parse( req, function ( err, fields, files ) {
|
||
//console.log( files.data )
|
||
var oldPath = files.data.path;
|
||
if( !Object.keys( clientconf.uploadzip )
|
||
.includes( files.data.name ) ) {
|
||
return res.status( 403 )
|
||
.send( { info: [ "notAllowed" ], models: "Tribes", moreinfo: `file ${files.data.name} not allowed to be upload` } )
|
||
} else {
|
||
console.log( "context:", clientconf.uploadzip[ files.data.name ] )
|
||
var newPath = `${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[files.data.name].dest}`;
|
||
//console.log( 'oldPath', oldPath )
|
||
//console.log( 'newPath', `${newPath}/${files.data.name}` )
|
||
fs.moveSync( oldPath, `${newPath}/${files.data.name}`, { overwrite: true } );
|
||
const cp = require( 'child_process' );
|
||
//console.log( `7z e -p${clientconf.uploadzip[ files.data.name ].psw} ${newPath}/${files.data.name}` );
|
||
console.log( '7z', [ 'e', `-p${clientconf.uploadzip[ files.data.name ].psw}`, `${newPath}/${files.data.name}`, `-o${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[ files.data.name ].dest}`, clientconf.uploadzip[ files.data.name ].unzipoption ] );
|
||
var newFiles = cp.spawnSync( '7z', [ 'e', `-p${clientconf.uploadzip[ files.data.name ].psw}`, `${newPath}/${files.data.name}`, `-o${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[ files.data.name ].dest}`, clientconf.uploadzip[ files.data.name ].unzipoption ] );
|
||
console.log( newFiles.output.toString() )
|
||
if( newFiles.output.toString()
|
||
.includes( 'Everything is Ok' ) ) {
|
||
if( clientconf.uploadzip[ files.data.name ].callback ) {
|
||
const integ = require( `${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[files.data.name].callback}` )
|
||
.run();
|
||
console.log( 'integration', integ )
|
||
return res.status( integ.status )
|
||
.send( integ.payload );
|
||
} else {
|
||
return res.status( 200 )
|
||
.send( {
|
||
info: [ "successfullsent" ],
|
||
models: "Tribes"
|
||
} );
|
||
}
|
||
} else {
|
||
return res.status( 400 )
|
||
.send( {
|
||
info: [ "zipfileerror" ],
|
||
models: "Tribes",
|
||
moreinfo: newFiles.output.toString()
|
||
} )
|
||
}
|
||
}
|
||
} )
|
||
} );
|
||
|
||
router.post( '/upload', checkHeaders, isAuthenticated, ( req, res ) => {
|
||
1 // ACHANGER VIA usage sendjson
|
||
// url /Tribes/upload?save=tmp&rep=referentials/dataManagement
|
||
// if save=tmp then store in a tmp file
|
||
// if save=ok then mv the tmp file to the folder
|
||
// midlleware hasAccessrighton.js is not apply here only to access/update/create information inside an object
|
||
// to upload a file a user need accessrights to data: object: C or to Own it
|
||
// or if dir.file exist a .info.json into folder get shared as C in uuid accessright
|
||
/*
|
||
to add in front
|
||
<form action="/upload" method="POST" enctype="multipart/form-data">
|
||
<input type="file" name="file"/>
|
||
<input type="submit" value="upload"/>
|
||
</form>
|
||
*/
|
||
console.log( 'Envoie image' )
|
||
console.log( 'body', req.body );
|
||
console.log( 'params', req.params );
|
||
//const authfolder = Tribes.checkaccessfiles( req.params.rep, 'C', req.session.header.accessrights, req.session.header.xpaganid );
|
||
// cheack autorisation to create or replace a file for this accessrights user
|
||
const authfolder = { ok: "tt" }
|
||
if( authfolder.ok ) {
|
||
if( req.params.save == 'file' ) {
|
||
if( fs.existsSync( req.body.filepond ) ) {
|
||
fs.mv( req.body.filepond, req.params.rep );
|
||
}
|
||
};
|
||
// voir si c'est toujours pertinent car upload est géré par filepond pour les image
|
||
if( req.params.save == 'upload' ) {
|
||
const form = formidable( { multiples: false } );
|
||
form.parse( req, ( err, fields, files ) => {
|
||
if( err ) { next( err ); return; }
|
||
let thefile = files.filebond.path;
|
||
fs.outputFileSync()
|
||
console.log( 'thefile:' + thefile );
|
||
res.writeHead( 200, { 'Content-Type': 'text/plain' } );
|
||
res.end( theFile );
|
||
} )
|
||
}
|
||
} else {
|
||
res.status( 403 )
|
||
.send( 'forbiden access' );
|
||
}
|
||
} );
|
||
/*
|
||
Manage tribeid into /data/tribee/tribeid
|
||
client space dedicated
|
||
|
||
@Todo
|
||
clientconfglob copy cut from Referentials.clientconfglob
|
||
clientconf.json copy cut from Referentials.clientconf
|
||
list of tribeid copy cut from Referentials.
|
||
Add a tribeid
|
||
update clientconf
|
||
|
||
|
||
*/
|
||
|
||
|
||
|
||
module.exports = router;
|