Skip to content

Commit

Permalink
closes #15
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeBild committed Aug 29, 2016
1 parent 42362eb commit cb0e1f0
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 28 deletions.
11 changes: 11 additions & 0 deletions example/getting-started/helloworld-html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Hello World HTML output example

// HTTP API
// http://localhost:3000/api/helloworld-html?name=Joe

module.exports = (ctx, input) => {
// Is authenticated via JWT
// if(!ctx.context.user) return ctx.failure(new Error(401));

ctx.success(`<h1>Hello ${input.name || 'World'}!</h1>`);
};
15 changes: 15 additions & 0 deletions example/getting-started/helloworld.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Hello World example

// HTTP API
// http://localhost:3000/api/helloworld?name=joe

module.exports = (ctx, input) => {
// Is authenticated via JWT
if(!ctx.context.user) return ctx.failure(new Error(401));

ctx.success({
input: input,
context: ctx.context,
msg: 'Hello World!',
});
};
15 changes: 10 additions & 5 deletions lib/functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const vm = require('vm');
const _ = require('lodash');
const EXEC_TIMEOUT = 60000;
const pouch = require('../pouch-graphql/pouchdb');
const session = {};

module.exports = {
exec: exec,
Expand All @@ -24,14 +25,15 @@ function exec(args) {
console: console,
Buffer: Buffer,
};

const moduleExecutionContext = {
pouchdb: envName => pouch.createPouchDB(envName || 'default'),
log: value => {
logOutput += `${JSON.stringify(value, null, 4)}\\r\\n`;
logOutput += `${JSON.stringify(value, null, 2)}\\r\\n`;
},
user: args.context.user,
context: Object.assign({}, args.context, {variables: _.mapKeys(process.env, (value, key) => (key.indexOf('GP_') !== -1) ? key.replace('GP_','') : null)}),
session: session,
};
_.unset(moduleExecutionContext, 'context.variables.null');

const done = new Promise((resolve, reject) => {
moduleExecutionContext.success = resolve;
Expand All @@ -42,11 +44,14 @@ function exec(args) {
scriptSandbox.data = args.input;
scriptSandbox.context = args.context;
vm.createContext(scriptSandbox);
setTimeout(() => moduleExecutionContext.failure(new Error('Time out')), EXEC_TIMEOUT);
setTimeout(() => moduleExecutionContext.failure(new Error('Execution timeout')), EXEC_TIMEOUT);
vm.runInContext(`${implementation}\r\nmodule.exports(moduleExecutionContext, data);`, scriptSandbox, {filename: args.name, displayErrors: false, timeout: EXEC_TIMEOUT});

return done
.then(output => Object.assign(output, {log:logOutput}));
.then(output => {
if(_.isObject(output) && logOutput) return Object.assign(output, {log:logOutput});
return output;
});

} catch(error) {
console.error(error);
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
"dependencies": {
"body-parser": "^1.15.2",
"commander": "^2.9.0",
"cors": "^2.7.1",
"cors": "^2.8.0",
"dataloader": "^1.2.0",
"debug": "^2.2.0",
"eslint": "^3.3.1",
"eslint": "^3.4.0",
"express": "^4.14.0",
"express-graphql": "^0.5.3",
"express-graphql": "^0.5.4",
"express-jwt": "^3.4.0",
"graphql": "^0.6.2",
"graphql-relay": "^0.4.2",
Expand Down
40 changes: 20 additions & 20 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,34 @@ app.use('/graphql/:name?', checkJWT, (req, res, next) => {
formatError: environment.development ? developmentFormatError : GraphQL.formatError,
})(req, res, next);
});
app.all('/functions/:name', checkJWT, (req, res, next) => {
const docid = req.params.name;
if(!docid) return res.sendStatus(404);

const defaultEnvironment = resolveEnv('default');
if(defaultEnvironment.secret && !req.role === 'admin') return res.sendStatus(401);
app.all('/*', checkOptionalJWT, (req, res, next) => {
const docid = path.parse(req.params['0']).base || req.params[0] || 'index';

pouch.createPouchDB('default')
.find({ selector: {docid:docid, doctype:'Function'} })
.then(data => (!(data && data.docs.length)) ? Promise.reject(next()) : data)
.then(data => ({
id: data._id,
content: (data.docs && data.docs[0]) ? data.docs[0].content : undefined
}))
.then(data => {
return functions.exec({
input: req.query || req.body,
name: req.params.name,
context: {environment: 'default', user: req.user},
implementation: data.content,
});
})
.then(data => functions.exec({
input: Object.assign({}, req.query, req.body),
name: req.params.name,
context: {environment: 'default', user: req.user, method: req.method, name: req.params.name},
implementation: data.content,
}))
.then(data => {
if(data.message) return res.status(500).send({message: data.message});
res.set({'X-Response-Log': data.log});
res.send(data);
})
.catch(error => {
if(error && error.message && parseInt(error.message)) return res.sendStatus(parseInt(error.message));
if(error && error.message === 'Not found') return res.status(404).send({message: error.message});
res.status(500).send({message: error.message});
});
});
app.get('/*', (req, res, next) => {
const defaultEnvironment = resolveEnv('default');
if(defaultEnvironment.secret && !req.role === 'admin') return res.sendStatus(401);

}, (req, res, next) => {
const docid = path.parse(req.params['0']).base || req.params[0] || 'index.html';

pouch.createPouchDB('default')
.find({ selector: {docid:docid, doctype:'Static'} })
.then(data => ({
Expand Down Expand Up @@ -197,6 +189,14 @@ function checkJWT(req, res, next){
})(req, res, next);
}

function checkOptionalJWT(req, res, next){
return expressJWT({
secret: resolveSecret,
credentialsRequired: false,
getToken: () => getTokenFromHeaderOrQuerystring(req),
})(req, res, next);
}

function getTokenFromHeaderOrQuerystring(req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') return req.headers.authorization.split(' ')[1];
if (req.query && req.query.token) return req.query.token;
Expand Down

0 comments on commit cb0e1f0

Please sign in to comment.