topbit 1.0.0 → 3.0.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/LICENSE +128 -0
- package/README.cn.md +1519 -0
- package/README.md +1483 -0
- package/bin/app.js +17 -0
- package/bin/loadinfo.sh +18 -0
- package/bin/new-ctl.js +234 -0
- package/bin/newapp.js +22 -0
- package/demo/allow.js +98 -0
- package/demo/cert/localhost-cert.pem +19 -0
- package/demo/cert/localhost-privkey.pem +28 -0
- package/demo/controller/api.js +15 -0
- package/demo/extends.js +5 -0
- package/demo/group-api.js +161 -0
- package/demo/group-api2.js +109 -0
- package/demo/http2.js +34 -0
- package/demo/http2_proxy_backend.js +45 -0
- package/demo/http2proxy.js +48 -0
- package/demo/http_proxy_backend.js +44 -0
- package/demo/httpproxy.js +47 -0
- package/demo/loader.js +27 -0
- package/demo/log.js +118 -0
- package/demo/memlimit.js +31 -0
- package/demo/min.js +7 -0
- package/demo/serv.js +15 -0
- package/images/middleware.jpg +0 -0
- package/images/topbit-middleware.png +0 -0
- package/images/topbit.png +0 -0
- package/package.json +42 -11
- package/src/_loadExtends.js +21 -0
- package/src/bodyparser.js +420 -0
- package/src/connfilter.js +125 -0
- package/src/context1.js +166 -0
- package/src/context2.js +182 -0
- package/src/ctxpool.js +39 -0
- package/src/ext.js +318 -0
- package/src/extends/Http2Pool.js +365 -0
- package/src/extends/__randstring.js +24 -0
- package/src/extends/cookie.js +44 -0
- package/src/extends/cors.js +334 -0
- package/src/extends/errorlog.js +252 -0
- package/src/extends/http2limit.js +126 -0
- package/src/extends/http2proxy.js +691 -0
- package/src/extends/jwt.js +217 -0
- package/src/extends/mixlogger.js +63 -0
- package/src/extends/paramcheck.js +266 -0
- package/src/extends/proxy.js +662 -0
- package/src/extends/realip.js +34 -0
- package/src/extends/referer.js +68 -0
- package/src/extends/resource.js +398 -0
- package/src/extends/session.js +174 -0
- package/src/extends/setfinal.js +50 -0
- package/src/extends/sni.js +48 -0
- package/src/extends/sse.js +293 -0
- package/src/extends/timing.js +111 -0
- package/src/extends/tofile.js +123 -0
- package/src/fastParseUrl.js +426 -0
- package/src/headerLimit.js +18 -0
- package/src/http1.js +336 -0
- package/src/http2.js +337 -0
- package/src/httpc.js +251 -0
- package/src/lib/npargv.js +354 -0
- package/src/lib/zipdata.js +45 -0
- package/src/loader/loader.js +999 -0
- package/src/logger.js +32 -0
- package/src/loggermsg.js +349 -0
- package/src/makeId.js +200 -0
- package/src/midcore.js +213 -0
- package/src/middleware1.js +103 -0
- package/src/middleware2.js +116 -0
- package/src/monitor.js +380 -0
- package/src/movefile.js +30 -0
- package/src/optionsCheck.js +54 -0
- package/src/randstring.js +23 -0
- package/src/router.js +682 -0
- package/src/sendmsg.js +27 -0
- package/src/strong.js +72 -0
- package/src/token/token.js +461 -0
- package/src/topbit.js +1293 -0
- package/src/versionCheck.js +31 -0
- package/test/test-bigctx.js +29 -0
- package/test/test-daemon-args.js +7 -0
- package/test/test-ext.js +81 -0
- package/test/test-find.js +69 -0
- package/test/test-route-sort.js +71 -0
- package/test/test-route.js +49 -0
- package/test/test-route2.js +51 -0
- package/test/test-run-args.js +7 -0
- package/test/test-url.js +52 -0
- package/main.js +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* jwt格式:
|
|
6
|
+
*
|
|
7
|
+
* base64UrlEncoded(header).base64UrlEncoded(payload).signature
|
|
8
|
+
*
|
|
9
|
+
* header: {
|
|
10
|
+
* "alg": "hs256",
|
|
11
|
+
* "typ": "JWT"
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* payload是任何object类型的数据
|
|
15
|
+
*
|
|
16
|
+
* payload 示例 {
|
|
17
|
+
* "id": "1234",
|
|
18
|
+
* "name": "okk"
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* signature是hamacsha256(base64UrlEncoded(header).base64UrlEncoded(payload), key)
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const randstring = require('./__randstring.js')
|
|
26
|
+
|
|
27
|
+
const crypto = require('node:crypto')
|
|
28
|
+
|
|
29
|
+
class JWT {
|
|
30
|
+
|
|
31
|
+
constructor(options = {}) {
|
|
32
|
+
this.expires = 3600000
|
|
33
|
+
this.autoTimeout = true
|
|
34
|
+
this.header = ''
|
|
35
|
+
|
|
36
|
+
this.algMap = {
|
|
37
|
+
HS256: 'sha256',
|
|
38
|
+
HS384: 'sha384',
|
|
39
|
+
HS512: 'sha512',
|
|
40
|
+
SM3: 'sm3',
|
|
41
|
+
SHA256: 'sha256',
|
|
42
|
+
SHA512: 'sha512',
|
|
43
|
+
SHA384: 'sha384'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.algKeys = Object.keys(this.algMap)
|
|
47
|
+
|
|
48
|
+
Object.defineProperty(this, '__key__', {
|
|
49
|
+
value: randstring(16),
|
|
50
|
+
enumerable: false,
|
|
51
|
+
configurable: false,
|
|
52
|
+
writable: true
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
Object.defineProperty(this, '__alg__', {
|
|
56
|
+
value: 'SM3',
|
|
57
|
+
enumerable: false,
|
|
58
|
+
configurable: false,
|
|
59
|
+
writable: true
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
Object.defineProperties(this, {
|
|
63
|
+
key: {
|
|
64
|
+
get: () => {
|
|
65
|
+
return this.__key__
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
set: (key) => {
|
|
69
|
+
this.__key__ = key
|
|
70
|
+
this.makeHeader()
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
alg: {
|
|
75
|
+
get: () => {
|
|
76
|
+
return this.__alg__
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
set: (a) => {
|
|
80
|
+
a = a.toUpperCase()
|
|
81
|
+
if (this.algKeys.indexOf(a) >= 0) {
|
|
82
|
+
this.__alg__ = a
|
|
83
|
+
this.makeHeader()
|
|
84
|
+
} else {
|
|
85
|
+
console.error(`无法支持的算法:${a}`)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
for (let k in options) {
|
|
92
|
+
switch(k) {
|
|
93
|
+
case 'expires':
|
|
94
|
+
case 'autoTimeout':
|
|
95
|
+
case 'alg':
|
|
96
|
+
case 'key':
|
|
97
|
+
this[k] = options[k];
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.makeHeader()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
makeHeader() {
|
|
106
|
+
let hdata = `{"alg":"${this.__alg__}","typ":"JWT"}`
|
|
107
|
+
this.header = Buffer.from(hdata).toString('base64url')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
make(data) {
|
|
111
|
+
if (typeof data === 'object') {
|
|
112
|
+
if (this.autoTimeout) {
|
|
113
|
+
data.__timeout__ = Date.now() + this.expires
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
data = JSON.stringify(data)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let org_str = `${this.header}.${Buffer.from(data).toString('base64url')}`
|
|
120
|
+
return `${org_str}.${this.sign(org_str, this.algMap[this.__alg__])}`
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
sign(org_str, a = 'sm3') {
|
|
124
|
+
let h = crypto.createHmac(a, this.__key__)
|
|
125
|
+
h.update(org_str)
|
|
126
|
+
return h.digest('base64url')
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
verify(token) {
|
|
130
|
+
let arr = token.split('.')
|
|
131
|
+
if (arr.length !== 3) {
|
|
132
|
+
return {
|
|
133
|
+
ok: false,
|
|
134
|
+
errcode: 'ILLEGAL'
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
let alg = this.__alg__
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
let header = JSON.parse(Buffer.from(arr[0], 'base64url').toString('utf8'))
|
|
142
|
+
alg = header.alg
|
|
143
|
+
} catch (err) {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
errcode: 'ERR_HEADER'
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let hs = this.algMap[alg]
|
|
151
|
+
|
|
152
|
+
if (!hs) {
|
|
153
|
+
return {
|
|
154
|
+
ok: false,
|
|
155
|
+
errcode: 'UNKNOW_ALG'
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let hstr = this.sign(`${arr[0]}.${arr[1]}`, hs)
|
|
160
|
+
|
|
161
|
+
if (hstr !== arr[2]) {
|
|
162
|
+
return {
|
|
163
|
+
ok: false,
|
|
164
|
+
errcode: 'FAILED'
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let data = Buffer.from(arr[1], 'base64url').toString('utf8')
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
data = JSON.parse(data)
|
|
172
|
+
} catch (err) {
|
|
173
|
+
return {
|
|
174
|
+
ok: false,
|
|
175
|
+
errcode: 'ERR_DATA'
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (data.__timeout__ !== undefined && (Date.now() > data.__timeout__)) {
|
|
180
|
+
return {
|
|
181
|
+
ok: false,
|
|
182
|
+
errcode: 'TIMEOUT'
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
ok: true,
|
|
188
|
+
data: data
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
mid() {
|
|
194
|
+
let self = this
|
|
195
|
+
|
|
196
|
+
return async (ctx, next) => {
|
|
197
|
+
let token = ctx.headers.authorization || ctx.query.token
|
|
198
|
+
if (!token) {
|
|
199
|
+
return ctx.status(401).send('unauthorized')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
let r = self.verify(token)
|
|
203
|
+
|
|
204
|
+
if (!r.ok) {
|
|
205
|
+
return ctx.status(401).send(r.errcode)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
ctx.box.user = r.data
|
|
209
|
+
ctx.user = r.data
|
|
210
|
+
|
|
211
|
+
await next(ctx)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
module.exports = JWT
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const cluster = require('node:cluster')
|
|
4
|
+
|
|
5
|
+
class MixLogger {
|
|
6
|
+
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.logHandle = (w, msg, handle) => {
|
|
9
|
+
return true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
this.quiet = true
|
|
13
|
+
|
|
14
|
+
for (let k in options) {
|
|
15
|
+
switch(k) {
|
|
16
|
+
case 'logHandle':
|
|
17
|
+
if (typeof options[k] === 'function') {
|
|
18
|
+
this.logHandle = options[k]
|
|
19
|
+
}
|
|
20
|
+
break
|
|
21
|
+
|
|
22
|
+
case 'quiet':
|
|
23
|
+
this.quiet = !!options[k]
|
|
24
|
+
break
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
init(app) {
|
|
31
|
+
if (cluster.isWorker) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//版本兼容
|
|
36
|
+
let mse = app.daeMsgEvent ? app.daeMsgEvent : app.msgEvent
|
|
37
|
+
|
|
38
|
+
if (mse['_log'] === undefined) {
|
|
39
|
+
if (!this.quiet) {
|
|
40
|
+
return console.error(`Warning: mixlogger must be running in daemon mode`)
|
|
41
|
+
}
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let self = this
|
|
46
|
+
|
|
47
|
+
let org_log = mse['_log'].callback
|
|
48
|
+
|
|
49
|
+
let log_handle = (w, msg, handle) => {
|
|
50
|
+
if (false === self.logHandle(w, msg, handle) ) {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
org_log(w, msg, handle)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
app.setMsgEvent('_log', log_handle)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = MixLogger
|
|
63
|
+
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 用于param或者query检测的中间件扩展,启用此扩展,会自动进行属性值的检测。
|
|
5
|
+
* 支持声明式的设计,避免重复劳动。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
let TYPE_STRING = 1
|
|
9
|
+
let TYPE_NUMBER = 2
|
|
10
|
+
|
|
11
|
+
class ParamCheck {
|
|
12
|
+
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.type = ['query', 'param', 'body']
|
|
15
|
+
this.key = 'param'
|
|
16
|
+
this.data = {}
|
|
17
|
+
this.errorMessage = "提交数据不符合要求"
|
|
18
|
+
//设置禁止提交的字段
|
|
19
|
+
this.deny = null
|
|
20
|
+
this.denyMessage = '存在禁止提交的数据'
|
|
21
|
+
this.deleteDeny = false
|
|
22
|
+
|
|
23
|
+
for (let k in options) {
|
|
24
|
+
switch (k) {
|
|
25
|
+
case 'key':
|
|
26
|
+
if (this.type.indexOf(options[k]) >= 0) {
|
|
27
|
+
this.key = options[k]
|
|
28
|
+
}
|
|
29
|
+
break
|
|
30
|
+
|
|
31
|
+
case 'data':
|
|
32
|
+
if (typeof options[k] === 'object') {
|
|
33
|
+
this.data = options[k]
|
|
34
|
+
}
|
|
35
|
+
break
|
|
36
|
+
|
|
37
|
+
case 'errorMessage':
|
|
38
|
+
this[k] = options[k]
|
|
39
|
+
break
|
|
40
|
+
|
|
41
|
+
case 'deny':
|
|
42
|
+
if (typeof options[k] === 'string') {
|
|
43
|
+
options[k] = [options[k]]
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(options[k])) {
|
|
46
|
+
this.deny = options[k]
|
|
47
|
+
}
|
|
48
|
+
break
|
|
49
|
+
|
|
50
|
+
case 'deleteDeny':
|
|
51
|
+
this.deleteDeny = !!options[k]
|
|
52
|
+
break
|
|
53
|
+
|
|
54
|
+
default:
|
|
55
|
+
this[k] = options[k]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let data_type = ''
|
|
60
|
+
for (let k in this.data) {
|
|
61
|
+
data_type = typeof this.data[k]
|
|
62
|
+
|
|
63
|
+
if (data_type === 'string' || data_type === 'number') {
|
|
64
|
+
this.data[k] = {
|
|
65
|
+
__is_value__: true,
|
|
66
|
+
__value__: this.data[k],
|
|
67
|
+
__type__: data_type === 'string' ? TYPE_STRING : TYPE_NUMBER
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
continue
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.data[k].__is_value__ = false
|
|
74
|
+
|
|
75
|
+
if (this.data[k].callback && typeof this.data[k].callback === 'function') {
|
|
76
|
+
this.data[k].__is_call__ = true
|
|
77
|
+
} else {
|
|
78
|
+
this.data[k].__is_call__ = false
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param {object} obj c.param or c.query
|
|
87
|
+
* @param {*} k key name
|
|
88
|
+
* @param {*} rule filter rule
|
|
89
|
+
*
|
|
90
|
+
* rule描述了如何进行数据的过滤,如果rule是字符串或数字则要求严格相等。
|
|
91
|
+
* 否则rule应该是一个object,可以包括的属性如下:
|
|
92
|
+
* - callback 用于过滤的回调函数,在验证时,会传递数据,除此之外没有其他参数。
|
|
93
|
+
* - must false|true,表示是不是必须,如果must为true,则表示数据不能是undefined。
|
|
94
|
+
* - default 默认值,如果存在,而参数属性未定义,则赋予默认值。
|
|
95
|
+
* - to int|float 要转换成哪种类型。
|
|
96
|
+
* - min 最小值,可以 >= 此值,数字或字符串。
|
|
97
|
+
* - max 最大值,可以 <= 此值,数字或字符串。
|
|
98
|
+
*/
|
|
99
|
+
checkData(obj, k, rule, method, ost) {
|
|
100
|
+
let typ = typeof rule
|
|
101
|
+
|
|
102
|
+
ost.ok = true
|
|
103
|
+
ost.key = k
|
|
104
|
+
|
|
105
|
+
if (!rule.__is_value__) {
|
|
106
|
+
if (obj[k] === undefined) {
|
|
107
|
+
if (rule.must) {
|
|
108
|
+
ost.ok = false
|
|
109
|
+
return false
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (rule.default !== undefined) {
|
|
113
|
+
obj[k] = rule.default
|
|
114
|
+
return true
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
} else {
|
|
118
|
+
//数据初始必然是字符串,转换只能是整数或浮点数或boolean。
|
|
119
|
+
if (rule.to) {
|
|
120
|
+
if (isNaN(obj[k])) {
|
|
121
|
+
ost.ok = false
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
switch(rule.to) {
|
|
126
|
+
case 'int':
|
|
127
|
+
obj[k] = parseInt(obj[k])
|
|
128
|
+
if (isNaN(obj[k])) {
|
|
129
|
+
if (rule.default !== undefined) {
|
|
130
|
+
obj[k] = rule.default
|
|
131
|
+
return true
|
|
132
|
+
}
|
|
133
|
+
ost.ok = false
|
|
134
|
+
return false
|
|
135
|
+
}
|
|
136
|
+
break
|
|
137
|
+
|
|
138
|
+
case 'float':
|
|
139
|
+
obj[k] = parseFloat(obj[k])
|
|
140
|
+
if (isNaN(obj[k])) {
|
|
141
|
+
if (rule.default !== undefined) {
|
|
142
|
+
obj[k] = rule.default
|
|
143
|
+
return true
|
|
144
|
+
}
|
|
145
|
+
ost.ok = false
|
|
146
|
+
return false
|
|
147
|
+
}
|
|
148
|
+
break
|
|
149
|
+
|
|
150
|
+
case 'boolean':
|
|
151
|
+
case 'bool':
|
|
152
|
+
obj[k] = obj[k] === 'true' ? true : false
|
|
153
|
+
break
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (rule.min !== undefined && obj[k] < rule.min) {
|
|
158
|
+
ost.ok = false
|
|
159
|
+
return false
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (rule.max !== undefined && obj[k] > rule.max) {
|
|
163
|
+
ost.ok = false
|
|
164
|
+
return false
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//无论obj[k]是否存在,只要存在callback,就要执行。
|
|
169
|
+
if (rule.__is_call__) {
|
|
170
|
+
if (rule.callback(obj, k, method) !== false) {
|
|
171
|
+
return true
|
|
172
|
+
}
|
|
173
|
+
ost.ok = false
|
|
174
|
+
return false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
} else if (rule.__type__ === TYPE_STRING) {
|
|
178
|
+
if (obj[k] === undefined || obj[k] !== rule.__value__) {
|
|
179
|
+
ost.ok = false
|
|
180
|
+
return false
|
|
181
|
+
}
|
|
182
|
+
} else if (rule.__type__ === TYPE_NUMBER) {
|
|
183
|
+
if (obj[k] === undefined || obj[k] != rule.__value__) {
|
|
184
|
+
ost.ok = false
|
|
185
|
+
return false
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return true
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
dataFilter(c) {
|
|
193
|
+
let d = c[this.key]
|
|
194
|
+
let ost = {ok: true, key: ''}
|
|
195
|
+
|
|
196
|
+
if (this.key !== 'body' || (c.body !== c.rawBody && typeof c.body === 'object')) {
|
|
197
|
+
for (let k in this.data) {
|
|
198
|
+
if (!this.checkData(d, k, this.data[k], c.method, ost)) {
|
|
199
|
+
return ost
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return ost
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
mid() {
|
|
208
|
+
let self = this
|
|
209
|
+
let dataObject = this.data
|
|
210
|
+
|
|
211
|
+
if (!Array.isArray(this.deny) || this.deny.length === 0) this.deny = null
|
|
212
|
+
|
|
213
|
+
if (this.deny) {
|
|
214
|
+
if (this.deleteDeny) {
|
|
215
|
+
return async (c, next) => {
|
|
216
|
+
|
|
217
|
+
if (self.key !== 'body' || (c.body !== c.rawBody && typeof c.body === 'object')) {
|
|
218
|
+
let obj = c[self.key]
|
|
219
|
+
|
|
220
|
+
for (let k of self.deny) {
|
|
221
|
+
if (obj[k] !== undefined) delete obj[k]
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
let r = self.dataFilter(c)
|
|
226
|
+
if (!r.ok) {
|
|
227
|
+
return c.status(400).to(dataObject[r.key].errorMessage || self.errorMessage)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
await next(c)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return async (c, next) => {
|
|
236
|
+
if (self.key !== 'body' || (c.body !== c.rawBody && typeof c.body === 'object')) {
|
|
237
|
+
let obj = c[self.key]
|
|
238
|
+
|
|
239
|
+
for (let k of self.deny) {
|
|
240
|
+
if (obj[k] !== undefined) return c.status(400).to(self.denyMessage)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
let r = self.dataFilter(c)
|
|
245
|
+
if (!r.ok) {
|
|
246
|
+
return c.status(400).to(dataObject[r.key].errorMessage || self.errorMessage)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
await next(c)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return async (c, next) => {
|
|
255
|
+
let r = self.dataFilter(c)
|
|
256
|
+
if (!r.ok) {
|
|
257
|
+
return c.status(400).to(dataObject[r.key].errorMessage || self.errorMessage)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
await next(c)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
module.exports = ParamCheck
|