@whyour/qinglong 2.17.13 → 2.18.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/package.json +9 -2
- package/sample/notify.js +47 -30
- package/sample/notify.py +36 -53
- package/shell/api.sh +26 -0
- package/shell/preload/sitecustomize.js +7 -1
- package/shell/preload/sitecustomize.py +9 -1
- package/shell/share.sh +3 -7
- package/shell/task.sh +1 -1
- package/shell/update.sh +2 -6
- package/static/build/api/config.js +2 -1
- package/static/build/api/script.js +4 -3
- package/static/build/api/system.js +16 -1
- package/static/build/api/user.js +1 -1
- package/static/build/config/util.js +10 -3
- package/static/build/data/system.js +1 -0
- package/static/build/loaders/express.js +8 -11
- package/static/build/loaders/initData.js +41 -5
- package/static/build/loaders/initFile.js +74 -76
- package/static/build/loaders/sock.js +4 -5
- package/static/build/services/cron.js +2 -1
- package/static/build/services/dependence.js +16 -7
- package/static/build/services/env.js +4 -27
- package/static/build/services/open.js +16 -14
- package/static/build/services/sshKey.js +5 -6
- package/static/build/services/system.js +15 -3
- package/static/build/services/user.js +116 -161
- package/static/build/shared/store.js +32 -0
- package/static/build/shared/utils.js +27 -0
- package/static/build/token.js +2 -6
- package/static/dist/{4642.260d2a8e.async.js → 4642.9e24d86c.async.js} +1 -1
- package/static/dist/4799.d5ca9f30.async.js +1 -0
- package/static/dist/index.html +2 -2
- package/static/dist/{preload_helper.2e4c8e3f.js → preload_helper.55b35ae0.js} +1 -1
- package/static/dist/{src__pages__crontab__index.7163c445.async.js → src__pages__crontab__index.55a8714d.async.js} +1 -1
- package/static/dist/{src__pages__script__index.b893a14e.async.js → src__pages__script__index.6a212c2d.async.js} +1 -1
- package/static/dist/{src__pages__setting__index.636a04c7.async.js → src__pages__setting__index.ffa1cdd6.async.js} +1 -1
- package/static/dist/{umi.916b40e1.js → umi.fb3ed7a0.js} +1 -1
- package/version.yaml +7 -8
- package/static/dist/4799.2c2c56e5.async.js +0 -1
|
@@ -21,20 +21,22 @@ const util_1 = require("../config/util");
|
|
|
21
21
|
const open_1 = require("../data/open");
|
|
22
22
|
const uuid_1 = require("uuid");
|
|
23
23
|
const sequelize_1 = require("sequelize");
|
|
24
|
+
const store_1 = require("../shared/store");
|
|
24
25
|
let OpenService = class OpenService {
|
|
25
26
|
constructor(logger) {
|
|
26
27
|
this.logger = logger;
|
|
27
28
|
}
|
|
28
|
-
async
|
|
29
|
+
async findApps() {
|
|
29
30
|
const docs = await this.find({});
|
|
30
|
-
|
|
31
|
-
return doc[0];
|
|
31
|
+
return docs;
|
|
32
32
|
}
|
|
33
33
|
async create(payload) {
|
|
34
34
|
const tab = Object.assign({}, payload);
|
|
35
35
|
tab.client_id = (0, util_1.createRandomString)(12, 12);
|
|
36
36
|
tab.client_secret = (0, util_1.createRandomString)(24, 24);
|
|
37
37
|
const doc = await this.insert(tab);
|
|
38
|
+
const apps = await this.find({});
|
|
39
|
+
await store_1.shareStore.updateApps(apps);
|
|
38
40
|
return Object.assign(Object.assign({}, doc), { tokens: [] });
|
|
39
41
|
}
|
|
40
42
|
async insert(payload) {
|
|
@@ -51,7 +53,9 @@ let OpenService = class OpenService {
|
|
|
51
53
|
}
|
|
52
54
|
async updateDb(payload) {
|
|
53
55
|
await open_1.AppModel.update(payload, { where: { id: payload.id } });
|
|
54
|
-
|
|
56
|
+
const apps = await this.find({});
|
|
57
|
+
await store_1.shareStore.updateApps(apps);
|
|
58
|
+
return apps === null || apps === void 0 ? void 0 : apps.find((x) => x.id === payload.id);
|
|
55
59
|
}
|
|
56
60
|
async getDb(query) {
|
|
57
61
|
const doc = await open_1.AppModel.findOne({ where: query });
|
|
@@ -62,6 +66,8 @@ let OpenService = class OpenService {
|
|
|
62
66
|
}
|
|
63
67
|
async remove(ids) {
|
|
64
68
|
await open_1.AppModel.destroy({ where: { id: ids } });
|
|
69
|
+
const apps = await this.find({});
|
|
70
|
+
await store_1.shareStore.updateApps(apps);
|
|
65
71
|
}
|
|
66
72
|
async resetSecret(id) {
|
|
67
73
|
const tab = {
|
|
@@ -123,6 +129,8 @@ let OpenService = class OpenService {
|
|
|
123
129
|
tokens = [...invalidTokens, { value: token, expiration }];
|
|
124
130
|
}
|
|
125
131
|
await open_1.AppModel.update({ tokens }, { where: { client_id, client_secret } });
|
|
132
|
+
const apps = await this.find({});
|
|
133
|
+
await store_1.shareStore.updateApps(apps);
|
|
126
134
|
return {
|
|
127
135
|
code: 200,
|
|
128
136
|
data: {
|
|
@@ -133,19 +141,13 @@ let OpenService = class OpenService {
|
|
|
133
141
|
};
|
|
134
142
|
}
|
|
135
143
|
else {
|
|
136
|
-
return { code: 400, message: 'client_id或client_seret有误' };
|
|
144
|
+
return { code: 400, message: 'client_id 或 client_seret 有误' };
|
|
137
145
|
}
|
|
138
146
|
}
|
|
139
147
|
async generateSystemToken() {
|
|
140
|
-
|
|
141
|
-
where: { name: 'system' },
|
|
142
|
-
})
|
|
143
|
-
if (!systemApp) {
|
|
144
|
-
systemApp = await this.create({
|
|
145
|
-
name: 'system',
|
|
146
|
-
scopes: ['crons', 'system'],
|
|
147
|
-
});
|
|
148
|
-
}
|
|
148
|
+
const [systemApp] = await open_1.AppModel.findOrCreate({
|
|
149
|
+
where: { name: 'system', scopes: ['crons', 'system'] },
|
|
150
|
+
});
|
|
149
151
|
const { data } = await this.authToken({
|
|
150
152
|
client_id: systemApp.client_id,
|
|
151
153
|
client_secret: systemApp.client_secret,
|
|
@@ -23,6 +23,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
23
23
|
const subscription_1 = require("../config/subscription");
|
|
24
24
|
const config_1 = __importDefault(require("../config"));
|
|
25
25
|
const util_1 = require("../config/util");
|
|
26
|
+
const utils_1 = require("../shared/utils");
|
|
26
27
|
let SshKeyService = class SshKeyService {
|
|
27
28
|
constructor(logger) {
|
|
28
29
|
this.logger = logger;
|
|
@@ -39,15 +40,15 @@ let SshKeyService = class SshKeyService {
|
|
|
39
40
|
config = await promises_1.default.readFile(this.sshConfigFilePath, { encoding: 'utf-8' });
|
|
40
41
|
}
|
|
41
42
|
else {
|
|
42
|
-
await
|
|
43
|
+
await (0, utils_1.writeFileWithLock)(this.sshConfigFilePath, '');
|
|
43
44
|
}
|
|
44
45
|
if (!config.includes(this.sshConfigHeader)) {
|
|
45
|
-
await
|
|
46
|
+
await (0, utils_1.writeFileWithLock)(this.sshConfigFilePath, `${this.sshConfigHeader}\n\n${config}`);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
async generatePrivateKeyFile(alias, key) {
|
|
49
50
|
try {
|
|
50
|
-
await
|
|
51
|
+
await (0, utils_1.writeFileWithLock)(path_1.default.join(this.sshPath, alias), `${key}${os_1.default.EOL}`, {
|
|
51
52
|
encoding: 'utf8',
|
|
52
53
|
mode: '400',
|
|
53
54
|
});
|
|
@@ -73,9 +74,7 @@ let SshKeyService = class SshKeyService {
|
|
|
73
74
|
? ` ProxyCommand nc -v -x ${proxy} %h %p 2>/dev/null\n`
|
|
74
75
|
: '';
|
|
75
76
|
const config = `Host ${alias}\n Hostname ${host}\n IdentityFile ${path_1.default.join(this.sshPath, alias)}\n StrictHostKeyChecking no\n${proxyStr}`;
|
|
76
|
-
await
|
|
77
|
-
encoding: 'utf8',
|
|
78
|
-
});
|
|
77
|
+
await (0, utils_1.writeFileWithLock)(`${path_1.default.join(this.sshPath, `${alias}.config`)}`, config);
|
|
79
78
|
}
|
|
80
79
|
async removeSshConfig(alias) {
|
|
81
80
|
try {
|
|
@@ -11,6 +11,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
12
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
13
|
};
|
|
14
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
15
|
+
var t = {};
|
|
16
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
17
|
+
t[p] = s[p];
|
|
18
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
19
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
20
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
21
|
+
t[p[i]] = s[p[i]];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
14
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
27
|
};
|
|
@@ -45,12 +56,13 @@ let SystemService = class SystemService {
|
|
|
45
56
|
return doc;
|
|
46
57
|
}
|
|
47
58
|
async updateAuthDb(payload) {
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
const { id } = payload, others = __rest(payload, ["id"]);
|
|
60
|
+
await system_1.SystemModel.update(others, { where: { id } });
|
|
61
|
+
const doc = await this.getDb({ id });
|
|
50
62
|
return doc;
|
|
51
63
|
}
|
|
52
64
|
async getDb(query) {
|
|
53
|
-
const doc = await system_1.SystemModel.findOne({ where:
|
|
65
|
+
const doc = await system_1.SystemModel.findOne({ where: query });
|
|
54
66
|
if (!doc) {
|
|
55
67
|
throw new Error(`System ${JSON.stringify(query)} not found`);
|
|
56
68
|
}
|
|
@@ -1,33 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
2
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
5
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
7
|
};
|
|
24
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
-
if (mod && mod.__esModule) return mod;
|
|
26
|
-
var result = {};
|
|
27
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
-
__setModuleDefault(result, mod);
|
|
29
|
-
return result;
|
|
30
|
-
};
|
|
31
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
32
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
10
|
};
|
|
@@ -42,7 +19,6 @@ const typedi_1 = require("typedi");
|
|
|
42
19
|
const winston_1 = __importDefault(require("winston"));
|
|
43
20
|
const util_1 = require("../config/util");
|
|
44
21
|
const config_1 = __importDefault(require("../config"));
|
|
45
|
-
const fs = __importStar(require("fs/promises"));
|
|
46
22
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
47
23
|
const preset_default_1 = require("@otplib/preset-default");
|
|
48
24
|
const system_1 = require("../data/system");
|
|
@@ -53,6 +29,7 @@ const dayjs_1 = __importDefault(require("dayjs"));
|
|
|
53
29
|
const ip2region_1 = __importDefault(require("ip2region"));
|
|
54
30
|
const request_ip_1 = __importDefault(require("request-ip"));
|
|
55
31
|
const uniq_1 = __importDefault(require("lodash/uniq"));
|
|
32
|
+
const store_1 = require("../shared/store");
|
|
56
33
|
let UserService = class UserService {
|
|
57
34
|
constructor(logger, scheduleService, sockService) {
|
|
58
35
|
this.logger = logger;
|
|
@@ -60,127 +37,109 @@ let UserService = class UserService {
|
|
|
60
37
|
this.sockService = sockService;
|
|
61
38
|
}
|
|
62
39
|
async login(payloads, req, needTwoFactor = true) {
|
|
63
|
-
const _exist = await (0, util_1.fileExist)(config_1.default.authConfigFile);
|
|
64
|
-
if (!_exist) {
|
|
65
|
-
return this.initAuthInfo();
|
|
66
|
-
}
|
|
67
40
|
let { username, password } = payloads;
|
|
68
41
|
const content = await this.getAuthInfo();
|
|
69
42
|
const timestamp = Date.now();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
43
|
+
let { username: cUsername, password: cPassword, retries = 0, lastlogon, lastip, lastaddr, twoFactorActivated, tokens = {}, platform, } = content;
|
|
44
|
+
const retriesTime = Math.pow(3, retries) * 1000;
|
|
45
|
+
if (retries > 2 && timestamp - lastlogon < retriesTime) {
|
|
46
|
+
const waitTime = Math.ceil((retriesTime - (timestamp - lastlogon)) / 1000);
|
|
47
|
+
return {
|
|
48
|
+
code: 410,
|
|
49
|
+
message: `失败次数过多,请${waitTime}秒后重试`,
|
|
50
|
+
data: waitTime,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (username === cUsername &&
|
|
54
|
+
password === cPassword &&
|
|
55
|
+
twoFactorActivated &&
|
|
56
|
+
needTwoFactor) {
|
|
57
|
+
await this.updateAuthInfo(content, {
|
|
58
|
+
isTwoFactorChecking: true,
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
code: 420,
|
|
62
|
+
message: '',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const ip = request_ip_1.default.getClientIp(req) || '';
|
|
66
|
+
const query = new ip2region_1.default();
|
|
67
|
+
const ipAddress = query.search(ip);
|
|
68
|
+
let address = '';
|
|
69
|
+
if (ipAddress) {
|
|
70
|
+
const { country, province, city, isp } = ipAddress;
|
|
71
|
+
address = (0, uniq_1.default)([country, province, city, isp]).filter(Boolean).join(' ');
|
|
72
|
+
}
|
|
73
|
+
if (username === cUsername && password === cPassword) {
|
|
74
|
+
const data = (0, util_1.createRandomString)(50, 100);
|
|
75
|
+
const expiration = twoFactorActivated ? 60 : 20;
|
|
76
|
+
let token = jsonwebtoken_1.default.sign({ data }, config_1.default.secret, {
|
|
77
|
+
expiresIn: 60 * 60 * 24 * expiration,
|
|
78
|
+
algorithm: 'HS384',
|
|
79
|
+
});
|
|
80
|
+
await this.updateAuthInfo(content, {
|
|
81
|
+
token,
|
|
82
|
+
tokens: Object.assign(Object.assign({}, tokens), { [req.platform]: token }),
|
|
83
|
+
lastlogon: timestamp,
|
|
84
|
+
retries: 0,
|
|
85
|
+
lastip: ip,
|
|
86
|
+
lastaddr: address,
|
|
87
|
+
platform: req.platform,
|
|
88
|
+
isTwoFactorChecking: false,
|
|
89
|
+
});
|
|
90
|
+
this.notificationService.notify('登录通知', `你于${(0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss')}在 ${address} ${req.platform}端 登录成功,ip地址 ${ip}`);
|
|
91
|
+
await this.insertDb({
|
|
92
|
+
type: system_1.AuthDataType.loginLog,
|
|
93
|
+
info: {
|
|
94
|
+
timestamp,
|
|
95
|
+
address,
|
|
96
|
+
ip,
|
|
97
|
+
platform: req.platform,
|
|
98
|
+
status: system_1.LoginStatus.success,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
this.getLoginLog();
|
|
102
|
+
return {
|
|
103
|
+
code: 200,
|
|
104
|
+
data: { token, lastip, lastaddr, lastlogon, retries, platform },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
await this.updateAuthInfo(content, {
|
|
109
|
+
retries: retries + 1,
|
|
110
|
+
lastlogon: timestamp,
|
|
111
|
+
lastip: ip,
|
|
112
|
+
lastaddr: address,
|
|
113
|
+
platform: req.platform,
|
|
114
|
+
});
|
|
115
|
+
this.notificationService.notify('登录通知', `你于${(0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss')}在 ${address} ${req.platform}端 登录失败,ip地址 ${ip}`);
|
|
116
|
+
await this.insertDb({
|
|
117
|
+
type: system_1.AuthDataType.loginLog,
|
|
118
|
+
info: {
|
|
119
|
+
timestamp,
|
|
120
|
+
address,
|
|
121
|
+
ip,
|
|
122
|
+
platform: req.platform,
|
|
123
|
+
status: system_1.LoginStatus.fail,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
this.getLoginLog();
|
|
127
|
+
if (retries > 2) {
|
|
128
|
+
const waitTime = Math.round(Math.pow(3, retries + 1));
|
|
82
129
|
return {
|
|
83
130
|
code: 410,
|
|
84
131
|
message: `失败次数过多,请${waitTime}秒后重试`,
|
|
85
132
|
data: waitTime,
|
|
86
133
|
};
|
|
87
134
|
}
|
|
88
|
-
if (username === cUsername &&
|
|
89
|
-
password === cPassword &&
|
|
90
|
-
twoFactorActivated &&
|
|
91
|
-
needTwoFactor) {
|
|
92
|
-
this.updateAuthInfo(content, {
|
|
93
|
-
isTwoFactorChecking: true,
|
|
94
|
-
});
|
|
95
|
-
return {
|
|
96
|
-
code: 420,
|
|
97
|
-
message: '',
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
const ip = request_ip_1.default.getClientIp(req) || '';
|
|
101
|
-
const query = new ip2region_1.default();
|
|
102
|
-
const ipAddress = query.search(ip);
|
|
103
|
-
let address = '';
|
|
104
|
-
if (ipAddress) {
|
|
105
|
-
const { country, province, city, isp } = ipAddress;
|
|
106
|
-
address = (0, uniq_1.default)([country, province, city, isp])
|
|
107
|
-
.filter(Boolean)
|
|
108
|
-
.join(' ');
|
|
109
|
-
}
|
|
110
|
-
if (username === cUsername && password === cPassword) {
|
|
111
|
-
const data = (0, util_1.createRandomString)(50, 100);
|
|
112
|
-
const expiration = twoFactorActivated ? 60 : 20;
|
|
113
|
-
let token = jsonwebtoken_1.default.sign({ data }, config_1.default.secret, {
|
|
114
|
-
expiresIn: 60 * 60 * 24 * expiration,
|
|
115
|
-
algorithm: 'HS384',
|
|
116
|
-
});
|
|
117
|
-
this.updateAuthInfo(content, {
|
|
118
|
-
token,
|
|
119
|
-
tokens: Object.assign(Object.assign({}, tokens), { [req.platform]: token }),
|
|
120
|
-
lastlogon: timestamp,
|
|
121
|
-
retries: 0,
|
|
122
|
-
lastip: ip,
|
|
123
|
-
lastaddr: address,
|
|
124
|
-
platform: req.platform,
|
|
125
|
-
isTwoFactorChecking: false,
|
|
126
|
-
});
|
|
127
|
-
this.notificationService.notify('登录通知', `你于${(0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss')}在 ${address} ${req.platform}端 登录成功,ip地址 ${ip}`);
|
|
128
|
-
await this.insertDb({
|
|
129
|
-
type: system_1.AuthDataType.loginLog,
|
|
130
|
-
info: {
|
|
131
|
-
timestamp,
|
|
132
|
-
address,
|
|
133
|
-
ip,
|
|
134
|
-
platform: req.platform,
|
|
135
|
-
status: system_1.LoginStatus.success,
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
this.getLoginLog();
|
|
139
|
-
return {
|
|
140
|
-
code: 200,
|
|
141
|
-
data: { token, lastip, lastaddr, lastlogon, retries, platform },
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
135
|
else {
|
|
145
|
-
|
|
146
|
-
retries: retries + 1,
|
|
147
|
-
lastlogon: timestamp,
|
|
148
|
-
lastip: ip,
|
|
149
|
-
lastaddr: address,
|
|
150
|
-
platform: req.platform,
|
|
151
|
-
});
|
|
152
|
-
this.notificationService.notify('登录通知', `你于${(0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss')}在 ${address} ${req.platform}端 登录失败,ip地址 ${ip}`);
|
|
153
|
-
await this.insertDb({
|
|
154
|
-
type: system_1.AuthDataType.loginLog,
|
|
155
|
-
info: {
|
|
156
|
-
timestamp,
|
|
157
|
-
address,
|
|
158
|
-
ip,
|
|
159
|
-
platform: req.platform,
|
|
160
|
-
status: system_1.LoginStatus.fail,
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
this.getLoginLog();
|
|
164
|
-
if (retries > 2) {
|
|
165
|
-
const waitTime = Math.round(Math.pow(3, retries + 1));
|
|
166
|
-
return {
|
|
167
|
-
code: 410,
|
|
168
|
-
message: `失败次数过多,请${waitTime}秒后重试`,
|
|
169
|
-
data: waitTime,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
return { code: 400, message: config_1.default.authError };
|
|
174
|
-
}
|
|
136
|
+
return { code: 400, message: config_1.default.authError };
|
|
175
137
|
}
|
|
176
138
|
}
|
|
177
|
-
else {
|
|
178
|
-
return this.initAuthInfo();
|
|
179
|
-
}
|
|
180
139
|
}
|
|
181
140
|
async logout(platform) {
|
|
182
141
|
const authInfo = await this.getAuthInfo();
|
|
183
|
-
this.updateAuthInfo(authInfo, {
|
|
142
|
+
await this.updateAuthInfo(authInfo, {
|
|
184
143
|
token: '',
|
|
185
144
|
tokens: Object.assign(Object.assign({}, authInfo.tokens), { [platform]: '' }),
|
|
186
145
|
});
|
|
@@ -205,44 +164,24 @@ let UserService = class UserService {
|
|
|
205
164
|
const doc = await system_1.SystemModel.create(Object.assign({}, payload), { returning: true });
|
|
206
165
|
return doc;
|
|
207
166
|
}
|
|
208
|
-
async initAuthInfo() {
|
|
209
|
-
await fs.writeFile(config_1.default.authConfigFile, JSON.stringify({
|
|
210
|
-
username: 'admin',
|
|
211
|
-
password: 'admin',
|
|
212
|
-
}));
|
|
213
|
-
return {
|
|
214
|
-
code: 100,
|
|
215
|
-
message: '未找到认证文件,重新初始化',
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
167
|
async updateUsernameAndPassword({ username, password, }) {
|
|
219
168
|
if (password === 'admin') {
|
|
220
169
|
return { code: 400, message: '密码不能设置为admin' };
|
|
221
170
|
}
|
|
222
171
|
const authInfo = await this.getAuthInfo();
|
|
223
|
-
this.updateAuthInfo(authInfo, { username, password });
|
|
172
|
+
await this.updateAuthInfo(authInfo, { username, password });
|
|
224
173
|
return { code: 200, message: '更新成功' };
|
|
225
174
|
}
|
|
226
175
|
async updateAvatar(avatar) {
|
|
227
176
|
const authInfo = await this.getAuthInfo();
|
|
228
|
-
this.updateAuthInfo(authInfo, { avatar });
|
|
177
|
+
await this.updateAuthInfo(authInfo, { avatar });
|
|
229
178
|
return { code: 200, data: avatar, message: '更新成功' };
|
|
230
179
|
}
|
|
231
|
-
async getUserInfo() {
|
|
232
|
-
const authFileExist = await (0, util_1.fileExist)(config_1.default.authConfigFile);
|
|
233
|
-
if (!authFileExist) {
|
|
234
|
-
await (0, util_1.createFile)(config_1.default.authConfigFile, JSON.stringify({
|
|
235
|
-
username: 'admin',
|
|
236
|
-
password: 'admin',
|
|
237
|
-
}));
|
|
238
|
-
}
|
|
239
|
-
return await this.getAuthInfo();
|
|
240
|
-
}
|
|
241
180
|
async initTwoFactor() {
|
|
242
181
|
const secret = preset_default_1.authenticator.generateSecret();
|
|
243
182
|
const authInfo = await this.getAuthInfo();
|
|
244
183
|
const otpauth = preset_default_1.authenticator.keyuri(authInfo.username, 'qinglong', secret);
|
|
245
|
-
this.updateAuthInfo(authInfo, { twoFactorSecret: secret });
|
|
184
|
+
await this.updateAuthInfo(authInfo, { twoFactorSecret: secret });
|
|
246
185
|
return { secret, url: otpauth };
|
|
247
186
|
}
|
|
248
187
|
async activeTwoFactor(code) {
|
|
@@ -252,7 +191,7 @@ let UserService = class UserService {
|
|
|
252
191
|
secret: authInfo.twoFactorSecret,
|
|
253
192
|
});
|
|
254
193
|
if (isValid) {
|
|
255
|
-
this.updateAuthInfo(authInfo, { twoFactorActivated: true });
|
|
194
|
+
await this.updateAuthInfo(authInfo, { twoFactorActivated: true });
|
|
256
195
|
}
|
|
257
196
|
return isValid;
|
|
258
197
|
}
|
|
@@ -271,7 +210,7 @@ let UserService = class UserService {
|
|
|
271
210
|
}
|
|
272
211
|
else {
|
|
273
212
|
const { ip, address } = await (0, util_1.getNetIp)(req);
|
|
274
|
-
this.updateAuthInfo(authInfo, {
|
|
213
|
+
await this.updateAuthInfo(authInfo, {
|
|
275
214
|
lastip: ip,
|
|
276
215
|
lastaddr: address,
|
|
277
216
|
platform: req.platform,
|
|
@@ -281,26 +220,34 @@ let UserService = class UserService {
|
|
|
281
220
|
}
|
|
282
221
|
async deactiveTwoFactor() {
|
|
283
222
|
const authInfo = await this.getAuthInfo();
|
|
284
|
-
this.updateAuthInfo(authInfo, {
|
|
223
|
+
await this.updateAuthInfo(authInfo, {
|
|
285
224
|
twoFactorActivated: false,
|
|
286
|
-
twoFactorActived: false,
|
|
287
225
|
twoFactorSecret: '',
|
|
288
226
|
});
|
|
289
227
|
return true;
|
|
290
228
|
}
|
|
291
229
|
async getAuthInfo() {
|
|
292
|
-
const
|
|
293
|
-
|
|
230
|
+
const authInfo = await store_1.shareStore.getAuthInfo();
|
|
231
|
+
if (authInfo) {
|
|
232
|
+
return authInfo;
|
|
233
|
+
}
|
|
234
|
+
const doc = await this.getDb({ type: system_1.AuthDataType.authConfig });
|
|
235
|
+
return (doc.info || {});
|
|
294
236
|
}
|
|
295
237
|
async updateAuthInfo(authInfo, info) {
|
|
296
|
-
|
|
238
|
+
const result = Object.assign(Object.assign({}, authInfo), info);
|
|
239
|
+
await store_1.shareStore.updateAuthInfo(result);
|
|
240
|
+
await this.updateAuthDb({
|
|
241
|
+
type: system_1.AuthDataType.authConfig,
|
|
242
|
+
info: result,
|
|
243
|
+
});
|
|
297
244
|
}
|
|
298
245
|
async getNotificationMode() {
|
|
299
246
|
const doc = await this.getDb({ type: system_1.AuthDataType.notification });
|
|
300
247
|
return (doc.info || {});
|
|
301
248
|
}
|
|
302
249
|
async updateAuthDb(payload) {
|
|
303
|
-
let doc = await system_1.SystemModel.findOne({ type: payload.type });
|
|
250
|
+
let doc = await system_1.SystemModel.findOne({ where: { type: payload.type } });
|
|
304
251
|
if (doc) {
|
|
305
252
|
const updateResult = await system_1.SystemModel.update(payload, {
|
|
306
253
|
where: { id: doc.id },
|
|
@@ -334,6 +281,14 @@ let UserService = class UserService {
|
|
|
334
281
|
return { code: 400, message: '通知发送失败,请检查参数' };
|
|
335
282
|
}
|
|
336
283
|
}
|
|
284
|
+
async resetAuthInfo(info) {
|
|
285
|
+
const { retries, twoFactorActivated } = info;
|
|
286
|
+
const authInfo = await this.getAuthInfo();
|
|
287
|
+
await this.updateAuthInfo(authInfo, {
|
|
288
|
+
retries,
|
|
289
|
+
twoFactorActivated,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
337
292
|
};
|
|
338
293
|
__decorate([
|
|
339
294
|
(0, typedi_1.Inject)((type) => notify_1.default),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.shareStore = exports.keyvStore = exports.EKeyv = void 0;
|
|
7
|
+
const keyv_1 = __importDefault(require("keyv"));
|
|
8
|
+
const sqlite_1 = __importDefault(require("@keyv/sqlite"));
|
|
9
|
+
const config_1 = __importDefault(require("../config"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
var EKeyv;
|
|
12
|
+
(function (EKeyv) {
|
|
13
|
+
EKeyv["apps"] = "apps";
|
|
14
|
+
EKeyv["authInfo"] = "authInfo";
|
|
15
|
+
})(EKeyv || (exports.EKeyv = EKeyv = {}));
|
|
16
|
+
const keyvSqlite = new sqlite_1.default(path_1.default.join(config_1.default.dbPath, 'keyv.sqlite'));
|
|
17
|
+
exports.keyvStore = new keyv_1.default({ store: keyvSqlite });
|
|
18
|
+
exports.shareStore = {
|
|
19
|
+
getAuthInfo() {
|
|
20
|
+
return exports.keyvStore.get(EKeyv.authInfo);
|
|
21
|
+
},
|
|
22
|
+
updateAuthInfo(value) {
|
|
23
|
+
return exports.keyvStore.set(EKeyv.authInfo, value);
|
|
24
|
+
},
|
|
25
|
+
getApps() {
|
|
26
|
+
return exports.keyvStore.get(EKeyv.apps);
|
|
27
|
+
},
|
|
28
|
+
updateApps(apps) {
|
|
29
|
+
return exports.keyvStore.set(EKeyv.apps, apps);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeFileWithLock = void 0;
|
|
4
|
+
const proper_lockfile_1 = require("proper-lockfile");
|
|
5
|
+
const promises_1 = require("fs/promises");
|
|
6
|
+
const util_1 = require("../config/util");
|
|
7
|
+
async function writeFileWithLock(path, content, options = {}) {
|
|
8
|
+
if (typeof options === 'string') {
|
|
9
|
+
options = { encoding: options };
|
|
10
|
+
}
|
|
11
|
+
if (!(await (0, util_1.fileExist)(path))) {
|
|
12
|
+
const fileHandle = await (0, promises_1.open)(path, 'w');
|
|
13
|
+
fileHandle.close();
|
|
14
|
+
}
|
|
15
|
+
const release = await (0, proper_lockfile_1.lock)(path, {
|
|
16
|
+
retries: {
|
|
17
|
+
retries: 10,
|
|
18
|
+
factor: 2,
|
|
19
|
+
minTimeout: 100,
|
|
20
|
+
maxTimeout: 3000,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
await (0, promises_1.writeFile)(path, content, Object.assign({ encoding: 'utf8' }, options));
|
|
24
|
+
await release();
|
|
25
|
+
}
|
|
26
|
+
exports.writeFileWithLock = writeFileWithLock;
|
|
27
|
+
//# sourceMappingURL=utils.js.map
|
package/static/build/token.js
CHANGED
|
@@ -7,10 +7,10 @@ require("reflect-metadata");
|
|
|
7
7
|
const open_1 = __importDefault(require("./services/open"));
|
|
8
8
|
const typedi_1 = require("typedi");
|
|
9
9
|
const logger_1 = __importDefault(require("./loaders/logger"));
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
11
10
|
const config_1 = __importDefault(require("./config"));
|
|
12
11
|
const path_1 = __importDefault(require("path"));
|
|
13
12
|
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const utils_1 = require("./shared/utils");
|
|
14
14
|
const tokenFile = path_1.default.join(config_1.default.configPath, 'token.json');
|
|
15
15
|
async function getToken() {
|
|
16
16
|
try {
|
|
@@ -28,11 +28,7 @@ async function getToken() {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
async function writeFile(data) {
|
|
31
|
-
|
|
32
|
-
fs_1.default.writeFile(tokenFile, `${JSON.stringify(data)}${os_1.default.EOL}`, { encoding: 'utf8' }, () => {
|
|
33
|
-
resolve();
|
|
34
|
-
});
|
|
35
|
-
});
|
|
31
|
+
await (0, utils_1.writeFileWithLock)(tokenFile, `${JSON.stringify(data)}${os_1.default.EOL}`);
|
|
36
32
|
}
|
|
37
33
|
getToken();
|
|
38
34
|
//# sourceMappingURL=token.js.map
|