diff --git a/api/controllers/application.js b/api/controllers/application.js index cebaadf..d37bc33 100644 --- a/api/controllers/application.js +++ b/api/controllers/application.js @@ -156,13 +156,17 @@ exports.publicGet = function(args, res, next) { }; exports.protectedGet = function(args, res, next) { + var query = {}; + var sort = {}; var skip = null; var limit = null; - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on appId route - var query = {}; if (args.swagger.params.appId) { query = Utils.buildQuery('_id', args.swagger.params.appId.value, query); } else { @@ -171,6 +175,12 @@ exports.protectedGet = function(args, res, next) { skip = processedParameters.skip; limit = processedParameters.limit; + if (args.swagger.params.sortBy && args.swagger.params.sortBy.value) { + var order_by = args.swagger.params.sortBy.value.charAt(0) == '-' ? -1 : 1; + var sort_by = args.swagger.params.sortBy.value.slice(1); + sort[sort_by] = order_by; + } + try { query = addStandardQueryFilters(query, args); } catch (error) { @@ -192,7 +202,7 @@ exports.protectedGet = function(args, res, next) { query, getSanitizedFields(args.swagger.params.fields.value), // Fields null, // sort warmup - null, // sort + sort, // sort skip, // skip limit, // limit false @@ -207,7 +217,10 @@ exports.protectedGet = function(args, res, next) { }; exports.protectedHead = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on appId route var query = {}; @@ -719,10 +732,18 @@ var addStandardQueryFilters = function(query, args) { _.assignIn(query, { agency: args.swagger.params.agency.value }); } if (args.swagger.params.businessUnit && args.swagger.params.businessUnit.value !== undefined) { - _.assignIn(query, { businessUnit: args.swagger.params.businessUnit.value }); + _.assignIn(query, { businessUnit: { $eq: args.swagger.params.businessUnit.value.eq } }); } if (args.swagger.params.client && args.swagger.params.client.value !== undefined) { - _.assignIn(query, { client: args.swagger.params.client.value }); + var queryString = qs.parse(args.swagger.params.client.value); + if (queryString.text) { + // This searches for text indexed fields, which client is currently marked as in the application model. + // If more fields are added to the text index, this logic may need to change as it will then search those fields + // as well, which may be un-desired. See docs.mongodb.com/manual/reference/operator/query/text/ + _.assignIn(query, { $text: { $search: queryString.text } }); + } else if (queryString.eq) { + _.assignIn(query, { client: { $eq: queryString.eq } }); + } } if (args.swagger.params.tenureStage && args.swagger.params.tenureStage.value !== undefined) { _.assignIn(query, { tenureStage: args.swagger.params.tenureStage.value }); @@ -831,6 +852,8 @@ var addStandardQueryFilters = function(query, args) { } } + defaultLog.debug('query:', JSON.stringify(query)); + return query; }; /* eslint-enable no-redeclare */ diff --git a/api/controllers/comment.js b/api/controllers/comment.js index 01dd616..fa04f2c 100644 --- a/api/controllers/comment.js +++ b/api/controllers/comment.js @@ -103,7 +103,10 @@ exports.publicGet = function(args, res, next) { }; exports.protectedHead = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on CommentPeriodId route var query = {}; diff --git a/api/controllers/commentperiod.js b/api/controllers/commentperiod.js index 812345f..cd9e534 100644 --- a/api/controllers/commentperiod.js +++ b/api/controllers/commentperiod.js @@ -42,7 +42,10 @@ exports.publicGet = function(args, res, next) { }; exports.protectedHead = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on CommentPeriodId route var query = {}; @@ -85,7 +88,10 @@ exports.protectedHead = function(args, res, next) { }; exports.protectedGet = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on CommentPeriodId route var query = {}; diff --git a/api/controllers/decision.js b/api/controllers/decision.js index d97d7fe..e662689 100644 --- a/api/controllers/decision.js +++ b/api/controllers/decision.js @@ -42,7 +42,10 @@ exports.publicGet = function(args, res, next) { }; exports.protectedHead = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on decisionId route var query = {}; @@ -82,7 +85,10 @@ exports.protectedHead = function(args, res, next) { }; exports.protectedGet = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on decisionId route var query = {}; diff --git a/api/controllers/document.js b/api/controllers/document.js index e678398..b7b2d72 100644 --- a/api/controllers/document.js +++ b/api/controllers/document.js @@ -107,7 +107,10 @@ exports.unProtectedPost = function(args, res, next) { }; exports.protectedHead = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on docId route var query = {}; @@ -153,7 +156,10 @@ exports.protectedHead = function(args, res, next) { }; exports.protectedGet = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on docId route var query = {}; @@ -229,7 +235,10 @@ exports.publicDownload = function(args, res, next) { }; exports.protectedDownload = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on docId route var query = {}; diff --git a/api/controllers/feature.js b/api/controllers/feature.js index 140db58..a4c4e8a 100644 --- a/api/controllers/feature.js +++ b/api/controllers/feature.js @@ -43,7 +43,10 @@ exports.publicGet = function(args, res, next) { }); }; exports.protectedGet = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); var query = {}; // Build match query if on featureId route @@ -88,7 +91,10 @@ exports.protectedGet = function(args, res, next) { exports.protectedDelete = function(args, res, next) { defaultLog.info('Deleting a Feature(s)'); - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); var Feature = mongoose.model('Feature'); var query = {}; diff --git a/api/controllers/user.js b/api/controllers/user.js index 7d41f58..8eaf5b5 100644 --- a/api/controllers/user.js +++ b/api/controllers/user.js @@ -10,7 +10,10 @@ exports.protectedOptions = function(args, res, rest) { }; exports.protectedGet = function(args, res, next) { - defaultLog.info('args.swagger.params:', JSON.stringify(args.swagger.operation['x-security-scopes'])); + defaultLog.info( + 'args.swagger.operation.x-security-scopes:', + JSON.stringify(args.swagger.operation['x-security-scopes']) + ); // Build match query if on userId route var query = {}; diff --git a/api/helpers/models/application.js b/api/helpers/models/application.js index 88023f5..e1c2a8b 100644 --- a/api/helpers/models/application.js +++ b/api/helpers/models/application.js @@ -30,5 +30,8 @@ module.exports = require('../models')('Application', { // Note: Default on tag property is purely for display only, they have no real effect on the model. // This must be done in the code. - tags: [[{ type: String, trim: true, default: '[["sysadmin"]]' }]] // updated by API + tags: [[{ type: String, trim: true, default: '[["sysadmin"]]' }]], // updated by API + + // Used to enable client (applicant) $text search. + __index: { client: 'text' } }); diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 8c1d8cd..4c54d35 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -421,7 +421,6 @@ definitions: - _addedBy - _application - tags - - name - startDate - endDate - isDeleted @@ -1038,6 +1037,11 @@ paths: format: date-time required: false description: "Status History Effective Date that Applications must compare to" + - in: query + name: sortBy + type: string + required: false + description: "Application field to sort by" responses: "200": description: "Success" @@ -1637,6 +1641,7 @@ paths: required: false description: "Publish Date(s) that Applications must match" type: string + format: date-time responses: "200": description: "Success" diff --git a/database.json b/database.json index e373e27..31d2479 100644 --- a/database.json +++ b/database.json @@ -25,33 +25,6 @@ "host": "MONGODB_SERVICE_HOST" }, - "demo": { - "driver": "mongodb", - "database": { "ENV": "MONGODB_DATABASE" }, - "user": { "ENV": "MONGODB_USERNAME" }, - "password": { "ENV": "MONGODB_PASSWORD" }, - "authSource": "admin", - "host": "DEMO_MONGODB_SERVICE_HOST" - }, - - "scale": { - "driver": "mongodb", - "database": { "ENV": "MONGODB_DATABASE" }, - "user": { "ENV": "MONGODB_USERNAME" }, - "password": { "ENV": "MONGODB_PASSWORD" }, - "authSource": "admin", - "host": "MONGODB_SCALE_SERVICE_HOST" - }, - - "beta": { - "driver": "mongodb", - "database": { "ENV": "MONGODB_DATABASE" }, - "user": { "ENV": "MONGODB_USERNAME" }, - "password": { "ENV": "MONGODB_PASSWORD" }, - "authSource": "admin", - "host": "MONGODB_BETA_SERVICE_HOST" - }, - "master": { "driver": "mongodb", "database": { "ENV": "MONGODB_DATABASE" }, diff --git a/package.json b/package.json index 968968d..126ed7d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "main": "app", "scripts": { "start": "node app", - "test": "echo Test suite should be run with `npm run tests` or npm `run tests-ci`", + "test": "echo Test suite should be run with `npm run tests` or `npm run tests-ci`", "tests": "SET UPLOAD_DIRECTORY=./api/test/uploads/ & jest --runInBand", "tests-debug": "node --inspect node_modules/.bin/jest --runInBand", "lint": "eslint .",