@whyour/qinglong 2.20.2-3 → 2.21.0-10
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/.env.example +5 -0
- package/AGENTS.md +43 -0
- package/README-en.md +11 -0
- package/README.md +11 -0
- package/back/protos/api.proto +3 -0
- package/deploy/kubernetes/README.md +81 -0
- package/deploy/kubernetes/base/kustomization.yaml +5 -0
- package/deploy/kubernetes/base/qinglong.yaml +95 -0
- package/deploy/kubernetes/overlays/example/kustomization.yaml +10 -0
- package/docker/Dockerfile +51 -69
- package/docker/Dockerfile.310 +94 -0
- package/docker/Dockerfile.debian +120 -0
- package/docker/{310.Dockerfile → Dockerfile.debian310} +13 -5
- package/docker/docker-entrypoint.sh +95 -3
- package/docs/PROJECT_ARCHITECTURE.md +550 -0
- package/package.json +29 -28
- package/sample/config.sample.sh +19 -3
- package/sample/notify.js +145 -9
- package/sample/notify.py +110 -11
- package/shell/api.sh +51 -21
- package/shell/bot.sh +30 -16
- package/shell/check.sh +21 -19
- package/shell/lang/en.sh +105 -0
- package/shell/lang/zh.sh +105 -0
- package/shell/otask.sh +117 -28
- package/shell/preload/client.js +20 -2
- package/shell/preload/esm-loader.mjs +41 -0
- package/shell/preload/sitecustomize.js +36 -0
- package/shell/pub.sh +8 -8
- package/shell/rmlog.sh +5 -5
- package/shell/share.sh +50 -31
- package/shell/start.sh +40 -27
- package/shell/task.sh +10 -2
- package/shell/update.sh +22 -22
- package/static/build/api/config.js +17 -7
- package/static/build/api/cron.js +40 -3
- package/static/build/api/dashboard.js +344 -0
- package/static/build/api/env.js +40 -2
- package/static/build/api/index.js +2 -0
- package/static/build/api/log.js +15 -5
- package/static/build/api/script.js +34 -9
- package/static/build/api/system.js +22 -8
- package/static/build/api/user.js +6 -5
- package/static/build/app.js +22 -19
- package/static/build/config/const.js +8 -6
- package/static/build/config/container.js +12 -0
- package/static/build/config/grpcCerts.js +150 -0
- package/static/build/config/index.js +6 -4
- package/static/build/config/util.js +69 -18
- package/static/build/data/cron.js +3 -1
- package/static/build/data/cronStats.js +59 -0
- package/static/build/data/env.js +2 -0
- package/static/build/data/notify.js +18 -1
- package/static/build/data/runningInstance.js +57 -0
- package/static/build/data/sock.js +1 -0
- package/static/build/loaders/app.js +7 -7
- package/static/build/loaders/db.js +8 -2
- package/static/build/loaders/deps.js +1 -22
- package/static/build/loaders/express.js +19 -15
- package/static/build/loaders/initData.js +20 -2
- package/static/build/loaders/initFile.js +3 -1
- package/static/build/loaders/initTask.js +3 -2
- package/static/build/loaders/server.js +1 -1
- package/static/build/protos/api.js +23 -1
- package/static/build/schedule/addCron.js +67 -10
- package/static/build/schedule/api.js +1 -1
- package/static/build/schedule/client.js +9 -1
- package/static/build/schedule/delCron.js +11 -1
- package/static/build/schedule/health.js +1 -1
- package/static/build/services/config.js +19 -5
- package/static/build/services/cron.js +198 -38
- package/static/build/services/dependence.js +19 -18
- package/static/build/services/env.js +31 -3
- package/static/build/services/grpc.js +32 -6
- package/static/build/services/http.js +33 -18
- package/static/build/services/notify.js +87 -8
- package/static/build/services/open.js +2 -1
- package/static/build/services/sshKey.js +6 -3
- package/static/build/services/subscription.js +8 -5
- package/static/build/services/system.js +34 -9
- package/static/build/services/user.js +39 -13
- package/static/build/shared/auth.js +7 -1
- package/static/build/shared/i18n.js +160 -0
- package/static/build/shared/pLimit.js +15 -3
- package/static/build/shared/runCron.js +5 -0
- package/static/build/shared/store.js +7 -0
- package/static/build/validation/schedule.js +10 -0
- package/static/dist/1089.0ecc5383.async.js +1 -0
- package/static/dist/1147.62793604.async.js +1 -0
- package/static/dist/1192.4e5740f2.async.js +1 -0
- package/static/dist/1214.c6469b53.async.js +1 -0
- package/static/dist/134.54df9e38.async.js +1 -0
- package/static/dist/1352.96a77e1d.async.js +1 -0
- package/static/dist/{1765.d8e002d7.async.js → 1765.5ac01a93.async.js} +1 -1
- package/static/dist/1836.f0b74cf1.async.js +1 -0
- package/static/dist/{1885.e0d00d2d.async.js → 1885.e1ea09f6.async.js} +1 -1
- package/static/dist/1967.3f3945d0.async.js +1 -0
- package/static/dist/{2096.383c1047.async.js → 2096.6d98fd12.async.js} +1 -1
- package/static/dist/2208.85285476.async.js +1 -0
- package/static/dist/2286.f371c743.async.js +1 -0
- package/static/dist/2476.4e9b0992.async.js +1 -0
- package/static/dist/2537.2b262ee0.async.js +1 -0
- package/static/dist/{255.12f03ab2.async.js → 255.8a80b983.async.js} +1 -1
- package/static/dist/2635.d4c59d23.async.js +1 -0
- package/static/dist/2808.cdc0995c.async.js +1 -0
- package/static/dist/{2821.be3dc88e.async.js → 2821.651f31e5.async.js} +1 -1
- package/static/dist/2986.4c49eef7.async.js +1 -0
- package/static/dist/300.08ac9875.async.js +1 -0
- package/static/dist/3191.545ab873.async.js +1 -0
- package/static/dist/3714.8d6dba9e.async.js +1 -0
- package/static/dist/3906.a5eee612.async.js +1 -0
- package/static/dist/{6541.a6d499de.async.js → 3948.4fe809fd.async.js} +1 -1
- package/static/dist/{5171.7fc6d0a2.async.js → 4573.16f19278.async.js} +1 -1
- package/static/dist/{4859.93e63ea6.async.js → 4859.6592cebb.async.js} +1 -1
- package/static/dist/4887.8e3ae573.async.js +1 -0
- package/static/dist/{4902.54ecbdb5.async.js → 4902.555f92ab.async.js} +1 -1
- package/static/dist/{4934.1ca6b6b0.async.js → 4934.f3539d08.async.js} +1 -1
- package/static/dist/5077.cbd111cd.async.js +1 -0
- package/static/dist/{6247.b550d996.async.js → 5157.7c5af144.async.js} +1 -1
- package/static/dist/{540.481d4708.async.js → 540.19ddf020.async.js} +1 -1
- package/static/dist/{5970.10ac4f16.async.js → 5970.d3a6e7bd.async.js} +1 -1
- package/static/dist/{6013.2d7bb12a.async.js → 6013.4e38de36.async.js} +1 -1
- package/static/dist/{6016.9c379049.async.js → 6016.1e6574b6.async.js} +1 -1
- package/static/dist/{6035.5889ddc7.async.js → 6035.32ebfad9.async.js} +1 -1
- package/static/dist/6339.ab305e96.async.js +1 -0
- package/static/dist/6569.55177f6a.async.js +1 -0
- package/static/dist/6610.c111af7e.async.js +1 -0
- package/static/dist/{3034.6413c38e.async.js → 6638.87a163d2.async.js} +1 -1
- package/static/dist/{6646.5fc37228.async.js → 6646.95e92533.async.js} +1 -1
- package/static/dist/6665.1d099ad1.async.js +1 -0
- package/static/dist/{7355.b7c0562f.async.js → 7355.f9f263d8.async.js} +1 -1
- package/static/dist/{7384.065ccae2.async.js → 7384.1bb449d5.async.js} +1 -1
- package/static/dist/7441.ee1bf2bb.async.js +1 -0
- package/static/dist/{7508.a31662a3.async.js → 7508.7dcee91c.async.js} +1 -1
- package/static/dist/{7802.6b73f16a.async.js → 7802.34255805.async.js} +1 -1
- package/static/dist/{7984.e6bb9378.async.js → 7984.594296a5.async.js} +1 -1
- package/static/dist/{5653.4fce7ce8.async.js → 8033.5cb31493.async.js} +1 -1
- package/static/dist/8147.2fb55202.async.js +1 -0
- package/static/dist/8187.48c130d6.async.js +1 -0
- package/static/dist/8495.d53e15ca.async.js +1 -0
- package/static/dist/8587.315b06c0.async.js +1 -0
- package/static/dist/8826.db34ad8d.async.js +1 -0
- package/static/dist/{2742.4852aac8.async.js → 8865.ed665d31.async.js} +1 -1
- package/static/dist/901.7ee5c6d3.async.js +1 -0
- package/static/dist/9271.231db2ce.async.js +1 -0
- package/static/dist/9323.a33f47da.async.js +1 -0
- package/static/dist/{9730.30083c91.async.js → 9730.801665a3.async.js} +1 -1
- package/static/dist/{9761.627ca3b5.async.js → 9761.360a19d8.async.js} +1 -1
- package/static/dist/index.html +2 -2
- package/static/dist/layouts__index.a7a2bfe0.async.js +1 -0
- package/static/dist/layouts__index.adf0692f.chunk.css +1 -0
- package/static/dist/preload_helper.3048fe5b.js +1 -0
- package/static/dist/{src__pages__config__index.622b6ee8.async.js → src__pages__config__index.a22ff7dc.async.js} +1 -1
- package/static/dist/{src__pages__crontab__const.323d5124.async.js → src__pages__crontab__const.aba07deb.async.js} +1 -1
- package/static/dist/src__pages__crontab__detail.b98f0084.async.js +1 -0
- package/static/dist/src__pages__crontab__index.68e78a33.async.js +1 -0
- package/static/dist/{src__pages__crontab__logModal.5e6a4bf2.async.js → src__pages__crontab__logModal.831d5e4b.async.js} +1 -1
- package/static/dist/src__pages__crontab__modal.f7041c7c.async.js +1 -0
- package/static/dist/src__pages__crontab__type.d7af36e5.async.js +1 -0
- package/static/dist/{src__pages__crontab__viewCreateModal.ffcf7a24.async.js → src__pages__crontab__viewCreateModal.4d589f66.async.js} +1 -1
- package/static/dist/{src__pages__crontab__viewManageModal.c2724575.async.js → src__pages__crontab__viewManageModal.0e317746.async.js} +1 -1
- package/static/dist/src__pages__dashboard__index.58177357.async.js +1 -0
- package/static/dist/src__pages__dependence__index.b7bbc795.async.js +1 -0
- package/static/dist/{src__pages__dependence__logModal.f123e2ac.async.js → src__pages__dependence__logModal.0681830b.async.js} +1 -1
- package/static/dist/src__pages__dependence__modal.f7bb47ba.async.js +1 -0
- package/static/dist/src__pages__env__editNameModal.48715576.async.js +1 -0
- package/static/dist/src__pages__env__index.452cdc47.async.js +1 -0
- package/static/dist/src__pages__env__modal.e1234834.async.js +1 -0
- package/static/dist/src__pages__error__index.dedb2b90.async.js +1 -0
- package/static/dist/src__pages__initialization__index.22620a77.async.js +1 -0
- package/static/dist/src__pages__log__index.9c66639f.async.js +1 -0
- package/static/dist/{src__pages__login__index.cd6e3152.async.js → src__pages__login__index.8c813eb1.async.js} +1 -1
- package/static/dist/{src__pages__script__components__UnsupportedFilePreview__index.39074c68.async.js → src__pages__script__components__UnsupportedFilePreview__index.c347a13a.async.js} +1 -1
- package/static/dist/src__pages__script__editNameModal.532a3044.async.js +1 -0
- package/static/dist/src__pages__script__index.1fc20f22.async.js +1 -0
- package/static/dist/src__pages__script__renameModal.5cdde919.async.js +1 -0
- package/static/dist/src__pages__script__saveModal.5ffed35f.async.js +1 -0
- package/static/dist/src__pages__script__setting.1a82c6d7.async.js +1 -0
- package/static/dist/src__pages__setting__appModal.43b7758a.async.js +1 -0
- package/static/dist/src__pages__setting__checkUpdate.34d773f2.async.js +1 -0
- package/static/dist/src__pages__setting__dependence.9c04c79a.async.js +1 -0
- package/static/dist/src__pages__setting__index.7e070838.async.js +1 -0
- package/static/dist/src__pages__setting__notification.bac481c2.async.js +1 -0
- package/static/dist/src__pages__setting__other.707cfafe.async.js +1 -0
- package/static/dist/src__pages__setting__security.b7235753.async.js +1 -0
- package/static/dist/src__pages__setting__systemLog.b81a8c1d.async.js +1 -0
- package/static/dist/{src__pages__subscription__logModal.0caa7283.async.js → src__pages__subscription__logModal.3864b37f.async.js} +1 -1
- package/static/dist/src__pages__subscription__modal.562448e2.async.js +1 -0
- package/static/dist/{umi.ef8199a4.js → umi.a54a59f6.js} +1 -1
- package/version.yaml +33 -4
- package/sample/notify.py.save +0 -1010
- package/static/dist/105.85a5c47a.async.js +0 -1
- package/static/dist/1083.f86ce804.async.js +0 -1
- package/static/dist/1147.32f41a88.async.js +0 -1
- package/static/dist/1352.ab6da08e.async.js +0 -1
- package/static/dist/1690.f0290540.async.js +0 -1
- package/static/dist/1742.6cbe5aca.async.js +0 -1
- package/static/dist/2208.8e3a7325.async.js +0 -1
- package/static/dist/3191.70bc19db.async.js +0 -1
- package/static/dist/5312.74b95311.async.js +0 -1
- package/static/dist/5691.931f59c5.async.js +0 -1
- package/static/dist/6159.55cb068a.async.js +0 -1
- package/static/dist/7025.f4080d63.async.js +0 -1
- package/static/dist/739.6be5552a.async.js +0 -1
- package/static/dist/7571.4f6240b1.async.js +0 -1
- package/static/dist/786.59fc381c.async.js +0 -1
- package/static/dist/8317.c44c1ebd.async.js +0 -1
- package/static/dist/8826.0291edfd.async.js +0 -1
- package/static/dist/955.3c9481f7.async.js +0 -1
- package/static/dist/layouts__index.1fce90e0.chunk.css +0 -1
- package/static/dist/layouts__index.8dcf1576.async.js +0 -1
- package/static/dist/preload_helper.116a62f6.js +0 -1
- package/static/dist/src__pages__crontab__detail.b07f0c0a.async.js +0 -1
- package/static/dist/src__pages__crontab__index.2e2e1096.async.js +0 -1
- package/static/dist/src__pages__crontab__modal.4d8c2a22.async.js +0 -1
- package/static/dist/src__pages__crontab__type.db7c1858.async.js +0 -1
- package/static/dist/src__pages__dependence__index.3d87ceac.async.js +0 -1
- package/static/dist/src__pages__dependence__modal.631ffb5b.async.js +0 -1
- package/static/dist/src__pages__env__editNameModal.ff85ef8c.async.js +0 -1
- package/static/dist/src__pages__env__index.a0a2fece.async.js +0 -1
- package/static/dist/src__pages__env__modal.d1004662.async.js +0 -1
- package/static/dist/src__pages__error__index.1bc3c90b.async.js +0 -1
- package/static/dist/src__pages__initialization__index.8b1cbaf9.async.js +0 -1
- package/static/dist/src__pages__log__index.cf00c9af.async.js +0 -1
- package/static/dist/src__pages__script__editNameModal.53424d49.async.js +0 -1
- package/static/dist/src__pages__script__index.e65df827.async.js +0 -1
- package/static/dist/src__pages__script__renameModal.4bbe7fb1.async.js +0 -1
- package/static/dist/src__pages__script__saveModal.cf449f3c.async.js +0 -1
- package/static/dist/src__pages__script__setting.b345d59a.async.js +0 -1
- package/static/dist/src__pages__setting__appModal.03faec89.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.46efe057.async.js +0 -1
- package/static/dist/src__pages__setting__dependence.4495c7b6.async.js +0 -1
- package/static/dist/src__pages__setting__index.6919c399.async.js +0 -1
- package/static/dist/src__pages__setting__notification.d6a3884f.async.js +0 -1
- package/static/dist/src__pages__setting__other.0d931d6f.async.js +0 -1
- package/static/dist/src__pages__setting__security.91cb545f.async.js +0 -1
- package/static/dist/src__pages__setting__systemLog.1d433a48.async.js +0 -1
- package/static/dist/src__pages__subscription__modal.0b84f6cf.async.js +0 -1
|
@@ -6,20 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const path_1 = __importDefault(require("path"));
|
|
7
7
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
8
|
const os_1 = __importDefault(require("os"));
|
|
9
|
-
const chokidar_1 = __importDefault(require("chokidar"));
|
|
10
9
|
const index_1 = __importDefault(require("../config/index"));
|
|
11
10
|
const logger_1 = __importDefault(require("./logger"));
|
|
12
|
-
async function linkToNodeModule(src, dst) {
|
|
13
|
-
const target = path_1.default.join(index_1.default.rootPath, 'node_modules', dst || src);
|
|
14
|
-
const source = path_1.default.join(index_1.default.rootPath, src);
|
|
15
|
-
try {
|
|
16
|
-
const stats = await promises_1.default.lstat(target);
|
|
17
|
-
if (!stats) {
|
|
18
|
-
await promises_1.default.symlink(source, target, 'dir');
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
catch (error) { }
|
|
22
|
-
}
|
|
23
11
|
async function linkCommand() {
|
|
24
12
|
const homeDir = os_1.default.homedir();
|
|
25
13
|
let userBinDir = path_1.default.join(homeDir, 'bin');
|
|
@@ -59,16 +47,7 @@ async function linkCommandToDir(commandDir) {
|
|
|
59
47
|
await promises_1.default.rename(tmpTarget, target);
|
|
60
48
|
}
|
|
61
49
|
}
|
|
62
|
-
exports.default = async (
|
|
50
|
+
exports.default = async () => {
|
|
63
51
|
await linkCommand();
|
|
64
|
-
await linkToNodeModule(src);
|
|
65
|
-
const source = path_1.default.join(index_1.default.rootPath, src);
|
|
66
|
-
const watcher = chokidar_1.default.watch(source, {
|
|
67
|
-
ignored: /(^|[\/\\])\../,
|
|
68
|
-
persistent: true,
|
|
69
|
-
});
|
|
70
|
-
watcher
|
|
71
|
-
.on('add', () => linkToNodeModule(src))
|
|
72
|
-
.on('change', () => linkToNodeModule(src));
|
|
73
52
|
};
|
|
74
53
|
//# sourceMappingURL=deps.js.map
|
|
@@ -16,6 +16,7 @@ const serverEnv_1 = require("../config/serverEnv");
|
|
|
16
16
|
const store_1 = require("../shared/store");
|
|
17
17
|
const auth_1 = require("../shared/auth");
|
|
18
18
|
const path_1 = __importDefault(require("path"));
|
|
19
|
+
const i18n_1 = require("../shared/i18n");
|
|
19
20
|
exports.default = ({ app }) => {
|
|
20
21
|
// Security: Enable strict routing to prevent case-insensitive path bypass
|
|
21
22
|
app.set('case sensitive routing', true);
|
|
@@ -77,14 +78,22 @@ exports.default = ({ app }) => {
|
|
|
77
78
|
const currentToken = doc.tokens.find((x) => x.value === headerToken);
|
|
78
79
|
const keyMatch = pathLower.match(/\/open\/([a-z]+)\/*/);
|
|
79
80
|
const key = keyMatch && keyMatch[1];
|
|
80
|
-
if (doc.scopes.includes(key)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
if (!doc.scopes.includes(key)) {
|
|
82
|
+
const err = new express_jwt_1.UnauthorizedError('credentials_bad_scheme', {
|
|
83
|
+
message: (0, i18n_1.t)('暂无权限'),
|
|
84
|
+
});
|
|
85
|
+
return next(err);
|
|
84
86
|
}
|
|
87
|
+
if (!currentToken || currentToken.expiration < Math.round(Date.now() / 1000)) {
|
|
88
|
+
const err = new express_jwt_1.UnauthorizedError('invalid_token', {
|
|
89
|
+
message: (0, i18n_1.t)('Token 已失效'),
|
|
90
|
+
});
|
|
91
|
+
return next(err);
|
|
92
|
+
}
|
|
93
|
+
return next();
|
|
85
94
|
}
|
|
86
95
|
}
|
|
87
|
-
const originPath = `${req.baseUrl}${
|
|
96
|
+
const originPath = `${req.baseUrl}${pathLower === '/' ? '' : pathLower}`;
|
|
88
97
|
if (!headerToken &&
|
|
89
98
|
originPath &&
|
|
90
99
|
config_1.default.apiWhiteList.includes(originPath)) {
|
|
@@ -96,8 +105,8 @@ exports.default = ({ app }) => {
|
|
|
96
105
|
}
|
|
97
106
|
const errorCode = headerToken ? 'invalid_token' : 'credentials_required';
|
|
98
107
|
const errorMessage = headerToken
|
|
99
|
-
? '
|
|
100
|
-
:
|
|
108
|
+
? (0, i18n_1.t)('Token 已失效')
|
|
109
|
+
: (0, i18n_1.t)('请先登录');
|
|
101
110
|
const err = new express_jwt_1.UnauthorizedError(errorCode, { message: errorMessage });
|
|
102
111
|
next(err);
|
|
103
112
|
});
|
|
@@ -108,18 +117,13 @@ exports.default = ({ app }) => {
|
|
|
108
117
|
'/api/user/notification/init',
|
|
109
118
|
'/open/user/init',
|
|
110
119
|
'/open/user/notification/init',
|
|
111
|
-
].includes(
|
|
120
|
+
].includes(pathLower)) {
|
|
112
121
|
return next();
|
|
113
122
|
}
|
|
114
123
|
const authInfo = (await store_1.shareStore.getAuthInfo()) || {};
|
|
115
|
-
let isInitialized =
|
|
116
|
-
if (Object.keys(authInfo).length === 2 &&
|
|
117
|
-
authInfo.username === 'admin' &&
|
|
118
|
-
authInfo.password === 'admin') {
|
|
119
|
-
isInitialized = false;
|
|
120
|
-
}
|
|
124
|
+
let isInitialized = !(0, auth_1.isDefaultAuthInfo)(authInfo);
|
|
121
125
|
if (isInitialized) {
|
|
122
|
-
return res.send({ code: 450, message: '未知错误' });
|
|
126
|
+
return res.send({ code: 450, message: (0, i18n_1.t)('未知错误') });
|
|
123
127
|
}
|
|
124
128
|
else {
|
|
125
129
|
return next();
|
|
@@ -46,8 +46,10 @@ const open_1 = __importDefault(require("../services/open"));
|
|
|
46
46
|
const store_1 = require("../shared/store");
|
|
47
47
|
const logger_1 = __importDefault(require("./logger"));
|
|
48
48
|
const open_2 = require("../data/open");
|
|
49
|
+
const runningInstance_1 = require("../data/runningInstance");
|
|
50
|
+
const i18n_1 = require("../shared/i18n");
|
|
49
51
|
exports.default = async () => {
|
|
50
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
52
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
51
53
|
const cronService = typedi_1.Container.get(cron_2.default);
|
|
52
54
|
const envService = typedi_1.Container.get(env_1.default);
|
|
53
55
|
const dependenceService = typedi_1.Container.get(dependence_1.default);
|
|
@@ -61,11 +63,14 @@ exports.default = async () => {
|
|
|
61
63
|
if (!systemApp) {
|
|
62
64
|
systemApp = await open_2.AppModel.create({
|
|
63
65
|
name: 'system',
|
|
64
|
-
scopes: ['crons', 'system'],
|
|
66
|
+
scopes: ['crons', 'system', 'dashboard'],
|
|
65
67
|
client_id: (0, util_1.createRandomString)(12, 12),
|
|
66
68
|
client_secret: (0, util_1.createRandomString)(24, 24),
|
|
67
69
|
});
|
|
68
70
|
}
|
|
71
|
+
else if (!systemApp.scopes.includes('dashboard')) {
|
|
72
|
+
await open_2.AppModel.update({ scopes: [...systemApp.scopes, 'dashboard'] }, { where: { name: 'system' } });
|
|
73
|
+
}
|
|
69
74
|
const [systemConfig] = await system_1.SystemModel.findOrCreate({
|
|
70
75
|
where: { type: system_1.AuthDataType.systemConfig },
|
|
71
76
|
});
|
|
@@ -146,6 +151,8 @@ exports.default = async () => {
|
|
|
146
151
|
});
|
|
147
152
|
// 初始化更新所有任务状态为空闲
|
|
148
153
|
await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle }, { where: {} });
|
|
154
|
+
// 清空所有运行中的实例记录(服务重启后进程已不存在)
|
|
155
|
+
await runningInstance_1.RunningInstanceModel.update({ status: runningInstance_1.InstanceStatus.stopped }, { where: { status: runningInstance_1.InstanceStatus.running } });
|
|
149
156
|
// 初始化时执行一次所有的 ql repo 任务
|
|
150
157
|
cron_1.CrontabModel.findAll({
|
|
151
158
|
where: {
|
|
@@ -199,6 +206,17 @@ exports.default = async () => {
|
|
|
199
206
|
}
|
|
200
207
|
}
|
|
201
208
|
});
|
|
209
|
+
// 初始化语言(必须在 autosave_crontab 之前)
|
|
210
|
+
const lang = ((_h = systemConfig.info) === null || _h === void 0 ? void 0 : _h.lang) || (0, i18n_1.systemLang)();
|
|
211
|
+
(0, i18n_1.setLang)(lang);
|
|
212
|
+
// 确保 lang_env.sh 存在
|
|
213
|
+
try {
|
|
214
|
+
const langEnvExist = await (0, util_1.fileExist)(config_1.default.langEnvFile);
|
|
215
|
+
if (!langEnvExist) {
|
|
216
|
+
await (0, promises_1.writeFile)(config_1.default.langEnvFile, `export QL_LANG='${lang}'\n`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (_j) { }
|
|
202
220
|
// 初始化保存一次ck和定时任务数据
|
|
203
221
|
await cronService.autosave_crontab();
|
|
204
222
|
await envService.set_envs();
|
|
@@ -22,6 +22,7 @@ const uploadPath = path_1.default.join(dataPath, 'upload/');
|
|
|
22
22
|
const bakPath = path_1.default.join(dataPath, 'bak/');
|
|
23
23
|
const samplePath = path_1.default.join(rootPath, 'sample/');
|
|
24
24
|
const tmpPath = path_1.default.join(logPath, '.tmp/');
|
|
25
|
+
const rootTmpPath = path_1.default.join(rootPath, '.tmp/');
|
|
25
26
|
const confFile = path_1.default.join(configPath, 'config.sh');
|
|
26
27
|
const sampleConfigFile = path_1.default.join(samplePath, 'config.sample.sh');
|
|
27
28
|
const sampleTaskShellFile = path_1.default.join(samplePath, 'task.sample.sh');
|
|
@@ -45,6 +46,7 @@ const directories = [
|
|
|
45
46
|
preloadPath,
|
|
46
47
|
logPath,
|
|
47
48
|
tmpPath,
|
|
49
|
+
rootTmpPath,
|
|
48
50
|
uploadPath,
|
|
49
51
|
sshPath,
|
|
50
52
|
bakPath,
|
|
@@ -115,6 +117,6 @@ exports.default = async () => {
|
|
|
115
117
|
await (0, utils_1.writeFileWithLock)(item.target, content);
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
|
-
logger_1.default.info('
|
|
120
|
+
logger_1.default.info('[boot] Init file down');
|
|
119
121
|
};
|
|
120
122
|
//# sourceMappingURL=initFile.js.map
|
|
@@ -11,6 +11,7 @@ const sshKey_1 = __importDefault(require("../services/sshKey"));
|
|
|
11
11
|
const config_1 = __importDefault(require("../config"));
|
|
12
12
|
const util_1 = require("../config/util");
|
|
13
13
|
const path_1 = require("path");
|
|
14
|
+
const i18n_1 = require("../shared/i18n");
|
|
14
15
|
exports.default = async () => {
|
|
15
16
|
const systemService = typedi_1.Container.get(system_1.default);
|
|
16
17
|
const scheduleService = typedi_1.Container.get(schedule_1.default);
|
|
@@ -24,7 +25,7 @@ exports.default = async () => {
|
|
|
24
25
|
}
|
|
25
26
|
const cron = {
|
|
26
27
|
id: NaN,
|
|
27
|
-
name: '生成token',
|
|
28
|
+
name: (0, i18n_1.t)('生成token'),
|
|
28
29
|
command: tokenCommand,
|
|
29
30
|
runOrigin: 'system',
|
|
30
31
|
};
|
|
@@ -38,7 +39,7 @@ exports.default = async () => {
|
|
|
38
39
|
if (data.info.logRemoveFrequency) {
|
|
39
40
|
const rmlogCron = {
|
|
40
41
|
id: data.id,
|
|
41
|
-
name: '删除日志',
|
|
42
|
+
name: (0, i18n_1.t)('删除日志'),
|
|
42
43
|
command: `ql rmlog ${data.info.logRemoveFrequency}`,
|
|
43
44
|
runOrigin: 'system',
|
|
44
45
|
};
|
|
@@ -7,7 +7,7 @@ const logger_1 = __importDefault(require("./logger"));
|
|
|
7
7
|
const sock_1 = __importDefault(require("./sock"));
|
|
8
8
|
exports.default = async ({ server }) => {
|
|
9
9
|
await (0, sock_1.default)({ server });
|
|
10
|
-
logger_1.default.info('
|
|
10
|
+
logger_1.default.info('[boot] Sock loaded');
|
|
11
11
|
process.on('uncaughtException', (error) => {
|
|
12
12
|
logger_1.default.error('Uncaught exception:', error);
|
|
13
13
|
});
|
|
@@ -33,6 +33,7 @@ var NotificationMode;
|
|
|
33
33
|
NotificationMode[NotificationMode["chronocat"] = 18] = "chronocat";
|
|
34
34
|
NotificationMode[NotificationMode["ntfy"] = 19] = "ntfy";
|
|
35
35
|
NotificationMode[NotificationMode["wxPusherBot"] = 20] = "wxPusherBot";
|
|
36
|
+
NotificationMode[NotificationMode["wxPusherSpt"] = 21] = "wxPusherSpt";
|
|
36
37
|
NotificationMode[NotificationMode["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
|
37
38
|
})(NotificationMode || (exports.NotificationMode = NotificationMode = {}));
|
|
38
39
|
function notificationModeFromJSON(object) {
|
|
@@ -100,6 +101,9 @@ function notificationModeFromJSON(object) {
|
|
|
100
101
|
case 20:
|
|
101
102
|
case "wxPusherBot":
|
|
102
103
|
return NotificationMode.wxPusherBot;
|
|
104
|
+
case 21:
|
|
105
|
+
case "wxPusherSpt":
|
|
106
|
+
return NotificationMode.wxPusherSpt;
|
|
103
107
|
case -1:
|
|
104
108
|
case "UNRECOGNIZED":
|
|
105
109
|
default:
|
|
@@ -151,6 +155,8 @@ function notificationModeToJSON(object) {
|
|
|
151
155
|
return "ntfy";
|
|
152
156
|
case NotificationMode.wxPusherBot:
|
|
153
157
|
return "wxPusherBot";
|
|
158
|
+
case NotificationMode.wxPusherSpt:
|
|
159
|
+
return "wxPusherSpt";
|
|
154
160
|
case NotificationMode.UNRECOGNIZED:
|
|
155
161
|
default:
|
|
156
162
|
return "UNRECOGNIZED";
|
|
@@ -2495,6 +2501,7 @@ function createBaseNotificationInfo() {
|
|
|
2495
2501
|
wxPusherBotAppToken: undefined,
|
|
2496
2502
|
wxPusherBotTopicIds: undefined,
|
|
2497
2503
|
wxPusherBotUids: undefined,
|
|
2504
|
+
wxPusherSptList: undefined,
|
|
2498
2505
|
};
|
|
2499
2506
|
}
|
|
2500
2507
|
exports.NotificationInfo = {
|
|
@@ -2706,6 +2713,9 @@ exports.NotificationInfo = {
|
|
|
2706
2713
|
if (message.wxPusherBotUids !== undefined) {
|
|
2707
2714
|
writer.uint32(546).string(message.wxPusherBotUids);
|
|
2708
2715
|
}
|
|
2716
|
+
if (message.wxPusherSptList !== undefined) {
|
|
2717
|
+
writer.uint32(562).string(message.wxPusherSptList);
|
|
2718
|
+
}
|
|
2709
2719
|
return writer;
|
|
2710
2720
|
},
|
|
2711
2721
|
decode(input, length) {
|
|
@@ -3198,6 +3208,13 @@ exports.NotificationInfo = {
|
|
|
3198
3208
|
message.wxPusherBotUids = reader.string();
|
|
3199
3209
|
continue;
|
|
3200
3210
|
}
|
|
3211
|
+
case 70: {
|
|
3212
|
+
if (tag !== 562) {
|
|
3213
|
+
break;
|
|
3214
|
+
}
|
|
3215
|
+
message.wxPusherSptList = reader.string();
|
|
3216
|
+
continue;
|
|
3217
|
+
}
|
|
3201
3218
|
}
|
|
3202
3219
|
if ((tag & 7) === 4 || tag === 0) {
|
|
3203
3220
|
break;
|
|
@@ -3289,6 +3306,7 @@ exports.NotificationInfo = {
|
|
|
3289
3306
|
? globalThis.String(object.wxPusherBotTopicIds)
|
|
3290
3307
|
: undefined,
|
|
3291
3308
|
wxPusherBotUids: isSet(object.wxPusherBotUids) ? globalThis.String(object.wxPusherBotUids) : undefined,
|
|
3309
|
+
wxPusherSptList: isSet(object.wxPusherSptList) ? globalThis.String(object.wxPusherSptList) : undefined,
|
|
3292
3310
|
};
|
|
3293
3311
|
},
|
|
3294
3312
|
toJSON(message) {
|
|
@@ -3500,13 +3518,16 @@ exports.NotificationInfo = {
|
|
|
3500
3518
|
if (message.wxPusherBotUids !== undefined) {
|
|
3501
3519
|
obj.wxPusherBotUids = message.wxPusherBotUids;
|
|
3502
3520
|
}
|
|
3521
|
+
if (message.wxPusherSptList !== undefined) {
|
|
3522
|
+
obj.wxPusherSptList = message.wxPusherSptList;
|
|
3523
|
+
}
|
|
3503
3524
|
return obj;
|
|
3504
3525
|
},
|
|
3505
3526
|
create(base) {
|
|
3506
3527
|
return exports.NotificationInfo.fromPartial(base !== null && base !== void 0 ? base : {});
|
|
3507
3528
|
},
|
|
3508
3529
|
fromPartial(object) {
|
|
3509
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44;
|
|
3530
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45;
|
|
3510
3531
|
const message = createBaseNotificationInfo();
|
|
3511
3532
|
message.type = (_a = object.type) !== null && _a !== void 0 ? _a : 0;
|
|
3512
3533
|
message.gotifyUrl = (_b = object.gotifyUrl) !== null && _b !== void 0 ? _b : undefined;
|
|
@@ -3577,6 +3598,7 @@ exports.NotificationInfo = {
|
|
|
3577
3598
|
message.wxPusherBotAppToken = (_42 = object.wxPusherBotAppToken) !== null && _42 !== void 0 ? _42 : undefined;
|
|
3578
3599
|
message.wxPusherBotTopicIds = (_43 = object.wxPusherBotTopicIds) !== null && _43 !== void 0 ? _43 : undefined;
|
|
3579
3600
|
message.wxPusherBotUids = (_44 = object.wxPusherBotUids) !== null && _44 !== void 0 ? _44 : undefined;
|
|
3601
|
+
message.wxPusherSptList = (_45 = object.wxPusherSptList) !== null && _45 !== void 0 ? _45 : undefined;
|
|
3580
3602
|
return message;
|
|
3581
3603
|
},
|
|
3582
3604
|
};
|
|
@@ -4,14 +4,59 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.addCron = void 0;
|
|
7
|
+
const grpc_js_1 = require("@grpc/grpc-js");
|
|
7
8
|
const node_schedule_1 = __importDefault(require("node-schedule"));
|
|
8
9
|
const data_1 = require("./data");
|
|
9
10
|
const runCron_1 = require("../shared/runCron");
|
|
10
11
|
const logger_1 = __importDefault(require("../loaders/logger"));
|
|
12
|
+
const i18n_1 = require("../shared/i18n");
|
|
13
|
+
/**
|
|
14
|
+
* 预校验 cron 表达式,检测 node-schedule 会拒绝但 cron-parser 会接受的 pattern。
|
|
15
|
+
* node-schedule 对 bare /N(字段以 / 开头,如前无星号/数字前缀的 /6)返回 null,
|
|
16
|
+
* 提前拦截避免走 scheduleJob 后才发现无效。
|
|
17
|
+
*/
|
|
18
|
+
const isValidCronField = (cron) => {
|
|
19
|
+
// 检测 bare /N 模式:字段以 / 开头如 "/6",或空格后紧跟 "/6"
|
|
20
|
+
// node-schedule 会对这种字段返回 null
|
|
21
|
+
if (/\s\/\d/.test(cron) || /^\/\d/.test(cron)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// 检测 ? 字符:Quartz cron 语法,node-schedule 在大多数位置返回 null
|
|
25
|
+
// cron-parser 接受但 node-schedule 拒绝,提前拦截
|
|
26
|
+
if (/\?/.test(cron)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
11
31
|
const addCron = (call, callback) => {
|
|
12
32
|
var _a;
|
|
33
|
+
// ===== 第一遍:预校验所有 cron 表达式 =====
|
|
34
|
+
const validationErrors = [];
|
|
35
|
+
for (const item of call.request.crons) {
|
|
36
|
+
const { id, schedule, extra_schedules } = item;
|
|
37
|
+
if (!isValidCronField(schedule)) {
|
|
38
|
+
validationErrors.push((0, i18n_1.tf)('任务ID %s: 无效的 cron 表达式 "%s"(不支持裸 /N 步长和 ? 字符)', String(id), schedule));
|
|
39
|
+
}
|
|
40
|
+
if (extra_schedules === null || extra_schedules === void 0 ? void 0 : extra_schedules.length) {
|
|
41
|
+
extra_schedules.forEach((x) => {
|
|
42
|
+
if (!isValidCronField(x.schedule)) {
|
|
43
|
+
validationErrors.push((0, i18n_1.tf)('任务ID %s (extra_schedule): 无效的 cron 表达式 "%s"(不支持裸 /N 步长和 ? 字符)', String(id), x.schedule));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (validationErrors.length > 0) {
|
|
49
|
+
const details = validationErrors.join('\n');
|
|
50
|
+
const err = new Error(details);
|
|
51
|
+
err.code = grpc_js_1.status.INVALID_ARGUMENT;
|
|
52
|
+
err.details = details;
|
|
53
|
+
callback(err, null);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// ===== 第二遍:注册所有任务 =====
|
|
13
57
|
for (const item of call.request.crons) {
|
|
14
58
|
const { id, schedule, command, extra_schedules, name } = item;
|
|
59
|
+
// 取消该 id 已有的旧任务
|
|
15
60
|
if (data_1.scheduleStacks.has(id)) {
|
|
16
61
|
(_a = data_1.scheduleStacks.get(id)) === null || _a === void 0 ? void 0 : _a.forEach((x) => x.cancel());
|
|
17
62
|
}
|
|
@@ -21,18 +66,30 @@ const addCron = (call, callback) => {
|
|
|
21
66
|
logger_1.default.info('[schedule][创建定时任务] 任务ID: %s, 名称: %s, cron: %s, 执行命令: %s', id, name, x.schedule, command);
|
|
22
67
|
});
|
|
23
68
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
69
|
+
const mainJob = node_schedule_1.default.scheduleJob(id, schedule, async () => {
|
|
70
|
+
logger_1.default.info(`[schedule][准备运行任务] 命令: ${command}`);
|
|
71
|
+
(0, runCron_1.runCron)(command, item);
|
|
72
|
+
});
|
|
73
|
+
if (!mainJob) {
|
|
74
|
+
logger_1.default.warn('[schedule][创建定时任务] scheduleJob 返回 null(不符合预期,已通过预校验): 任务ID: %s, cron: %s', id, schedule);
|
|
75
|
+
}
|
|
76
|
+
const extraJobs = (extra_schedules === null || extra_schedules === void 0 ? void 0 : extra_schedules.length)
|
|
77
|
+
? extra_schedules.map((x) => {
|
|
78
|
+
const job = node_schedule_1.default.scheduleJob(id, x.schedule, async () => {
|
|
31
79
|
logger_1.default.info(`[schedule][准备运行任务] 命令: ${command}`);
|
|
32
80
|
(0, runCron_1.runCron)(command, item);
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
|
|
81
|
+
});
|
|
82
|
+
if (!job) {
|
|
83
|
+
logger_1.default.warn('[schedule][创建定时任务] scheduleJob 返回 null(不符合预期,已通过预校验): 任务ID: %s, cron: %s', id, x.schedule);
|
|
84
|
+
}
|
|
85
|
+
return job;
|
|
86
|
+
})
|
|
87
|
+
: [];
|
|
88
|
+
// 过滤 null(兜底保护,正常情况下预校验已拦截)
|
|
89
|
+
const jobs = [mainJob, ...extraJobs].filter((x) => x != null);
|
|
90
|
+
if (jobs.length > 0) {
|
|
91
|
+
data_1.scheduleStacks.set(id, jobs);
|
|
92
|
+
}
|
|
36
93
|
}
|
|
37
94
|
callback(null, null);
|
|
38
95
|
};
|
|
@@ -203,7 +203,7 @@ const normalizeCronData = (data) => {
|
|
|
203
203
|
var _a, _b, _c, _d, _e;
|
|
204
204
|
if (!data)
|
|
205
205
|
return undefined;
|
|
206
|
-
return Object.assign(Object.assign({}, data), { sub_id: (_a = data.sub_id) !== null && _a !== void 0 ? _a : undefined, extra_schedules: (_b = data.extra_schedules) !== null && _b !== void 0 ? _b :
|
|
206
|
+
return Object.assign(Object.assign({}, data), { sub_id: (_a = data.sub_id) !== null && _a !== void 0 ? _a : undefined, extra_schedules: (_b = data.extra_schedules) !== null && _b !== void 0 ? _b : [], pid: (_c = data.pid) !== null && _c !== void 0 ? _c : undefined, task_before: (_d = data.task_before) !== null && _d !== void 0 ? _d : undefined, task_after: (_e = data.task_after) !== null && _e !== void 0 ? _e : undefined });
|
|
207
207
|
};
|
|
208
208
|
const getCronDetail = async (call, callback) => {
|
|
209
209
|
try {
|
|
@@ -6,9 +6,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const grpc_js_1 = require("@grpc/grpc-js");
|
|
7
7
|
const cron_1 = require("../protos/cron");
|
|
8
8
|
const config_1 = __importDefault(require("../config"));
|
|
9
|
+
const grpcCerts_1 = require("../config/grpcCerts");
|
|
9
10
|
class Client {
|
|
10
11
|
constructor() {
|
|
11
|
-
this.
|
|
12
|
+
this._client = null;
|
|
13
|
+
}
|
|
14
|
+
get client() {
|
|
15
|
+
if (!this._client) {
|
|
16
|
+
const tlsConfig = (0, grpcCerts_1.getGrpcCerts)();
|
|
17
|
+
this._client = new cron_1.CronClient(`localhost:${config_1.default.grpcPort}`, grpc_js_1.credentials.createSsl(Buffer.from(tlsConfig.caCert), Buffer.from(tlsConfig.clientKey), Buffer.from(tlsConfig.clientCert)), { 'grpc.enable_http_proxy': 0 });
|
|
18
|
+
}
|
|
19
|
+
return this._client;
|
|
12
20
|
}
|
|
13
21
|
addCron(request) {
|
|
14
22
|
return new Promise((resolve, reject) => {
|
|
@@ -11,7 +11,17 @@ const delCron = (call, callback) => {
|
|
|
11
11
|
for (const id of call.request.ids) {
|
|
12
12
|
if (data_1.scheduleStacks.has(id)) {
|
|
13
13
|
logger_1.default.info('[schedule][取消定时任务] 任务ID: %s', id);
|
|
14
|
-
|
|
14
|
+
// 过滤掉 nodeSchedule.scheduleJob() 对无效表达式返回的 null,
|
|
15
|
+
// 否则对 null 调 cancel() 会让整个取消流程抛出 UNKNOWN 错误,
|
|
16
|
+
// 进而导致 HTTP 端的 remove() 跳过 setCrontab(),造成 crontab.list 残留。
|
|
17
|
+
(_a = data_1.scheduleStacks.get(id)) === null || _a === void 0 ? void 0 : _a.filter((x) => x != null).forEach((x) => {
|
|
18
|
+
try {
|
|
19
|
+
x.cancel();
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
logger_1.default.warn('[schedule][取消任务失败] 任务ID: %s, 错误: %s', id, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
15
25
|
data_1.scheduleStacks.delete(id);
|
|
16
26
|
}
|
|
17
27
|
}
|
|
@@ -9,7 +9,7 @@ const util_1 = require("../config/util");
|
|
|
9
9
|
const check = async (call, callback) => {
|
|
10
10
|
switch (call.request.service) {
|
|
11
11
|
case 'cron':
|
|
12
|
-
const res = await (0, util_1.promiseExec)(`curl -s --noproxy '*' http://
|
|
12
|
+
const res = await (0, util_1.promiseExec)(`curl -s --noproxy '*' http://localhost:${config_1.default.port}/api/system`);
|
|
13
13
|
if (res.includes('200')) {
|
|
14
14
|
return callback(null, { status: 1 });
|
|
15
15
|
}
|
|
@@ -39,16 +39,30 @@ const typedi_1 = require("typedi");
|
|
|
39
39
|
const path_1 = __importStar(require("path"));
|
|
40
40
|
const config_1 = __importDefault(require("../config"));
|
|
41
41
|
const util_1 = require("../config/util");
|
|
42
|
+
const i18n_1 = require("../shared/i18n");
|
|
42
43
|
const undici_1 = require("undici");
|
|
43
44
|
let ConfigService = class ConfigService {
|
|
44
45
|
constructor() { }
|
|
45
46
|
async getFile(filePath, res) {
|
|
46
47
|
let content = '';
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
if (!filePath) {
|
|
49
|
+
return res.send({ code: 403, message: (0, i18n_1.t)('文件无法访问') });
|
|
50
|
+
}
|
|
51
|
+
const normalized = path_1.default.normalize(filePath);
|
|
52
|
+
if (normalized.startsWith('..') || path_1.default.isAbsolute(normalized)) {
|
|
53
|
+
return res.send({ code: 403, message: (0, i18n_1.t)('文件无法访问') });
|
|
54
|
+
}
|
|
55
|
+
const resolvedRoot = path_1.default.resolve(config_1.default.rootPath, normalized);
|
|
56
|
+
const resolvedConfig = path_1.default.resolve(config_1.default.configPath, normalized);
|
|
57
|
+
const isValidPath = resolvedRoot.startsWith(config_1.default.scriptPath) ||
|
|
58
|
+
resolvedRoot.startsWith(config_1.default.configPath) ||
|
|
59
|
+
resolvedConfig.startsWith(config_1.default.scriptPath) ||
|
|
60
|
+
resolvedConfig.startsWith(config_1.default.configPath);
|
|
61
|
+
if (!isValidPath) {
|
|
62
|
+
return res.send({ code: 403, message: (0, i18n_1.t)('文件无法访问') });
|
|
63
|
+
}
|
|
64
|
+
if (config_1.default.blackFileList.includes(path_1.default.basename(normalized))) {
|
|
65
|
+
return res.send({ code: 403, message: (0, i18n_1.t)('文件无法访问') });
|
|
52
66
|
}
|
|
53
67
|
if (filePath.startsWith('sample/')) {
|
|
54
68
|
const res = await (0, undici_1.request)(`https://gitlab.com/whyour/qinglong/-/raw/master/${filePath}`);
|