befly 3.76.1 → 3.76.2
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/Befly.js +159 -0
- package/README.md +50 -11
- package/apis/admin/delete.js +1 -3
- package/apis/admin/select.js +2 -7
- package/apis/admin/update.js +1 -5
- package/apis/api/select.js +2 -7
- package/apis/auth/login.js +16 -20
- package/apis/dict/delete.js +1 -1
- package/apis/dict/detail.js +1 -3
- package/apis/dict/select.js +1 -2
- package/apis/dict/update.js +1 -1
- package/apis/dictType/delete.js +1 -1
- package/apis/dictType/detail.js +1 -1
- package/apis/dictType/insert.js +1 -1
- package/apis/dictType/select.js +2 -7
- package/apis/dictType/update.js +2 -2
- package/apis/email/config.js +4 -7
- package/apis/email/logList.js +2 -7
- package/apis/email/send.js +1 -2
- package/apis/email/verify.js +1 -3
- package/apis/loginLog/select.js +2 -7
- package/apis/menu/select.js +2 -7
- package/apis/operateLog/select.js +2 -7
- package/apis/role/apiSave.js +2 -2
- package/apis/role/menuSave.js +2 -2
- package/apis/role/select.js +2 -7
- package/apis/source/imageList.js +2 -5
- package/apis/tongJi/dailyReport.js +12 -13
- package/apis/tongJi/dailyReportSelect.js +1 -2
- package/apis/tongJi/dailyStats.js +1 -1
- package/apis/tongJi/dailyStatsDistribution.js +2 -2
- package/apis/tongJi/errorList.js +1 -2
- package/apis/tongJi/errorReport.js +1 -2
- package/apis/tongJi/projectDelete.js +1 -3
- package/apis/tongJi/projectSelect.js +2 -4
- package/apis/tongJi/projectUpdate.js +2 -2
- package/apis/upload/file.js +7 -5
- package/checks/api.js +43 -66
- package/checks/config.js +17 -12
- package/checks/corns.js +28 -46
- package/checks/field.js +18 -0
- package/checks/items.js +16 -60
- package/checks/menu.js +28 -39
- package/checks/table.js +106 -26
- package/checks/validation.js +13 -0
- package/configs/beflyConfig.json +6 -6
- package/configs/constConfig.js +2 -63
- package/exports.js +2 -0
- package/hooks/auth.js +11 -7
- package/hooks/parser.js +55 -59
- package/hooks/permission.js +1 -0
- package/hooks/rateLimit.js +25 -62
- package/hooks/validator.js +43 -31
- package/index.js +43 -344
- package/{lib → libs}/cacheHelper.js +3 -8
- package/libs/cron.js +60 -0
- package/libs/logger/index.js +1 -0
- package/libs/logger/logger.js +245 -0
- package/libs/logger/sanitize.js +115 -0
- package/{lib → libs/mysql}/dbHelper.js +100 -73
- package/{lib → libs/mysql}/dbParse.js +16 -9
- package/{lib → libs/mysql}/dbUtil.js +15 -32
- package/libs/mysql/error.js +29 -0
- package/libs/mysql/index.js +6 -0
- package/libs/mysql/is.js +29 -0
- package/libs/mysql/mysql.js +43 -0
- package/libs/mysql/sql/identifier.js +85 -0
- package/libs/mysql/sql/index.js +2 -0
- package/{lib → libs/mysql/sql}/sqlBuilder.js +2 -3
- package/libs/mysql/util.js +44 -0
- package/libs/redis/index.js +2 -0
- package/libs/redis/redis.js +204 -0
- package/libs/redis/redisError.js +8 -0
- package/libs/tableModel.js +72 -0
- package/libs/tool.js +33 -0
- package/libs/validator/compiler.js +248 -0
- package/libs/validator/index.js +10 -0
- package/libs/validator/parser.js +173 -0
- package/libs/validator/util.js +5 -0
- package/package.json +10 -8
- package/paths.js +2 -3
- package/plugins/cache.js +2 -1
- package/plugins/email.js +4 -4
- package/plugins/mysql.js +5 -15
- package/plugins/redis.js +4 -12
- package/router/api.js +14 -10
- package/router/root.js +14 -0
- package/router/static.js +3 -3
- package/schemas/api.json +99 -0
- package/schemas/config.json +255 -0
- package/schemas/corn.json +39 -0
- package/schemas/item.json +43 -0
- package/schemas/menu.json +44 -0
- package/schemas/table.json +80 -0
- package/scripts/syncDb/apply.js +87 -0
- package/scripts/syncDb/ddl.js +43 -0
- package/scripts/syncDb/index.js +175 -30
- package/scripts/syncDb/model.js +60 -0
- package/scripts/syncDb/plan.js +160 -0
- package/scripts/syncDb/preflight.js +98 -0
- package/scripts/syncDb/report.js +177 -162
- package/scripts/syncDb/snapshot.js +118 -0
- package/tables/admin.json +51 -53
- package/tables/api.json +28 -39
- package/tables/dailyReport.json +85 -73
- package/tables/dict.json +27 -39
- package/tables/dictType.json +20 -34
- package/tables/emailLog.json +49 -47
- package/tables/errorReport.json +86 -60
- package/tables/file.json +47 -50
- package/tables/loginLog.json +68 -55
- package/tables/menu.json +20 -34
- package/tables/operateLog.json +53 -47
- package/tables/project.json +18 -30
- package/tables/role.json +33 -37
- package/utils/cors.js +37 -41
- package/utils/deepMerge.js +3 -1
- package/utils/error.js +1 -56
- package/utils/id.js +44 -0
- package/utils/is.js +6 -243
- package/utils/response.js +12 -1
- package/utils/scanFiles.js +13 -4
- package/utils/scanSources.js +58 -20
- package/utils/util.js +11 -163
- package/apis/_apis.js +0 -20
- package/apis/auth/sendSmsCode.js +0 -24
- package/configs/regexpAlias.json +0 -55
- package/lib/connect.js +0 -119
- package/lib/logger.js +0 -430
- package/lib/redisHelper.js +0 -399
- package/lib/validator.js +0 -274
- package/lib/xmlParse.js +0 -149
- package/plugins/config.js +0 -13
- package/plugins/cron.js +0 -115
- package/plugins/logger.js +0 -17
- package/plugins/tool.js +0 -131
- package/plugins/xmlParse.js +0 -10
- package/schemas/config.js +0 -67
- package/scripts/syncDb/context.js +0 -120
- package/scripts/syncDb/diff.js +0 -279
- package/scripts/syncDb/transform.js +0 -113
- package/sql/befly.sql +0 -271
- package/utils/email.js +0 -3
- package/utils/fieldClear.js +0 -22
- package/utils/formatValidationIssues.js +0 -28
- package/utils/getClientIp.js +0 -47
- package/utils/loggerUtils.js +0 -196
- package/utils/regexpUtil.js +0 -52
- /package/{lib → libs}/smtpText.js +0 -0
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
function pickFileLabel(item, itemLabel, index) {
|
|
2
|
-
if (item) {
|
|
3
|
-
if (item.filePath) return item.filePath;
|
|
4
|
-
if (item.relativePath) return item.relativePath;
|
|
5
|
-
if (item.fileName) return item.fileName;
|
|
6
|
-
if (item.name) return item.name;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
return typeof index === "number" ? `${itemLabel}[${index}]` : itemLabel;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function formatValidationIssues(issues, options = {}) {
|
|
13
|
-
const items = Array.isArray(options.items) ? options.items : null;
|
|
14
|
-
const item = options.item || null;
|
|
15
|
-
const itemLabel = options.itemLabel || "item";
|
|
16
|
-
|
|
17
|
-
return issues.map((issue) => {
|
|
18
|
-
const path = Array.isArray(issue.path) ? issue.path : [];
|
|
19
|
-
const hasIndex = items && typeof path[0] === "number";
|
|
20
|
-
const index = hasIndex ? path[0] : null;
|
|
21
|
-
const fieldPath = (hasIndex ? path.slice(1) : path).join(".") || "(root)";
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
file: pickFileLabel(hasIndex ? items[index] : item, itemLabel, index),
|
|
25
|
-
expected: `字段 ${fieldPath} ${issue.message}`
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
}
|
package/utils/getClientIp.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { isNonEmptyString } from "./is.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 获取客户端 IP(优先代理头,其次 Bun server.requestIP 兜底)
|
|
5
|
-
*
|
|
6
|
-
* 注意:目前策略是“尽量取到 IP”,未做 trustProxy 防伪造控制。
|
|
7
|
-
*/
|
|
8
|
-
export function getClientIp(req, server) {
|
|
9
|
-
// 1) 代理/网关常见头(优先取)
|
|
10
|
-
const xForwardedFor = req.headers.get("x-forwarded-for");
|
|
11
|
-
if (isNonEmptyString(xForwardedFor)) {
|
|
12
|
-
const first = xForwardedFor.split(",")[0];
|
|
13
|
-
if (isNonEmptyString(first)) {
|
|
14
|
-
return first.trim();
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const xRealIp = req.headers.get("x-real-ip");
|
|
19
|
-
if (isNonEmptyString(xRealIp)) {
|
|
20
|
-
return xRealIp.trim();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const cfConnectingIp = req.headers.get("cf-connecting-ip");
|
|
24
|
-
if (isNonEmptyString(cfConnectingIp)) {
|
|
25
|
-
return cfConnectingIp.trim();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const xClientIp = req.headers.get("x-client-ip");
|
|
29
|
-
if (isNonEmptyString(xClientIp)) {
|
|
30
|
-
return xClientIp.trim();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const trueClientIp = req.headers.get("true-client-ip");
|
|
34
|
-
if (isNonEmptyString(trueClientIp)) {
|
|
35
|
-
return trueClientIp.trim();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 2) 连接层兜底:Bun server.requestIP(req)
|
|
39
|
-
if (server && typeof server.requestIP === "function") {
|
|
40
|
-
const ipInfo = server.requestIP(req);
|
|
41
|
-
if (ipInfo && isNonEmptyString(ipInfo.address)) {
|
|
42
|
-
return ipInfo.address.trim();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return "unknown";
|
|
47
|
-
}
|
package/utils/loggerUtils.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { errorChainSummary } from "./error.js";
|
|
2
|
-
import { isBoolean, isNullable, isNumber, isPlainObject, isSensitiveKey, isString } from "./is.js";
|
|
3
|
-
|
|
4
|
-
export function buildSensitiveKeyMatcher(options) {
|
|
5
|
-
const exactSet = new Set();
|
|
6
|
-
const contains = [];
|
|
7
|
-
|
|
8
|
-
const addPattern = (item) => {
|
|
9
|
-
const trimmed = String(item).trim().toLowerCase();
|
|
10
|
-
if (trimmed.length === 0) return;
|
|
11
|
-
|
|
12
|
-
if (!trimmed.includes("*")) {
|
|
13
|
-
exactSet.add(trimmed);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const core = trimmed.replace(/\*+/g, "").trim();
|
|
18
|
-
if (!core) return;
|
|
19
|
-
contains.push(core);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
for (const item of options.builtinPatterns) {
|
|
23
|
-
addPattern(item);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (Array.isArray(options.userPatterns)) {
|
|
27
|
-
for (const item of options.userPatterns) {
|
|
28
|
-
addPattern(item);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return { exactSet: exactSet, contains: contains };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function sanitizeErrorValue(err, options) {
|
|
36
|
-
const out = {
|
|
37
|
-
name: err.name || "Error",
|
|
38
|
-
message: err.message || "",
|
|
39
|
-
chain: errorChainSummary(err)
|
|
40
|
-
};
|
|
41
|
-
const state = { nodes: 0 };
|
|
42
|
-
const visited = new WeakSet();
|
|
43
|
-
|
|
44
|
-
visited.add(err);
|
|
45
|
-
|
|
46
|
-
if (isString(err.stack)) {
|
|
47
|
-
out["stack"] = err.stack;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!isNullable(err.cause)) {
|
|
51
|
-
out["cause"] = sanitizeAny(err.cause, options, state, 0, visited);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const ownKeys = Object.keys(err);
|
|
55
|
-
for (const key of ownKeys) {
|
|
56
|
-
if (key === "name" || key === "message" || key === "stack" || key === "cause") {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
out[key] = sanitizeAny(err[key], options, state, 0, visited);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return out;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function safeToStringMasked(value, options, visited) {
|
|
67
|
-
if (isString(value)) return value;
|
|
68
|
-
|
|
69
|
-
if (value instanceof Error) {
|
|
70
|
-
try {
|
|
71
|
-
return JSON.stringify(sanitizeErrorValue(value, options));
|
|
72
|
-
} catch {
|
|
73
|
-
return `${value.name || "Error"}: ${value.message || ""}`;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (value && typeof value === "object") {
|
|
78
|
-
if (visited.has(value)) {
|
|
79
|
-
return "[Circular]";
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
const localVisited = visited;
|
|
85
|
-
const replacer = (k, v) => {
|
|
86
|
-
if (k && isSensitiveKey(k, options.sensitiveKeyMatcher)) {
|
|
87
|
-
return "[MASKED]";
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (v && typeof v === "object") {
|
|
91
|
-
if (localVisited.has(v)) {
|
|
92
|
-
return "[Circular]";
|
|
93
|
-
}
|
|
94
|
-
localVisited.add(v);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return v;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
return JSON.stringify(value, replacer);
|
|
101
|
-
} catch {
|
|
102
|
-
try {
|
|
103
|
-
return String(value);
|
|
104
|
-
} catch {
|
|
105
|
-
return "[Unserializable]";
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function sanitizeAny(value, options, state, depth, visited) {
|
|
111
|
-
if (isNullable(value)) return value;
|
|
112
|
-
|
|
113
|
-
if (isString(value)) {
|
|
114
|
-
return value;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (isNumber(value) || isBoolean(value) || typeof value === "bigint") {
|
|
118
|
-
return value;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (value instanceof Error) {
|
|
122
|
-
return sanitizeErrorValue(value, options);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const isArr = Array.isArray(value);
|
|
126
|
-
const isObj = isPlainObject(value);
|
|
127
|
-
|
|
128
|
-
if (!isArr && !isObj) {
|
|
129
|
-
return safeToStringMasked(value, options, visited);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (visited.has(value)) {
|
|
133
|
-
return "[Circular]";
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (depth >= options.sanitizeDepth) {
|
|
137
|
-
return safeToStringMasked(value, options, visited);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (state.nodes >= options.sanitizeNodes) {
|
|
141
|
-
return safeToStringMasked(value, options, visited);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
visited.add(value);
|
|
145
|
-
state.nodes = state.nodes + 1;
|
|
146
|
-
|
|
147
|
-
if (isArr) {
|
|
148
|
-
const arr = value;
|
|
149
|
-
const out = [];
|
|
150
|
-
|
|
151
|
-
const limit = arr.length;
|
|
152
|
-
for (let i = 0; i < limit; i++) {
|
|
153
|
-
out[i] = sanitizeAny(arr[i], options, state, depth + 1, visited);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return out;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const obj = value;
|
|
160
|
-
const out = {};
|
|
161
|
-
|
|
162
|
-
const entries = Object.entries(obj);
|
|
163
|
-
const limit = entries.length > options.sanitizeObjectKeys ? options.sanitizeObjectKeys : entries.length;
|
|
164
|
-
|
|
165
|
-
for (let i = 0; i < limit; i++) {
|
|
166
|
-
const entry = entries[i];
|
|
167
|
-
const key = entry[0];
|
|
168
|
-
const child = entry[1];
|
|
169
|
-
|
|
170
|
-
if (isSensitiveKey(key, options.sensitiveKeyMatcher)) {
|
|
171
|
-
out[key] = "[MASKED]";
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
out[key] = sanitizeAny(child, options, state, depth + 1, visited);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return out;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export function sanitizeLogObject(obj, options) {
|
|
182
|
-
const visited = new WeakSet();
|
|
183
|
-
const state = { nodes: 0 };
|
|
184
|
-
|
|
185
|
-
const out = {};
|
|
186
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
187
|
-
if (isSensitiveKey(key, options.sensitiveKeyMatcher)) {
|
|
188
|
-
out[key] = "[MASKED]";
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
out[key] = sanitizeAny(val, options, state, 0, visited);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return out;
|
|
196
|
-
}
|
package/utils/regexpUtil.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import RegexAliases from "../configs/regexpAlias.json";
|
|
2
|
-
import { isMinLengthString } from "./is.js";
|
|
3
|
-
|
|
4
|
-
const regexCache = new Map();
|
|
5
|
-
|
|
6
|
-
export function getRegex(name) {
|
|
7
|
-
if (name.startsWith("@")) {
|
|
8
|
-
const alias = name.slice(1);
|
|
9
|
-
return RegexAliases[alias] || name;
|
|
10
|
-
}
|
|
11
|
-
return name;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function parseRegexLiteral(pattern) {
|
|
15
|
-
const trimmed = String(pattern || "").trim();
|
|
16
|
-
if (!isMinLengthString(trimmed, 2)) return null;
|
|
17
|
-
if (!trimmed.startsWith("/")) return null;
|
|
18
|
-
|
|
19
|
-
const lastSlash = trimmed.lastIndexOf("/");
|
|
20
|
-
if (lastSlash <= 0) return null;
|
|
21
|
-
|
|
22
|
-
const flags = trimmed.slice(lastSlash + 1);
|
|
23
|
-
if (flags !== "" && !/^[gimsuy]+$/.test(flags)) return null;
|
|
24
|
-
|
|
25
|
-
return { source: trimmed.slice(1, lastSlash), flags: flags };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function getCompiledRegex(pattern, flags) {
|
|
29
|
-
const literal = parseRegexLiteral(pattern);
|
|
30
|
-
const regexStr = literal ? literal.source : getRegex(pattern);
|
|
31
|
-
const useFlags = literal && literal.flags !== "" ? literal.flags : flags || "";
|
|
32
|
-
const cacheKey = `${regexStr}:${useFlags}`;
|
|
33
|
-
|
|
34
|
-
let cached = regexCache.get(cacheKey);
|
|
35
|
-
if (!cached) {
|
|
36
|
-
cached = new RegExp(regexStr, useFlags);
|
|
37
|
-
regexCache.set(cacheKey, cached);
|
|
38
|
-
}
|
|
39
|
-
return cached;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function matchRegex(value, pattern) {
|
|
43
|
-
return getCompiledRegex(pattern).test(value);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function clearRegexCache() {
|
|
47
|
-
regexCache.clear();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function getRegexCacheSize() {
|
|
51
|
-
return regexCache.size;
|
|
52
|
-
}
|
|
File without changes
|