@maiyunnet/kebab 2.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/.VSCodeCounter/2025-02-14_14-46-44/details.md +82 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +15 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +2 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +19 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +22 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +69 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.json +1 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.md +48 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +118 -0
- package/.vscode/tasks.json +15 -0
- package/LICENSE +201 -0
- package/README.md +201 -0
- package/bin/kebab.js +2 -0
- package/eslint.config.js +22 -0
- package/index.js +19 -0
- package/index.ts +33 -0
- package/lib/buffer.js +108 -0
- package/lib/buffer.ts +152 -0
- package/lib/captcha/zcool-addict-italic.ttf +0 -0
- package/lib/captcha.js +71 -0
- package/lib/captcha.ts +63 -0
- package/lib/consistent.js +171 -0
- package/lib/consistent.ts +219 -0
- package/lib/core.js +663 -0
- package/lib/core.ts +880 -0
- package/lib/crypto.js +256 -0
- package/lib/crypto.ts +384 -0
- package/lib/db.js +521 -0
- package/lib/db.ts +719 -0
- package/lib/dns.js +321 -0
- package/lib/dns.ts +405 -0
- package/lib/fs.js +405 -0
- package/lib/fs.ts +527 -0
- package/lib/jwt.js +223 -0
- package/lib/jwt.ts +276 -0
- package/lib/kv.js +1004 -0
- package/lib/kv.ts +1489 -0
- package/lib/lan.js +99 -0
- package/lib/lan.ts +87 -0
- package/lib/net/cacert.pem +3480 -0
- package/lib/net/formdata.js +137 -0
- package/lib/net/formdata.ts +166 -0
- package/lib/net/request.js +102 -0
- package/lib/net/request.ts +150 -0
- package/lib/net/response.js +28 -0
- package/lib/net/response.ts +59 -0
- package/lib/net.js +462 -0
- package/lib/net.ts +662 -0
- package/lib/s3.js +180 -0
- package/lib/s3.ts +235 -0
- package/lib/scan.js +276 -0
- package/lib/scan.ts +364 -0
- package/lib/session.js +177 -0
- package/lib/session.ts +230 -0
- package/lib/sql.js +818 -0
- package/lib/sql.ts +1151 -0
- package/lib/ssh/sftp.js +373 -0
- package/lib/ssh/sftp.ts +508 -0
- package/lib/ssh/shell.js +109 -0
- package/lib/ssh/shell.ts +123 -0
- package/lib/ssh.js +171 -0
- package/lib/ssh.ts +191 -0
- package/lib/text/tld.json +1 -0
- package/lib/text.js +452 -0
- package/lib/text.ts +607 -0
- package/lib/time.js +216 -0
- package/lib/time.ts +254 -0
- package/lib/ws.js +373 -0
- package/lib/ws.ts +523 -0
- package/lib/zip.js +381 -0
- package/lib/zip.ts +447 -0
- package/lib/zlib.js +289 -0
- package/lib/zlib.ts +350 -0
- package/main.js +51 -0
- package/main.ts +27 -0
- package/package.json +37 -0
- package/sys/child.js +585 -0
- package/sys/child.ts +678 -0
- package/sys/cmd.js +226 -0
- package/sys/cmd.ts +225 -0
- package/sys/ctr.js +608 -0
- package/sys/ctr.ts +904 -0
- package/sys/master.js +314 -0
- package/sys/master.ts +355 -0
- package/sys/mod.js +1273 -0
- package/sys/mod.ts +1871 -0
- package/sys/route.js +922 -0
- package/sys/route.ts +1113 -0
- package/types/index.d.ts +283 -0
- package/www/example/ctr/main.js +42 -0
- package/www/example/ctr/main.ts +9 -0
- package/www/example/ctr/middle.js +57 -0
- package/www/example/ctr/middle.ts +26 -0
- package/www/example/ctr/test.js +2818 -0
- package/www/example/ctr/test.ts +3218 -0
- package/www/example/data/locale/en.test.json +8 -0
- package/www/example/data/locale/index.html +1 -0
- package/www/example/data/locale/ja.test.json +8 -0
- package/www/example/data/locale/sc.test.json +8 -0
- package/www/example/data/locale/tc.test.json +8 -0
- package/www/example/data/test.zip +0 -0
- package/www/example/kebab.json +24 -0
- package/www/example/mod/test.js +49 -0
- package/www/example/mod/test.ts +47 -0
- package/www/example/mod/testdata.js +11 -0
- package/www/example/mod/testdata.ts +30 -0
- package/www/example/route.json +6 -0
- package/www/example/view/test.ejs +11 -0
- package/www/example/ws/mproxy.js +49 -0
- package/www/example/ws/mproxy.ts +16 -0
- package/www/example/ws/rproxy.js +47 -0
- package/www/example/ws/rproxy.ts +14 -0
- package/www/example/ws/test.js +68 -0
- package/www/example/ws/test.ts +36 -0
package/lib/scan.ts
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
3
|
+
* Date: 2022-09-24 15:23:25
|
|
4
|
+
* Last: 2022-09-24 15:23:25, 2022-9-26 12:37:01, 2022-12-29 00:11:16
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
CREATE TABLE IF NOT EXISTS `scan` (
|
|
9
|
+
`id` bigint NOT NULL AUTO_INCREMENT,
|
|
10
|
+
`token` char (32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
|
11
|
+
`data` text NOT NULL,
|
|
12
|
+
`time_update` bigint NOT NULL,
|
|
13
|
+
`time_add` bigint NOT NULL,
|
|
14
|
+
`time_exp` bigint NOT NULL,
|
|
15
|
+
PRIMARY KEY (`id`),
|
|
16
|
+
UNIQUE KEY `token` (`token`) USING btree
|
|
17
|
+
KEY `time_update` (`time_update`),
|
|
18
|
+
KEY `time_exp` (`time_exp`)
|
|
19
|
+
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
|
20
|
+
*/
|
|
21
|
+
import * as lCore from '~/lib/core';
|
|
22
|
+
import * as lDb from '~/lib/db';
|
|
23
|
+
import * as lKv from '~/lib/kv';
|
|
24
|
+
import * as lSql from '~/lib/sql';
|
|
25
|
+
import * as lTime from '~/lib/time';
|
|
26
|
+
import * as lText from '~/lib/text';
|
|
27
|
+
import * as sCtr from '~/sys/ctr';
|
|
28
|
+
|
|
29
|
+
/** --- Scan 设置的选项 --- */
|
|
30
|
+
export interface IOptions {
|
|
31
|
+
'ttl'?: number;
|
|
32
|
+
'sqlPre'?: sCtr.Ctr | string;
|
|
33
|
+
'name'?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** --- scanned 函数的选项 --- */
|
|
37
|
+
export interface IStaticOptions {
|
|
38
|
+
'sqlPre'?: sCtr.Ctr | string;
|
|
39
|
+
'name'?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class Scan {
|
|
43
|
+
|
|
44
|
+
private readonly _link: lDb.Pool | lKv.Pool;
|
|
45
|
+
|
|
46
|
+
private readonly _sql: lSql.Sql | null = null;
|
|
47
|
+
|
|
48
|
+
/** --- 表名或者 kv 里 key 的前缀 --- */
|
|
49
|
+
private readonly _name: string = 'scan';
|
|
50
|
+
|
|
51
|
+
private _token: string | null = null;
|
|
52
|
+
|
|
53
|
+
/** --- 有效期,默认 5 分钟 --- */
|
|
54
|
+
private _ttl = 60 * 5;
|
|
55
|
+
|
|
56
|
+
public constructor(link: lDb.Pool | lKv.Pool, token?: string, opt: IOptions = {}) {
|
|
57
|
+
if (opt.ttl !== undefined) {
|
|
58
|
+
this._ttl = opt.ttl;
|
|
59
|
+
}
|
|
60
|
+
if (opt.name) {
|
|
61
|
+
this._name = opt.name;
|
|
62
|
+
}
|
|
63
|
+
this._link = link;
|
|
64
|
+
if (link instanceof lDb.Pool) {
|
|
65
|
+
this._sql = lSql.get(opt.sqlPre);
|
|
66
|
+
}
|
|
67
|
+
if (token) {
|
|
68
|
+
this._token = token;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** --- 二维码剩余有效时间 --- */
|
|
73
|
+
private _timeLeft: number | null = null;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* --- 生成二维码处的轮询,检查是否被扫码、被录入数据 ---
|
|
77
|
+
* @returns -3 系统错误 -2 token 不存在或已过期 -1 无操作, 0 已扫码, 其他返回为存的数据并结束轮询
|
|
78
|
+
*/
|
|
79
|
+
public async poll(): Promise<any> {
|
|
80
|
+
if (!this._token) {
|
|
81
|
+
return -3;
|
|
82
|
+
}
|
|
83
|
+
const time = lTime.stamp();
|
|
84
|
+
if (this._link instanceof lDb.Pool) {
|
|
85
|
+
// --- Db ---
|
|
86
|
+
this._sql!.select('*', this._name).where([
|
|
87
|
+
{ 'token': this._token },
|
|
88
|
+
['time_exp', '>', time]
|
|
89
|
+
]);
|
|
90
|
+
const r = await this._link.query(this._sql!.getSql(), this._sql!.getData());
|
|
91
|
+
if (r.error) {
|
|
92
|
+
// --- 出错 ---
|
|
93
|
+
return -3;
|
|
94
|
+
}
|
|
95
|
+
const data = r.rows?.[0];
|
|
96
|
+
if (!data) {
|
|
97
|
+
// --- 不存在或过期 ---
|
|
98
|
+
return -2;
|
|
99
|
+
}
|
|
100
|
+
// --- 存在,判断是否被扫码,以及是否被写入数据 ---
|
|
101
|
+
this._timeLeft = data['time_exp'] - time;
|
|
102
|
+
if (data['data'] !== '') {
|
|
103
|
+
// --- 已经写入数据了,删除数据库条目并返回写入的数据内容 ---
|
|
104
|
+
this._sql!.delete(this._name).where({
|
|
105
|
+
'id': data['id']
|
|
106
|
+
});
|
|
107
|
+
const r = lText.parseJson(data['data']);
|
|
108
|
+
return r === false ? -3 : r;
|
|
109
|
+
}
|
|
110
|
+
else if (data['time_update'] > 0) {
|
|
111
|
+
// --- 已被扫描 ---
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// --- 未扫描 ---
|
|
116
|
+
return -1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// --- Kv ---
|
|
121
|
+
const data = await this._link.getJson('scan-' + this._name + '_' + this._token);
|
|
122
|
+
if (data === null) {
|
|
123
|
+
// --- 不存在或过期 ---
|
|
124
|
+
return -2;
|
|
125
|
+
}
|
|
126
|
+
const ttl = await this._link.ttl('scan-' + this._name + '_' + this._token);
|
|
127
|
+
if (ttl === null) {
|
|
128
|
+
return -3;
|
|
129
|
+
}
|
|
130
|
+
this._timeLeft = ttl;
|
|
131
|
+
if (data['data'] !== null) {
|
|
132
|
+
// --- 已经写入数据了,删除数据库条目并返回写入的数据内容 ---
|
|
133
|
+
await this._link.del('scan-' + this._name + '_' + this._token);
|
|
134
|
+
return data;
|
|
135
|
+
}
|
|
136
|
+
else if (data['time_update'] > 0) {
|
|
137
|
+
// --- 已被扫描 ---
|
|
138
|
+
return 0;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// --- 未扫描 ---
|
|
142
|
+
return -1;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* --- 创建 token,直接应用到本类 ---
|
|
149
|
+
*/
|
|
150
|
+
public async createToken(): Promise<boolean> {
|
|
151
|
+
await this._gc();
|
|
152
|
+
const time = lTime.stamp();
|
|
153
|
+
let count = 0;
|
|
154
|
+
while (true) {
|
|
155
|
+
if (count === 5) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
this._token = lCore.random(32, lCore.RANDOM_LUN);
|
|
159
|
+
if (this._link instanceof lDb.Pool) {
|
|
160
|
+
// --- Db ---
|
|
161
|
+
this._sql!.insert(this._name).values({
|
|
162
|
+
'token': this._token,
|
|
163
|
+
'data': '',
|
|
164
|
+
'time_update': '0',
|
|
165
|
+
'time_add': time,
|
|
166
|
+
'time_exp': time + this._ttl
|
|
167
|
+
});
|
|
168
|
+
const r = await this._link.execute(this._sql!.getSql(), this._sql!.getData());
|
|
169
|
+
if (r.error) {
|
|
170
|
+
if (r.error.errno !== 1062) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// --- Kv ---
|
|
180
|
+
if (await this._link.set('scan-' + this._name + '_' + this._token, {
|
|
181
|
+
'time_update': 0,
|
|
182
|
+
'data': null
|
|
183
|
+
}, this._ttl, 'nx')) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
++count;
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* --- 获取当前 token ---
|
|
194
|
+
*/
|
|
195
|
+
public getToken(): string | null {
|
|
196
|
+
return this._token;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* --- 设置有效期,设置后的新 token 被创建有效 ---
|
|
201
|
+
* @param ttl
|
|
202
|
+
*/
|
|
203
|
+
public setTTL(ttl: number): void {
|
|
204
|
+
this._ttl = ttl;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* --- 获取设置的有效期 ---
|
|
209
|
+
*/
|
|
210
|
+
public getTTL(): number {
|
|
211
|
+
return this._ttl;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* --- 获取当前 token 可扫剩余有效期 ---
|
|
216
|
+
*/
|
|
217
|
+
public getTimeLeft(): number | null {
|
|
218
|
+
return this._timeLeft;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* --- 根据情况清空 Db 状态下的 scan 表垃圾数据 ---
|
|
223
|
+
*/
|
|
224
|
+
private async _gc(): Promise<void> {
|
|
225
|
+
if (this._link instanceof lKv.Pool) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (lCore.rand(0, 10) !== 5) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this._sql!.delete(this._name).where([
|
|
232
|
+
['time_exp', '<', lTime.stamp()]
|
|
233
|
+
]);
|
|
234
|
+
await this._link.execute(this._sql!.getSql(), this._sql!.getData());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* -- 创建 Scan 对象 ---
|
|
241
|
+
* @param link
|
|
242
|
+
* @param token Token
|
|
243
|
+
* @param opt
|
|
244
|
+
*/
|
|
245
|
+
export async function get(link: lDb.Pool | lKv.Pool, token?: string, opt: IOptions = {}): Promise<Scan> {
|
|
246
|
+
const scan = new Scan(link, token, opt);
|
|
247
|
+
if (!token) {
|
|
248
|
+
await scan.createToken();
|
|
249
|
+
}
|
|
250
|
+
return scan;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* --- 对 token 执行访问操作,通常用户扫码后展示的网页所调用,代表已扫码 ---
|
|
255
|
+
* @param link
|
|
256
|
+
* @patam token 必填
|
|
257
|
+
* @param opt
|
|
258
|
+
*/
|
|
259
|
+
export async function scanned(
|
|
260
|
+
link: lDb.Pool | lKv.Pool,
|
|
261
|
+
token: string,
|
|
262
|
+
opt: IStaticOptions = {}
|
|
263
|
+
): Promise<boolean> {
|
|
264
|
+
const time = lTime.stamp();
|
|
265
|
+
const name = opt.name ?? 'scan';
|
|
266
|
+
if (link instanceof lDb.Pool) {
|
|
267
|
+
// --- Db ---
|
|
268
|
+
const sql = lSql.get(opt.sqlPre);
|
|
269
|
+
sql.update(name, {
|
|
270
|
+
'time_update': time
|
|
271
|
+
}).where([
|
|
272
|
+
{
|
|
273
|
+
'token': token,
|
|
274
|
+
'time_update': '0'
|
|
275
|
+
},
|
|
276
|
+
['time_exp', '>', time]
|
|
277
|
+
]);
|
|
278
|
+
const r = await link.execute(sql.getSql(), sql.getData());
|
|
279
|
+
if (r.error) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
if (r.packet?.affectedRows && r.packet.affectedRows > 0) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// --- Kv ---
|
|
288
|
+
const ldata = await link.getJson('scan-' + name + '_' + token);
|
|
289
|
+
if (ldata === null) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
if (ldata['time_update'] > 0) {
|
|
293
|
+
// --- 已经被扫码过了 ---
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
ldata['time_update'] = time;
|
|
297
|
+
const ttl = await link.ttl('scan-' + name + '_' + token);
|
|
298
|
+
if (ttl === null) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
return link.set('scan-' + name + '_' + token, ldata, ttl + 1, 'xx');
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* --- 将数据写入 token,通常在客户的逻辑下去写,服务器会 poll 到 ---
|
|
308
|
+
* @param link
|
|
309
|
+
* @param token
|
|
310
|
+
* @param data
|
|
311
|
+
* @param opt
|
|
312
|
+
*/
|
|
313
|
+
export async function setData(
|
|
314
|
+
link: lDb.Pool | lKv.Pool,
|
|
315
|
+
token: string,
|
|
316
|
+
data: Record<string, any> | string | number,
|
|
317
|
+
opt: IStaticOptions = {}
|
|
318
|
+
): Promise<boolean> {
|
|
319
|
+
if (typeof data === 'number' && Number.isInteger(data)) {
|
|
320
|
+
if (data >= -3 && data <= 1) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const time = lTime.stamp();
|
|
325
|
+
const name = opt.name ?? 'scan';
|
|
326
|
+
if (link instanceof lDb.Pool) {
|
|
327
|
+
// --- Db ---
|
|
328
|
+
const sql = lSql.get(opt.sqlPre);
|
|
329
|
+
sql.update(name, {
|
|
330
|
+
'data': lText.stringifyJson(data)
|
|
331
|
+
}).where([
|
|
332
|
+
{
|
|
333
|
+
'token': token,
|
|
334
|
+
},
|
|
335
|
+
['time_update', '>', '0'],
|
|
336
|
+
['time_exp', '>', time]
|
|
337
|
+
]);
|
|
338
|
+
const r = await link.execute(sql.getSql(), sql.getData());
|
|
339
|
+
if (r.error) {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
if (r.packet?.affectedRows && r.packet?.affectedRows > 0) {
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
// --- Kv ---
|
|
348
|
+
const ldata = await link.getJson('scan-' + name + '_' + token);
|
|
349
|
+
if (ldata === null) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
if (ldata['time_update'] === 0) {
|
|
353
|
+
// --- 还未被扫码,无法操作 ---
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
const ttl = await link.ttl('scan-' + name + '_' + token);
|
|
357
|
+
if (ttl === null) {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
ldata['data'] = data;
|
|
361
|
+
return link.set('scan-' + name + '_' + token, ldata, ttl + 1, 'xx');
|
|
362
|
+
}
|
|
363
|
+
return false;
|
|
364
|
+
}
|
package/lib/session.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
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
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Session = void 0;
|
|
37
|
+
const core = __importStar(require("~/lib/core"));
|
|
38
|
+
const time = __importStar(require("~/lib/time"));
|
|
39
|
+
const db = __importStar(require("~/lib/db"));
|
|
40
|
+
const kv = __importStar(require("~/lib/kv"));
|
|
41
|
+
const sql = __importStar(require("~/lib/sql"));
|
|
42
|
+
const text = __importStar(require("~/lib/text"));
|
|
43
|
+
class Session {
|
|
44
|
+
constructor() {
|
|
45
|
+
this._token = '';
|
|
46
|
+
this._ttl = 0;
|
|
47
|
+
}
|
|
48
|
+
async init(ctr, link, auth = false, opt = {}) {
|
|
49
|
+
const config = ctr.getPrototype('_config');
|
|
50
|
+
const ssl = opt.ssl ?? config.session.ssl;
|
|
51
|
+
const pre = opt.sqlPre ?? null;
|
|
52
|
+
this._name = opt.name ?? config.session.name;
|
|
53
|
+
this._ttl = opt.ttl ?? config.session.ttl;
|
|
54
|
+
const tim = time.stamp();
|
|
55
|
+
this._ctr = ctr;
|
|
56
|
+
if (auth) {
|
|
57
|
+
const a = ctr.getAuthorization();
|
|
58
|
+
if (a && typeof a !== 'string' && (a.user === 'token')) {
|
|
59
|
+
this._token = a.pwd;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const cookie = ctr.getPrototype('_cookie');
|
|
63
|
+
if ((this._token === '') && cookie[this._name]) {
|
|
64
|
+
this._token = cookie[this._name];
|
|
65
|
+
}
|
|
66
|
+
this._link = link;
|
|
67
|
+
if (link instanceof db.Pool) {
|
|
68
|
+
this._sql = sql.get(pre ? pre : ctr);
|
|
69
|
+
await this._gc();
|
|
70
|
+
}
|
|
71
|
+
let session = {};
|
|
72
|
+
let needInsert = false;
|
|
73
|
+
if (this._token !== '') {
|
|
74
|
+
if (this._link instanceof kv.Pool) {
|
|
75
|
+
let data;
|
|
76
|
+
if ((data = await this._link.getJson(this._name + '_' + this._token)) === null) {
|
|
77
|
+
needInsert = true;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
session = data;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
this._sql.select('*', 'session').where([
|
|
85
|
+
['time_update', '>=', tim - this._ttl],
|
|
86
|
+
{ 'token': this._token }
|
|
87
|
+
]);
|
|
88
|
+
const data = await this._link.query(this._sql.getSql(), this._sql.getData());
|
|
89
|
+
if (data.rows?.[0]) {
|
|
90
|
+
session = text.parseJson(data.rows[0].data);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
needInsert = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
ctr.setPrototype('_session', session);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
needInsert = true;
|
|
100
|
+
}
|
|
101
|
+
if (needInsert) {
|
|
102
|
+
if (this._link instanceof kv.Pool) {
|
|
103
|
+
let count = 0;
|
|
104
|
+
do {
|
|
105
|
+
if (count === 5) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
this._token = core.random(16, core.RANDOM_LUN);
|
|
109
|
+
++count;
|
|
110
|
+
} while (!await this._link.set(this._name + '_' + this._token, [], this._ttl, 'nx'));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
let count = 0;
|
|
114
|
+
while (true) {
|
|
115
|
+
if (count === 5) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
this._token = core.random(16, core.RANDOM_LUN);
|
|
119
|
+
this._sql.insert('session').values({
|
|
120
|
+
'token': this._token,
|
|
121
|
+
'data': '{}',
|
|
122
|
+
'time_update': tim,
|
|
123
|
+
'time_add': tim
|
|
124
|
+
});
|
|
125
|
+
++count;
|
|
126
|
+
const r = await this._link.execute(this._sql.getSql(), this._sql.getData());
|
|
127
|
+
if (r.error) {
|
|
128
|
+
if (r.error.errno !== 1062) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
core.setCookie(ctr, this._name, this._token, {
|
|
139
|
+
'ttl': this._ttl,
|
|
140
|
+
'ssl': ssl
|
|
141
|
+
});
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
getToken() {
|
|
145
|
+
return this._token;
|
|
146
|
+
}
|
|
147
|
+
getName() {
|
|
148
|
+
return this._name;
|
|
149
|
+
}
|
|
150
|
+
async update() {
|
|
151
|
+
if (this._link instanceof kv.Pool) {
|
|
152
|
+
await this._link.set(this._name + '_' + this._token, this._ctr.getPrototype('_session'), this._ttl);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
this._sql.update('session', [{
|
|
156
|
+
'data': text.stringifyJson(this._ctr.getPrototype('_session')),
|
|
157
|
+
'time_update': time.stamp()
|
|
158
|
+
}]).where([{
|
|
159
|
+
'token': this._token
|
|
160
|
+
}]);
|
|
161
|
+
await this._link.execute(this._sql.getSql(), this._sql.getData());
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async _gc() {
|
|
165
|
+
if (!(this._link instanceof db.Pool)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (core.rand(0, 20) !== 10) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
this._sql.delete('session').where([
|
|
172
|
+
['time_update', '<', time.stamp() - this._ttl]
|
|
173
|
+
]);
|
|
174
|
+
await this._link.execute(this._sql.getSql(), this._sql.getData());
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.Session = Session;
|