in progress

This commit is contained in:
2023-04-27 06:17:20 +02:00
parent 0c74da3b20
commit a1fa43e2bd
279 changed files with 1706 additions and 95255 deletions

37
api/routes/nations.js Executable file
View File

@@ -0,0 +1,37 @@
const express = require( 'express' );
const config = require( '../../nationchains/tribes/conf.json' );
// Classes
const Nations = require( '../models/Nations.js' );
// Middlewares
const checkHeaders = require( '../middlewares/checkHeaders' );
const isAuthenticated = require( '../middlewares/isAuthenticated' );
const hasAccessrighton = require( '../middlewares/hasAccessrighton' );
const router = express.Router();
/*
Manage the social world
@Todo
Manage a new nation
A major create a nation with at least a town => nation:{name, towns:[]} contracts/nationname.js + contracts/townsname.js
Manage a new towns in a nation => update nation:[nationname:towns:[]} contracts/townname.js
*/
router.post( '/push', checkHeaders, ( req, res ) => {
// Get information from other apxtrib instance in req.body
// check req.body.hashnext => means this is a candidate to validate next block
//
// return it's own information back with the last call to Nationchains.synchronize()
res.send( { status: 200, payload: { moreinfo: fs.readFileSync( `${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`, 'utf-8' ) } } )
} )
module.exports = router;

201
api/routes/odmdb.js Normal file
View File

