@moxon/api 6.0.0-pre
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/.prettierignore +5 -0
- package/LICENSE +28 -0
- package/README.md +277 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.js +55 -0
- package/dist/app.js.map +1 -0
- package/dist/config/env.d.ts +22 -0
- package/dist/config/env.js +36 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/plans.d.ts +26 -0
- package/dist/config/plans.js +44 -0
- package/dist/config/plans.js.map +1 -0
- package/dist/config/versions.d.ts +18 -0
- package/dist/config/versions.js +248 -0
- package/dist/config/versions.js.map +1 -0
- package/dist/constants.d.ts +48 -0
- package/dist/constants.js +75 -0
- package/dist/constants.js.map +1 -0
- package/dist/middleware/cors.d.ts +2 -0
- package/dist/middleware/cors.js +31 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/error.d.ts +4 -0
- package/dist/middleware/error.js +8 -0
- package/dist/middleware/error.js.map +1 -0
- package/dist/middleware/json.d.ts +2 -0
- package/dist/middleware/json.js +8 -0
- package/dist/middleware/json.js.map +1 -0
- package/dist/middleware/logger.d.ts +26 -0
- package/dist/middleware/logger.js +65 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/ratelimit.d.ts +2 -0
- package/dist/middleware/ratelimit.js +83 -0
- package/dist/middleware/ratelimit.js.map +1 -0
- package/dist/middleware/version.d.ts +3 -0
- package/dist/middleware/version.js +30 -0
- package/dist/middleware/version.js.map +1 -0
- package/dist/modules/v4/address.d.ts +20 -0
- package/dist/modules/v4/address.js +381 -0
- package/dist/modules/v4/address.js.map +1 -0
- package/dist/modules/v4/agent.d.ts +30 -0
- package/dist/modules/v4/agent.js +92 -0
- package/dist/modules/v4/agent.js.map +1 -0
- package/dist/modules/v4/algorithms.d.ts +90 -0
- package/dist/modules/v4/algorithms.js +279 -0
- package/dist/modules/v4/algorithms.js.map +1 -0
- package/dist/modules/v4/avatar.d.ts +23 -0
- package/dist/modules/v4/avatar.js +136 -0
- package/dist/modules/v4/avatar.js.map +1 -0
- package/dist/modules/v4/barcode.d.ts +27 -0
- package/dist/modules/v4/barcode.js +440 -0
- package/dist/modules/v4/barcode.js.map +1 -0
- package/dist/modules/v4/captcha.d.ts +22 -0
- package/dist/modules/v4/captcha.js +79 -0
- package/dist/modules/v4/captcha.js.map +1 -0
- package/dist/modules/v4/chat.d.ts +21 -0
- package/dist/modules/v4/chat.js +100 -0
- package/dist/modules/v4/chat.js.map +1 -0
- package/dist/modules/v4/color.d.ts +16 -0
- package/dist/modules/v4/color.js +59 -0
- package/dist/modules/v4/color.js.map +1 -0
- package/dist/modules/v4/convert.d.ts +15 -0
- package/dist/modules/v4/convert.js +116 -0
- package/dist/modules/v4/convert.js.map +1 -0
- package/dist/modules/v4/credit.d.ts +22 -0
- package/dist/modules/v4/credit.js +104 -0
- package/dist/modules/v4/credit.js.map +1 -0
- package/dist/modules/v4/cron.d.ts +17 -0
- package/dist/modules/v4/cron.js +202 -0
- package/dist/modules/v4/cron.js.map +1 -0
- package/dist/modules/v4/dice.d.ts +16 -0
- package/dist/modules/v4/dice.js +37 -0
- package/dist/modules/v4/dice.js.map +1 -0
- package/dist/modules/v4/domain.d.ts +6 -0
- package/dist/modules/v4/domain.js +83 -0
- package/dist/modules/v4/domain.js.map +1 -0
- package/dist/modules/v4/encode.d.ts +81 -0
- package/dist/modules/v4/encode.js +236 -0
- package/dist/modules/v4/encode.js.map +1 -0
- package/dist/modules/v4/geo.d.ts +30 -0
- package/dist/modules/v4/geo.js +51 -0
- package/dist/modules/v4/geo.js.map +1 -0
- package/dist/modules/v4/hash.d.ts +15 -0
- package/dist/modules/v4/hash.js +25 -0
- package/dist/modules/v4/hash.js.map +1 -0
- package/dist/modules/v4/hyperplanning.d.ts +19 -0
- package/dist/modules/v4/hyperplanning.js +80 -0
- package/dist/modules/v4/hyperplanning.js.map +1 -0
- package/dist/modules/v4/ip.d.ts +19 -0
- package/dist/modules/v4/ip.js +132 -0
- package/dist/modules/v4/ip.js.map +1 -0
- package/dist/modules/v4/levenshtein.d.ts +13 -0
- package/dist/modules/v4/levenshtein.js +37 -0
- package/dist/modules/v4/levenshtein.js.map +1 -0
- package/dist/modules/v4/palette.d.ts +19 -0
- package/dist/modules/v4/palette.js +56 -0
- package/dist/modules/v4/palette.js.map +1 -0
- package/dist/modules/v4/password.d.ts +25 -0
- package/dist/modules/v4/password.js +343 -0
- package/dist/modules/v4/password.js.map +1 -0
- package/dist/modules/v4/personal.d.ts +6 -0
- package/dist/modules/v4/personal.js +121 -0
- package/dist/modules/v4/personal.js.map +1 -0
- package/dist/modules/v4/placeholder.d.ts +30 -0
- package/dist/modules/v4/placeholder.js +160 -0
- package/dist/modules/v4/placeholder.js.map +1 -0
- package/dist/modules/v4/qrcode.d.ts +25 -0
- package/dist/modules/v4/qrcode.js +92 -0
- package/dist/modules/v4/qrcode.js.map +1 -0
- package/dist/modules/v4/regex.d.ts +23 -0
- package/dist/modules/v4/regex.js +48 -0
- package/dist/modules/v4/regex.js.map +1 -0
- package/dist/modules/v4/statistics.d.ts +20 -0
- package/dist/modules/v4/statistics.js +48 -0
- package/dist/modules/v4/statistics.js.map +1 -0
- package/dist/modules/v4/text.d.ts +43 -0
- package/dist/modules/v4/text.js +323 -0
- package/dist/modules/v4/text.js.map +1 -0
- package/dist/modules/v4/tic_tac_toe.d.ts +19 -0
- package/dist/modules/v4/tic_tac_toe.js +214 -0
- package/dist/modules/v4/tic_tac_toe.js.map +1 -0
- package/dist/modules/v4/time.d.ts +15 -0
- package/dist/modules/v4/time.js +124 -0
- package/dist/modules/v4/time.js.map +1 -0
- package/dist/modules/v4/token.d.ts +9 -0
- package/dist/modules/v4/token.js +45 -0
- package/dist/modules/v4/token.js.map +1 -0
- package/dist/modules/v4/username.d.ts +6 -0
- package/dist/modules/v4/username.js +92 -0
- package/dist/modules/v4/username.js.map +1 -0
- package/dist/modules/v4/validate.d.ts +34 -0
- package/dist/modules/v4/validate.js +75 -0
- package/dist/modules/v4/validate.js.map +1 -0
- package/dist/modules/v4.d.ts +32 -0
- package/dist/modules/v4.js +33 -0
- package/dist/modules/v4.js.map +1 -0
- package/dist/modules/v5/address.d.ts +5 -0
- package/dist/modules/v5/address.js +20 -0
- package/dist/modules/v5/address.js.map +1 -0
- package/dist/modules/v5/algorithms.d.ts +9 -0
- package/dist/modules/v5/algorithms.js +39 -0
- package/dist/modules/v5/algorithms.js.map +1 -0
- package/dist/modules/v5/asymmetric.d.ts +26 -0
- package/dist/modules/v5/asymmetric.js +74 -0
- package/dist/modules/v5/asymmetric.js.map +1 -0
- package/dist/modules/v5/barcode.d.ts +27 -0
- package/dist/modules/v5/barcode.js +424 -0
- package/dist/modules/v5/barcode.js.map +1 -0
- package/dist/modules/v5/base.d.ts +16 -0
- package/dist/modules/v5/base.js +41 -0
- package/dist/modules/v5/base.js.map +1 -0
- package/dist/modules/v5/captcha.d.ts +27 -0
- package/dist/modules/v5/captcha.js +136 -0
- package/dist/modules/v5/captcha.js.map +1 -0
- package/dist/modules/v5/case.d.ts +10 -0
- package/dist/modules/v5/case.js +57 -0
- package/dist/modules/v5/case.js.map +1 -0
- package/dist/modules/v5/chart.d.ts +53 -0
- package/dist/modules/v5/chart.js +385 -0
- package/dist/modules/v5/chart.js.map +1 -0
- package/dist/modules/v5/chat.d.ts +21 -0
- package/dist/modules/v5/chat.js +107 -0
- package/dist/modules/v5/chat.js.map +1 -0
- package/dist/modules/v5/csv.d.ts +29 -0
- package/dist/modules/v5/csv.js +143 -0
- package/dist/modules/v5/csv.js.map +1 -0
- package/dist/modules/v5/diff.d.ts +20 -0
- package/dist/modules/v5/diff.js +81 -0
- package/dist/modules/v5/diff.js.map +1 -0
- package/dist/modules/v5/evaluate.d.ts +14 -0
- package/dist/modules/v5/evaluate.js +284 -0
- package/dist/modules/v5/evaluate.js.map +1 -0
- package/dist/modules/v5/jwt.d.ts +11 -0
- package/dist/modules/v5/jwt.js +42 -0
- package/dist/modules/v5/jwt.js.map +1 -0
- package/dist/modules/v5/matrix.d.ts +77 -0
- package/dist/modules/v5/matrix.js +239 -0
- package/dist/modules/v5/matrix.js.map +1 -0
- package/dist/modules/v5/otp.d.ts +30 -0
- package/dist/modules/v5/otp.js +117 -0
- package/dist/modules/v5/otp.js.map +1 -0
- package/dist/modules/v5/pow.d.ts +29 -0
- package/dist/modules/v5/pow.js +49 -0
- package/dist/modules/v5/pow.js.map +1 -0
- package/dist/modules/v5/read.d.ts +20 -0
- package/dist/modules/v5/read.js +59 -0
- package/dist/modules/v5/read.js.map +1 -0
- package/dist/modules/v5/semver.d.ts +33 -0
- package/dist/modules/v5/semver.js +99 -0
- package/dist/modules/v5/semver.js.map +1 -0
- package/dist/modules/v5/symmetric.d.ts +15 -0
- package/dist/modules/v5/symmetric.js +88 -0
- package/dist/modules/v5/symmetric.js.map +1 -0
- package/dist/modules/v5/text.d.ts +5 -0
- package/dist/modules/v5/text.js +12 -0
- package/dist/modules/v5/text.js.map +1 -0
- package/dist/modules/v5/tic_tac_toe.d.ts +19 -0
- package/dist/modules/v5/tic_tac_toe.js +226 -0
- package/dist/modules/v5/tic_tac_toe.js.map +1 -0
- package/dist/modules/v5/url.d.ts +18 -0
- package/dist/modules/v5/url.js +51 -0
- package/dist/modules/v5/url.js.map +1 -0
- package/dist/modules/v5/uuid.d.ts +25 -0
- package/dist/modules/v5/uuid.js +40 -0
- package/dist/modules/v5/uuid.js.map +1 -0
- package/dist/modules/v5.d.ts +24 -0
- package/dist/modules/v5.js +25 -0
- package/dist/modules/v5.js.map +1 -0
- package/dist/modules/v6.d.ts +1 -0
- package/dist/modules/v6.js +2 -0
- package/dist/modules/v6.js.map +1 -0
- package/dist/routes/delete.d.ts +2 -0
- package/dist/routes/delete.js +73 -0
- package/dist/routes/delete.js.map +1 -0
- package/dist/routes/get.d.ts +2 -0
- package/dist/routes/get.js +857 -0
- package/dist/routes/get.js.map +1 -0
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.js +95 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/patch.d.ts +2 -0
- package/dist/routes/patch.js +45 -0
- package/dist/routes/patch.js.map +1 -0
- package/dist/routes/post.d.ts +2 -0
- package/dist/routes/post.js +604 -0
- package/dist/routes/post.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +14 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types/storage.d.ts +52 -0
- package/dist/types/storage.js +2 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/utils/challenge.d.ts +40 -0
- package/dist/utils/challenge.js +75 -0
- package/dist/utils/challenge.js.map +1 -0
- package/dist/utils/colors.d.ts +44 -0
- package/dist/utils/colors.js +93 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/helpers.d.ts +55 -0
- package/dist/utils/helpers.js +82 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/response.d.ts +9 -0
- package/dist/utils/response.js +24 -0
- package/dist/utils/response.js.map +1 -0
- package/package.json +90 -0
- package/robots.txt +74 -0
- package/src/favicon.ico +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import * as apiv4 from '../modules/v4.js';
|
|
2
|
+
import * as apiv5 from '../modules/v5.js';
|
|
3
|
+
import * as apiv6 from '../modules/v6.js';
|
|
4
|
+
/**
|
|
5
|
+
* Merges a base list of endpoints with additions, deduplicating by `name`.
|
|
6
|
+
* If an addition has the same name as a base entry, it overrides it.
|
|
7
|
+
*
|
|
8
|
+
* @param base - Endpoints inherited from the previous API version
|
|
9
|
+
* @param additions - New or overriding endpoints for this version
|
|
10
|
+
* @returns Merged endpoint list, sorted as base entries first then new additions
|
|
11
|
+
*/
|
|
12
|
+
const merge = (base, additions) => {
|
|
13
|
+
const map = new Map(base.map((e) => [e.name, e]));
|
|
14
|
+
for (const e of additions)
|
|
15
|
+
map.set(e.name, e);
|
|
16
|
+
return [...map.values()];
|
|
17
|
+
};
|
|
18
|
+
const v4 = {
|
|
19
|
+
get: [
|
|
20
|
+
{
|
|
21
|
+
name: 'algorithms',
|
|
22
|
+
path: '/algorithms?method={algorithm}&value={value}(&value2={value2})',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'captcha',
|
|
26
|
+
path: '/captcha(&text={text}&length={n}&width={px}&height={px}&noise={low|medium|high}&bg={hex}&color={hex})',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'color',
|
|
30
|
+
path: '/color(&hex={hex})',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'convert',
|
|
34
|
+
path: '/convert?value={value}&from={unit}&to={unit}',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'domain',
|
|
38
|
+
path: '/domain',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'infos',
|
|
42
|
+
path: '/infos',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'personal',
|
|
46
|
+
path: '/personal',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'qrcode',
|
|
50
|
+
path: '/qrcode?url={URL}(&size={px}&margin={n}&correction={L|M|Q|H}&dark={hex}&light={hex}&icon={URL}&iconSize={px}&iconPadding={px}&iconRadius={px}&format={png|base64})',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'username',
|
|
54
|
+
path: '/username',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'chat',
|
|
58
|
+
path: '/chat',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'levenshtein',
|
|
62
|
+
path: '/levenshtein?str1={string}&str2={string}',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'time',
|
|
66
|
+
path: '/time(?type={live|random|countdown}&target={date}&start={timestamp}&end={timestamp}&format={format}&timezone={timezone})',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'address',
|
|
70
|
+
path: '/address(&country={code}&count={n})',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'agent',
|
|
74
|
+
path: '/agent(&ua={string})',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'avatar',
|
|
78
|
+
path: '/avatar(&seed={string}&size={50-2000}&type={identicon|pixel}&bg={hex}&format={png|svg})',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'barcode',
|
|
82
|
+
path: '/barcode?data={string}(&type={type}&width={px}&height={px}&format={svg|png}&color={hex}&bg={hex})',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'credit',
|
|
86
|
+
path: '/credit(&brand={visa|mastercard|amex|discover}&count={n}&format={full|masked})',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'cron',
|
|
90
|
+
path: '/cron?expr={expression}(&count={n}&from={date}&timezone={timezone})',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'dice',
|
|
94
|
+
path: '/dice?roll={NdX+M}',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'encode',
|
|
98
|
+
path: '/encode?method={method}&text={text}(&shift={shift})',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'geo',
|
|
102
|
+
path: '/geo?lat1={lat}&lon1={lon}&lat2={lat}&lon2={lon}',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'headers',
|
|
106
|
+
path: '/headers(&filter={header1,header2})',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'ip',
|
|
110
|
+
path: '/ip(&address={ip})',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'palette',
|
|
114
|
+
path: '/palette?color={#hex}&type={type}',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'password',
|
|
118
|
+
path: '/password(&type={random|passphrase}&length={n}&uppercase={bool}&lowercase={bool}&digits={bool}&symbols={bool}&exclude={chars}&count={n}&separator={char})',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'placeholder',
|
|
122
|
+
path: '/placeholder?type={image|skeleton}&width={w}&height={h}(&bg={hex}&color={hex}&text={text}&rows={n}&avatar={bool})',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'regex',
|
|
126
|
+
path: '/regex?pattern={regex}&text={string}(&flags={flags})',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'statistics',
|
|
130
|
+
path: '/statistics?values={n1,n2,n3,...}',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'text',
|
|
134
|
+
path: '/text?method={method}(&value={value}&type={type}&count={count}&lang={lang})',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'validate',
|
|
138
|
+
path: '/validate?type={type}&value={value}',
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
post: [
|
|
142
|
+
{
|
|
143
|
+
name: 'token',
|
|
144
|
+
path: '/token',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'chat',
|
|
148
|
+
children: {
|
|
149
|
+
chat: '/chat',
|
|
150
|
+
private: '/chat/private',
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'hash',
|
|
155
|
+
path: '/hash',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'tic_tac_toe',
|
|
159
|
+
children: {
|
|
160
|
+
tic_tac_toe: '/tic-tac-toe',
|
|
161
|
+
fetch: '/tic-tac-toe/fetch',
|
|
162
|
+
list: '/tic-tac-toe/list',
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'hyperplanning',
|
|
167
|
+
path: '/hyperplanning',
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
patch: [
|
|
171
|
+
{
|
|
172
|
+
name: 'tic-tac-toe',
|
|
173
|
+
path: '/tic-tac-toe/:game',
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
delete: [
|
|
177
|
+
{
|
|
178
|
+
name: 'chat',
|
|
179
|
+
path: '/chat/:token',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: 'tic-tac-toe',
|
|
183
|
+
path: '/tic-tac-toe/:game',
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
const v5 = {
|
|
188
|
+
get: merge(v4.get, [
|
|
189
|
+
{ name: 'base', path: '/base?value={value}(&from={from})(&to={to})' },
|
|
190
|
+
{
|
|
191
|
+
name: 'captcha',
|
|
192
|
+
path: '/captcha(&mode={image|challenge}&text={text}&length={n}&width={px}&height={px}&noise={low|medium|high}&bg={hex}&color={hex})',
|
|
193
|
+
},
|
|
194
|
+
{ name: 'case', path: '/case?text={text}(&to={target})' },
|
|
195
|
+
{ name: 'evaluate', path: '/evaluate?expr={expression}(&precision={0-15})' },
|
|
196
|
+
{ name: 'pow', path: '/pow(?difficulty={n})' },
|
|
197
|
+
{ name: 'semver', path: '/semver?version={version}(&action={action})(&part={part})(&other={other})' },
|
|
198
|
+
{ name: 'url', path: '/url?url={URL}' },
|
|
199
|
+
{ name: 'uuid', path: '/uuid(?uuid={uuid})(&count={count})' },
|
|
200
|
+
]),
|
|
201
|
+
post: merge(v4.post, [
|
|
202
|
+
{ name: 'asymmetric', path: '/asymmetric' },
|
|
203
|
+
{ name: 'captcha', path: '/captcha' },
|
|
204
|
+
{ name: 'chart', path: '/chart' },
|
|
205
|
+
{ name: 'csv', path: '/csv' },
|
|
206
|
+
{ name: 'diff', path: '/diff' },
|
|
207
|
+
{ name: 'jwt', path: '/jwt' },
|
|
208
|
+
{ name: 'matrix', path: '/matrix' },
|
|
209
|
+
{ name: 'otp', path: '/otp' },
|
|
210
|
+
{ name: 'pow', path: '/pow' },
|
|
211
|
+
{ name: 'read', path: '/read' },
|
|
212
|
+
{ name: 'symmetric', path: '/symmetric' },
|
|
213
|
+
]),
|
|
214
|
+
patch: [...v4.patch],
|
|
215
|
+
delete: [...v4.delete],
|
|
216
|
+
};
|
|
217
|
+
const v6 = {
|
|
218
|
+
get: merge(v5.get.filter((e) => e.name !== 'levenshtein'), [
|
|
219
|
+
{
|
|
220
|
+
name: 'captcha',
|
|
221
|
+
path: '/captcha(&mode={challenge|image}&text={text}&length={n}&width={px}&height={px}&noise={low|medium|high}&bg={hex}&color={hex})',
|
|
222
|
+
},
|
|
223
|
+
]),
|
|
224
|
+
post: merge(v5.post.filter((e) => e.name !== 'hyperplanning'), [
|
|
225
|
+
{ name: 'levenshtein', path: '/levenshtein' },
|
|
226
|
+
{
|
|
227
|
+
name: 'chat',
|
|
228
|
+
path: '/chat',
|
|
229
|
+
children: { clear: '/chat/clear', message: '/chat', private: '/chat/private' },
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'tic_tac_toe',
|
|
233
|
+
path: '/tic-tac-toe',
|
|
234
|
+
children: {
|
|
235
|
+
fetch: '/tic-tac-toe/fetch',
|
|
236
|
+
forfeit: '/tic-tac-toe/forfeit',
|
|
237
|
+
list: '/tic-tac-toe/list',
|
|
238
|
+
play: '/tic-tac-toe/play',
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
]),
|
|
242
|
+
};
|
|
243
|
+
export const versions = {
|
|
244
|
+
v4: { endpoints: v4, modules: apiv4 },
|
|
245
|
+
v5: { endpoints: v5, modules: apiv5 },
|
|
246
|
+
v6: { endpoints: v6, modules: apiv6 },
|
|
247
|
+
};
|
|
248
|
+
//# sourceMappingURL=versions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/config/versions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare const APP_VERSION: string;
|
|
2
|
+
export declare const DEFAULT_PORT = 3000;
|
|
3
|
+
export declare const START_TIME: number;
|
|
4
|
+
export declare const CHALLENGE_TTL = 300000;
|
|
5
|
+
export declare const GAME_CLEANUP_TTL = 600000;
|
|
6
|
+
export declare const MAX_LOG_ENTRIES = 1000;
|
|
7
|
+
export declare const RATE_LIMIT_WINDOW = 10000;
|
|
8
|
+
export declare const RATE_LIMIT_MAX = 50;
|
|
9
|
+
export declare const SESSION_TTL = 3600000;
|
|
10
|
+
export declare const STATUS_MESSAGES: Record<number, string>;
|
|
11
|
+
export declare const EARTH_RADIUS_KM = 6371;
|
|
12
|
+
export declare const MAX_ADDRESS_COUNT = 10;
|
|
13
|
+
export declare const MAX_BASE_VALUE_LENGTH = 100;
|
|
14
|
+
export declare const MAX_CHART_DATASETS = 5;
|
|
15
|
+
export declare const MAX_CHART_LABELS = 20;
|
|
16
|
+
export declare const MAX_CSV_LENGTH = 50000;
|
|
17
|
+
export declare const MAX_CSV_ROWS = 1000;
|
|
18
|
+
export declare const MAX_CREDIT_COUNT = 10;
|
|
19
|
+
export declare const MAX_COUNTDOWN_YEARS = 100;
|
|
20
|
+
export declare const MAX_CRON_ITERATIONS: number;
|
|
21
|
+
export declare const MAX_CRON_RESULTS = 20;
|
|
22
|
+
export declare const MAX_DIFF_LENGTH = 10000;
|
|
23
|
+
export declare const MAX_DIFF_PARTS = 2000;
|
|
24
|
+
export declare const MAX_EXPR_DEPTH = 100;
|
|
25
|
+
export declare const MAX_EXPR_LENGTH = 500;
|
|
26
|
+
export declare const MAX_FACTORIAL = 170;
|
|
27
|
+
export declare const MAX_GCD_VALUE = 100000;
|
|
28
|
+
export declare const MAX_JWT_LENGTH = 8192;
|
|
29
|
+
export declare const MAX_LEVENSHTEIN_LENGTH = 1000;
|
|
30
|
+
export declare const MIN_PASSWORD_LENGTH = 8;
|
|
31
|
+
export declare const MAX_PASSWORD_LENGTH = 128;
|
|
32
|
+
export declare const MAX_PASSWORD_COUNT = 20;
|
|
33
|
+
export declare const MAX_MATRIX_SIZE = 20;
|
|
34
|
+
export declare const MAX_PATTERN_LENGTH = 200;
|
|
35
|
+
export declare const MAX_POW_DIFFICULTY = 6;
|
|
36
|
+
export declare const MAX_PRIME_LIST = 10000;
|
|
37
|
+
export declare const POW_DEFAULT_DIFFICULTY = 4;
|
|
38
|
+
export declare const MAX_QRCODE_LOGO_BYTES: number;
|
|
39
|
+
export declare const MAX_READ_LENGTH = 50000;
|
|
40
|
+
export declare const MAX_REGEX_MATCHES = 100;
|
|
41
|
+
export declare const MAX_RSA_MODULUS = 4096;
|
|
42
|
+
export declare const MAX_SEMVER_LENGTH = 256;
|
|
43
|
+
export declare const MAX_STRING_LENGTH = 1000;
|
|
44
|
+
export declare const MIN_TOKEN_LENGTH = 12;
|
|
45
|
+
export declare const MAX_TOKEN_LENGTH = 4096;
|
|
46
|
+
export declare const MAX_URL_LENGTH = 2048;
|
|
47
|
+
export declare const MAX_UUID_COUNT = 50;
|
|
48
|
+
export declare const ROMAN_VALUES: [number, string][];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
2
|
+
// App
|
|
3
|
+
export const APP_VERSION = pkg.version;
|
|
4
|
+
export const DEFAULT_PORT = 3000;
|
|
5
|
+
export const START_TIME = Date.now();
|
|
6
|
+
// Server
|
|
7
|
+
export const CHALLENGE_TTL = 300_000;
|
|
8
|
+
export const GAME_CLEANUP_TTL = 600_000;
|
|
9
|
+
export const MAX_LOG_ENTRIES = 1000;
|
|
10
|
+
export const RATE_LIMIT_WINDOW = 10_000;
|
|
11
|
+
export const RATE_LIMIT_MAX = 50;
|
|
12
|
+
export const SESSION_TTL = 3_600_000;
|
|
13
|
+
export const STATUS_MESSAGES = {
|
|
14
|
+
400: 'Bad Request',
|
|
15
|
+
401: 'Unauthorized',
|
|
16
|
+
404: 'Not Found',
|
|
17
|
+
405: 'Method Not Allowed',
|
|
18
|
+
413: 'Payload Too Large',
|
|
19
|
+
429: 'Too Many Requests',
|
|
20
|
+
500: 'Internal Server Error',
|
|
21
|
+
};
|
|
22
|
+
// Modules
|
|
23
|
+
export const EARTH_RADIUS_KM = 6371;
|
|
24
|
+
export const MAX_ADDRESS_COUNT = 10;
|
|
25
|
+
export const MAX_BASE_VALUE_LENGTH = 100;
|
|
26
|
+
export const MAX_CHART_DATASETS = 5;
|
|
27
|
+
export const MAX_CHART_LABELS = 20;
|
|
28
|
+
export const MAX_CSV_LENGTH = 50_000;
|
|
29
|
+
export const MAX_CSV_ROWS = 1000;
|
|
30
|
+
export const MAX_CREDIT_COUNT = 10;
|
|
31
|
+
export const MAX_COUNTDOWN_YEARS = 100;
|
|
32
|
+
export const MAX_CRON_ITERATIONS = 365 * 24 * 60;
|
|
33
|
+
export const MAX_CRON_RESULTS = 20;
|
|
34
|
+
export const MAX_DIFF_LENGTH = 10_000;
|
|
35
|
+
export const MAX_DIFF_PARTS = 2000;
|
|
36
|
+
export const MAX_EXPR_DEPTH = 100;
|
|
37
|
+
export const MAX_EXPR_LENGTH = 500;
|
|
38
|
+
export const MAX_FACTORIAL = 170;
|
|
39
|
+
export const MAX_GCD_VALUE = 100_000;
|
|
40
|
+
export const MAX_JWT_LENGTH = 8192;
|
|
41
|
+
export const MAX_LEVENSHTEIN_LENGTH = 1000;
|
|
42
|
+
export const MIN_PASSWORD_LENGTH = 8;
|
|
43
|
+
export const MAX_PASSWORD_LENGTH = 128;
|
|
44
|
+
export const MAX_PASSWORD_COUNT = 20;
|
|
45
|
+
export const MAX_MATRIX_SIZE = 20;
|
|
46
|
+
export const MAX_PATTERN_LENGTH = 200;
|
|
47
|
+
export const MAX_POW_DIFFICULTY = 6;
|
|
48
|
+
export const MAX_PRIME_LIST = 10_000;
|
|
49
|
+
export const POW_DEFAULT_DIFFICULTY = 4;
|
|
50
|
+
export const MAX_QRCODE_LOGO_BYTES = 2 * 1024 * 1024;
|
|
51
|
+
export const MAX_READ_LENGTH = 50_000;
|
|
52
|
+
export const MAX_REGEX_MATCHES = 100;
|
|
53
|
+
export const MAX_RSA_MODULUS = 4096;
|
|
54
|
+
export const MAX_SEMVER_LENGTH = 256;
|
|
55
|
+
export const MAX_STRING_LENGTH = 1000;
|
|
56
|
+
export const MIN_TOKEN_LENGTH = 12;
|
|
57
|
+
export const MAX_TOKEN_LENGTH = 4096;
|
|
58
|
+
export const MAX_URL_LENGTH = 2048;
|
|
59
|
+
export const MAX_UUID_COUNT = 50;
|
|
60
|
+
export const ROMAN_VALUES = [
|
|
61
|
+
[1000, 'M'],
|
|
62
|
+
[900, 'CM'],
|
|
63
|
+
[500, 'D'],
|
|
64
|
+
[400, 'CD'],
|
|
65
|
+
[100, 'C'],
|
|
66
|
+
[90, 'XC'],
|
|
67
|
+
[50, 'L'],
|
|
68
|
+
[40, 'XL'],
|
|
69
|
+
[10, 'X'],
|
|
70
|
+
[9, 'IX'],
|
|
71
|
+
[5, 'V'],
|
|
72
|
+
[4, 'IV'],
|
|
73
|
+
[1, 'I'],
|
|
74
|
+
];
|
|
75
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import cors from 'cors';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { env } from '../config/env.js';
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
export function setupCors(app) {
|
|
9
|
+
app.set('trust proxy', env.TRUSTED_PROXIES ?? 1);
|
|
10
|
+
app.use(cors({
|
|
11
|
+
methods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
12
|
+
exposedHeaders: [
|
|
13
|
+
'X-Captcha-Text',
|
|
14
|
+
'X-Captcha-Token',
|
|
15
|
+
'X-RateLimit-Limit',
|
|
16
|
+
'X-RateLimit-Remaining',
|
|
17
|
+
'X-RateLimit-Reset',
|
|
18
|
+
'Retry-After',
|
|
19
|
+
],
|
|
20
|
+
}));
|
|
21
|
+
app.use(express.urlencoded({ extended: true, limit: '10kb' }));
|
|
22
|
+
app.use(express.json({ limit: '10kb' }));
|
|
23
|
+
app.use((_req, res, next) => {
|
|
24
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
25
|
+
res.setHeader('X-Frame-Options', 'DENY');
|
|
26
|
+
next();
|
|
27
|
+
});
|
|
28
|
+
app.use('/favicon.ico', express.static(join(__dirname, '..', '..', 'src', 'favicon.ico')));
|
|
29
|
+
app.use('/robots.txt', express.static(join(__dirname, '..', '..', 'robots.txt')));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAyB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,UAAU,SAAS,CAAC,GAAY;IAClC,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC;IAEjD,GAAG,CAAC,GAAG,CACH,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;QACtD,cAAc,EAAE;YACZ,gBAAgB;YAChB,iBAAiB;YACjB,mBAAmB;YACnB,uBAAuB;YACvB,mBAAmB;YACnB,aAAa;SAChB;KACJ,CAAC,CACL,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/D,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAEzC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;QACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC3F,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { error } from '../utils/response.js';
|
|
2
|
+
export function errorHandler(err, _req, res, _next) {
|
|
3
|
+
console.error(err.stack);
|
|
4
|
+
const status = err.status && err.status >= 400 && err.status < 600 ? err.status : 500;
|
|
5
|
+
const sensitive = status === 500 && /\/[a-z]|\\[a-z]|ECONNREFUSED|ENOENT|EPERM|at\s+\w/i.test(err.message);
|
|
6
|
+
error(res, status, sensitive ? 'An unexpected error occurred.' : err.message);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,MAAM,UAAU,YAAY,CACxB,GAAgC,EAChC,IAAa,EACb,GAAa,EACb,KAAmB;IAEnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IACtF,MAAM,SAAS,GAAG,MAAM,KAAK,GAAG,IAAI,oDAAoD,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3G,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/middleware/json.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,sBAAsB,CAAC,IAAa,EAAE,GAAa,EAAE,IAAkB;IACnF,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAClD,GAAG,CAAC,YAAY,GAAG,CAAC,IAAa,EAAE,EAAE;QACjC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC;IACF,IAAI,EAAE,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from 'express';
|
|
2
|
+
export declare const logger: import("@20syldev/logger.ts").Logger;
|
|
3
|
+
/**
|
|
4
|
+
* Masks an identifier carried in the path, leaving the named sub-routes visible.
|
|
5
|
+
*
|
|
6
|
+
* @param path - Request path, without its query string
|
|
7
|
+
* @returns The path, with a trailing identifier segment masked
|
|
8
|
+
*/
|
|
9
|
+
export declare function redactPath(path: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Strips query string values from a URL, keeping the path and parameter names.
|
|
12
|
+
*
|
|
13
|
+
* GET endpoints carry user input in the query string — text passed to /encode,
|
|
14
|
+
* card numbers and IBANs passed to /validate, URLs passed to /qrcode — and the
|
|
15
|
+
* log buffer is readable over /logs. Names alone keep the trace useful for
|
|
16
|
+
* debugging without retaining anybody's payload.
|
|
17
|
+
*
|
|
18
|
+
* Names are kept percent-encoded on purpose. Decoding them would let a caller
|
|
19
|
+
* write raw newlines and ANSI escapes into the operator's terminal and into the
|
|
20
|
+
* /logs buffer, and would expose the theme's {placeholder} syntax.
|
|
21
|
+
*
|
|
22
|
+
* @param originalUrl - Request URL, with or without a query string
|
|
23
|
+
* @returns The path, followed by the parameter names when the URL had any
|
|
24
|
+
*/
|
|
25
|
+
export declare function redactQuery(originalUrl: string): string;
|
|
26
|
+
export declare function loggerMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createLogger } from '@20syldev/logger.ts';
|
|
2
|
+
import { MAX_LOG_ENTRIES } from '../constants.js';
|
|
3
|
+
export const logger = createLogger({
|
|
4
|
+
maxEntries: MAX_LOG_ENTRIES,
|
|
5
|
+
console: true,
|
|
6
|
+
theme: 'colored',
|
|
7
|
+
});
|
|
8
|
+
const SECRET_PATH = /^(\/v\d+\/(?:chat|tic-tac-toe))\/(?!clear$|fetch$|forfeit$|list$|play$|private$)[^/]+/;
|
|
9
|
+
/**
|
|
10
|
+
* Masks an identifier carried in the path, leaving the named sub-routes visible.
|
|
11
|
+
*
|
|
12
|
+
* @param path - Request path, without its query string
|
|
13
|
+
* @returns The path, with a trailing identifier segment masked
|
|
14
|
+
*/
|
|
15
|
+
export function redactPath(path) {
|
|
16
|
+
return path.replace(SECRET_PATH, '$1/[redacted]');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Strips query string values from a URL, keeping the path and parameter names.
|
|
20
|
+
*
|
|
21
|
+
* GET endpoints carry user input in the query string — text passed to /encode,
|
|
22
|
+
* card numbers and IBANs passed to /validate, URLs passed to /qrcode — and the
|
|
23
|
+
* log buffer is readable over /logs. Names alone keep the trace useful for
|
|
24
|
+
* debugging without retaining anybody's payload.
|
|
25
|
+
*
|
|
26
|
+
* Names are kept percent-encoded on purpose. Decoding them would let a caller
|
|
27
|
+
* write raw newlines and ANSI escapes into the operator's terminal and into the
|
|
28
|
+
* /logs buffer, and would expose the theme's {placeholder} syntax.
|
|
29
|
+
*
|
|
30
|
+
* @param originalUrl - Request URL, with or without a query string
|
|
31
|
+
* @returns The path, followed by the parameter names when the URL had any
|
|
32
|
+
*/
|
|
33
|
+
export function redactQuery(originalUrl) {
|
|
34
|
+
const [path = '', ...rest] = originalUrl.split('?');
|
|
35
|
+
const query = rest.join('?');
|
|
36
|
+
if (!query)
|
|
37
|
+
return redactPath(path);
|
|
38
|
+
const names = [...new Set(query.split('&').map((pair) => pair.split('=')[0] ?? ''))].filter(Boolean);
|
|
39
|
+
return names.length ? `${redactPath(path)}?${names.join('&')}` : redactPath(path);
|
|
40
|
+
}
|
|
41
|
+
export function loggerMiddleware(req, res, next) {
|
|
42
|
+
if (req.method === 'HEAD') {
|
|
43
|
+
next();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (req.originalUrl === '/logs') {
|
|
47
|
+
next();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const startTime = Date.now();
|
|
51
|
+
const platform = req.headers['sec-ch-ua-platform']?.replace(/"/g, '');
|
|
52
|
+
res.on('finish', () => {
|
|
53
|
+
const status = res.statusCode === 304 ? 200 : res.statusCode;
|
|
54
|
+
const duration = `${Date.now() - startTime}ms`;
|
|
55
|
+
const entry = { method: req.method, url: redactQuery(req.originalUrl), status, duration, platform };
|
|
56
|
+
if (status >= 500)
|
|
57
|
+
logger.error(entry);
|
|
58
|
+
else if (status >= 400)
|
|
59
|
+
logger.warn(entry);
|
|
60
|
+
else
|
|
61
|
+
logger.info(entry);
|
|
62
|
+
});
|
|
63
|
+
next();
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,CAAC;IAC/B,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,SAAS;CACnB,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,uFAAuF,CAAC;AAE5G;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC3C,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK;QAAE,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrG,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IAC5E,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC;QACP,OAAO;IACX,CAAC;IACD,IAAI,GAAG,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC;QAC9B,IAAI,EAAE,CAAC;QACP,OAAO;IACX,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAI,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAY,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAElF,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QAClB,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;QAC7D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,CAAC;QAE/C,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAEpG,IAAI,MAAM,IAAI,GAAG;YAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;aAClC,IAAI,MAAM,IAAI,GAAG;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;YACtC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,IAAI,EAAE,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getPlan, globalLimit } from '../config/plans.js';
|
|
2
|
+
import { RATE_LIMIT_WINDOW, SESSION_TTL } from '../constants.js';
|
|
3
|
+
import { ipLimits } from '../storage/index.js';
|
|
4
|
+
import { error } from '../utils/response.js';
|
|
5
|
+
let requests = 0;
|
|
6
|
+
let resetTime = Date.now() + SESSION_TTL;
|
|
7
|
+
const burstTracker = {};
|
|
8
|
+
// Cleanup stale IPs every hour
|
|
9
|
+
setInterval(() => {
|
|
10
|
+
const currentHour = String(Math.floor(Date.now() / 3600000) % 24);
|
|
11
|
+
for (const ip of Object.keys(ipLimits)) {
|
|
12
|
+
const hours = Object.keys(ipLimits[ip]);
|
|
13
|
+
if (hours.length === 0 || (hours.length === 1 && hours[0] !== currentHour)) {
|
|
14
|
+
delete ipLimits[ip];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
for (const ip of Object.keys(burstTracker)) {
|
|
19
|
+
burstTracker[ip] = burstTracker[ip].filter((t) => now - t < RATE_LIMIT_WINDOW);
|
|
20
|
+
if (burstTracker[ip].length === 0)
|
|
21
|
+
delete burstTracker[ip];
|
|
22
|
+
}
|
|
23
|
+
}, SESSION_TTL).unref();
|
|
24
|
+
export function rateLimitMiddleware(req, res, next) {
|
|
25
|
+
const ip = req.ip || req.socket.remoteAddress || '';
|
|
26
|
+
const token = req.headers.authorization?.split(' ')[1] || '';
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
const minute = String(Math.floor(now / 60000) % 60);
|
|
29
|
+
const hour = String(Math.floor(now / 3600000) % 24);
|
|
30
|
+
const match = getPlan(token);
|
|
31
|
+
if (!match) {
|
|
32
|
+
error(res, 401, 'Invalid token.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const { plan } = match;
|
|
36
|
+
if (now > resetTime) {
|
|
37
|
+
requests = 0;
|
|
38
|
+
resetTime = now + SESSION_TTL;
|
|
39
|
+
}
|
|
40
|
+
if (++requests > Math.max(globalLimit, plan.hourly)) {
|
|
41
|
+
res.setHeader('Retry-After', Math.ceil((resetTime - now) / 1000));
|
|
42
|
+
error(res, 429, 'Global rate limit exceeded.');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (['__proto__', 'constructor', 'prototype'].includes(ip)) {
|
|
46
|
+
error(res, 400, 'Invalid IP address.');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Burst protection per tier
|
|
50
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
51
|
+
if (!burstTracker[ip])
|
|
52
|
+
burstTracker[ip] = [];
|
|
53
|
+
burstTracker[ip] = burstTracker[ip].filter((t) => now - t < RATE_LIMIT_WINDOW);
|
|
54
|
+
burstTracker[ip].push(now);
|
|
55
|
+
if (burstTracker[ip].length > plan.burst) {
|
|
56
|
+
res.setHeader('Retry-After', Math.ceil(RATE_LIMIT_WINDOW / 1000));
|
|
57
|
+
error(res, 429, 'Too many requests, please slow down.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Hourly rate limit per IP
|
|
62
|
+
if (!ipLimits[ip])
|
|
63
|
+
ipLimits[ip] = {};
|
|
64
|
+
if (!ipLimits[ip][hour])
|
|
65
|
+
ipLimits[ip][hour] = {};
|
|
66
|
+
ipLimits[ip][hour][minute] = (ipLimits[ip][hour][minute] ?? 0) + 1;
|
|
67
|
+
const hourTotal = Object.values(ipLimits[ip][hour]).reduce((sum, count) => sum + count, 0);
|
|
68
|
+
const hourEnds = Math.ceil(now / 3600000) * 3600000;
|
|
69
|
+
res.setHeader('X-RateLimit-Limit', plan.hourly);
|
|
70
|
+
res.setHeader('X-RateLimit-Remaining', Math.max(0, plan.hourly - hourTotal));
|
|
71
|
+
res.setHeader('X-RateLimit-Reset', Math.floor(hourEnds / 1000));
|
|
72
|
+
if (hourTotal > plan.hourly) {
|
|
73
|
+
res.setHeader('Retry-After', Math.ceil((hourEnds - now) / 1000));
|
|
74
|
+
error(res, 429, `You have exceeded the limit of ${plan.hourly} requests per hour.`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
Object.keys(ipLimits[ip]).forEach((h) => {
|
|
78
|
+
if (h != hour)
|
|
79
|
+
delete ipLimits[ip][h];
|
|
80
|
+
});
|
|
81
|
+
next();
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=ratelimit.js.map
|