UNPKG

koa-neo4j

Version:

Rapidly create REST APIs, powered by Koa and Neo4j -- batteries included with built-in role based authentication via JWT and reusable backend components

116 lines (93 loc) 4.52 kB
'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _extends = Object.assign || function (target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i];for (var key in source) {if (Object.prototype.hasOwnProperty.call(source, key)) {target[key] = source[key];}}}return target;};var _koa = require('koa');var _koa2 = _interopRequireDefault(_koa); var _koaRouter = require('koa-router');var _koaRouter2 = _interopRequireDefault(_koaRouter); var _koaBodyparser = require('koa-bodyparser');var _koaBodyparser2 = _interopRequireDefault(_koaBodyparser); var _kcors = require('kcors');var _kcors2 = _interopRequireDefault(_kcors); var _auth = require('./auth'); var _data = require('./data'); var _procedure = require('./procedure'); var _util = require('./util'); var _http = require('http');var _http2 = _interopRequireDefault(_http);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const defaultOptions = { apis: [], neo4j: { url: 'neo4j://localhost', user: 'neo4j', password: 'neo4j' }, sensitive: true }; class KoaNeo4jApp extends _koa2.default { constructor(options) { super(); options = _extends({}, defaultOptions, options); this.router = new _koaRouter2.default({ sensitive: options.sensitive }); this.methods = { 'GET': this.router.get, 'POST': this.router.post, 'PUT': this.router.put, 'DEL': this.router.del, 'PATCH': this.router.patch }; this.neo4jConnection = new _data.Neo4jConnection(options.neo4j); this.neo4jInitialized = this.neo4jConnection.initialized; const server = _http2.default.createServer(this.callback()); this.server = server; if (!options.loadMiddlewareByApp) { this.configuredAuthentication = false; if (options.authentication) this.configureAuthentication(options.authentication); this. use((0, _kcors2.default)(options.cors)). use((0, _koaBodyparser2.default)({ onerror(error, ctx) { ctx.throw(400, `cannot parse request body, ${JSON.stringify(error)}`); } })); this.use(async (ctx, next) => { try { const start = new Date(); await next(); const ms = new Date() - start; console.log('%s %s - %s ms', ctx.method, ctx.originalUrl, ms); } catch (error) { ctx.body = String(error); ctx.status = error.status || 500; console.log('%s %s - then%s', ctx.method, ctx.originalUrl, error.stack || error); } }); } if (!options.loadRouteByApp) { this.use(this.router.routes()); for (const api of options.apis) this.defineAPI(api); } } defineAPI(options) { const api = new _data.API(this.neo4jConnection, options); const handler = async (ctx, next) => { if (api.requiresJwtAuthentication) try { await this.authentication.authenticateJwt(ctx, () => {}); } catch (error) { // No Authorization header ctx.throw(401, 'authorization required'); } if (api.requiresJwtAuthentication && !(0, _util.haveIntersection)(ctx.user.roles, api.allowedRoles)) ctx.throw(403, 'user does not have permission for this resource'); const params = _extends({}, ctx.query, ctx.params, ctx.request.body); ctx.body = await api.invoke(params, ctx); await next(); }; this.methods[api.method].apply(this.router, [api.route, handler]); return api; } configureAuthentication(options) { if (this.configuredAuthentication) throw new Error('authentication already configured'); this.authentication = new _auth.Authentication(this.neo4jConnection, options); this.use(this.authentication.passport.initialize()); this.router.post(options.route, this.authentication.authenticateLocal); this.configuredAuthentication = true; } createProcedure(options) { return (0, _procedure.createProcedure)(this.neo4jConnection, options); }}exports.default = KoaNeo4jApp;