@toa.io/extensions.origins 0.10.0-dev.12 → 0.10.0-dev.13
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.origins",
|
|
3
|
-
"version": "0.10.0-dev.
|
|
3
|
+
"version": "0.10.0-dev.13",
|
|
4
4
|
"description": "Toa Origins",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -19,15 +19,15 @@
|
|
|
19
19
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@toa.io/core": "1.1.0-dev.
|
|
23
|
-
"@toa.io/generic": "0.11.0-dev.
|
|
24
|
-
"@toa.io/schemas": "0.8.4-dev.
|
|
25
|
-
"@toa.io/yaml": "0.7.6-dev.
|
|
22
|
+
"@toa.io/core": "1.1.0-dev.13",
|
|
23
|
+
"@toa.io/generic": "0.11.0-dev.13",
|
|
24
|
+
"@toa.io/schemas": "0.8.4-dev.13",
|
|
25
|
+
"@toa.io/yaml": "0.7.6-dev.13",
|
|
26
26
|
"comq": "0.7.0",
|
|
27
27
|
"node-fetch": "2.6.7"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node-fetch": "2.6.2"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "8c824ed7448e01f0ddf44500a4a6e692d35eaa1b"
|
|
33
33
|
}
|
package/source/factory.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { echo } = require('@toa.io/generic')
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* @implements {toa.origins.http.Permissions}
|
|
5
7
|
*/
|
|
@@ -26,9 +28,7 @@ class Permissions {
|
|
|
26
28
|
|
|
27
29
|
const allowance = this.#allowances.findIndex((regexp) => regexp.test(url))
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return this.#default
|
|
31
|
+
return allowance !== -1
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
#parse (properties) {
|
|
@@ -44,7 +44,8 @@ class Permissions {
|
|
|
44
44
|
|
|
45
45
|
if (match === null) throw new Error(`'${key}' is not a regular expression`)
|
|
46
46
|
|
|
47
|
-
const
|
|
47
|
+
const expression = echo(match.groups.expression)
|
|
48
|
+
const regex = new RegExp(expression)
|
|
48
49
|
|
|
49
50
|
this.#addRule(regex, rule)
|
|
50
51
|
}
|
|
@@ -55,8 +56,9 @@ class Permissions {
|
|
|
55
56
|
* @param {boolean} rule
|
|
56
57
|
*/
|
|
57
58
|
#addRule (regex, rule) {
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
const rules = rule ? this.#allowances : this.#denials
|
|
60
|
+
|
|
61
|
+
rules.push(regex)
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { generate } = require('randomstring')
|
|
4
|
+
const { Permissions } = require('./permissions')
|
|
5
|
+
|
|
6
|
+
it('should be', async () => {
|
|
7
|
+
expect(Permissions).toBeInstanceOf(Function)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('should substitute env vars', async () => {
|
|
11
|
+
const name = 'FOO_VALUE'
|
|
12
|
+
const value = generate()
|
|
13
|
+
|
|
14
|
+
process.env[name] = value
|
|
15
|
+
|
|
16
|
+
const properties = { '/http:\/\/domain.com\/${FOO_VALUE}/': true }
|
|
17
|
+
const permissions = new Permissions(properties)
|
|
18
|
+
|
|
19
|
+
expect(permissions.test('http://other.domain.com/')).toStrictEqual(false)
|
|
20
|
+
expect(permissions.test('http://domain.com/' + value)).toStrictEqual(true)
|
|
21
|
+
|
|
22
|
+
delete process.env[name]
|
|
23
|
+
})
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('node-fetch').RequestInit} Request
|
|
5
|
+
* @typedef {import('node-fetch').Response} Response
|
|
6
|
+
*/
|
|
7
|
+
|
|
3
8
|
const fetch = require('node-fetch')
|
|
4
9
|
|
|
5
10
|
const { Connector } = require('@toa.io/core')
|
|
@@ -37,12 +42,8 @@ class Aspect extends Connector {
|
|
|
37
42
|
let origin = this.#origins[name]
|
|
38
43
|
|
|
39
44
|
if (origin === undefined) {
|
|
40
|
-
if (isAbsoluteURL(/** @type {
|
|
41
|
-
|
|
42
|
-
/** @type {string} */ name,
|
|
43
|
-
/** @type {import('node-fetch').RequestInit} */ path
|
|
44
|
-
)
|
|
45
|
-
} else throw new Error(`Origin '${name}' is not defined`)
|
|
45
|
+
if (isAbsoluteURL(name)) return this.#invokeURL(name, /** @type {Request} */ path)
|
|
46
|
+
else throw new Error(`Origin '${name}' is not defined`)
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
// absolute urls are forbidden when using origins
|
|
@@ -57,8 +58,8 @@ class Aspect extends Connector {
|
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
60
|
* @param {string} url
|
|
60
|
-
* @param {
|
|
61
|
-
* @return {Promise<
|
|
61
|
+
* @param {Request} request
|
|
62
|
+
* @return {Promise<Response>}
|
|
62
63
|
*/
|
|
63
64
|
async #invokeURL (url, request) {
|
|
64
65
|
if (this.#permissions.test(url) === false) throw new Error(`URL '${url}' is not allowed`)
|
|
@@ -68,9 +69,9 @@ class Aspect extends Connector {
|
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
71
|
* @param {string} url
|
|
71
|
-
* @param {
|
|
72
|
+
* @param {Request} request
|
|
72
73
|
* @param {toa.generic.retry.Options} [options]
|
|
73
|
-
* @return {Promise<
|
|
74
|
+
* @return {Promise<Response>}
|
|
74
75
|
*/
|
|
75
76
|
async #request (url, request, options) {
|
|
76
77
|
const call = () => fetch(url, request)
|
|
@@ -172,25 +172,6 @@ describe.each(protocols)('absolute URL', (protocol) => {
|
|
|
172
172
|
expect(mock.fetch).toHaveBeenCalledWith(url, request)
|
|
173
173
|
})
|
|
174
174
|
|
|
175
|
-
it('should allow if TOA_DEV=1 and no properties', async () => {
|
|
176
|
-
const dev = process.env.TOA_DEV
|
|
177
|
-
|
|
178
|
-
process.env.TOA_DEV = '1'
|
|
179
|
-
|
|
180
|
-
mock.fetch.respond(200, response)
|
|
181
|
-
|
|
182
|
-
const url = protocol + '//' + generate()
|
|
183
|
-
const request = { method: 'POST' }
|
|
184
|
-
|
|
185
|
-
aspect = create(fixtures.manifest)
|
|
186
|
-
|
|
187
|
-
await aspect.invoke(url, request)
|
|
188
|
-
|
|
189
|
-
expect(mock.fetch).toHaveBeenCalledWith(url, request)
|
|
190
|
-
|
|
191
|
-
process.env.TOA_DEV = dev
|
|
192
|
-
})
|
|
193
|
-
|
|
194
175
|
it('should throw if URL not allowed', async () => {
|
|
195
176
|
mock.fetch.respond(200, response)
|
|
196
177
|
|