@lowdefy/plugin-aws 0.0.0-experimental-20261007090522 → 0.0.0-experimental-20261007124348

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.
@@ -15,8 +15,8 @@
15
15
  */ import { Readable } from 'node:stream';
16
16
  import { PutObjectCommand } from '@aws-sdk/client-s3';
17
17
  import { type } from '@lowdefy/helpers';
18
+ import createConnectPublic from '@lowdefy/node-utils/createConnectPublic.js';
18
19
  import { Agent, fetch } from 'undici';
19
- import connectPublic from './connectPublic.js';
20
20
  import createCopyError from './createCopyError.js';
21
21
  import limitBody from './limitBody.js';
22
22
  import matchesContentType from './matchesContentType.js';
@@ -36,7 +36,12 @@ const REDIRECT_STATUSES = new Set([
36
36
  ]);
37
37
  const MAX_REDIRECTS = 20;
38
38
  const dispatcher = new Agent({
39
- connect: connectPublic
39
+ connect: createConnectPublic({
40
+ createNotPublicError: ()=>createCopyError({
41
+ code: 'url_not_public',
42
+ message: 'AwsS3PutObject "url" leads to an address that is not public.'
43
+ })
44
+ })
40
45
  });
41
46
  function isHttps(link) {
42
47
  return URL.parse(link)?.protocol === 'https:';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/plugin-aws",
3
- "version": "0.0.0-experimental-20261007090522",
3
+ "version": "0.0.0-experimental-20261007124348",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -50,11 +50,12 @@
50
50
  "dist/*"
51
51
  ],
52
52
  "dependencies": {
53
- "@lowdefy/block-utils": "0.0.0-experimental-20261007090522",
54
- "@lowdefy/blocks-antd": "0.0.0-experimental-20261007090522",
55
- "@lowdefy/blocks-files": "0.0.0-experimental-20261007090522",
56
- "@lowdefy/errors": "0.0.0-experimental-20261007090522",
57
- "@lowdefy/helpers": "0.0.0-experimental-20261007090522",
53
+ "@lowdefy/block-utils": "0.0.0-experimental-20261007124348",
54
+ "@lowdefy/blocks-antd": "0.0.0-experimental-20261007124348",
55
+ "@lowdefy/blocks-files": "0.0.0-experimental-20261007124348",
56
+ "@lowdefy/errors": "0.0.0-experimental-20261007124348",
57
+ "@lowdefy/helpers": "0.0.0-experimental-20261007124348",
58
+ "@lowdefy/node-utils": "0.0.0-experimental-20261007124348",
58
59
  "@aws-sdk/client-s3": "3.1141.0",
59
60
  "@aws-sdk/s3-presigned-post": "3.1141.0",
60
61
  "@aws-sdk/s3-request-presigner": "3.1141.0",
@@ -67,9 +68,9 @@
67
68
  },
