@creator.co/wapi 1.9.3 → 1.10.0
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/dist/package-lock.json +104 -65
- package/dist/package.json +3 -3
- package/dist/src/Server/lib/container/Proxy.js +24 -6
- package/dist/src/Server/lib/container/Proxy.js.map +1 -1
- package/package.json +3 -3
- package/src/Server/lib/container/Proxy.ts +22 -7
- package/tests/Server/lib/container/RateLimit.test.ts +137 -11
package/dist/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creator.co/wapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@creator.co/wapi",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.10.0",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@aws-sdk/client-dynamodb": "^3.730.0",
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"cuid": "^3.0.0",
|
|
27
27
|
"dotenv": "^16.4.1",
|
|
28
28
|
"email-templates": "^13.0.1",
|
|
29
|
-
"express": "^4.22.
|
|
29
|
+
"express": "^4.22.2",
|
|
30
30
|
"express-rate-limit": "^7.5.0",
|
|
31
31
|
"json-stringify-safe": "^5.0.1",
|
|
32
32
|
"jsonwebtoken": "^9.0.2",
|
|
33
33
|
"knex": "^3.0.1",
|
|
34
34
|
"knex-stringcase": "^1.4.6",
|
|
35
|
-
"kysely": "^0.28.
|
|
35
|
+
"kysely": "^0.28.17",
|
|
36
36
|
"node-cache": "^5.1.2",
|
|
37
37
|
"nodemailer": "^8.0.5",
|
|
38
38
|
"object-hash": "^3.0.0",
|
|
@@ -3271,21 +3271,6 @@
|
|
|
3271
3271
|
"node": ">=18"
|
|
3272
3272
|
}
|
|
3273
3273
|
},
|
|
3274
|
-
"node_modules/@ladjs/i18n/node_modules/qs": {
|
|
3275
|
-
"version": "6.15.1",
|
|
3276
|
-
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
|
|
3277
|
-
"integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
|
|
3278
|
-
"license": "BSD-3-Clause",
|
|
3279
|
-
"dependencies": {
|
|
3280
|
-
"side-channel": "^1.1.0"
|
|
3281
|
-
},
|
|
3282
|
-
"engines": {
|
|
3283
|
-
"node": ">=0.6"
|
|
3284
|
-
},
|
|
3285
|
-
"funding": {
|
|
3286
|
-
"url": "https://github.com/sponsors/ljharb"
|
|
3287
|
-
}
|
|
3288
|
-
},
|
|
3289
3274
|
"node_modules/@messageformat/core": {
|
|
3290
3275
|
"version": "3.4.0",
|
|
3291
3276
|
"resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.4.0.tgz",
|
|
@@ -6037,22 +6022,23 @@
|
|
|
6037
6022
|
]
|
|
6038
6023
|
},
|
|
6039
6024
|
"node_modules/body-parser": {
|
|
6040
|
-
"version": "1.20.
|
|
6041
|
-
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.
|
|
6042
|
-
"integrity": "sha512-
|
|
6025
|
+
"version": "1.20.5",
|
|
6026
|
+
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
|
6027
|
+
"integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==",
|
|
6028
|
+
"license": "MIT",
|
|
6043
6029
|
"dependencies": {
|
|
6044
|
-
"bytes": "3.1.2",
|
|
6030
|
+
"bytes": "~3.1.2",
|
|
6045
6031
|
"content-type": "~1.0.5",
|
|
6046
6032
|
"debug": "2.6.9",
|
|
6047
6033
|
"depd": "2.0.0",
|
|
6048
|
-
"destroy": "1.2.0",
|
|
6049
|
-
"http-errors": "2.0.
|
|
6050
|
-
"iconv-lite": "0.4.24",
|
|
6051
|
-
"on-finished": "2.4.1",
|
|
6052
|
-
"qs": "6.
|
|
6053
|
-
"raw-body": "2.5.
|
|
6034
|
+
"destroy": "~1.2.0",
|
|
6035
|
+
"http-errors": "~2.0.1",
|
|
6036
|
+
"iconv-lite": "~0.4.24",
|
|
6037
|
+
"on-finished": "~2.4.1",
|
|
6038
|
+
"qs": "~6.15.1",
|
|
6039
|
+
"raw-body": "~2.5.3",
|
|
6054
6040
|
"type-is": "~1.6.18",
|
|
6055
|
-
"unpipe": "1.0.0"
|
|
6041
|
+
"unpipe": "~1.0.0"
|
|
6056
6042
|
},
|
|
6057
6043
|
"engines": {
|
|
6058
6044
|
"node": ">= 0.8",
|
|
@@ -6063,14 +6049,36 @@
|
|
|
6063
6049
|
"version": "2.6.9",
|
|
6064
6050
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
6065
6051
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
6052
|
+
"license": "MIT",
|
|
6066
6053
|
"dependencies": {
|
|
6067
6054
|
"ms": "2.0.0"
|
|
6068
6055
|
}
|
|
6069
6056
|
},
|
|
6057
|
+
"node_modules/body-parser/node_modules/http-errors": {
|
|
6058
|
+
"version": "2.0.1",
|
|
6059
|
+
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
|
6060
|
+
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
|
6061
|
+
"license": "MIT",
|
|
6062
|
+
"dependencies": {
|
|
6063
|
+
"depd": "~2.0.0",
|
|
6064
|
+
"inherits": "~2.0.4",
|
|
6065
|
+
"setprototypeof": "~1.2.0",
|
|
6066
|
+
"statuses": "~2.0.2",
|
|
6067
|
+
"toidentifier": "~1.0.1"
|
|
6068
|
+
},
|
|
6069
|
+
"engines": {
|
|
6070
|
+
"node": ">= 0.8"
|
|
6071
|
+
},
|
|
6072
|
+
"funding": {
|
|
6073
|
+
"type": "opencollective",
|
|
6074
|
+
"url": "https://opencollective.com/express"
|
|
6075
|
+
}
|
|
6076
|
+
},
|
|
6070
6077
|
"node_modules/body-parser/node_modules/iconv-lite": {
|
|
6071
6078
|
"version": "0.4.24",
|
|
6072
6079
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
|
6073
6080
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
|
6081
|
+
"license": "MIT",
|
|
6074
6082
|
"dependencies": {
|
|
6075
6083
|
"safer-buffer": ">= 2.1.2 < 3"
|
|
6076
6084
|
},
|
|
@@ -6081,7 +6089,17 @@
|
|
|
6081
6089
|
"node_modules/body-parser/node_modules/ms": {
|
|
6082
6090
|
"version": "2.0.0",
|
|
6083
6091
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
6084
|
-
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
|
6092
|
+
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
|
6093
|
+
"license": "MIT"
|
|
6094
|
+
},
|
|
6095
|
+
"node_modules/body-parser/node_modules/statuses": {
|
|
6096
|
+
"version": "2.0.2",
|
|
6097
|
+
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
|
6098
|
+
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
|
6099
|
+
"license": "MIT",
|
|
6100
|
+
"engines": {
|
|
6101
|
+
"node": ">= 0.8"
|
|
6102
|
+
}
|
|
6085
6103
|
},
|
|
6086
6104
|
"node_modules/boolbase": {
|
|
6087
6105
|
"version": "1.0.0",
|
|
@@ -6196,6 +6214,7 @@
|
|
|
6196
6214
|
"version": "3.1.2",
|
|
6197
6215
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
|
6198
6216
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
|
6217
|
+
"license": "MIT",
|
|
6199
6218
|
"engines": {
|
|
6200
6219
|
"node": ">= 0.8"
|
|
6201
6220
|
}
|
|
@@ -6600,6 +6619,7 @@
|
|
|
6600
6619
|
"version": "1.0.5",
|
|
6601
6620
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
|
6602
6621
|
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
|
6622
|
+
"license": "MIT",
|
|
6603
6623
|
"engines": {
|
|
6604
6624
|
"node": ">= 0.6"
|
|
6605
6625
|
}
|
|
@@ -8310,14 +8330,14 @@
|
|
|
8310
8330
|
}
|
|
8311
8331
|
},
|
|
8312
8332
|
"node_modules/express": {
|
|
8313
|
-
"version": "4.22.
|
|
8314
|
-
"resolved": "https://registry.npmjs.org/express/-/express-4.22.
|
|
8315
|
-
"integrity": "sha512-
|
|
8333
|
+
"version": "4.22.2",
|
|
8334
|
+
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
|
8335
|
+
"integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==",
|
|
8316
8336
|
"license": "MIT",
|
|
8317
8337
|
"dependencies": {
|
|
8318
8338
|
"accepts": "~1.3.8",
|
|
8319
8339
|
"array-flatten": "1.1.1",
|
|
8320
|
-
"body-parser": "~1.20.
|
|
8340
|
+
"body-parser": "~1.20.5",
|
|
8321
8341
|
"content-disposition": "~0.5.4",
|
|
8322
8342
|
"content-type": "~1.0.4",
|
|
8323
8343
|
"cookie": "~0.7.1",
|
|
@@ -8336,7 +8356,7 @@
|
|
|
8336
8356
|
"parseurl": "~1.3.3",
|
|
8337
8357
|
"path-to-regexp": "~0.1.12",
|
|
8338
8358
|
"proxy-addr": "~2.0.7",
|
|
8339
|
-
"qs": "~6.
|
|
8359
|
+
"qs": "~6.15.1",
|
|
8340
8360
|
"range-parser": "~1.2.1",
|
|
8341
8361
|
"safe-buffer": "5.2.1",
|
|
8342
8362
|
"send": "~0.19.0",
|
|
@@ -8388,21 +8408,6 @@
|
|
|
8388
8408
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
|
8389
8409
|
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
|
8390
8410
|
},
|
|
8391
|
-
"node_modules/express/node_modules/qs": {
|
|
8392
|
-
"version": "6.14.0",
|
|
8393
|
-
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
|
8394
|
-
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
|
8395
|
-
"license": "BSD-3-Clause",
|
|
8396
|
-
"dependencies": {
|
|
8397
|
-
"side-channel": "^1.1.0"
|
|
8398
|
-
},
|
|
8399
|
-
"engines": {
|
|
8400
|
-
"node": ">=0.6"
|
|
8401
|
-
},
|
|
8402
|
-
"funding": {
|
|
8403
|
-
"url": "https://github.com/sponsors/ljharb"
|
|
8404
|
-
}
|
|
8405
|
-
},
|
|
8406
8411
|
"node_modules/extend-object": {
|
|
8407
8412
|
"version": "1.0.0",
|
|
8408
8413
|
"resolved": "https://registry.npmjs.org/extend-object/-/extend-object-1.0.0.tgz",
|
|
@@ -11180,9 +11185,9 @@
|
|
|
11180
11185
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
|
11181
11186
|
},
|
|
11182
11187
|
"node_modules/kysely": {
|
|
11183
|
-
"version": "0.28.
|
|
11184
|
-
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.
|
|
11185
|
-
"integrity": "sha512-
|
|
11188
|
+
"version": "0.28.17",
|
|
11189
|
+
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.17.tgz",
|
|
11190
|
+
"integrity": "sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==",
|
|
11186
11191
|
"license": "MIT",
|
|
11187
11192
|
"engines": {
|
|
11188
11193
|
"node": ">=20.0.0"
|
|
@@ -11448,6 +11453,7 @@
|
|
|
11448
11453
|
"version": "0.3.0",
|
|
11449
11454
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
|
11450
11455
|
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
|
11456
|
+
"license": "MIT",
|
|
11451
11457
|
"engines": {
|
|
11452
11458
|
"node": ">= 0.6"
|
|
11453
11459
|
}
|
|
@@ -12868,11 +12874,12 @@
|
|
|
12868
12874
|
]
|
|
12869
12875
|
},
|
|
12870
12876
|
"node_modules/qs": {
|
|
12871
|
-
"version": "6.
|
|
12872
|
-
"resolved": "https://registry.npmjs.org/qs/-/qs-6.
|
|
12873
|
-
"integrity": "sha512
|
|
12877
|
+
"version": "6.15.2",
|
|
12878
|
+
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
|
|
12879
|
+
"integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
|
|
12880
|
+
"license": "BSD-3-Clause",
|
|
12874
12881
|
"dependencies": {
|
|
12875
|
-
"side-channel": "^1.0
|
|
12882
|
+
"side-channel": "^1.1.0"
|
|
12876
12883
|
},
|
|
12877
12884
|
"engines": {
|
|
12878
12885
|
"node": ">=0.6"
|
|
@@ -12932,23 +12939,45 @@
|
|
|
12932
12939
|
}
|
|
12933
12940
|
},
|
|
12934
12941
|
"node_modules/raw-body": {
|
|
12935
|
-
"version": "2.5.
|
|
12936
|
-
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.
|
|
12937
|
-
"integrity": "sha512-
|
|
12942
|
+
"version": "2.5.3",
|
|
12943
|
+
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
|
|
12944
|
+
"integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
|
|
12945
|
+
"license": "MIT",
|
|
12938
12946
|
"dependencies": {
|
|
12939
|
-
"bytes": "3.1.2",
|
|
12940
|
-
"http-errors": "2.0.
|
|
12941
|
-
"iconv-lite": "0.4.24",
|
|
12942
|
-
"unpipe": "1.0.0"
|
|
12947
|
+
"bytes": "~3.1.2",
|
|
12948
|
+
"http-errors": "~2.0.1",
|
|
12949
|
+
"iconv-lite": "~0.4.24",
|
|
12950
|
+
"unpipe": "~1.0.0"
|
|
12943
12951
|
},
|
|
12944
12952
|
"engines": {
|
|
12945
12953
|
"node": ">= 0.8"
|
|
12946
12954
|
}
|
|
12947
12955
|
},
|
|
12956
|
+
"node_modules/raw-body/node_modules/http-errors": {
|
|
12957
|
+
"version": "2.0.1",
|
|
12958
|
+
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
|
12959
|
+
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
|
12960
|
+
"license": "MIT",
|
|
12961
|
+
"dependencies": {
|
|
12962
|
+
"depd": "~2.0.0",
|
|
12963
|
+
"inherits": "~2.0.4",
|
|
12964
|
+
"setprototypeof": "~1.2.0",
|
|
12965
|
+
"statuses": "~2.0.2",
|
|
12966
|
+
"toidentifier": "~1.0.1"
|
|
12967
|
+
},
|
|
12968
|
+
"engines": {
|
|
12969
|
+
"node": ">= 0.8"
|
|
12970
|
+
},
|
|
12971
|
+
"funding": {
|
|
12972
|
+
"type": "opencollective",
|
|
12973
|
+
"url": "https://opencollective.com/express"
|
|
12974
|
+
}
|
|
12975
|
+
},
|
|
12948
12976
|
"node_modules/raw-body/node_modules/iconv-lite": {
|
|
12949
12977
|
"version": "0.4.24",
|
|
12950
12978
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
|
12951
12979
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
|
12980
|
+
"license": "MIT",
|
|
12952
12981
|
"dependencies": {
|
|
12953
12982
|
"safer-buffer": ">= 2.1.2 < 3"
|
|
12954
12983
|
},
|
|
@@ -12956,6 +12985,15 @@
|
|
|
12956
12985
|
"node": ">=0.10.0"
|
|
12957
12986
|
}
|
|
12958
12987
|
},
|
|
12988
|
+
"node_modules/raw-body/node_modules/statuses": {
|
|
12989
|
+
"version": "2.0.2",
|
|
12990
|
+
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
|
12991
|
+
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
|
12992
|
+
"license": "MIT",
|
|
12993
|
+
"engines": {
|
|
12994
|
+
"node": ">= 0.8"
|
|
12995
|
+
}
|
|
12996
|
+
},
|
|
12959
12997
|
"node_modules/rc": {
|
|
12960
12998
|
"version": "1.2.8",
|
|
12961
12999
|
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
|
@@ -14550,6 +14588,7 @@
|
|
|
14550
14588
|
"version": "1.6.18",
|
|
14551
14589
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
|
14552
14590
|
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
|
14591
|
+
"license": "MIT",
|
|
14553
14592
|
"dependencies": {
|
|
14554
14593
|
"media-typer": "0.3.0",
|
|
14555
14594
|
"mime-types": "~2.1.24"
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creator.co/wapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"cuid": "^3.0.0",
|
|
41
41
|
"dotenv": "^16.4.1",
|
|
42
42
|
"email-templates": "^13.0.1",
|
|
43
|
-
"express": "^4.22.
|
|
43
|
+
"express": "^4.22.2",
|
|
44
44
|
"express-rate-limit": "^7.5.0",
|
|
45
45
|
"json-stringify-safe": "^5.0.1",
|
|
46
46
|
"jsonwebtoken": "^9.0.2",
|
|
47
47
|
"knex": "^3.0.1",
|
|
48
48
|
"knex-stringcase": "^1.4.6",
|
|
49
|
-
"kysely": "^0.28.
|
|
49
|
+
"kysely": "^0.28.17",
|
|
50
50
|
"node-cache": "^5.1.2",
|
|
51
51
|
"nodemailer": "^8.0.5",
|
|
52
52
|
"object-hash": "^3.0.0",
|
|
@@ -36,6 +36,9 @@ export default class Proxy {
|
|
|
36
36
|
this.serverlessHandler = serverlessHandler;
|
|
37
37
|
this.logger = new Logger({ logLevel: 'INFO' }, 'proxy-container');
|
|
38
38
|
this.app = express();
|
|
39
|
+
// Trust the first proxy hop so req.ip resolves to the real client IP
|
|
40
|
+
// (not the load balancer's IP) when running behind ALB or similar.
|
|
41
|
+
this.app.set('trust proxy', 1);
|
|
39
42
|
/* Opinionated Express configs */
|
|
40
43
|
this.app.use(express.json({
|
|
41
44
|
verify(req, res, buf) {
|
|
@@ -169,12 +172,27 @@ export default class Proxy {
|
|
|
169
172
|
// Key generator - how to identify unique clients
|
|
170
173
|
keyGenerator: config.keyGenerator ||
|
|
171
174
|
((req) => {
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
'
|
|
175
|
+
// For authenticated requests, use the stable user ID from the JWT
|
|
176
|
+
// payload so that multiple users behind the same IP are bucketed
|
|
177
|
+
// independently and token rotation doesn't change a user's bucket.
|
|
178
|
+
const authHeader = req.headers['authorization'];
|
|
179
|
+
if (authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith('Bearer ')) {
|
|
180
|
+
const parts = authHeader.slice(7).split('.');
|
|
181
|
+
if (parts.length === 3) {
|
|
182
|
+
try {
|
|
183
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
|
|
184
|
+
const userId = payload.sub || payload.id || payload.userId;
|
|
185
|
+
if (userId)
|
|
186
|
+
return String(userId);
|
|
187
|
+
}
|
|
188
|
+
catch (_a) {
|
|
189
|
+
// malformed token — fall through to IP
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Unauthenticated: fall back to real client IP.
|
|
194
|
+
// trust proxy is set so req.ip reflects x-forwarded-for correctly.
|
|
195
|
+
return req.ip || req.socket.remoteAddress || 'unknown';
|
|
178
196
|
}),
|
|
179
197
|
// Custom handler when rate limit is exceeded
|
|
180
198
|
handler: config.handler ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../../../../src/Server/lib/container/Proxy.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../../../../src/Server/lib/container/Proxy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creator.co/wapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"cuid": "^3.0.0",
|
|
41
41
|
"dotenv": "^16.4.1",
|
|
42
42
|
"email-templates": "^13.0.1",
|
|
43
|
-
"express": "^4.22.
|
|
43
|
+
"express": "^4.22.2",
|
|
44
44
|
"express-rate-limit": "^7.5.0",
|
|
45
45
|
"json-stringify-safe": "^5.0.1",
|
|
46
46
|
"jsonwebtoken": "^9.0.2",
|
|
47
47
|
"knex": "^3.0.1",
|
|
48
48
|
"knex-stringcase": "^1.4.6",
|
|
49
|
-
"kysely": "^0.28.
|
|
49
|
+
"kysely": "^0.28.17",
|
|
50
50
|
"node-cache": "^5.1.2",
|
|
51
51
|
"nodemailer": "^8.0.5",
|
|
52
52
|
"object-hash": "^3.0.0",
|
|
@@ -66,6 +66,9 @@ export default class Proxy {
|
|
|
66
66
|
this.serverlessHandler = serverlessHandler
|
|
67
67
|
this.logger = new Logger({ logLevel: 'INFO' }, 'proxy-container')
|
|
68
68
|
this.app = express()
|
|
69
|
+
// Trust the first proxy hop so req.ip resolves to the real client IP
|
|
70
|
+
// (not the load balancer's IP) when running behind ALB or similar.
|
|
71
|
+
this.app.set('trust proxy', 1)
|
|
69
72
|
/* Opinionated Express configs */
|
|
70
73
|
this.app.use(
|
|
71
74
|
express.json({
|
|
@@ -211,13 +214,25 @@ export default class Proxy {
|
|
|
211
214
|
keyGenerator:
|
|
212
215
|
config.keyGenerator ||
|
|
213
216
|
((req: express.Request) => {
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
'
|
|
220
|
-
|
|
217
|
+
// For authenticated requests, use the stable user ID from the JWT
|
|
218
|
+
// payload so that multiple users behind the same IP are bucketed
|
|
219
|
+
// independently and token rotation doesn't change a user's bucket.
|
|
220
|
+
const authHeader = req.headers['authorization']
|
|
221
|
+
if (authHeader?.startsWith('Bearer ')) {
|
|
222
|
+
const parts = authHeader.slice(7).split('.')
|
|
223
|
+
if (parts.length === 3) {
|
|
224
|
+
try {
|
|
225
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'))
|
|
226
|
+
const userId = payload.sub || payload.id || payload.userId
|
|
227
|
+
if (userId) return String(userId)
|
|
228
|
+
} catch {
|
|
229
|
+
// malformed token — fall through to IP
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Unauthenticated: fall back to real client IP.
|
|
234
|
+
// trust proxy is set so req.ip reflects x-forwarded-for correctly.
|
|
235
|
+
return req.ip || req.socket.remoteAddress || 'unknown'
|
|
221
236
|
}),
|
|
222
237
|
|
|
223
238
|
// Custom handler when rate limit is exceeded
|
|
@@ -548,24 +548,19 @@ describe('Rate Limiting', () => {
|
|
|
548
548
|
|
|
549
549
|
await proxy.load()
|
|
550
550
|
|
|
551
|
-
//
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
.set('x-forwarded-for', '10.0.0.1, 10.0.0.2')
|
|
555
|
-
.expect(200)
|
|
551
|
+
// With trust proxy=1, req.ip is the rightmost entry of x-forwarded-for.
|
|
552
|
+
// Two requests with the same rightmost IP share a bucket.
|
|
553
|
+
const res1 = await request(url).get('/test').set('x-forwarded-for', '10.0.0.1').expect(200)
|
|
556
554
|
c_expect(res1.body).to.deep.equal({ success: true })
|
|
557
555
|
|
|
558
|
-
// Second request from same IP should be rate limited
|
|
559
|
-
const res2 = await request(url)
|
|
560
|
-
.get('/test')
|
|
561
|
-
.set('x-forwarded-for', '10.0.0.1, 10.0.0.3')
|
|
562
|
-
.expect(429)
|
|
556
|
+
// Second request from same IP (same rightmost x-forwarded-for) should be rate limited
|
|
557
|
+
const res2 = await request(url).get('/test').set('x-forwarded-for', '10.0.0.1').expect(429)
|
|
563
558
|
c_expect(res2.body).to.have.property('error', 'rate_limit_exceeded')
|
|
564
559
|
|
|
565
560
|
// Wait for window to reset
|
|
566
561
|
await new Promise(resolve => setTimeout(resolve, 1100))
|
|
567
562
|
|
|
568
|
-
// Different IP should
|
|
563
|
+
// Different IP should have its own clean bucket
|
|
569
564
|
const res3 = await request(url).get('/test').set('x-forwarded-for', '10.0.0.99').expect(200)
|
|
570
565
|
c_expect(res3.body).to.deep.equal({ success: true })
|
|
571
566
|
}, 10000)
|
|
@@ -701,6 +696,137 @@ describe('Rate Limiting', () => {
|
|
|
701
696
|
// Verify proxy is running
|
|
702
697
|
c_expect(proxy).to.exist
|
|
703
698
|
})
|
|
699
|
+
|
|
700
|
+
test('Rate limit default keyGenerator - same bearer token shares a bucket', async () => {
|
|
701
|
+
const port = 57017
|
|
702
|
+
const url = defaultUrl.replace(String(Globals.Listener_HTTP_DefaultPort), String(port))
|
|
703
|
+
|
|
704
|
+
// Build a fake but structurally-valid JWT for user1
|
|
705
|
+
const makeJwt = (sub: string) => {
|
|
706
|
+
const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url')
|
|
707
|
+
const payload = Buffer.from(JSON.stringify({ sub })).toString('base64url')
|
|
708
|
+
return `${header}.${payload}.fakesignature`
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const rateLimitConfig: GlobalRateLimitConfig = {
|
|
712
|
+
enabled: true,
|
|
713
|
+
windowMs: 1000,
|
|
714
|
+
limit: 2,
|
|
715
|
+
// NO custom keyGenerator - should default to bearer token extraction
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
proxy = new Proxy(
|
|
719
|
+
{
|
|
720
|
+
routes: [],
|
|
721
|
+
port,
|
|
722
|
+
rateLimit: rateLimitConfig,
|
|
723
|
+
},
|
|
724
|
+
async (event: APIGatewayProxyEvent, context: Context) => {
|
|
725
|
+
context.succeed({
|
|
726
|
+
body: JSON.stringify({ success: true }),
|
|
727
|
+
statusCode: 200,
|
|
728
|
+
})
|
|
729
|
+
}
|
|
730
|
+
)
|
|
731
|
+
|
|
732
|
+
await proxy.load()
|
|
733
|
+
|
|
734
|
+
const token = makeJwt('user1')
|
|
735
|
+
|
|
736
|
+
// First 2 requests with same token should succeed
|
|
737
|
+
await request(url).get('/test').set('Authorization', `Bearer ${token}`).expect(200)
|
|
738
|
+
await request(url).get('/test').set('Authorization', `Bearer ${token}`).expect(200)
|
|
739
|
+
|
|
740
|
+
// 3rd request from same user (same token sub) should be rate limited
|
|
741
|
+
const rateLimitedRes = await request(url)
|
|
742
|
+
.get('/test')
|
|
743
|
+
.set('Authorization', `Bearer ${token}`)
|
|
744
|
+
.expect(429)
|
|
745
|
+
c_expect(rateLimitedRes.body).to.have.property('error', 'rate_limit_exceeded')
|
|
746
|
+
}, 10000)
|
|
747
|
+
|
|
748
|
+
test('Rate limit default keyGenerator - different users have separate buckets', async () => {
|
|
749
|
+
const port = 57018
|
|
750
|
+
const url = defaultUrl.replace(String(Globals.Listener_HTTP_DefaultPort), String(port))
|
|
751
|
+
|
|
752
|
+
const makeJwt = (sub: string) => {
|
|
753
|
+
const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url')
|
|
754
|
+
const payload = Buffer.from(JSON.stringify({ sub })).toString('base64url')
|
|
755
|
+
return `${header}.${payload}.fakesignature`
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
const rateLimitConfig: GlobalRateLimitConfig = {
|
|
759
|
+
enabled: true,
|
|
760
|
+
windowMs: 1000,
|
|
761
|
+
limit: 2,
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
proxy = new Proxy(
|
|
765
|
+
{
|
|
766
|
+
routes: [],
|
|
767
|
+
port,
|
|
768
|
+
rateLimit: rateLimitConfig,
|
|
769
|
+
},
|
|
770
|
+
async (event: APIGatewayProxyEvent, context: Context) => {
|
|
771
|
+
context.succeed({
|
|
772
|
+
body: JSON.stringify({ success: true }),
|
|
773
|
+
statusCode: 200,
|
|
774
|
+
})
|
|
775
|
+
}
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
await proxy.load()
|
|
779
|
+
|
|
780
|
+
const user1Token = makeJwt('user1')
|
|
781
|
+
const user2Token = makeJwt('user2')
|
|
782
|
+
|
|
783
|
+
// User 1 exhausts their bucket
|
|
784
|
+
await request(url).get('/test').set('Authorization', `Bearer ${user1Token}`).expect(200)
|
|
785
|
+
await request(url).get('/test').set('Authorization', `Bearer ${user1Token}`).expect(200)
|
|
786
|
+
await request(url).get('/test').set('Authorization', `Bearer ${user1Token}`).expect(429)
|
|
787
|
+
|
|
788
|
+
// User 2 has their own independent bucket — should still be allowed
|
|
789
|
+
const user2Res = await request(url)
|
|
790
|
+
.get('/test')
|
|
791
|
+
.set('Authorization', `Bearer ${user2Token}`)
|
|
792
|
+
.expect(200)
|
|
793
|
+
c_expect(user2Res.body).to.deep.equal({ success: true })
|
|
794
|
+
}, 10000)
|
|
795
|
+
|
|
796
|
+
test('Rate limit default keyGenerator - unauthenticated requests fall back to IP', async () => {
|
|
797
|
+
const port = 57019
|
|
798
|
+
const url = defaultUrl.replace(String(Globals.Listener_HTTP_DefaultPort), String(port))
|
|
799
|
+
|
|
800
|
+
const rateLimitConfig: GlobalRateLimitConfig = {
|
|
801
|
+
enabled: true,
|
|
802
|
+
windowMs: 1000,
|
|
803
|
+
limit: 2,
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
proxy = new Proxy(
|
|
807
|
+
{
|
|
808
|
+
routes: [],
|
|
809
|
+
port,
|
|
810
|
+
rateLimit: rateLimitConfig,
|
|
811
|
+
},
|
|
812
|
+
async (event: APIGatewayProxyEvent, context: Context) => {
|
|
813
|
+
context.succeed({
|
|
814
|
+
body: JSON.stringify({ success: true }),
|
|
815
|
+
statusCode: 200,
|
|
816
|
+
})
|
|
817
|
+
}
|
|
818
|
+
)
|
|
819
|
+
|
|
820
|
+
await proxy.load()
|
|
821
|
+
|
|
822
|
+
// Requests with no Authorization header are bucketed by IP (all from ::1 in tests)
|
|
823
|
+
await request(url).get('/test').expect(200)
|
|
824
|
+
await request(url).get('/test').expect(200)
|
|
825
|
+
|
|
826
|
+
// Same IP, 3rd request exceeds the limit
|
|
827
|
+
const rateLimitedRes = await request(url).get('/test').expect(429)
|
|
828
|
+
c_expect(rateLimitedRes.body).to.have.property('error', 'rate_limit_exceeded')
|
|
829
|
+
}, 10000)
|
|
704
830
|
})
|
|
705
831
|
|
|
706
832
|
export {}
|