mirror of
https://github.com/bckelley/cgm-remote-monitor.git
synced 2026-08-24 03:14:12 -05:00
* extended .gitignore for Visual Studio 2017 * creating a lib for api3 and exposing it's swagger file * adding pilot test (for /swagger.yaml) * implementing public GET /version * setting api version to 3.0.0-alpha * creating authorization skeleton + fetching some API env variables * reusing authorization library * implementing security * forcing HTTPS and removing x-powered-by from response * moving messages to constants, creating https instance fixture * testing HTTPS requiring * testing Date header * testing permission check * testing allowed operation * refactoring + storage stub * create architecture for generic operations * beginning of READ operation * tidying the code up * basic READ part * going further with READ operation * DELETE operation * handling fields parameter * refactoring to classes * going further with SEARCH operation * refactoring file structure * filtering for SEARCH operation * preparations for fallback deduplication * CREATE operation * UPDATE operation * PATCH operation * HISTORY operation * creating more precise variant of HISTORY operation * autopruning * long for timestamps in swagger * bug fix (when search fields=srvCreated) * creating skeleton for generic collection API test * specific HISTORY skeleton * distinguish between collection logical and storage name * renaming operation to LAST MODIFIED and getting it to work * fallback for LAST MODIFIED operation * tidying a bit * LAST MODIFIED documentation * bugfix + emitting data-received * adding some validations * bugfix - remove 'token' parameter from filtering * testing and debugging generic workflow * test fix for empty db * fixing security test fixture * trying to fix Travis CI testing DB problem * multiple auth callback bugfix + adding user field on authed create/update * messages for Travis CI debugging * messages for Travis CI debugging * messages for Travis CI debugging * test fix (to be prepared for future dates in db) * test fix * adding fallback created_at filling on each create/update * STATUS operation with API permissions * querying srvDate from storage + include storage version info * bugfix of missing apiConst require * getting mongo version with read-only user rights * getting mongo current date with read-only user rights * trying to diagnose travis CI timeout * refactoring storage version caching (due to some environments problems) * making VERSION work on empty database * more fixes * skipping API HTTPS test for node 8 * making code more readable using ES6 (Promises, async + await) * extending treatments collection docs by inspecting the careportal code * tidying existing API3 tests up to allow further grow * tidying the authorization code up to increase readability and performance a bit * more refactoring to ES6 and making APIv3 files structure more extendable * normalizing incoming dates to UTC and storing utcOffset * fixing srvDate to be of node.js server, not the mongo DB * preparing test fixtures for permissions testing + skeleton for CREATE operation test * intensive CREATE operation testing + minor bug fixes * correcting the deduplication test * more deduplication testing of CREATE operation * adding test skeletons for other generic operations * added variability in filtering by date, created_at, srvModified, srvCreated fields * fixing test accordingly to previous commit * adding new collection settings for centralized apps' settings storage * trying to solve travis CI testing problem - adding default collections names * another attempt to travis CI test fix * adding some tests for READ operation * adding custom error handler (overriding bodyparser's errors) * securing settings collection more and updating swagger accordingly * making HISTORY timestamp parameter more flexible + updating swagger documentation * more testing and bug fixing * sending only HTTP status with empty body, when there is no message + minor bug fixing * more refactoring and testing (especially of UPDATE operation) * PATCH testing + adding userModified field for troubleshooting purposes * basic SEARCH operation testing * more SEARCH operation testing * adding alternative 'now' query parameter to 'Date' header to make GET easier * adding 'now' to reserved query parameters for SEARCH operation * more testing * renaming field user to subject (and modifiedBy) * bugfix - fixing RFC 2822 constant for moment parsing * storageSocket: creating skeleton for new Socket.IO namespace * storageSocket: authentication by accessToken * storageSocket: authorizing to subscribe rooms * storageSocket: emitting create, update and delete events * APIv3: adding support for swagger UI at /api/v3/swagger-ui-dist * solving some problems detected by eslint * solving some problems detected by eslint * APIv3: testing and debugging Socket.IO * APIv3: testing and debugging Socket.IO * APIv3: Socket.IO documentation * APIv3: making the sample real * APIv3: starting to create a simple tutorial MD file * APIv3: small corrections * APIv3: minor corrections after dev merge * APIv3: adding CREATE and READ operations to the tutorial.md * APIv3: adding SEARCH, LAST MODIFIED, UPDATE operations to the tutorial.md * APIv3: finishing the tutorial.md * APIv3: minor bugfix (bad location after upsert) * APIv3: refactoring SEARCH complexity * APIv3: refactoring mongoCollection complexity * APIv3: refactoring complexity * APIv3: tidying up a bit * APIv3: refactoring security (start) * APIv3: refactoring lastModified * APIv3: refactoring create (start) * APIv3: refactoring create (finish) * APIv3: refactoring delete * APIv3: refactoring history * APIv3: refactoring update * APIv3: refactoring patch * APIv3: refactoring read * APIv3: refactoring search + removing deprecated authorizationBuilder * APIv3: adding best practise for identifier constructing * APIv3: refactoring and enhancing the validation (immutable fields) * APIv3: adding security.md documentation file * APIv3: refactoring - splitting index.js into multiple files * APIv3: calculating identifier on server side + deduplicating * APIv3: refactoring cosmetics * APIv3: updating the documentation * APIv3: making basic and security tests more readable using async/await * APIv3: making the rest of tests more readable using async/await * APIv3: adapting test of previous API * APIv3: adapting test of previous API
163 lines
4.5 KiB
JavaScript
163 lines
4.5 KiB
JavaScript
'use strict';
|
|
|
|
var fs = require('fs')
|
|
, language = require('../../../lib/language')()
|
|
, api = require('../../../lib/api3/')
|
|
, http = require('http')
|
|
, https = require('https')
|
|
, request = require('supertest')
|
|
, websocket = require('../../../lib/server/websocket')
|
|
, io = require('socket.io-client')
|
|
;
|
|
|
|
function configure () {
|
|
const self = { };
|
|
|
|
self.prepareEnv = function prepareEnv({ apiSecret, useHttps, authDefaultRoles, enable }) {
|
|
|
|
if (useHttps) {
|
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
}
|
|
else {
|
|
process.env.INSECURE_USE_HTTP = true;
|
|
}
|
|
process.env.API_SECRET = apiSecret;
|
|
|
|
process.env.HOSTNAME = 'localhost';
|
|
const env = require('../../../env')();
|
|
|
|
if (useHttps) {
|
|
env.ssl = {
|
|
key: fs.readFileSync(__dirname + '/localhost.key'),
|
|
cert: fs.readFileSync(__dirname + '/localhost.crt')
|
|
};
|
|
}
|
|
|
|
env.settings.authDefaultRoles = authDefaultRoles;
|
|
env.settings.enable = enable;
|
|
|
|
return env;
|
|
};
|
|
|
|
|
|
self.addSecuredOperations = function addSecuredOperations (instance) {
|
|
|
|
instance.get = (url) => request(instance.baseUrl).get(url).set('Date', new Date().toUTCString());
|
|
|
|
instance.post = (url) => request(instance.baseUrl).post(url).set('Date', new Date().toUTCString());
|
|
|
|
instance.put = (url) => request(instance.baseUrl).put(url).set('Date', new Date().toUTCString());
|
|
|
|
instance.patch = (url) => request(instance.baseUrl).patch(url).set('Date', new Date().toUTCString());
|
|
|
|
instance.delete = (url) => request(instance.baseUrl).delete(url).set('Date', new Date().toUTCString());
|
|
};
|
|
|
|
|
|
self.bindSocket = function bindSocket (storageSocket, instance) {
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
if (!storageSocket) {
|
|
resolve();
|
|
}
|
|
else {
|
|
let socket = io(`${instance.baseUrl}/storage`, {
|
|
origins:"*",
|
|
transports: ['websocket', 'flashsocket', 'polling'],
|
|
rejectUnauthorized: false
|
|
});
|
|
|
|
socket.on('connect', function () {
|
|
resolve(socket);
|
|
});
|
|
socket.on('connect_error', function (error) {
|
|
console.error(error);
|
|
reject(error);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
|
|
self.unbindSocket = function unbindSocket (instance) {
|
|
if (instance.clientSocket.connected) {
|
|
instance.clientSocket.disconnect();
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Create new web server instance for testing purposes
|
|
*/
|
|
self.create = function createHttpServer ({
|
|
apiSecret = 'this is my long pass phrase',
|
|
disableSecurity = false,
|
|
useHttps = true,
|
|
authDefaultRoles = '',
|
|
enable = ['careportal', 'api'],
|
|
storageSocket = null
|
|
}) {
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
|
|
try {
|
|
let instance = { },
|
|
hasBooted = false
|
|
;
|
|
|
|
instance.env = self.prepareEnv({ apiSecret, useHttps, authDefaultRoles, enable });
|
|
|
|
self.wares = require('../../../lib/middleware/')(instance.env);
|
|
instance.app = require('express')();
|
|
instance.app.enable('api');
|
|
|
|
require('../../../lib/server/bootevent')(instance.env, language).boot(function booted (ctx) {
|
|
instance.ctx = ctx;
|
|
instance.ctx.ddata = require('../../../lib/data/ddata')();
|
|
instance.ctx.apiApp = api(instance.env, ctx);
|
|
|
|
if (disableSecurity) {
|
|
instance.ctx.apiApp.set('API3_SECURITY_ENABLE', false);
|
|
}
|
|
|
|
instance.app.use('/api/v3', instance.ctx.apiApp);
|
|
|
|
const transport = useHttps ? https : http;
|
|
|
|
instance.server = transport.createServer(instance.env.ssl || { }, instance.app).listen(0);
|
|
instance.env.PORT = instance.server.address().port;
|
|
|
|
instance.baseUrl = `${useHttps ? 'https' : 'http'}://${instance.env.HOSTNAME}:${instance.env.PORT}`;
|
|
|
|
self.addSecuredOperations(instance);
|
|
|
|
websocket(instance.env, instance.ctx, instance.server);
|
|
|
|
self.bindSocket(storageSocket, instance)
|
|
.then((socket) => {
|
|
instance.clientSocket = socket;
|
|
|
|
console.log(`Started ${useHttps ? 'SSL' : 'HTTP'} instance on ${instance.baseUrl}`);
|
|
hasBooted = true;
|
|
resolve(instance);
|
|
})
|
|
.catch((reason) => {
|
|
console.error(reason);
|
|
reject(reason);
|
|
});
|
|
});
|
|
|
|
setTimeout(function watchDog() {
|
|
if (!hasBooted)
|
|
reject('timeout');
|
|
}, 30000);
|
|
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
};
|
|
|
|
return self;
|
|
}
|
|
|
|
module.exports = configure(); |