68
69
  "devDependencies": {
69
70
  "@jest/globals": "28.1.3",
70
- "@lowdefy/ajv": "0.0.0-experimental-20261007090522",
71
- "@lowdefy/block-dev": "0.0.0-experimental-20261007090522",
72
- "@lowdefy/jest-yaml-transform": "0.0.0-experimental-20261007090522",
71
+ "@lowdefy/ajv": "0.0.0-experimental-20261007124348",
72
+ "@lowdefy/block-dev": "0.0.0-experimental-20261007124348",
73
+ "@lowdefy/jest-yaml-transform": "0.0.0-experimental-20261007124348",
73
74
  "@swc/cli": "0.8.1",
74
75
  "@swc/core": "1.15.32",
75
76
  "@swc/jest": "0.2.39",
@@ -1,39 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { isIP } from 'node:net';
16
- import { buildConnector } from 'undici';
17
- import lookupPublicAddress from './lookupPublicAddress.js';
18
- const connect = buildConnector({
19
- lookup: lookupPublicAddress
20
- });
21
- // The undici connector for a url copy: it opens a socket only to a public address, for the first
22
- // link and every redirect alike. A socket to an IP literal skips the lookup, so a literal is
23
- // checked here before connecting.
24
- function connectPublic(options, callback) {
25
- if (isIP(options.hostname) === 0) {
26
- connect(options, callback);
27
- return;
28
- }
29
- lookupPublicAddress(options.hostname, {
30
- all: true
31
- }, (error)=>{
32
- if (error) {
33
- callback(error, null);
34
- return;
35
- }
36
- connect(options, callback);
37
- });
38
- }
39
- export default connectPublic;
@@ -1,106 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { BlockList, isIPv6 } from 'node:net';
16
- // Ranges a url copy may not reach: anything that is not a public unicast address. BlockList also
17
- // matches an IPv4-mapped IPv6 address (::ffff:127.0.0.1) against the IPv4 ranges.
18
- const notPublicIPv4 = [
19
- [
20
- '0.0.0.0',
21
- 8
22
- ],
23
- [
24
- '10.0.0.0',
25
- 8
26
- ],
27
- [
28
- '100.64.0.0',
29
- 10
30
- ],
31
- [
32
- '127.0.0.0',
33
- 8
34
- ],
35
- [
36
- '169.254.0.0',
37
- 16
38
- ],
39
- [
40
- '172.16.0.0',
41
- 12
42
- ],
43
- [
44
- '192.0.0.0',
45
- 24
46
- ],
47
- [
48
- '192.168.0.0',
49
- 16
50
- ],
51
- [
52
- '198.18.0.0',
53
- 15
54
- ],
55
- [
56
- '224.0.0.0',
57
- 4
58
- ],
59
- [
60
- '240.0.0.0',
61
- 4
62
- ]
63
- ];
64
- // The 6to4 address (2002::/16) that carries an IPv4 network in its next 32 bits.
65
- function sixToFourNetwork(network) {
66
- const [a, b, c, d] = network.split('.').map(Number);
67
- return `2002:${(a << 8 | b).toString(16)}:${(c << 8 | d).toString(16)}::`;
68
- }
69
- const notPublic = new BlockList();
70
- notPublicIPv4.forEach(([network, prefix])=>{
71
- notPublic.addSubnet(network, prefix, 'ipv4');
72
- // An IPv6 address that embeds one of these IPv4 addresses: a NAT64 gateway (64:ff9b::/96)
73
- // or a 6to4 relay forwards it to that IPv4 address.
74
- notPublic.addSubnet(`64:ff9b::${network}`, 96 + prefix, 'ipv6');
75
- notPublic.addSubnet(sixToFourNetwork(network), 16 + prefix, 'ipv6');
76
- });
77
- [
78
- [
79
- '::',
80
- 96
81
- ],
82
- [
83
- '64:ff9b:1::',
84
- 48
85
- ],
86
- [
87
- 'fc00::',
88
- 7
89
- ],
90
- [
91
- 'fe80::',
92
- 10
93
- ],
94
- [
95
- 'fec0::',
96
- 10
97
- ],
98
- [
99
- 'ff00::',
100
- 8
101
- ]
102
- ].forEach(([network, prefix])=>notPublic.addSubnet(network, prefix, 'ipv6'));
103
- function isPublicAddress(address) {
104
- return !notPublic.check(address, isIPv6(address) ? 'ipv6' : 'ipv4');
105
- }
106
- export default isPublicAddress;
@@ -1,40 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { lookup } from 'node:dns';
16
- import createCopyError from './createCopyError.js';
17
- import isPublicAddress from './isPublicAddress.js';
18
- // A dns.lookup for the socket to use: the socket connects to the addresses this answers, so the
19
- // address checked is the address connected to, and a name that resolves differently on a second
20
- // lookup cannot get past the check. Refuses a name when any of its addresses is not public.
21
- function lookupPublicAddress(hostname, options, callback) {
22
- lookup(hostname, options, (error, address, family)=>{
23
- if (error) {
24
- callback(error);
25
- return;
26
- }
27
- const addresses = Array.isArray(address) ? address.map((entry)=>entry.address) : [
28
- address
29
- ];
30
- if (!addresses.every(isPublicAddress)) {
31
- callback(createCopyError({
32
- code: 'url_not_public',
33
- message: 'AwsS3PutObject "url" leads to an address that is not public.'
34
- }));
35
- return;
36
- }
37
- callback(null, address, family);
38
- });
39
- }
40
- export default lookupPublicAddress;