@@ -0,0 +1,201 @@
const express = require("express");
const glob = require("glob");
const fs = require("fs-extra");
const path = require("path");
const conf = require("../../nationchains/tribes/conf.json");
const Odmdb = require("../models/Odmdb.js");
// Middlewares
const checkHeaders = require("../middlewares/checkHeaders");
const isAuthenticated = require("../middlewares/isAuthenticated");
const hasAccessrighton = require("../middlewares/hasAccessrighton");
const router = express.Router();
router.get(
"/:objectname/idx/:indexname",
checkHeaders,
isAuthenticated,
(req, res) => {
/**
* @api {get} /odmdb/idx/:indexname
* @apiName Get index file for an object
* @apiGroup Odmdb
*
* @apiUse apxHeader
* @objectname {string} Mandatory
* @apiParam {String} indexname Mandatory if in conf.nationObjects then file is into nationchains/ else in /nationchains/tribes/xtribe/objectname/idx/indexname indexname contains the ObjectName .*_ (before the first _)
*
* @apiError (404) {string} status the file does not exist
* @apiError (404) {string} ref objectmodel to get in the right language
* @apiError (404) {string} msg key to get template from objectmodel
* @apiError (404) {object} data use to render lg/objectmodel_lg.json
*
* @apiSuccess (200) {object} data contains indexfile requested
*
*/
// indexname = objectname_key_value.json
let objectLocation = "../../nationchains/";
if (!conf.api.nationObjects.includes(req.params.objectname)) {
objectLocation += `tribes/${req.session.headers.xtribe}/`;
// check if accessright
}
const indexpath = `${objectLocation}/${req.params.objectname}/idx/${req.params.indexname}`;
if (fs.existsSync(indexpath)) {
res.status(200).json({ data: fs.readJsonSync(indexpath) });
} else {
res
.status(404)
.json({
ref: "Odmdb",
msg: "objectfiledoesnotexist",
data: { indexpath },
});
}
}
);
router.get(
"/:objectname/itm/:primaryindex",
checkHeaders,
isAuthenticated,
(req, res) => {
/**
* @api {get} /odmdb/item/:objectname/:primaryindex
* @apiName Get index file for an object
* @apiGroup Odmdb
*
* @apiUse apxHeader
*
* @apiParam {String} objectname name Mandatory if in conf.nationObjects then file is into nationchains/ else in /nationchains/tribes/xtribe/objectname
* @apiParam {String} primaryindex the unique id where item is store
* @apiError (404) {string} status the file does not exist
* @apiError (404) {string} ref objectmodel to get in the right language
* @apiError (404) {string} msg key to get template from objectmodel
* @apiError (404) {object} data use to render lg/objectmodel_lg.json
*
* @apiSuccess (200) {object} data contains indexfile requested
*
*/
// indexname = objectname_key_value.json
const objectName = req.params.objectname;
const objectId = req.params.primaryindex;
let objectLocation = "../../nationchains/";
if (!conf.api.nationObjects.includes(objectName)) {
objectLocation += `tribes/${req.session.headers.xtribe}/${objectName}`;
// check if accessright on object on item
// in case not res.status(403)
}
const objectpath = `${objectLocation}/${objectName}/itm/${objectId}`;
if (fs.existsSync(objectpath)) {
res.status(200).json({ data: fs.readJsonSync(objectpath) });
} else {
res
.status(404)
.json({
ref: "Odmdb",
msg: "objectfiledoesnotexist",
data: { objectpath },
});
}
}
);
router.post(":objectname/itm", checkHeaders, isAuthenticated, (req, res) => {
// Create an item of an object
});
router.get(
"/searchitems/:objectname/:question",
checkHeaders,
isAuthenticated,
(req, res) => {
/**
*
*
*/
console.log(
"route referentials get all language" +
req.params.objectname +
"-" +
req.params.question
);
const getref = Referentials.getref(
true,
req.params.source,
req.params.idref,
req.session.header.xworkon,
req.session.header.xlang
);
// Return any status the data if any erreur return empty object
res.jsonp(getref.payload.data);
}
);
router.get("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => {
/**
* @api {get} /odmdb/schema/:objectname
* @apiName GetSchema
* @apiGroup Odmdb
*
* @apiUse apxHeader
*
* @apiParam {String} objectname Mandatory if headers.xworkon == nationchains then into ./nationchains/ else into ./tribes/xworkon/
*
* @apiError (404) {string} status a key word to understand not found schema
* @apiError (404) {string} ref objectmodel to get in the right language
* @apiError (404) {string} msg key to get template from objectmodel
* @apiError (404) {object} data use to render lg/objectmodel_lg.json
*
* @apiSuccess (200) {object} data contains schema requested
*
*/
const fullpath = path.resolve(
`${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json`
);
if (fs.existsSync(fullpath)) {
res.status(200).json({ data: fs.readJsonSync(fullpath) });
} else {
res
.status(404)
.json({ msg: "schemanotfound", ref: "odmdb", data: { fullpath } });
}
});
router.put("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => {
/**
* @api {put} /odmdb/schema/:objectname
* @apiName putSchema
* @apiGroup Odmdb
*
* @apiUse apxHeader
*
* @apiParam {String} objectname Mandatory if headers.xworkon == nationchains then into ./nationchains/ else into ./tribes/xworkon/
* @apiBody {string} schemapath where to store schema .../schema
* @apiBody {string} objectpath where to store object ...objectname/idx/config.json
* @apiBody {json} schema content
* @apiBody {json} schemalang content in lg
* @apiBody {string} lang define which schemalg is (2 letters)
*
* @apiError (404) {string} status a key word to understand not found schema
* @apiError (404) {string} ref objectmodel to get in the right language
* @apiError (404) {string} msg key to get template from objectmodel
* @apiError (404) {object} data use to render lg/objectmodel_lg.json
*
*
* @apiSuccess (200) {object} data contains schema requested
*
*/
const fullpath = path.resolve(
`${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json`
);
const set = Odmdb.setObject(
path.resolve(`${__dirname}/tribes/${req.session.header.xworkon}`)
);
if (fs.existsSync(fullpath)) {
res.status(200).json({ data: fs.readJsonSync(fullpath) });
} else {
res
.status(404)
.json({ msg: "schemanotfound", ref: "odmdb", data: { fullpath } });
}
});
module.exports = router;

242
api/routes/pagans.js Executable file
View File

