Files
cgm-remote-monitor/tests/fixtures/api3/instance.js
T
Petr OndrusekandSulka Haro 2dd576a629 API V3 (#4250)
* 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
2019-10-09 22:53:55 +03:00

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();