Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
frankpagan committed May 5, 2021
2 parents 63147e2 + 7f9d07e commit 361c78b
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 73 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
"express": "^4.17.1",
"express-session": "^1.17.1",
"json-2-csv": "^3.7.6",
"mime-types": "^2.1.30",
"mongodb": "^3.5.8",
"node-html-parser": "^3.2.0",
"querystring": "^0.2.0"
}
}
15 changes: 14 additions & 1 deletion src/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ServerPermission extends CoCreatePermission {
constructor(db_client) {
super()
this.dbClient = db_client;
this.initEvent()
}

getParameters(action, data) {
Expand All @@ -20,6 +21,18 @@ class ServerPermission extends CoCreatePermission {
}
}

initEvent() {
const self = this;
process.on('changed-document', async (data) => {
const {collection, document_id, organization_id, data : permissionData } = data

if (collection === 'permissions' && self.hasPermission(permissionData.key)) {
let new_permission = await self.getPermissionObject(permissionData.key, organization_id, permissionData.type)
self.setPermissionObject(permissionData.key, new_permission)
}
})
}

async getPermissionObject(key, organization_id, type) {

try {
Expand Down Expand Up @@ -63,7 +76,7 @@ class ServerPermission extends CoCreatePermission {
})
}

console.log('WS permission fetch data----', permission)
// console.log('WS permission fetch data----', permission)

return permission;
} catch (error) {
Expand Down
155 changes: 84 additions & 71 deletions src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,94 @@ var router = express.Router();
var path = require('path');
var utils = require("../helpers/utils.js");
var fs = require('fs');
const mime = require('mime-types')
const render = require('./render');

router.get('/*', async (req, res, next) => {
console.log("GetRoutes by organization")

let hostname = req.hostname;
let url = req.url;
let route_uri = url.split(req.hostname)[0];
let masterDB = '5ae0cfac6fb8c4e656fdaf92'
route_uri = route_uri.indexOf('?') ? route_uri.split('?')[0] : route_uri

let organization = await utils.organizationsfindOne({domains:hostname},masterDB)
if(organization == null) {
res.send('Organization cannot be found using the domain:'+hostname);
return null;
} else {

let organization_id = organization._id.toString();
route_uri = route_uri.indexOf('/ws') != -1 ? route_uri.substr(3) : route_uri;
let route_files = await utils.routesfindOne({hostname:hostname , route_uri : route_uri },organization_id);
// console.log(organization, hostname, route_uri,route_files);
let data = null;

if (route_files != null){
try{
//verifing if exists
console.log("GET SOURCE ")
data = route_files['src'];
if(data=='')
throw "Error src empty";
}catch(e){
console.log("Exception GET SOURCE ",e)
var route_export = await utils.getDocument({
'collection':route_files['collection'],
'document_id':route_files['document_id']
}, organization_id);
data = route_export[route_files['name']]
}


if (data != null) {
let content_type = '';
let is_file = route_files['is_file'];
let ext = path.extname(route_uri).substr(1);
if (!is_file) {
switch(ext){
case 'css':
content_type = 'text/css'
break;
case 'js':
content_type = 'text/javascript'
break;
case 'xml':
content_type = 'text/xml'
break;
default:
content_type = 'text/html'
}
res.type(content_type);
res.send(data);
} else {
// let content_type = route['content_type'] || "image/png";
let file = Buffer.from(data, 'base64');
// res.set('Content-Type', content_type);
res.send(file);
}
}
else {
res.send('Document provided by routes could not be found ');
}
/**
* <write a short decription>
*
* 1. with hostname we query a master db in order to find the organization_id...
* with the org id we can now query for the uri in collection "files" and return value for fieldName "src"
* 2. in db we store path as /docs/dnd but need something more flexible so we can respond even if request /docs/dnd/
*
* */
const masterDB = '5ae0cfac6fb8c4e656fdaf92'
router.get('/*', async(req, res, next) => {
let hostname = req.hostname;
let organization = await utils.organizationsfindOne({ domains: hostname }, masterDB)
if (!organization)
return res.send('Organization cannot be found using the domain:' + hostname);


let url = req.url;
if (url.endsWith('/'))
url = url.substring(0, url.length - 1);

url = url.startsWith('/ws') ? url.substr(3) : url; // dev

// console.log('>>>>>>>>>>>>>', url, organization)
let organization_id = organization._id.toString();
let route_files = await utils.routesfindOne({ hostname: hostname, route_uri: url }, organization_id);


if (!route_files)
return res.send(`there is no ${url} in masterDb ${organization_id} `);
let data;
if (route_files['src'])
data = route_files['src'];
else {
let route_export = await utils.getDocument({
collection: route_files['collection'],
document_id: route_files['document_id']
}, organization_id);
data = route_export[route_files['name']];

}

if (!data) {
res.send('Document provided by routes could not be found and has no src ');
}





let content_type = route_files['content_type'] ||
mime.lookup(url) ||
'text/html';

console.log('(>>>>>>>>>>>>>>', content_type, route_files['content_type'], route_files['route'])

if (content_type.startsWith('image/') || content_type.startsWith('audio/') || content_type.startsWith('video/')) {
// let content_type = route['content_type'] || "image/png";
// todo: is there are better alternative or conevention not to process base64
let file = Buffer.from(data, 'base64');
res.set('Content-Type', content_type);
res.send(file);
}
else if (content_type === 'text/html') {


try {

let fullHtml = await render(data, organization_id);
res.type(content_type);
res.send(fullHtml);
}
else {
res.send('Organization could not be found for ['+hostname+'] in masterDb ['+organization_id+'] ');
catch (err) {
if (err.message.startsWith('infinite loop:'))
return res.send('there is a infinite loop');
else
return res.send('something is wrong')
}

}

else {
res.type(content_type);
res.send(data);
}


});

module.exports = router;
67 changes: 67 additions & 0 deletions src/routes/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
let { parse } = require("node-html-parser");
let { getDocument } = require('../helpers/utils');

module.exports = async function renderHtml(html, organization_id) {

let dep = [];
let dbCache = new Map();

async function render(html, lastKey) {
const dom = parse(html);
for (let el of dom.querySelectorAll(
"[data-collection][name][data-document_id]"
)) {
let meta = el.attributes;
let id = meta["data-document_id"],
coll = meta['data-collection'],
name = meta['name'];
let key = id + coll + name;
if(!id || !name || !coll) continue;
if (dep.includes(key))
throw new Error(
`infinite loop: ${lastKey} ${id} ${coll} ${name} has been already rendered`
);
else
dep.push(key)

let cacheKey = id + coll;
let record;
if (dbCache.has(cacheKey))
record = dbCache.get(cacheKey)
else {

record = await
getDocument({
collection: coll,
document_id: id
}, organization_id);
dbCache.set(cacheKey, record)
}



if(!record || !record[name])
{
dep.pop();
continue;
}
let chunk = record[name];
if (!chunk) {

dep.pop();
continue;
}
let dom = await render(chunk);

el.innerHTML = "";
el.appendChild(dom);


dep.pop();
}

return dom;
}
let result = (await render(html, 'root')).toString();
return result;
}
Loading

0 comments on commit 361c78b

Please sign in to comment.