1 | const micromatch = require('micromatch');
|
2 | const { set } = require('lodash');
|
3 | const { exception } = require('q3-core-responder');
|
4 | const hasField = require('./hasField');
|
5 |
|
6 | class IsAuthorizedInLocationRef {
|
7 | constructor(modelName) {
|
8 | this.source = modelName;
|
9 | this.locations = {
|
10 | request: [],
|
11 | response: [],
|
12 | };
|
13 | }
|
14 |
|
15 | done() {
|
16 | return this.middleware.bind(this);
|
17 | }
|
18 |
|
19 | middleware(req, res, next) {
|
20 | try {
|
21 | const m = this.source;
|
22 | const grant = req.authorize(m);
|
23 | const { fields, readOnly } = grant;
|
24 |
|
25 | if (!this.meetsFieldRequirements(fields))
|
26 | throw new Error('Failed field authorization');
|
27 |
|
28 | set(req, `redactions.${m}`, {
|
29 | locations: this.locations,
|
30 | readOnly,
|
31 | fields,
|
32 | });
|
33 |
|
34 | req.grant = grant;
|
35 | next();
|
36 | } catch (err) {
|
37 | next(exception('Authorization').boomerang());
|
38 | }
|
39 | }
|
40 |
|
41 | withPrefix(prefix) {
|
42 | this.locations.prefix = prefix;
|
43 | return this;
|
44 | }
|
45 |
|
46 | inRequest(location) {
|
47 | this.locations.request.push(location);
|
48 | return this;
|
49 | }
|
50 |
|
51 | inResponse(location) {
|
52 | this.locations.response.push(location);
|
53 | return this;
|
54 | }
|
55 |
|
56 | requireField(field) {
|
57 | this.locations.required = hasField(this.source, field);
|
58 | return this;
|
59 | }
|
60 |
|
61 | meetsFieldRequirements(fields) {
|
62 | const { required } = this.locations;
|
63 | if (!required) return true;
|
64 |
|
65 | return Array.isArray(required)
|
66 | ? micromatch(required, fields).length ===
|
67 | required.length
|
68 | : micromatch.isMatch(this.locations.required, fields);
|
69 | }
|
70 | }
|
71 |
|
72 | module.exports = (m) => new IsAuthorizedInLocationRef(m);
|
73 |
|
\ | No newline at end of file |