@universis/janitor 1.6.1 → 1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -296,6 +296,45 @@ app.use('/api', passport.authenticate('bearer', {session: false}), validateScope
296
296
 
297
297
  A `403 - Access denied due to authorization scopes` error will be thrown if the user does not have access to the resource.
298
298
 
299
+ ## ExtendScopeAccessConfiguration
300
+
301
+ `ExtendScopeAccessConfiguration` is a configurable application service for extending scope access configuration with additional scopes.
302
+
303
+ Register service under application services:
304
+
305
+ ```json
306
+ {
307
+ "services": [
308
+ {
309
+ "serviceType": "@universis/janitor#ExtendScopeAccessConfiguration"
310
+ }
311
+ ]
312
+ }
313
+ ```
314
+
315
+ add `scopeAccess` section under `settings/universis/janitor` configuration and start configuring scope access extension:
316
+
317
+ ```json
318
+ {
319
+ "settings": {
320
+ "universis": {
321
+ "janitor": {
322
+ "scopeAccess": {
323
+ "imports": [
324
+ "./custom.scope.access.json"
325
+ ],
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+ ```
332
+
333
+ `ExtendScopeAccessConfiguration` service will import additional scope access configuration from the files listed in the `imports` array. The file path is relative to the application configuration directory e.g. `server/config/` where the main configuration file is located.
334
+
335
+ The given files should contain an array of scope access configuration elements as described in the `ScopeAccessConfiguration` section.
336
+
337
+
299
338
  ## RemoteAddressValidator
300
339
 
301
340
  `RemoteAddressValidator` is a configurable application service for validating access to service endpoints based on remote address provided by OAuth2 token.
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.ScopeString = exports.ScopeAccessConfiguration = exports.DefaultScopeAccessConfiguration = void 0;var _common = require("@themost/common");
1
+ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.ScopeString = exports.ScopeAccessConfiguration = exports.ExtendScopeAccessConfiguration = exports.DefaultScopeAccessConfiguration = void 0;var _common = require("@themost/common");
2
2
  var _path = _interopRequireDefault(require("path"));
3
3
  var _url = _interopRequireDefault(require("url"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
4
4
 
@@ -119,5 +119,42 @@ class DefaultScopeAccessConfiguration extends ScopeAccessConfiguration {
119
119
  }
120
120
  this.elements.push.apply(this.elements, defaults);
121
121
  }
122
- }exports.DefaultScopeAccessConfiguration = DefaultScopeAccessConfiguration;
122
+ }
123
+
124
+
125
+ /**
126
+ * @class
127
+ */exports.DefaultScopeAccessConfiguration = DefaultScopeAccessConfiguration;
128
+ class ExtendScopeAccessConfiguration extends _common.ApplicationService {
129
+ constructor(app) {var _app$getConfiguration, _app$getConfiguration2;
130
+ super(app);
131
+ // Get the additional scope access extensions from the configuration
132
+ const scopeAccessExtensions = (_app$getConfiguration = app.getConfiguration().settings.universis) === null || _app$getConfiguration === void 0 ? void 0 : (_app$getConfiguration2 = _app$getConfiguration.janitor) === null || _app$getConfiguration2 === void 0 ? void 0 : _app$getConfiguration2.scopeAccess["imports"];
133
+ if (app && app.container && scopeAccessExtensions != null) {
134
+ app.container.subscribe((container) => {
135
+ if (container) {
136
+ const scopeAccess = app.getConfiguration().getStrategy(function ScopeAccessConfiguration() {});
137
+ if (scopeAccess != null) {
138
+ for (const scopeAccessExtension of scopeAccessExtensions) {
139
+ try {
140
+ const element = require(_path.default.resolve(app.getConfiguration().getConfigurationPath(), scopeAccessExtension));
141
+ if (element) {
142
+ // add extra scope access elements
143
+ scopeAccess.elements.push.apply(scopeAccess.elements, element);
144
+ }
145
+ }
146
+ catch (err) {
147
+ // if an error occurred other than module not found (there are no default access policies)
148
+ if (err.code !== 'MODULE_NOT_FOUND') {
149
+ // throw error
150
+ throw err;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ });
157
+ }
158
+ }
159
+ }exports.ExtendScopeAccessConfiguration = ExtendScopeAccessConfiguration;
123
160
  //# sourceMappingURL=ScopeAccessConfiguration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScopeAccessConfiguration.js","names":["_common","require","_path","_interopRequireDefault","_url","obj","__esModule","default","HTTP_METHOD_REGEXP","ScopeString","constructor","str","value","toString","split","re","results","match","exec","push","exports","ScopeAccessConfiguration","ConfigurationStrategy","configuration","elements","Object","defineProperty","get","enumerable","verify","req","Promise","resolve","reject","Args","notNull","context","user","authenticationScope","length","reqUrl","url","parse","originalUrl","pathname","reqScopes","reqAccess","test","method","result","find","x","access","indexOf","RegExp","resource","scope","y","err","DefaultScopeAccessConfiguration","defaults","path","getConfigurationPath","code","apply"],"sources":["../src/ScopeAccessConfiguration.js"],"sourcesContent":["import {ConfigurationStrategy, Args} from '@themost/common';\nimport path from 'path';\nimport url from 'url';\n\nconst HTTP_METHOD_REGEXP = /^\\b(POST|PUT|PATCH|DELETE)\\b$/i;\n\nclass ScopeString {\n constructor(str) {\n this.value = str;\n }\n toString() {\n return this.value;\n }\n /**\n * Splits a comma-separated or space-separated scope string e.g. \"profile email\" or \"profile,email\"\n *\n * Important note: https://www.rfc-editor.org/rfc/rfc6749#section-3.3 defines the regular expression of access token scopes\n * which is a space separated string. Several OAuth2 servers use a comma-separated list instead.\n *\n * The operation will try to use both implementations by excluding comma ',' from access token regular expressions\n * @returns {Array<string>}\n */\n split() {\n // the default regular expression includes comma /([\\x21\\x23-\\x5B\\x5D-\\x7E]+)/g\n // the modified regular expression excludes comma /x2C /([\\x21\\x23-\\x2B\\x2D-\\x5B\\x5D-\\x7E]+)/g\n const re = /([\\x21\\x23-\\x2B\\x2D-\\x5B\\x5D-\\x7E]+)/g\n const results = [];\n let match = re.exec(this.value);\n while(match !== null) {\n results.push(match[0]);\n match = re.exec(this.value);\n }\n return results;\n }\n}\n\nclass ScopeAccessConfiguration extends ConfigurationStrategy {\n /**\n * @param {import('@themost/common').ConfigurationBase} configuration\n */\n constructor(configuration) {\n super(configuration);\n let elements = [];\n // define property\n Object.defineProperty(this, 'elements', {\n get: () => {\n return elements;\n },\n enumerable: true\n });\n }\n\n /**\n * @param {Request} req\n * @returns Promise<ScopeAccessConfigurationElement>\n */\n verify(req) {\n return new Promise((resolve, reject) => {\n try {\n // validate request context\n Args.notNull(req.context,'Context');\n // validate request context user\n Args.notNull(req.context.user,'User');\n if (req.context.user.authenticationScope && req.context.user.authenticationScope.length>0) {\n // get original url\n let reqUrl = url.parse(req.originalUrl).pathname;\n // get user context scopes as array e.g, ['students', 'students:read']\n let reqScopes = new ScopeString(req.context.user.authenticationScope).split();\n // get user access based on HTTP method e.g. GET -> read access\n let reqAccess = HTTP_METHOD_REGEXP.test(req.method) ? 'write' : 'read';\n let result = this.elements.find(x => {\n // filter element by access level\n return x.access.indexOf(reqAccess)>=0\n // resource path\n && new RegExp( '^' + x.resource, 'i').test(reqUrl)\n // and scopes\n && x.scope.find(y => {\n // search user scopes (validate wildcard scope)\n return y === '*' || reqScopes.indexOf(y)>=0;\n });\n });\n return resolve(result);\n }\n return resolve();\n }\n catch(err) {\n return reject(err);\n }\n\n });\n }\n\n}\n\n/**\n * @class\n */\nclass DefaultScopeAccessConfiguration extends ScopeAccessConfiguration {\n /**\n * @param {import('@themost/common').ConfigurationBase} configuration\n */\n constructor(configuration) {\n super(configuration);\n let defaults = [];\n // load scope access from configuration resource\n try {\n /**\n * @type {Array<ScopeAccessConfigurationElement>}\n */\n defaults = require(path.resolve(configuration.getConfigurationPath(), 'scope.access.json'));\n }\n catch(err) {\n // if an error occurred other than module not found (there are no default access policies)\n if (err.code !== 'MODULE_NOT_FOUND') {\n // throw error\n throw err;\n }\n // otherwise continue\n }\n this.elements.push.apply(this.elements, defaults);\n }\n}\n\nexport {\n ScopeString,\n ScopeAccessConfiguration,\n DefaultScopeAccessConfiguration\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ScopeAccessConfiguration.js","names":["_common","require","_path","_interopRequireDefault","_url","obj","__esModule","default","HTTP_METHOD_REGEXP","ScopeString","constructor","str","value","toString","split","re","results","match","exec","push","exports","ScopeAccessConfiguration","ConfigurationStrategy","configuration","elements","Object","defineProperty","get","enumerable","verify","req","Promise","resolve","reject","Args","notNull","context","user","authenticationScope","length","reqUrl","url","parse","originalUrl","pathname","reqScopes","reqAccess","test","method","result","find","x","access","indexOf","RegExp","resource","scope","y","err","DefaultScopeAccessConfiguration","defaults","path","getConfigurationPath","code","apply","ExtendScopeAccessConfiguration","ApplicationService","app","_app$getConfiguration","_app$getConfiguration2","scopeAccessExtensions","getConfiguration","settings","universis","janitor","scopeAccess","container","subscribe","getStrategy","scopeAccessExtension","element"],"sources":["../src/ScopeAccessConfiguration.js"],"sourcesContent":["import {ConfigurationStrategy, Args, ApplicationService} from '@themost/common';\nimport path from 'path';\nimport url from 'url';\n\nconst HTTP_METHOD_REGEXP = /^\\b(POST|PUT|PATCH|DELETE)\\b$/i;\n\nclass ScopeString {\n constructor(str) {\n this.value = str;\n }\n toString() {\n return this.value;\n }\n /**\n * Splits a comma-separated or space-separated scope string e.g. \"profile email\" or \"profile,email\"\n *\n * Important note: https://www.rfc-editor.org/rfc/rfc6749#section-3.3 defines the regular expression of access token scopes\n * which is a space separated string. Several OAuth2 servers use a comma-separated list instead.\n *\n * The operation will try to use both implementations by excluding comma ',' from access token regular expressions\n * @returns {Array<string>}\n */\n split() {\n // the default regular expression includes comma /([\\x21\\x23-\\x5B\\x5D-\\x7E]+)/g\n // the modified regular expression excludes comma /x2C /([\\x21\\x23-\\x2B\\x2D-\\x5B\\x5D-\\x7E]+)/g\n const re = /([\\x21\\x23-\\x2B\\x2D-\\x5B\\x5D-\\x7E]+)/g\n const results = [];\n let match = re.exec(this.value);\n while(match !== null) {\n results.push(match[0]);\n match = re.exec(this.value);\n }\n return results;\n }\n}\n\nclass ScopeAccessConfiguration extends ConfigurationStrategy {\n /**\n * @param {import('@themost/common').ConfigurationBase} configuration\n */\n constructor(configuration) {\n super(configuration);\n let elements = [];\n // define property\n Object.defineProperty(this, 'elements', {\n get: () => {\n return elements;\n },\n enumerable: true\n });\n }\n\n /**\n * @param {Request} req\n * @returns Promise<ScopeAccessConfigurationElement>\n */\n verify(req) {\n return new Promise((resolve, reject) => {\n try {\n // validate request context\n Args.notNull(req.context,'Context');\n // validate request context user\n Args.notNull(req.context.user,'User');\n if (req.context.user.authenticationScope && req.context.user.authenticationScope.length>0) {\n // get original url\n let reqUrl = url.parse(req.originalUrl).pathname;\n // get user context scopes as array e.g, ['students', 'students:read']\n let reqScopes = new ScopeString(req.context.user.authenticationScope).split();\n // get user access based on HTTP method e.g. GET -> read access\n let reqAccess = HTTP_METHOD_REGEXP.test(req.method) ? 'write' : 'read';\n let result = this.elements.find(x => {\n // filter element by access level\n return x.access.indexOf(reqAccess)>=0\n // resource path\n && new RegExp( '^' + x.resource, 'i').test(reqUrl)\n // and scopes\n && x.scope.find(y => {\n // search user scopes (validate wildcard scope)\n return y === '*' || reqScopes.indexOf(y)>=0;\n });\n });\n return resolve(result);\n }\n return resolve();\n }\n catch(err) {\n return reject(err);\n }\n\n });\n }\n\n}\n\n/**\n * @class\n */\nclass DefaultScopeAccessConfiguration extends ScopeAccessConfiguration {\n /**\n * @param {import('@themost/common').ConfigurationBase} configuration\n */\n constructor(configuration) {\n super(configuration);\n let defaults = [];\n // load scope access from configuration resource\n try {\n /**\n * @type {Array<ScopeAccessConfigurationElement>}\n */\n defaults = require(path.resolve(configuration.getConfigurationPath(), 'scope.access.json'));\n }\n catch(err) {\n // if an error occurred other than module not found (there are no default access policies)\n if (err.code !== 'MODULE_NOT_FOUND') {\n // throw error\n throw err;\n }\n // otherwise continue\n }\n this.elements.push.apply(this.elements, defaults);\n }\n}\n\n\n/**\n * @class\n */\nclass ExtendScopeAccessConfiguration extends ApplicationService {\n constructor(app) {\n super(app);\n // Get the additional scope access extensions from the configuration\n const scopeAccessExtensions = app.getConfiguration().settings.universis?.janitor?.scopeAccess[\"imports\"];\n if (app && app.container && scopeAccessExtensions != null) {\n app.container.subscribe((container) => {\n if (container) {\n const scopeAccess = app.getConfiguration().getStrategy(function ScopeAccessConfiguration() { });\n if (scopeAccess != null) {\n for (const scopeAccessExtension of scopeAccessExtensions) {\n try {\n const element = require(path.resolve(app.getConfiguration().getConfigurationPath(), scopeAccessExtension));\n if (element) {\n // add extra scope access elements\n scopeAccess.elements.push.apply(scopeAccess.elements, element);\n }\n }\n catch(err) {\n // if an error occurred other than module not found (there are no default access policies)\n if (err.code !== 'MODULE_NOT_FOUND') {\n // throw error\n throw err;\n }\n }\n }\n }\n }\n });\n }\n }\n}\n\nexport {\n ScopeString,\n ScopeAccessConfiguration,\n DefaultScopeAccessConfiguration,\n ExtendScopeAccessConfiguration\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@universis/janitor",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "Universis api plugin for rate limiting requests",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import {ConfigurationStrategy, Args} from '@themost/common';
1
+ import {ConfigurationStrategy, Args, ApplicationService} from '@themost/common';
2
2
  import path from 'path';
3
3
  import url from 'url';
4
4
 
@@ -121,8 +121,46 @@ class DefaultScopeAccessConfiguration extends ScopeAccessConfiguration {
121
121
  }
122
122
  }
123
123
 
124
+
125
+ /**
126
+ * @class
127
+ */
128
+ class ExtendScopeAccessConfiguration extends ApplicationService {
129
+ constructor(app) {
130
+ super(app);
131
+ // Get the additional scope access extensions from the configuration
132
+ const scopeAccessExtensions = app.getConfiguration().settings.universis?.janitor?.scopeAccess["imports"];
133
+ if (app && app.container && scopeAccessExtensions != null) {
134
+ app.container.subscribe((container) => {
135
+ if (container) {
136
+ const scopeAccess = app.getConfiguration().getStrategy(function ScopeAccessConfiguration() { });
137
+ if (scopeAccess != null) {
138
+ for (const scopeAccessExtension of scopeAccessExtensions) {
139
+ try {
140
+ const element = require(path.resolve(app.getConfiguration().getConfigurationPath(), scopeAccessExtension));
141
+ if (element) {
142
+ // add extra scope access elements
143
+ scopeAccess.elements.push.apply(scopeAccess.elements, element);
144
+ }
145
+ }
146
+ catch(err) {
147
+ // if an error occurred other than module not found (there are no default access policies)
148
+ if (err.code !== 'MODULE_NOT_FOUND') {
149
+ // throw error
150
+ throw err;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ });
157
+ }
158
+ }
159
+ }
160
+
124
161
  export {
125
162
  ScopeString,
126
163
  ScopeAccessConfiguration,
127
- DefaultScopeAccessConfiguration
164
+ DefaultScopeAccessConfiguration,
165
+ ExtendScopeAccessConfiguration
128
166
  }