@@ -0,0 +1,242 @@
const express = require( 'express' );
const path = require( 'path' );
// Classes
const Pagans = require( '../models/Pagans.js' );
// Middlewares
const checkHeaders = require( '../middlewares/checkHeaders' );
const isAuthenticated = require( '../middlewares/isAuthenticated' );
const hasAccessrighton = require( '../middlewares/hasAccessrighton' );
const router = express.Router();
/*
models/Pagans.js
Managed:
/data/tribee/client-Id/users/uuid.json
/searchindex/emails.json {email:uuid}
/login.json {login:uuid}
/uids.json {uuid;[[
login,
email,
encrypted psw,
accessrights]}
ACCESSRIGHTS = {
app:{"tribeid:appname":"profil"},
data:{"tribeid":{object:"CRUDO"}}
}
ACCESSRIGHTS is store into the token and is load into req.session.header.accessrights by hasAccessrighton() middleware
appname is a website space object /sitewebsrc/appname
website live is strored into /dist source in /src
This can be managed by maildigitcreator or not.
apxtrib/sitewebs/webapp is the webinterface of apxtrib
profil: admin / manager / user are key word to give specific access to data into model. Any kind of other profil can exist. It is usefull to manage specific menu in an app.
It is also possible to authorize update a field's object depending of rule into dataManagement/object/
{ field:X
nouserupdate: "!(['admin','manager'].includes(contexte.profil))",
}
data allow a user to access tribeid with Create Read Update Delete Own (CRUDO) on each object of a tribeid independantly of any app.
Create allow to create a new object respecting rules defined into /referentials/dataManagement/object/name.json
Update idem
Delete idem
Owner means it can be Write/Delete if field OWNER contain the UUID that try to act on this object. Usefull to allow someone to fully manage its objects.
*/
router.get('/isregister', checkHeaders, isAuthenticated,(req,res)=>{
/**
* @api {get} /pagans/isregister
* @apiName Is register check xalias and xhash
* @apiGroup Odmdb
*
* @apiUse apxHeader
*
* @apiParam {String} indexname Mandatory if in conf.nationObjects then file is into nationchains/ else in /nationchains/tribes/xtribe/objectname/idx/indexname indexname contains the ObjectName .*_ (before the first _)
*
* @apiError (404) {string} status the file does not exist
* @apiError (404) {string} ref objectmodel to get in the right language
* @apiError (404) {string} msg key to get template from objectmodel
* @apiError (404) {object} data use to pagansmodel: 'Pagans' } );render lg/objectmodel_lg.json
*
* @apiSuccess (200) {object} data contains indexfile requested
*
*/
res.send(Pagans.checkdetachedSignature(req.session.header.xalias,req.session.header.xhash));
res.send({status:200,ref:"headers",msg:"authenticated",data:{xalias:req.session.header.xalias,xtribe:req.session.header.xtribe}})
})
router.post('/', checkHeaders, (req,res)=>{
// create a pagan account from alias, publickey, if trusted recovery={email,privatekey}
console.log(req.body)
} )
router.delete( '/:alias', checkHeaders, isAuthenticated, ( req, res ) => {
console.log( `DELETE pagans nationchains/pagans/${req.params.alias}.json` );
const result = Pagans.delete( req.params.id, req.session.header );
res.status( result.status )
.send( result.data );
} );
router.get( '/isauth', checkHeaders, isAuthenticated, ( req, res ) => {
if( req.session.header.xpseudo == "1" ) {
return res.status( 401 )
.send( { info: "not authenticate" } );
} else return res.status( 200 )
.send( { info: "well authenticated" } )
} )
router.post( '/login', checkHeaders, async ( req, res ) => {
// console.log('POST /users/login with: ', req.app.locals.header);
/*
Check un mot de passe pour un login pour obtenir un token d'authentification
valable 1 hour, 1 day
@header
@body.LOGIN
@body.PASSWORD
@checkpsw = true check si les 2 mot de passe cryptés correspondent
false bypass le contrôle et permet de générer un token
utile le temps de reinitialisé son mot de passe.
@return
*/
console.log( 'login for ', req.body, "in", req.session.header )
const log = await Pagans.loginUser( req.session.header, req.body, true );
console.log( "log user login", log );
if( log.status == 200 ) {
// update req.app.locals.tokens for this uuid just after login success then next isAuth will be valid
req.app.locals.tokens[ log.data.user.UUID ] = { TOKEN: log.data.user.TOKEN, ACCESSRIGHTS: log.data.user.ACCESSRIGHTS }
console.log( req.app.locals )
}
return res.status( log.status )
.send( log.data );
} );
router.get( '/getlinkwithoutpsw/:email', checkHeaders, async ( req, res ) => {
/*
Permet pour un email existant de renvoyer un email avec un lien valable 1h
@email est le compte pour lequel on demande un accès
Réponse:
Si email n'existe pas on n'envoie pas d'email
Si email existe on envoie un email avec un lien dont le token est valable 1h
@return
{status:200 ou erreur ,
payload:{
info:[list de key to appear in correct requester langue],
model:'Pagans',
moreinfo: 'texte pour log '
}
}
*/
console.log( `GET /users/getlinkwithoutpsw for email: ${req.params.email} tribeid :${req.header('X-Client-Id')}` );
if( !req.params.email ) {
return res.status( 404 )
.send( {
info: [ 'emailmissing' ],
model: 'Pagans'
} );
} else {
try {
const getlink = await Pagans.getlinkwithoutpsw( req.params.email, req.session.header );
console.log( 'getlink', getlink )
//met à jour le token créer pour le uuid
req.app.locals.tokens[ getlink.data.info.xuuid ] = getlink.data.info.token;
// attention si on relance le serveur le token temporaire est perdu
return res.status( getlink.status )
.send( getlink.data );
} catch ( err ) {
console.log( err )
}
}
} );
router.post( '/register', checkHeaders, async ( req, res ) => {
console.log( `POST /users for ${req.session.header.xtribe}` );
if( req.session.header.xjwt == '123123' ) {
// Creation d'un utilisateur avec information de base aucun droit
// On modifie le contenu du form pour n egarder que login/email et psw
// pour le client_id permet de traiter un user en attente de validation
console.log( 'req du post', req );
}
} );
router.get( '/info/:listindex', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'R' ), async ( req, res ) => {
console.log( `get users info on tribeid ${req.session.header.xworkon} for ${req.params.listindex} with accessright`, req.session.header.accessrights.data );
const result = await Pagans.getinfoPagans( req.session.header.xpresworkon, req.session.header.accessrights, req.params.listindex );
res.status( result.status )
.send( result.data );
} );
router.get( '/list/:filter/:field', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'R' ), async ( req, res ) => {
console.log( 'GET /users/list/filtre/champs list for ' + req.session.header.xworkon );
if(
[ 'admin', 'manager' ].includes( req.session.header.decodetoken[ 'apps' + req.session.header.xworkon + 'profil' ] ) ) {
try {
const userslist = await Pagans.getUserlist( req.session.header, req.params.filter, req.params.field );
console.log( 'userslist', userslist );
if( userslist.status == 200 ) {
return res.status( userslist.status )
.send( userslist.data );
}
} catch ( err ) {
console.log( err );
return res.status( 400 )
.send( { info: 'erreur' } );
}
} else {
res.status( 403 )
.send( {
info: [ 'forbiddenAccess' ],
model: 'Pagans'
} );
}
} );
router.get( '/uuid/:id', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'R' ), async ( req, res ) => {
console.log( `GET /users/uuid/${req.params.id}` );
//console.log('req.app.locals: ', req.app.locals);
//console.log('req.session', req.session);
const result = await Pagans.getUser( req.params.id, req.session.header.xworkon, req.session.header.accessrights );
res.status( result.status )
.send( result.data );
} );
router.put( '/chgpsw/:id', checkHeaders, isAuthenticated, async ( req, res ) => {
console.log( `PUT update /users/chgpsw/${req.params.id}` );
try {
const majpsw = await Pagans.updateUserpassword( req.params.id, req.session.header, req.body );
res.status( majpsw.status )
.send( majpsw.data );
} catch ( {
status,
data
} ) {
res.status( status )
.send( data );
}
} );
router.post( '/uuid', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'C' ), async ( req, res ) => {
console.log( 'POST /users create for ' + req.session.header.xworkon, req.body );
const usercreate = await Pagans.createUser( req.session.header, req.body );
return res.status( usercreate.status )
.send( usercreate.data );
} );
router.put( '/uuid/:id', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'U' ), async ( req, res ) => {
console.log( `PUT update /users/${req.params.id}` );
// console.log('req.app.locals: ', req.app.locals);
// console.log('req.session', req.session);
try {
const majUser = await Pagans.updateUser( req.params.id, req.session.header, req.body );
res.status( majUser.status )
.send( majUser.data );
} catch ( {
status,
data
} ) {
res.status( status )
.send( data );
}
} );
module.exports = router;

374
api/routes/tribes.js Executable file
View File

@@ -0,0 +1,374 @@
const express = require( 'express' );
const fs = require( 'fs-extra' );
const path = require( 'path' );
const conf=require('../../nationchains/tribes/conf.json')
// Classes
const Tribes = require( '../models/Tribes.js' );
// Middlewares
const checkHeaders = require( '../middlewares/checkHeaders' );
const isAuthenticated = require( '../middlewares/isAuthenticated' );
const hasAccessrighton = require( '../middlewares/hasAccessrighton' );
const router = express.Router();
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
hasAccessrighton( req.body.object, "U" );
} else {
hasAccessrighton( 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;
};
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;