q3-core-composer
Advanced tools
Comparing version 1.18.5 to 1.19.0
@@ -6,2 +6,14 @@ # Change Log | ||
# [1.19.0](https://github.com/3merge/q3-api/compare/v1.18.5...v1.19.0) (2021-08-16) | ||
### Features | ||
* new changelog manager ([#142](https://github.com/3merge/q3-api/issues/142)) ([d7f6d21](https://github.com/3merge/q3-api/commit/d7f6d213bf4dc1122de7ad0fcdf667e3b21a15ac)) | ||
## [1.18.5](https://github.com/3merge/q3-api/compare/v1.18.4...v1.18.5) (2021-07-27) | ||
@@ -8,0 +20,0 @@ |
@@ -12,2 +12,3 @@ const connect = require('connect'); | ||
const isVerified = require('./middleware/isLoggedIn'); | ||
const { formatAsArray } = require('./utils'); | ||
@@ -41,3 +42,3 @@ const flatten = (a = [], b = []) => { | ||
sessionMiddleware, | ||
...(ctr.postAuthorization ? ctr.postAuthorization : []), | ||
flatten(formatAsArray(ctr.postAuthorization)), | ||
aa(ctr), | ||
@@ -50,2 +51,3 @@ ]); | ||
verify: isVerified, // alias | ||
isLoggedIn: isVerified, // alias | ||
isVerified, | ||
@@ -52,0 +54,0 @@ isAuthorized, |
@@ -32,5 +32,3 @@ const ApiMock = require('q3-test-utils/helpers/apiMock'); | ||
const fn = IsAuthorized(model) | ||
.inResponse('foo') | ||
.requireField('bar'); | ||
const fn = IsAuthorized(model).inResponse('foo'); | ||
@@ -42,5 +40,4 @@ const next = jest.fn(); | ||
expect(next).toHaveBeenCalledWith(); | ||
// expect(fn.locations.request).toEqual(['query', 'body']); | ||
expect(fn.locations.response).toEqual(['foo']); | ||
expect(fn.locations.required).toBe('bar'); | ||
}); | ||
@@ -55,5 +52,3 @@ | ||
const fn = IsAuthorized(model) | ||
.inResponse('foo') | ||
.requireField('bar'); | ||
const fn = IsAuthorized(model).inResponse('foo'); | ||
@@ -66,39 +61,3 @@ const next = jest.fn(); | ||
expect(fn.locations.response).toEqual(['foo']); | ||
expect(fn.locations.required).toBe('bar'); | ||
}); | ||
test.each([ | ||
['*', ['foo', 'bar'], {}, true], | ||
[['!quuz'], ['foo', 'bar'], {}, true], | ||
[['!foo'], ['foo', 'bar'], {}, false], | ||
[ | ||
[{ glob: 'quuz', negate: true, test: ['foo=1'] }], | ||
['foo', 'bar'], | ||
{}, | ||
true, | ||
], | ||
[ | ||
[{ glob: 'foo', negate: true, test: ['quuz=1'] }], | ||
['foo', 'bar'], | ||
{ foo: 1, bar: 1, quuz: 1 }, | ||
false, | ||
], | ||
])( | ||
'.meetsFieldRequirements()', | ||
(fields, required, body, expected) => { | ||
const out = IsAuthorized( | ||
'Test', | ||
).meetsFieldRequirements.call( | ||
{ | ||
locations: { | ||
required, | ||
}, | ||
}, | ||
fields, | ||
body, | ||
); | ||
expect(out).toBe(expected); | ||
}, | ||
); | ||
}); |
const { Grant } = require('q3-core-access'); | ||
const { get, invoke } = require('lodash'); | ||
const authorizeBody = require('./authorizeBody'); | ||
@@ -30,44 +29,2 @@ class Session { | ||
} | ||
setOperation() { | ||
switch (this.method) { | ||
case 'PATCH': | ||
case 'PUT': | ||
this.op = 'Update'; | ||
break; | ||
case 'GET': | ||
this.op = 'Read'; | ||
break; | ||
case 'POST': | ||
this.op = 'Create'; | ||
break; | ||
case 'DELETE': | ||
this.op = 'Delete'; | ||
break; | ||
default: | ||
throw new Error('Method not allowed'); | ||
} | ||
return this; | ||
} | ||
getPermission(collectionName, sessionUser) { | ||
const gen = (op) => | ||
new Grant(sessionUser) | ||
.can(op) | ||
.on(collectionName) | ||
.first(); | ||
const primary = gen(this.op); | ||
const secondary = gen('Read'); | ||
/** | ||
* @NOTE | ||
* Used to redact responses on non-read operations. | ||
*/ | ||
if (primary && secondary) | ||
primary.readOnly = secondary.fields; | ||
return primary; | ||
} | ||
} | ||
@@ -104,7 +61,7 @@ | ||
req.authorize = (collectionName) => | ||
identity | ||
.setOperation() | ||
.getPermission(collectionName, req.user); | ||
new Grant(req.user) | ||
.can('Read') | ||
.on(collectionName) | ||
.first(); | ||
authorizeBody(req); | ||
next(); | ||
@@ -111,0 +68,0 @@ }; |
@@ -1,6 +0,2 @@ | ||
const { size, compact, flatten } = require('lodash'); | ||
const { exception } = require('q3-core-responder'); | ||
const { Redact } = require('q3-core-access'); | ||
const hasField = require('./hasField'); | ||
const { moveWithinPropertyName } = require('../utils'); | ||
@@ -23,7 +19,3 @@ class IsAuthorizedInLocationRef { | ||
const grant = req.authorize(m); | ||
const { fields } = grant; | ||
if (!this.meetsFieldRequirements(fields, req.body)) | ||
throw new Error('Incomplete grant'); | ||
if (!Array.isArray(req.redactions)) | ||
@@ -43,3 +35,5 @@ req.redactions = []; | ||
req.user ? 'Authorization' : 'Authentication', | ||
).boomerang(), | ||
) | ||
.msg(err.message) | ||
.boomerang(), | ||
); | ||
@@ -58,51 +52,4 @@ } | ||
} | ||
requireField(field) { | ||
this.locations.required = hasField(this.source, field); | ||
return this; | ||
} | ||
meetsFieldRequirements(fields, body = {}) { | ||
const { required } = this.locations; | ||
const requiredPaths = compact(flatten([required])); | ||
if (!size(requiredPaths)) return true; | ||
try { | ||
const passedKeys = Object.keys( | ||
Redact.flattenAndReduceByFields( | ||
{ | ||
...requiredPaths.reduce( | ||
(acc, curr) => | ||
Object.assign(acc, { [curr]: 1 }), | ||
{}, | ||
), | ||
// a non-array indicates we just need a match | ||
// at the top-level | ||
...(Array.isArray(required) | ||
? moveWithinPropertyName( | ||
this.locations.prefix, | ||
body, | ||
) | ||
: body), | ||
}, | ||
{ | ||
fields, | ||
}, | ||
{ | ||
includeConditionalGlobs: true, | ||
keepFlat: true, | ||
}, | ||
), | ||
); | ||
return requiredPaths.every((item) => | ||
passedKeys.includes(item), | ||
); | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
} | ||
module.exports = (m) => new IsAuthorizedInLocationRef(m); |
const mung = require('express-mung'); | ||
const { kill } = require('q3-core-session'); | ||
const { Redact } = require('q3-core-access'); | ||
const { isObject, get } = require('lodash'); | ||
const { compact, isObject, get } = require('lodash'); | ||
const { | ||
@@ -13,2 +13,9 @@ mapAsync, | ||
const getDefaultPathValue = (xs) => | ||
Array.isArray( | ||
get(get(res, 'locals.fullParentDocument'), xs), | ||
) | ||
? [] | ||
: {}; | ||
const decorateWithLocals = (activeDocument) => { | ||
@@ -39,2 +46,3 @@ const fullParentDocument = get( | ||
const execRedactFn = async (data) => { | ||
const defaultOutput = getDefaultPathValue(select); | ||
const baseInput = moveWithinPropertyName( | ||
@@ -51,3 +59,9 @@ select, | ||
return get(baseOutput, select, baseOutput); | ||
const output = select | ||
? get(baseOutput, select, defaultOutput) | ||
: baseOutput; | ||
return Array.isArray(output) | ||
? compact(output) | ||
: output; | ||
}; | ||
@@ -54,0 +68,0 @@ |
@@ -1,4 +0,10 @@ | ||
const { clean, toJSON, merge } = require('../formatters'); | ||
const { | ||
clean, | ||
toJSON, | ||
merge, | ||
formatAsArray, | ||
} = require('../formatters'); | ||
const d = new Date(); | ||
const fn = jest.fn(); | ||
@@ -25,2 +31,11 @@ test.each([ | ||
test.each([ | ||
[[fn], [fn]], | ||
[fn, [fn]], | ||
[undefined, []], | ||
[[null], []], | ||
])('.formatAsArray', (a, expected) => { | ||
expect(formatAsArray(a)).toEqual(expected); | ||
}); | ||
test.each([ | ||
[ | ||
@@ -27,0 +42,0 @@ { foo: 1, bar: 1 }, |
@@ -57,2 +57,5 @@ /* eslint-disable no-nested-ternary */ | ||
const formatAsArray = (xs) => | ||
(Array.isArray(xs) ? xs : [xs].flat()).filter(isFunction); | ||
module.exports = { | ||
@@ -65,2 +68,3 @@ clean, | ||
merge, | ||
formatAsArray, | ||
}; |
{ | ||
"name": "q3-core-composer", | ||
"version": "1.18.5", | ||
"version": "1.19.0", | ||
"main": "lib/index.js", | ||
@@ -16,8 +16,8 @@ "dependencies": { | ||
"mongoose": "^5.11.8", | ||
"q3-core-access": "^1.18.5", | ||
"q3-core-responder": "^1.18.5", | ||
"q3-core-session": "^1.7.15" | ||
"q3-core-access": "^1.19.0", | ||
"q3-core-responder": "^1.19.0", | ||
"q3-core-session": "^1.19.0" | ||
}, | ||
"devDependencies": { | ||
"q3-test-utils": "^1.18.5", | ||
"q3-test-utils": "^1.19.0", | ||
"supertest": "^6.0.1" | ||
@@ -36,3 +36,3 @@ }, | ||
}, | ||
"gitHead": "21bf04f31308ceffc2078e4954b10d58b07b7cc9" | ||
"gitHead": "8915133b3a5b239dd2e61a4e0bb094bc5a68831d" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
486683
20
692
Updatedq3-core-access@^1.19.0
Updatedq3-core-responder@^1.19.0
Updatedq3-core-session@^1.19.0