bitabase-gateway
Advanced tools
Comparing version 1.4.3 to 1.5.0
@@ -7,3 +7,3 @@ const callarest = require('callarest'); | ||
url: `${server}/v1/databases/${databaseName}/collections`, | ||
data: collectionDefinition.schema | ||
body: collectionDefinition.schema | ||
}, callback); | ||
@@ -10,0 +10,0 @@ } |
const callarest = require('callarest'); | ||
const config = require('../config'); | ||
const selectRandomItemFromArray = require('../modules/selectRandomItemFromArray'); | ||
const ErrorObject = require('../modules/error'); | ||
function getCollectionSchema (databaseName, collectionName, callback) { | ||
function getCollectionDefinition (config, databaseName, collectionName, callback) { | ||
const managerUrl = selectRandomItemFromArray(config.managers); | ||
callarest({ | ||
url: `${config.managerUrl}/v1/databases/${databaseName}/collections/${collectionName}`, | ||
url: `${managerUrl}/v1/databases/${databaseName}/collections/${collectionName}`, | ||
headers: { | ||
@@ -32,2 +34,2 @@ 'X-Internal-Secret': config.secret | ||
module.exports = getCollectionSchema; | ||
module.exports = getCollectionDefinition; |
@@ -44,3 +44,3 @@ const callarest = require('callarest'); | ||
const performGet = config => function (request, response, databaseName, collectionName, recordId, usageCollector) { | ||
getCollectionDefinition(databaseName, collectionName, function (error, collectionDefinition) { | ||
getCollectionDefinition(config, databaseName, collectionName, function (error, collectionDefinition) { | ||
if (error) { | ||
@@ -47,0 +47,0 @@ return sendJsonResponse(error.status, { error: error.message }, response); |
@@ -54,3 +54,3 @@ const callarest = require('callarest'); | ||
const performGet = config => function (request, response, databaseName, collectionName, usageCollector) { | ||
getCollectionDefinition(databaseName, collectionName, function (error, collectionDefinition) { | ||
getCollectionDefinition(config, databaseName, collectionName, function (error, collectionDefinition) { | ||
if (error) { | ||
@@ -57,0 +57,0 @@ return sendJsonResponse(error.status, { error: error.message }, response); |
@@ -10,3 +10,3 @@ const righto = require('righto'); | ||
function postRecordToServer (server, databaseName, collectionName, body, resolveMissing = true, callback) { | ||
function postRecordToServer (config, server, databaseName, collectionName, body, resolveMissing = true, callback) { | ||
callarest({ | ||
@@ -17,3 +17,3 @@ method: 'post', | ||
}, | ||
data: JSON.stringify(body), | ||
body: JSON.stringify(body), | ||
url: `${server}/v1/databases/${databaseName}/records/${collectionName}` | ||
@@ -26,3 +26,3 @@ }, function (error, record) { | ||
if (record.response.statusCode === 404 && resolveMissing) { | ||
const collectionDefinition = righto(getCollectionDefinition, databaseName, collectionName); | ||
const collectionDefinition = righto(getCollectionDefinition, config, databaseName, collectionName); | ||
const createdCollection = righto(createCollection, server, databaseName, collectionName, collectionDefinition); | ||
@@ -35,3 +35,3 @@ | ||
postRecordToServer(server, databaseName, collectionName, body, false, callback); | ||
postRecordToServer(config, server, databaseName, collectionName, body, false, callback); | ||
}); | ||
@@ -49,3 +49,3 @@ | ||
const body = righto(parseJsonBody, request); | ||
const postedRecord = righto(postRecordToServer, server, databaseName, collectionName, body, true); | ||
const postedRecord = righto(postRecordToServer, config, server, databaseName, collectionName, body, true); | ||
@@ -52,0 +52,0 @@ postedRecord(function (error, result) { |
const callarest = require('callarest'); | ||
const selectRandomItemFromArray = require('../modules/selectRandomItemFromArray'); | ||
@@ -34,6 +35,8 @@ function createUsageCollector () { | ||
const managerUrl = selectRandomItemFromArray(config.managers); | ||
callarest({ | ||
method: 'post', | ||
url: `${config.managerUrl}/v1/usage-batch`, | ||
data: JSON.stringify(accumlationData), | ||
url: `${managerUrl}/v1/usage-batch`, | ||
body: JSON.stringify(accumlationData), | ||
headers: { | ||
@@ -44,3 +47,5 @@ 'X-Internal-Secret': config.secret | ||
if (error) { | ||
console.log(error.message) | ||
if (error.code === 'ECONNREFUSED') { | ||
return callback && callback(new Error('ECONNREFUSED while running /v1/usage-batch')); | ||
} | ||
return callback && callback(error); | ||
@@ -47,0 +52,0 @@ } |
58
index.js
@@ -1,3 +0,57 @@ | ||
const createServer = require('./server'); | ||
if (process.env.NODE_ENV === 'development') { | ||
require('async-bugs'); | ||
} | ||
createServer().start(); | ||
const chalk = require('chalk'); | ||
const minimist = require('minimist'); | ||
const packageJson = require('./package.json'); | ||
const args = minimist(process.argv); | ||
function showHelp () { | ||
console.log(` | ||
${chalk.green(chalk.bold('📦 Bitabase'))}-${chalk.green('Gateway')} ${chalk.green(`- v${packageJson.version}`)} | ||
The scalable, sharded database engine. | ||
https://docs.bitabase.com | ||
The following commands and arguments are available when starting Bitabase | ||
Commands: | ||
start Start the bitabase manager stack | ||
--bind-host Hostname to bind server to (default: 0.0.0.0) | ||
--bind-port Port to bind server to (default: 8001) | ||
--rqlite-addr Path to contact rqlite | ||
--secret The internal request secret | ||
--account-mapper The regex to take the account from the incoming host (default: (.*).bitabase.test) | ||
`.trim() + '\n'); | ||
} | ||
function main () { | ||
if (args.help || args._.length === 2) { | ||
showHelp(); | ||
console.log(chalk.red('No command specified')); | ||
process.exit(1); | ||
} | ||
if (args._[2] === 'start') { | ||
const createServer = require('./server'); | ||
createServer({ | ||
...args, | ||
bindHost: args['bind-host'], | ||
bindPort: args['bind-port'], | ||
secret: args.secret, | ||
accountMapper: args['account-mapper'], | ||
rqliteAddr: args['rqlite-addr'] | ||
}).start(); | ||
return; | ||
} | ||
showHelp(); | ||
console.log(args); | ||
console.log(chalk.red(`Unknown command "${args._[2]}"`)); | ||
process.exit(1); | ||
} | ||
main(); |
{ | ||
"name": "bitabase-gateway", | ||
"version": "1.4.3", | ||
"version": "1.5.0", | ||
"description": "", | ||
@@ -13,5 +13,8 @@ "main": "index.js", | ||
"dependencies": { | ||
"async-bugs": "^1.1.0", | ||
"axios": "^0.19.2", | ||
"callarest": "^1.4.0", | ||
"callarest": "^2.0.1", | ||
"chalk": "^4.1.0", | ||
"error-with-object": "^1.1.0", | ||
"final-stream": "^1.1.0", | ||
"finalhandler": "^1.1.2", | ||
@@ -21,2 +24,3 @@ "find-my-way": "^2.2.1", | ||
"lokijs": "^1.5.7", | ||
"minimist": "^1.2.5", | ||
"mkdirp": "^0.5.5", | ||
@@ -26,7 +30,9 @@ "node-mini-migrations": "^2.0.1", | ||
"righto": "^6.0.1", | ||
"rqlite-fp": "^2.8.1", | ||
"uuid": "^3.3.3", | ||
"write-response": "^1.0.0" | ||
"write-response": "^1.2.2" | ||
}, | ||
"devDependencies": { | ||
"clarify": "^2.1.0", | ||
"nodemon": "^2.0.4", | ||
"promises-debugger": "^1.0.3", | ||
@@ -33,0 +39,0 @@ "tape": "^4.11.0", |
if (process.env.NODE_ENV === 'development') { | ||
require('trace'); | ||
require('clarify'); | ||
require('async-bugs'); | ||
} | ||
@@ -8,16 +7,17 @@ | ||
const defaultConfig = require('./config'); | ||
const sendJsonResponse = require('./modules/sendJsonResponse'); | ||
const setCrossDomainOriginHeaders = require('./modules/setCrossDomainOriginHeaders'); | ||
const getDatabaseNameFromDomain = require('./common/getDatabaseNameFromDomain'); | ||
const getCollectionNameFromPath = require('./common/getCollectionNameFromPath'); | ||
const setupUsageCollector = require('./controllers/setupUsageCollector'); | ||
const setupServerSyncer = require('./controllers/setupServerSyncer'); | ||
function createServer (configOverrides) { | ||
const config = { | ||
...defaultConfig, | ||
...configOverrides | ||
}; | ||
function createServer (config = {}) { | ||
config.bindHost = config.bindHost || '0.0.0.0'; | ||
config.bindPort = config.bindPort || 8002; | ||
config.accountMapper = config.accountMapper || '(.*).bitabase.test'; | ||
if (!config.secret) { | ||
throw new Error('Config option secret is required but was not provided'); | ||
} | ||
const getRecord = require('./controllers/getRecord.js')(config); | ||
@@ -28,10 +28,7 @@ const getRecords = require('./controllers/getRecords.js')(config); | ||
const usageCollector = setupUsageCollector(config); | ||
const serverSyncer = setupServerSyncer(config); | ||
const [host, port] = config.bind.split(':'); | ||
let server; | ||
function start () { | ||
server = http.createServer((request, response) => { | ||
setCrossDomainOriginHeaders(request, response); | ||
const databaseName = getDatabaseNameFromDomain( | ||
@@ -71,6 +68,11 @@ config.accountMapper, request.headers.host | ||
sendJsonResponse(404, { error: 'not found' }, response); | ||
}).listen(port, host); | ||
}); | ||
console.log(`[bitabase-gateway] Listening on ${host}:${port}`); | ||
server.on('listening', function () { | ||
const address = server.address(); | ||
console.log(`[bitabase-manager] Listening on ${config.bindHost} (${address.address}:${address.port})`); | ||
}); | ||
server.listen(config.bindPort, config.bindHost); | ||
return { start, stop }; | ||
@@ -81,4 +83,6 @@ } | ||
console.log('[bitabase-gateway] Shutting down'); | ||
usageCollector.stop(callback); | ||
usageCollector.stop(); | ||
serverSyncer && serverSyncer.stop && serverSyncer.stop(); | ||
server && server.close(); | ||
callback && callback(); | ||
} | ||
@@ -85,0 +89,0 @@ |
@@ -1,8 +0,1 @@ | ||
// require('promises-debugger')({ | ||
// dimNodeModules: true, | ||
// dimInternalModules: false, | ||
// dimNotInProjectRoot: true, | ||
// removeInternalModules: true | ||
// }) | ||
require('./common/getCollectionNameFromPath-test.js'); | ||
@@ -9,0 +2,0 @@ require('./common/getDatabaseNameFromDomain-test.js'); |
@@ -1,17 +0,10 @@ | ||
const test = require('tape'); | ||
const { promisify } = require('util'); | ||
const querystring = require('querystring'); | ||
const { promisify } = require('util'); | ||
const config = require('../../config'); | ||
const test = require('tape'); | ||
const writeResponse = require('write-response'); | ||
const { bringUp, bringDown } = require('../helpers/environment'); | ||
const httpRequest = require('../helpers/httpRequest'); | ||
const { createUserAndSession } = require('../helpers/session'); | ||
const createMockServer = require('../helpers/createMockServer'); | ||
const { | ||
createDatabase, | ||
createCollection, | ||
createRecord | ||
} = require('../helpers/databases'); | ||
const createServer = require('../../server'); | ||
@@ -22,7 +15,17 @@ | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const result = await httpRequest('/one', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -33,4 +36,5 @@ host: 'notfound.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -47,12 +51,23 @@ t.equal(result.status, 404); | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const session = await createUserAndSession(); | ||
await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
if (request.url === '/v1/users') { | ||
return writeResponse(200, { sessionId: 1, sessionSecret: 1 }, response); | ||
} | ||
if (request.url === '/v1/sessions') { | ||
return writeResponse(200, { sessionId: 1, sessionSecret: 1 }, response); | ||
} | ||
writeResponse(404, {}, response); | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const result = await httpRequest('/notfoundcollection', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -63,4 +78,5 @@ host: 'founddb.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -77,15 +93,20 @@ t.equal(result.status, 404); | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const session = await createUserAndSession(); | ||
const database = await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
writeResponse(200, { | ||
count: 0, | ||
items: [] | ||
}, response); | ||
}); | ||
await createCollection(session.asHeaders, database, { | ||
name: 'foundcl' | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(200, {}, response); | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const response = await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -96,4 +117,5 @@ host: 'founddb.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -108,18 +130,34 @@ t.equal(response.status, 200); | ||
test('[get] missing collection -> proxy to an existing collection forwarding headers', async t => { | ||
test('[get] missing collection -> proxy to an existing collection with item', async t => { | ||
t.plan(3); | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
writeResponse(200, { | ||
count: 1, | ||
items: [{ | ||
headerTest: 'yes' | ||
}] | ||
}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
if (request.url === '/v1/users') { | ||
return writeResponse(200, { sessionId: 1, sessionSecret: 1 }, response); | ||
} | ||
if (request.url === '/v1/sessions') { | ||
return writeResponse(200, { sessionId: 1, sessionSecret: 1 }, response); | ||
} | ||
writeResponse(200, {}, response); | ||
}); | ||
const session = await createUserAndSession(); | ||
const database = await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
await httpRequest( | ||
`${config.managerUrl}/v1/databases/${database.name}/collections`, { | ||
'http://0.0.0.0:8001/v1/databases/founddb/collections', { | ||
method: 'post', | ||
headers: { | ||
host: 'founddb.bitabase.test', | ||
...session.asHeaders | ||
host: 'founddb.bitabase.test' | ||
}, | ||
@@ -136,3 +174,3 @@ data: { | ||
data: { a: 1 }, | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -144,3 +182,3 @@ host: 'founddb.bitabase.test' | ||
const response = await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -152,4 +190,5 @@ host: 'founddb.bitabase.test', | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -164,20 +203,32 @@ t.equal(response.status, 200); | ||
await bringUp(2); | ||
const mockServer1 = createMockServer(8010, function (request, response) { | ||
writeResponse(200, { | ||
count: 0, | ||
items: [] | ||
}, response); | ||
}); | ||
const mockServer2 = createMockServer(8011, function (request, response) { | ||
writeResponse(200, { | ||
count: 0, | ||
items: [] | ||
}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
if (request.url === '/v1/users') { | ||
return writeResponse(200, { sessionId: 1, sessionSecret: 1 }, response); | ||
} | ||
if (request.url === '/v1/sessions') { | ||
return writeResponse(200, { sessionId: 1, sessionSecret: 1 }, response); | ||
} | ||
writeResponse(200, {}, response); | ||
}); | ||
const server = await createServer({ | ||
servers: [ | ||
'http://localhost:8000', | ||
'http://localhost:8001' | ||
] | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8010', 'http://0.0.0.0:8011'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const session = await createUserAndSession(); | ||
const database = await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
}); | ||
await createCollection(session.asHeaders, database, { | ||
name: 'foundcl' | ||
}); | ||
const response = await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -188,4 +239,6 @@ host: 'founddb.bitabase.test' | ||
mockServer1.close(); | ||
mockServer2.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -200,29 +253,39 @@ t.equal(response.status, 200); | ||
test('[get] missing collection -> two database servers -> proxy to an existing collection with 1 record', async t => { | ||
test('[get] missing collection -> two database servers -> proxy to an existing collection with records', async t => { | ||
t.plan(9); | ||
await bringUp(2); | ||
const mockServer1 = createMockServer(8010, function (request, response) { | ||
writeResponse(200, { | ||
count: 10, | ||
items: Array(10).fill('').map((_, i) => ({ | ||
id: i + 1, | ||
firstName: `Joe${i}`, | ||
lastName: `Bloggs${i}`, | ||
email: `joe.bloggs${i}@example.com` | ||
})) | ||
}, response); | ||
}); | ||
const mockServer2 = createMockServer(8011, function (request, response) { | ||
writeResponse(200, { | ||
count: 10, | ||
items: Array(10).fill('').map((_, i) => ({ | ||
id: i + 11, | ||
firstName: `Bill${i}`, | ||
lastName: `Bloggs${i}`, | ||
email: `joe.bloggs${i}@example.com` | ||
})) | ||
}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(200, {}, response); | ||
}); | ||
const server = await createServer({ | ||
servers: [ | ||
'http://localhost:8000', | ||
'http://localhost:8001' | ||
] | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8010', 'http://0.0.0.0:8011'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const session = await createUserAndSession(); | ||
const database = await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
}); | ||
const collection = await createCollection(session.asHeaders, database, { | ||
name: 'foundcl', | ||
schema: { | ||
firstName: ['required', 'string'], | ||
lastName: ['required', 'string'], | ||
email: ['required', 'string'] | ||
} | ||
}); | ||
// Do a GET to create the collections from manager api... | ||
await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -233,28 +296,4 @@ host: 'founddb.bitabase.test' | ||
const promises = []; | ||
const servers = [ | ||
'http://localhost:8000', | ||
'http://localhost:8001' | ||
]; | ||
for (let i = 0; i < 10; i++) { | ||
promises.push( | ||
createRecord({ | ||
headers: session.asHeaders, | ||
database: database, | ||
collection: collection, | ||
server: servers[i % 2], | ||
data: { | ||
firstName: `Joe${i}`, | ||
lastName: `Bloggs${i}`, | ||
email: `joe.bloggs${i}@example.com` | ||
} | ||
}) | ||
); | ||
} | ||
await Promise.all(promises); | ||
const response = await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -265,8 +304,10 @@ host: 'founddb.bitabase.test' | ||
mockServer1.close(); | ||
mockServer2.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
t.equal(response.status, 200, 'correct status code 200 returned'); | ||
t.equal(response.data.count, 10, 'correct count returned'); | ||
t.equal(response.data.count, 20, 'correct count returned'); | ||
t.equal(response.data.items.length, 10, 'correct items returned'); | ||
@@ -279,66 +320,31 @@ | ||
t.ok(response.data.items.find(item => item.firstName === 'Joe1'), 'a record with firstName Joe1 exists'); | ||
t.ok(response.data.items.find(item => item.lastName === 'Bloggs9'), 'a record with lastName Bloggs9 exists'); | ||
t.ok(response.data.items.find(item => item.firstName === 'Joe4'), 'a record with firstName Joe4 exists'); | ||
t.ok(response.data.items.find(item => item.lastName === 'Bloggs4'), 'a record with lastName Bloggs4 exists'); | ||
}); | ||
async function setupNewCollectionWithRecords (recordCount) { | ||
const session = await createUserAndSession(); | ||
const database = await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
}); | ||
const collection = await createCollection(session.asHeaders, database, { | ||
name: 'foundcl', | ||
schema: { | ||
firstName: ['required', 'string'], | ||
lastName: ['required', 'string'], | ||
email: ['required', 'string'] | ||
} | ||
}); | ||
test('[get] missing collection -> two database servers -> proxy to an existing collection containing 1 record with a filter', async t => { | ||
t.plan(4); | ||
// Do a GET to create the collections from manager api... | ||
await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
headers: { | ||
host: 'founddb.bitabase.test' | ||
} | ||
}); | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
const url = new URL(`http://localhost${request.url}`); | ||
const promises = []; | ||
const servers = [ | ||
'http://localhost:8000', | ||
'http://localhost:8001' | ||
]; | ||
t.equal(url.searchParams.get('query'), '{"firstName":"Joe4"}'); | ||
for (let i = 0; i < recordCount; i++) { | ||
promises.push( | ||
createRecord({ | ||
headers: session.asHeaders, | ||
database: database, | ||
collection: collection, | ||
server: servers[i % 2], | ||
data: { | ||
firstName: `Joe${i}`, | ||
lastName: `Bloggs${i}`, | ||
email: `joe.bloggs${i}@example.com` | ||
} | ||
}) | ||
); | ||
} | ||
writeResponse(200, { | ||
count: 1, | ||
items: [{ | ||
headerTest: 'yes' | ||
}] | ||
}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(200, {}, response); | ||
}); | ||
return Promise.all(promises); | ||
} | ||
test('[get] missing collection -> two database servers -> proxy to an existing collection containing 1 record with a filter', async t => { | ||
t.plan(7); | ||
await bringUp(2); | ||
const server = await createServer({ | ||
servers: [ | ||
'http://localhost:8000', | ||
'http://localhost:8001' | ||
] | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
await setupNewCollectionWithRecords(10); | ||
const query = querystring.stringify({ | ||
@@ -351,3 +357,3 @@ query: JSON.stringify({ | ||
const response = await httpRequest(`/foundcl?${query}`, { | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -358,4 +364,5 @@ host: 'founddb.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -366,24 +373,38 @@ t.equal(response.status, 200, 'correct status code 200 returned'); | ||
t.equal(response.data.items.length, 1, 'correct items returned'); | ||
t.ok(response.data.items[0].id, 'first item has id field'); | ||
t.equal(response.data.items[0].firstName, 'Joe4', 'first item firstName was Joe4'); | ||
t.equal(response.data.items[0].lastName, 'Bloggs4', 'first item firstName was Bloggs4'); | ||
t.equal(response.data.items[0].email, 'joe.bloggs4@example.com', 'first item email was joe.bloggs4@example.com'); | ||
}); | ||
test('[get] missing collection -> two database servers -> proxy to an existing collection containing 100 records with default pagination', async t => { | ||
t.plan(3); | ||
test('[get] missing collection -> two database servers -> proxy to an existing collection containing 1 record with pagination', async t => { | ||
t.plan(4); | ||
await bringUp(2); | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
const url = new URL(`http://localhost${request.url}`); | ||
t.equal(url.searchParams.get('query'), '{"limit":25,"offset":50}'); | ||
writeResponse(200, { | ||
count: 1, | ||
items: [{ | ||
headerTest: 'yes' | ||
}] | ||
}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(200, {}, response); | ||
}); | ||
const server = await createServer({ | ||
servers: [ | ||
'http://localhost:8000', | ||
'http://localhost:8001' | ||
] | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
await setupNewCollectionWithRecords(100); | ||
const query = querystring.stringify({ | ||
query: JSON.stringify({ | ||
limit: 25, | ||
offset: 50 | ||
}) | ||
}); | ||
const response = await httpRequest('/foundcl', { | ||
baseURL: 'http://localhost:8082', | ||
const response = await httpRequest(`/foundcl?${query}`, { | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -394,9 +415,10 @@ host: 'founddb.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
t.equal(response.status, 200, 'correct status code 200 returned'); | ||
t.equal(response.data.count, 100, 'correct count returned'); | ||
t.equal(response.data.items.length, 10, 'correct items returned'); | ||
t.equal(response.data.count, 1, 'correct count returned'); | ||
t.equal(response.data.items.length, 1, 'correct items returned'); | ||
}); |
const test = require('tape'); | ||
const writeResponse = require('write-response'); | ||
const finalStream = require('final-stream'); | ||
const { promisify } = require('util'); | ||
const { bringUp, bringDown } = require('../helpers/environment'); | ||
const httpRequest = require('../helpers/httpRequest'); | ||
const { createUserAndSession } = require('../helpers/session'); | ||
const createMockServer = require('../helpers/createMockServer'); | ||
const { | ||
createDatabase, | ||
createCollection | ||
} = require('../helpers/databases'); | ||
const createServer = require('../../server'); | ||
@@ -18,9 +14,19 @@ | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const result = await httpRequest('/one', { | ||
method: 'post', | ||
data: { a: 1 }, | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -31,4 +37,5 @@ host: 'notfound.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -45,14 +52,19 @@ t.equal(result.status, 404); | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const session = await createUserAndSession(); | ||
await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(404, {}, response); | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const result = await httpRequest('/notfoundcollection', { | ||
method: 'post', | ||
data: { a: 1 }, | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -63,4 +75,5 @@ host: 'founddb.bitabase.test' | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -75,15 +88,37 @@ t.equal(result.status, 404); | ||
test('[post] missing collection -> proxy to an existing collection', async t => { | ||
t.plan(10); | ||
t.plan(5); | ||
await bringUp(); | ||
const server = await createServer().start(); | ||
const mockServer = createMockServer(8000, function (request, response) { | ||
finalStream(request, function (error, rawBody) { | ||
if (error) { | ||
throw error; | ||
} | ||
const session = await createUserAndSession(); | ||
const database = await createDatabase(session.asHeaders, { | ||
name: 'founddb' | ||
if (request.method === 'POST') { | ||
let body; | ||
try { | ||
body = JSON.parse(rawBody); | ||
} catch (error) {} | ||
writeResponse(201, { | ||
...body, | ||
id: Date.now() | ||
}, response); | ||
return; | ||
} | ||
writeResponse(200, {}, response); | ||
}); | ||
}); | ||
await createCollection(session.asHeaders, database, { | ||
name: 'foundcl' | ||
const mockManager = createMockServer(8001, function (request, response) { | ||
writeResponse(200, {}, response); | ||
}); | ||
const server = await createServer({ | ||
secret: 'test', | ||
servers: ['http://0.0.0.0:8000'], | ||
managers: ['http://0.0.0.0:8001'] | ||
}).start(); | ||
const createResponse = await httpRequest('/foundcl', { | ||
@@ -96,3 +131,3 @@ method: 'post', | ||
}, | ||
baseURL: 'http://localhost:8082', | ||
baseURL: 'http://localhost:8002', | ||
headers: { | ||
@@ -103,11 +138,5 @@ host: 'founddb.bitabase.test' | ||
const getResponse = await httpRequest(`/foundcl/${createResponse.data.id}`, { | ||
baseURL: 'http://localhost:8082', | ||
headers: { | ||
host: 'founddb.bitabase.test' | ||
} | ||
}); | ||
mockServer.close(); | ||
mockManager.close(); | ||
await promisify(server.stop)(); | ||
await bringDown(); | ||
@@ -119,8 +148,2 @@ t.equal(createResponse.status, 201); | ||
t.ok(createResponse.data.id); | ||
t.equal(getResponse.status, 200); | ||
t.equal(getResponse.data.firstName, 'Joe'); | ||
t.equal(getResponse.data.lastName, 'Bloggs'); | ||
t.equal(getResponse.data.email, 'joe.bloggs@example.com'); | ||
t.equal(getResponse.data.id, createResponse.data.id); | ||
}); |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
76034
1077
18
5
29
2
+ Addedasync-bugs@^1.1.0
+ Addedchalk@^4.1.0
+ Addedfinal-stream@^1.1.0
+ Addedminimist@^1.2.5
+ Addedrqlite-fp@^2.8.1
+ Addedansi-styles@4.3.0(transitive)
+ Addedasync-bugs@1.1.2(transitive)
+ Addedbig-integer@1.6.52(transitive)
+ Addedbinary@0.3.0(transitive)
+ Addedbluebird@3.4.7(transitive)
+ Addedbuffer-indexof-polyfill@1.0.2(transitive)
+ Addedbuffers@0.1.1(transitive)
+ Addedcalladownload@1.2.1(transitive)
+ Addedcalladownload-extract@1.2.0(transitive)
+ Addedcallarest@2.0.2(transitive)
+ Addedchainsaw@0.1.0(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedchownr@2.0.0(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addedduplexer2@0.1.4(transitive)
+ Addedfinal-stream@1.1.1(transitive)
+ Addedfollow-redirects@1.15.6(transitive)
+ Addedfs-minipass@2.1.0(transitive)
+ Addedfstream@1.0.12(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedlistenercount@1.0.1(transitive)
+ Addedminipass@3.3.65.0.0(transitive)
+ Addedminizlib@2.1.2(transitive)
+ Addedmkdirp@1.0.4(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedrqlite-fp@2.10.1(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedsqlstring@2.3.3(transitive)
+ Addedstack-chain@2.0.0(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedsupports-color@7.2.0(transitive)
+ Addedtar@6.2.1(transitive)
+ Addedtrace@3.1.1(transitive)
+ Addedtrace-cleaner@1.2.3(transitive)
+ Addedtraverse@0.3.9(transitive)
+ Addedunzipper@0.10.14(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedyallist@4.0.0(transitive)
- Removed@bcoe/v8-coverage@0.2.3(transitive)
- Removed@types/is-windows@0.2.0(transitive)
- Removed@types/istanbul-lib-coverage@2.0.6(transitive)
- Removedansi-regex@4.1.1(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedc8@6.0.1(transitive)
- Removedcallarest@1.6.0(transitive)
- Removedcamelcase@5.3.1(transitive)
- Removedcliui@5.0.0(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedconvert-source-map@1.9.0(transitive)
- Removedcross-spawn@7.0.3(transitive)
- Removeddecamelize@1.2.0(transitive)
- Removedemoji-regex@7.0.3(transitive)
- Removederror-ex@1.3.2(transitive)
- Removedfind-up@3.0.04.1.0(transitive)
- Removedforeground-child@2.0.0(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedfuri@1.3.0(transitive)
- Removedget-caller-file@2.0.5(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedhosted-git-info@2.8.9(transitive)
- Removedhtml-escaper@2.0.2(transitive)
- Removedis-arrayish@0.2.1(transitive)
- Removedis-core-module@2.13.1(transitive)
- Removedis-fullwidth-code-point@2.0.0(transitive)
- Removedis-windows@1.0.2(transitive)
- Removedisexe@2.0.0(transitive)
- Removedistanbul-lib-coverage@2.0.5(transitive)
- Removedistanbul-lib-report@2.0.8(transitive)
- Removedistanbul-reports@2.2.7(transitive)
- Removedjson-parse-better-errors@1.0.2(transitive)
- Removedload-json-file@4.0.0(transitive)
- Removedlocate-path@3.0.05.0.0(transitive)
- Removedmake-dir@2.1.0(transitive)
- Removednormalize-package-data@2.5.0(transitive)
- Removedp-limit@2.3.0(transitive)
- Removedp-locate@3.0.04.1.0(transitive)
- Removedp-try@2.2.0(transitive)
- Removedparse-json@4.0.0(transitive)
- Removedpath-exists@3.0.04.0.0(transitive)
- Removedpath-key@3.1.1(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedpath-type@3.0.0(transitive)
- Removedpify@3.0.04.0.1(transitive)
- Removedread-pkg@3.0.0(transitive)
- Removedread-pkg-up@4.0.0(transitive)
- Removedrequire-directory@2.1.1(transitive)
- Removedrequire-main-filename@2.0.0(transitive)
- Removedresolve@1.22.8(transitive)
- Removedrimraf@3.0.2(transitive)
- Removedsemver@5.7.2(transitive)
- Removedset-blocking@2.0.0(transitive)
- Removedshebang-command@2.0.0(transitive)
- Removedshebang-regex@3.0.0(transitive)
- Removedsignal-exit@3.0.7(transitive)
- Removedsource-map@0.7.4(transitive)
- Removedspdx-correct@3.2.0(transitive)
- Removedspdx-exceptions@2.5.0(transitive)
- Removedspdx-expression-parse@3.0.1(transitive)
- Removedspdx-license-ids@3.0.18(transitive)
- Removedstring-width@3.1.0(transitive)
- Removedstrip-ansi@5.2.0(transitive)
- Removedstrip-bom@3.0.0(transitive)
- Removedsupports-color@6.1.0(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removedtest-exclude@5.2.3(transitive)
- Removedv8-to-istanbul@3.2.6(transitive)
- Removedvalidate-npm-package-license@3.0.4(transitive)
- Removedwhich@2.0.2(transitive)
- Removedwhich-module@2.0.1(transitive)
- Removedwrap-ansi@5.1.0(transitive)
- Removedy18n@4.0.3(transitive)
- Removedyargs@14.2.3(transitive)
- Removedyargs-parser@15.0.3(transitive)
Updatedcallarest@^2.0.1
Updatedwrite-response@^1.2.2