@jayfong/x-server 2.9.8 → 2.9.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/lib/_cjs/cli/templates/crons.ts +1 -1
- package/lib/_cjs/cli/templates/handlers.ts +1 -1
- package/lib/_cjs/cli/templates/hooks.ts +1 -1
- package/lib/_cjs/cli/templates/routes.ts +3 -3
- package/lib/_cjs/core/define_task.js +3 -3
- package/lib/_cjs/plugins/cors.js +1 -3
- package/lib/_cjs/plugins/file_parser.js +12 -1
- package/lib/_cjs/services/cache.js +2 -2
- package/lib/_cjs/services/jwt.js +41 -14
- package/lib/cli/templates/crons.ts +1 -1
- package/lib/cli/templates/handlers.ts +1 -1
- package/lib/cli/templates/hooks.ts +1 -1
- package/lib/cli/templates/routes.ts +3 -3
- package/lib/core/define_task.js +1 -1
- package/lib/core/handler.d.ts +1 -0
- package/lib/core/types.d.ts +1 -1
- package/lib/plugins/cors.d.ts +1 -1
- package/lib/plugins/cors.js +1 -1
- package/lib/plugins/file_parser.d.ts +2 -0
- package/lib/plugins/file_parser.js +11 -1
- package/lib/services/cache.d.ts +1 -1
- package/lib/services/cache.js +1 -1
- package/lib/services/captcha.d.ts +1 -1
- package/lib/services/jwt.d.ts +4 -1
- package/lib/services/jwt.js +38 -13
- package/lib/services/rate_limit.d.ts +1 -1
- package/package.json +8 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// @index(['../../src/crons/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `import '${f.path}'`)
|
|
1
|
+
// @index(['../../src/crons/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `import '${f.path}'`)
|
|
2
2
|
// @endindex
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `export * as __${_.pascal(f.path.replace('/src/handlers/', ''))}__ from '${f.path}'`)
|
|
1
|
+
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `export * as __${_.pascal(f.path.replace('/src/handlers/', ''))}__ from '${f.path}'`)
|
|
2
2
|
|
|
3
3
|
// @endindex
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// @index(['../../src/hooks/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `import '${f.path}'`)
|
|
1
|
+
// @index(['../../src/hooks/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `import '${f.path}'`)
|
|
2
2
|
// @endindex
|
|
@@ -2,7 +2,7 @@ import * as handlers from './handlers'
|
|
|
2
2
|
import { Handler, XServer } from '@jayfong/x-server'
|
|
3
3
|
|
|
4
4
|
const basePathWithHandlers: Array<[string, Record<string, Handler>]> = [
|
|
5
|
-
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `['${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}', handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__ as any],`)
|
|
5
|
+
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `['${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}', handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__ as any],`)
|
|
6
6
|
// @endindex
|
|
7
7
|
]
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
|
13
13
|
? I
|
|
14
14
|
: never
|
|
15
15
|
type RouteMap = {
|
|
16
|
-
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `'${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}': typeof handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__,`)
|
|
16
|
+
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `'${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}': typeof handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__,`)
|
|
17
17
|
// @endindex
|
|
18
18
|
}
|
|
19
19
|
export type HandlerMap = UnionToIntersection<
|
|
@@ -27,7 +27,7 @@ export type HandlerMap = UnionToIntersection<
|
|
|
27
27
|
>
|
|
28
28
|
export type HandlerPath = keyof HandlerMap
|
|
29
29
|
export type HandlerPayloadMap = {
|
|
30
|
-
[K in HandlerPath]: HandlerMap[K] extends Handler<infer X> ? X : {}
|
|
30
|
+
[K in HandlerPath]: HandlerMap[K] extends Handler<infer X, any> ? X : {}
|
|
31
31
|
}
|
|
32
32
|
export type HandlerResultMap = {
|
|
33
33
|
[K in HandlerPath]: HandlerMap[K] extends Handler<any, infer X> ? X : {}
|
|
@@ -10,7 +10,7 @@ var _assert = _interopRequireDefault(require("assert"));
|
|
|
10
10
|
|
|
11
11
|
var _bull = _interopRequireDefault(require("bull"));
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _vtils = require("vtils");
|
|
14
14
|
|
|
15
15
|
var _x = require("../x");
|
|
16
16
|
|
|
@@ -51,9 +51,9 @@ function defineSliceTask(options) {
|
|
|
51
51
|
const res = {
|
|
52
52
|
add: async (data, addOptions) => {
|
|
53
53
|
const key = (addOptions == null ? void 0 : addOptions.key) || '';
|
|
54
|
-
const duration = (addOptions == null ? void 0 : addOptions.duration) != null ? (0,
|
|
54
|
+
const duration = (addOptions == null ? void 0 : addOptions.duration) != null ? (0, _vtils.ms)(addOptions.duration) : typeof options.duration === 'function' ? (0, _vtils.ms)(options.duration(key)) : options.duration && (0, _vtils.ms)(options.duration);
|
|
55
55
|
const threshold = (addOptions == null ? void 0 : addOptions.threshold) || typeof options.threshold && (typeof options.threshold === 'function' ? options.threshold(key) : options.threshold);
|
|
56
|
-
const thresholdTimeout = (addOptions == null ? void 0 : addOptions.thresholdTimeout) != null ? (0,
|
|
56
|
+
const thresholdTimeout = (addOptions == null ? void 0 : addOptions.thresholdTimeout) != null ? (0, _vtils.ms)(addOptions.thresholdTimeout) : typeof options.thresholdTimeout === 'function' ? (0, _vtils.ms)(options.thresholdTimeout(key)) : options.thresholdTimeout && (0, _vtils.ms)(options.thresholdTimeout);
|
|
57
57
|
(0, _assert.default)(duration != null || threshold != null, '参数 threshold 和 duration 必须至少设置 1 个');
|
|
58
58
|
const redisKey = !key ? redisKeyPrefix : `${redisKeyPrefix}_${key}`;
|
|
59
59
|
const res = await _x.x.redis.multi([['llen', redisKey], ['lpush', redisKey, JSON.stringify(data)]]).exec();
|
package/lib/_cjs/plugins/cors.js
CHANGED
|
@@ -9,8 +9,6 @@ var _cors = _interopRequireDefault(require("@fastify/cors"));
|
|
|
9
9
|
|
|
10
10
|
var _vtils = require("vtils");
|
|
11
11
|
|
|
12
|
-
var _date = require("vtils/date");
|
|
13
|
-
|
|
14
12
|
/**
|
|
15
13
|
* CORS 支持插件
|
|
16
14
|
*/
|
|
@@ -36,7 +34,7 @@ class CorsPlugin {
|
|
|
36
34
|
});
|
|
37
35
|
fastify.register(_cors.default, {
|
|
38
36
|
origin: (origin, cb) => allowAll ? cb(null, true) : cb(null, origin ? check(origin) : true),
|
|
39
|
-
maxAge: (0,
|
|
37
|
+
maxAge: (0, _vtils.ms)(this.options.ttl, true)
|
|
40
38
|
});
|
|
41
39
|
}
|
|
42
40
|
|
|
@@ -7,8 +7,12 @@ exports.FileParserPlugin = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _multipart = _interopRequireDefault(require("@fastify/multipart"));
|
|
9
9
|
|
|
10
|
+
var _vtils = require("vtils");
|
|
11
|
+
|
|
10
12
|
/**
|
|
11
13
|
* file 解析器插件
|
|
14
|
+
*
|
|
15
|
+
* 注意:默认文件大小限制 1MB
|
|
12
16
|
*/
|
|
13
17
|
class FileParserPlugin {
|
|
14
18
|
constructor(options) {
|
|
@@ -16,7 +20,14 @@ class FileParserPlugin {
|
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
register(fastify) {
|
|
19
|
-
|
|
23
|
+
var _this$options;
|
|
24
|
+
|
|
25
|
+
fastify.register(_multipart.default, { ...this.options,
|
|
26
|
+
limits: {
|
|
27
|
+
fileSize: (0, _vtils.bytes)(1, 'MB'),
|
|
28
|
+
...((_this$options = this.options) == null ? void 0 : _this$options.limits)
|
|
29
|
+
}
|
|
30
|
+
});
|
|
20
31
|
}
|
|
21
32
|
|
|
22
33
|
}
|
|
@@ -7,7 +7,7 @@ exports.CacheService = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _cuid = _interopRequireDefault(require("cuid"));
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _vtils = require("vtils");
|
|
11
11
|
|
|
12
12
|
var _x = require("../x");
|
|
13
13
|
|
|
@@ -39,7 +39,7 @@ class CacheService {
|
|
|
39
39
|
const redisKey = this.toRedisKey(key);
|
|
40
40
|
const redisValue = JSON.stringify(value);
|
|
41
41
|
await _x.x.redis.set(redisKey, redisValue, // 毫秒
|
|
42
|
-
'PX', (0,
|
|
42
|
+
'PX', (0, _vtils.ms)(redisTtl));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
return value;
|
package/lib/_cjs/services/jwt.js
CHANGED
|
@@ -7,35 +7,62 @@ exports.JwtService = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
|
|
9
9
|
|
|
10
|
+
var _date = require("vtils/date");
|
|
11
|
+
|
|
10
12
|
var _http_error = require("../core/http_error");
|
|
11
13
|
|
|
12
|
-
var
|
|
14
|
+
var _lruCache = require("lru-cache");
|
|
15
|
+
|
|
16
|
+
var _vtils = require("vtils");
|
|
13
17
|
|
|
14
18
|
class JwtService {
|
|
15
19
|
constructor(options) {
|
|
16
20
|
this.options = options;
|
|
17
21
|
this.serviceName = 'jwt';
|
|
22
|
+
this.cache = void 0;
|
|
23
|
+
|
|
24
|
+
if (options.cache) {
|
|
25
|
+
this.cache = new _lruCache.LRUCache(options.cache);
|
|
26
|
+
}
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
sign(payload, ttl = this.options.ttl) {
|
|
21
|
-
|
|
22
|
-
expiresIn: (0,
|
|
30
|
+
const token = _jsonwebtoken.default.sign(payload, this.options.secret, {
|
|
31
|
+
expiresIn: (0, _vtils.ms)(ttl, true)
|
|
23
32
|
});
|
|
33
|
+
|
|
34
|
+
if (this.cache) {
|
|
35
|
+
this.cache.set(token, payload, {
|
|
36
|
+
ttl: (0, _vtils.ms)(ttl)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return token;
|
|
24
41
|
}
|
|
25
42
|
|
|
26
43
|
async verify(token) {
|
|
27
44
|
var _this$options$onVerif, _this$options;
|
|
28
45
|
|
|
29
46
|
const data = await new Promise((resolve, reject) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
if (this.cache && this.cache.has(token)) {
|
|
48
|
+
resolve(this.cache.get(token));
|
|
49
|
+
} else {
|
|
50
|
+
_jsonwebtoken.default.verify(token, this.options.secret, {
|
|
51
|
+
ignoreExpiration: false
|
|
52
|
+
}, (err, data) => {
|
|
53
|
+
if (err || !data || typeof data === 'string' || !data.iat || !data.exp) {
|
|
54
|
+
reject(new _http_error.HttpError.Unauthorized('data'));
|
|
55
|
+
} else {
|
|
56
|
+
if (this.cache) {
|
|
57
|
+
this.cache.set(token, data, {
|
|
58
|
+
ttl: (0, _date.differenceInMilliseconds)((0, _date.fromUnixTime)(data.exp), new Date())
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
resolve(data);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
39
66
|
});
|
|
40
67
|
await ((_this$options$onVerif = (_this$options = this.options).onVerify) == null ? void 0 : _this$options$onVerif.call(_this$options, data));
|
|
41
68
|
return data;
|
|
@@ -45,13 +72,13 @@ class JwtService {
|
|
|
45
72
|
const authorization = headers.authorization || headers['sec-websocket-protocol'] && `Bearer ${headers['sec-websocket-protocol']}` || '';
|
|
46
73
|
|
|
47
74
|
if (!authorization) {
|
|
48
|
-
throw new _http_error.HttpError.Unauthorized();
|
|
75
|
+
throw new _http_error.HttpError.Unauthorized('header');
|
|
49
76
|
}
|
|
50
77
|
|
|
51
78
|
const [scheme, token] = authorization.split(' ');
|
|
52
79
|
|
|
53
80
|
if (scheme.toLowerCase() !== 'bearer') {
|
|
54
|
-
throw new _http_error.HttpError.Unauthorized();
|
|
81
|
+
throw new _http_error.HttpError.Unauthorized('bearer');
|
|
55
82
|
}
|
|
56
83
|
|
|
57
84
|
return this.verify(token);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// @index(['../../src/crons/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `import '${f.path}'`)
|
|
1
|
+
// @index(['../../src/crons/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `import '${f.path}'`)
|
|
2
2
|
// @endindex
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `export * as __${_.pascal(f.path.replace('/src/handlers/', ''))}__ from '${f.path}'`)
|
|
1
|
+
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `export * as __${_.pascal(f.path.replace('/src/handlers/', ''))}__ from '${f.path}'`)
|
|
2
2
|
|
|
3
3
|
// @endindex
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// @index(['../../src/hooks/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `import '${f.path}'`)
|
|
1
|
+
// @index(['../../src/hooks/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `import '${f.path}'`)
|
|
2
2
|
// @endindex
|
|
@@ -2,7 +2,7 @@ import * as handlers from './handlers'
|
|
|
2
2
|
import { Handler, XServer } from '@jayfong/x-server'
|
|
3
3
|
|
|
4
4
|
const basePathWithHandlers: Array<[string, Record<string, Handler>]> = [
|
|
5
|
-
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `['${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}', handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__ as any],`)
|
|
5
|
+
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `['${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}', handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__ as any],`)
|
|
6
6
|
// @endindex
|
|
7
7
|
]
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
|
13
13
|
? I
|
|
14
14
|
: never
|
|
15
15
|
type RouteMap = {
|
|
16
|
-
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**'], (f, _) => `'${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}': typeof handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__,`)
|
|
16
|
+
// @index(['../../src/handlers/**/*.ts', '!**/_*', '!**/_*/**', '!**/*.test.*'], (f, _) => `'${(f.path+'/').replace('../../src/handlers/', '/').replace(/\/index\/$/, '/').split('/').map(v => _.snake(v)).join('/')}': typeof handlers.__${_.pascal(f.path.replace('/src/handlers/', ''))}__,`)
|
|
17
17
|
// @endindex
|
|
18
18
|
}
|
|
19
19
|
export type HandlerMap = UnionToIntersection<
|
|
@@ -27,7 +27,7 @@ export type HandlerMap = UnionToIntersection<
|
|
|
27
27
|
>
|
|
28
28
|
export type HandlerPath = keyof HandlerMap
|
|
29
29
|
export type HandlerPayloadMap = {
|
|
30
|
-
[K in HandlerPath]: HandlerMap[K] extends Handler<infer X> ? X : {}
|
|
30
|
+
[K in HandlerPath]: HandlerMap[K] extends Handler<infer X, any> ? X : {}
|
|
31
31
|
}
|
|
32
32
|
export type HandlerResultMap = {
|
|
33
33
|
[K in HandlerPath]: HandlerMap[K] extends Handler<any, infer X> ? X : {}
|
package/lib/core/define_task.js
CHANGED
package/lib/core/handler.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { XHandler } from './types';
|
|
2
|
+
export type { HandlerPath, HandlerPayloadMap, HandlerResultMap, HandlerMethodMap } from '.x/routes';
|
|
2
3
|
export declare class Handler<TReqData extends any = void, TResData extends any = void, TReqMethod extends XHandler.Method = XHandler.Method> {
|
|
3
4
|
readonly options: XHandler.Options<TReqData, TResData, TReqMethod>;
|
|
4
5
|
private requestDataSchema;
|
package/lib/core/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { AsyncOrSync, LiteralUnion, OneOrMore, RequiredDeep } from 'vtils/t
|
|
|
8
8
|
import type { DisposeService } from '../services/dispose';
|
|
9
9
|
import type { Handler } from './handler';
|
|
10
10
|
import type { IncomingHttpHeaders } from 'http';
|
|
11
|
-
import type { MsValue } from 'vtils
|
|
11
|
+
import type { MsValue } from 'vtils';
|
|
12
12
|
import type { MultipartFile } from '@fastify/multipart';
|
|
13
13
|
import type { Queue } from 'bull';
|
|
14
14
|
import type { SocketStream } from '@fastify/websocket';
|
package/lib/plugins/cors.d.ts
CHANGED
package/lib/plugins/cors.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import FastifyMultipart from '@fastify/multipart';
|
|
2
|
+
import { bytes } from 'vtils';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* file 解析器插件
|
|
6
|
+
*
|
|
7
|
+
* 注意:默认文件大小限制 1MB
|
|
5
8
|
*/
|
|
6
9
|
export class FileParserPlugin {
|
|
7
10
|
constructor(options) {
|
|
@@ -9,7 +12,14 @@ export class FileParserPlugin {
|
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
register(fastify) {
|
|
12
|
-
|
|
15
|
+
var _this$options;
|
|
16
|
+
|
|
17
|
+
fastify.register(FastifyMultipart, { ...this.options,
|
|
18
|
+
limits: {
|
|
19
|
+
fileSize: bytes(1, 'MB'),
|
|
20
|
+
...((_this$options = this.options) == null ? void 0 : _this$options.limits)
|
|
21
|
+
}
|
|
22
|
+
});
|
|
13
23
|
}
|
|
14
24
|
|
|
15
25
|
}
|
package/lib/services/cache.d.ts
CHANGED
package/lib/services/cache.js
CHANGED
package/lib/services/jwt.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import jwt from 'jsonwebtoken';
|
|
3
3
|
import { BaseService } from './base';
|
|
4
|
-
import {
|
|
4
|
+
import { LRUCache } from 'lru-cache';
|
|
5
|
+
import { MsValue } from 'vtils';
|
|
5
6
|
import type { IncomingHttpHeaders } from 'http';
|
|
6
7
|
import type { RequiredBy } from 'vtils/types';
|
|
7
8
|
export interface JwtServiceOptions {
|
|
8
9
|
secret: string;
|
|
9
10
|
ttl: MsValue;
|
|
11
|
+
cache?: LRUCache.Options<string, Record<string, any>, any>;
|
|
10
12
|
onVerify?: (payload: RequiredBy<jwt.JwtPayload, 'iat' | 'exp'>) => any;
|
|
11
13
|
}
|
|
12
14
|
export declare class JwtService implements BaseService {
|
|
13
15
|
private options;
|
|
14
16
|
serviceName: string;
|
|
17
|
+
private cache;
|
|
15
18
|
constructor(options: JwtServiceOptions);
|
|
16
19
|
sign<T extends Record<string, any>>(payload: T, ttl?: MsValue): string;
|
|
17
20
|
verify<T extends Record<string, any>>(token: string): Promise<T>;
|
package/lib/services/jwt.js
CHANGED
|
@@ -1,31 +1,56 @@
|
|
|
1
1
|
import jwt from 'jsonwebtoken';
|
|
2
|
+
import { differenceInMilliseconds, fromUnixTime } from 'vtils/date';
|
|
2
3
|
import { HttpError } from "../core/http_error";
|
|
3
|
-
import {
|
|
4
|
+
import { LRUCache } from 'lru-cache';
|
|
5
|
+
import { ms } from 'vtils';
|
|
4
6
|
export class JwtService {
|
|
5
7
|
constructor(options) {
|
|
6
8
|
this.options = options;
|
|
7
9
|
this.serviceName = 'jwt';
|
|
10
|
+
this.cache = void 0;
|
|
11
|
+
|
|
12
|
+
if (options.cache) {
|
|
13
|
+
this.cache = new LRUCache(options.cache);
|
|
14
|
+
}
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
sign(payload, ttl = this.options.ttl) {
|
|
11
|
-
|
|
18
|
+
const token = jwt.sign(payload, this.options.secret, {
|
|
12
19
|
expiresIn: ms(ttl, true)
|
|
13
20
|
});
|
|
21
|
+
|
|
22
|
+
if (this.cache) {
|
|
23
|
+
this.cache.set(token, payload, {
|
|
24
|
+
ttl: ms(ttl)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return token;
|
|
14
29
|
}
|
|
15
30
|
|
|
16
31
|
async verify(token) {
|
|
17
32
|
var _this$options$onVerif, _this$options;
|
|
18
33
|
|
|
19
34
|
const data = await new Promise((resolve, reject) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
if (this.cache && this.cache.has(token)) {
|
|
36
|
+
resolve(this.cache.get(token));
|
|
37
|
+
} else {
|
|
38
|
+
jwt.verify(token, this.options.secret, {
|
|
39
|
+
ignoreExpiration: false
|
|
40
|
+
}, (err, data) => {
|
|
41
|
+
if (err || !data || typeof data === 'string' || !data.iat || !data.exp) {
|
|
42
|
+
reject(new HttpError.Unauthorized('data'));
|
|
43
|
+
} else {
|
|
44
|
+
if (this.cache) {
|
|
45
|
+
this.cache.set(token, data, {
|
|
46
|
+
ttl: differenceInMilliseconds(fromUnixTime(data.exp), new Date())
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
resolve(data);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
29
54
|
});
|
|
30
55
|
await ((_this$options$onVerif = (_this$options = this.options).onVerify) == null ? void 0 : _this$options$onVerif.call(_this$options, data));
|
|
31
56
|
return data;
|
|
@@ -35,13 +60,13 @@ export class JwtService {
|
|
|
35
60
|
const authorization = headers.authorization || headers['sec-websocket-protocol'] && `Bearer ${headers['sec-websocket-protocol']}` || '';
|
|
36
61
|
|
|
37
62
|
if (!authorization) {
|
|
38
|
-
throw new HttpError.Unauthorized();
|
|
63
|
+
throw new HttpError.Unauthorized('header');
|
|
39
64
|
}
|
|
40
65
|
|
|
41
66
|
const [scheme, token] = authorization.split(' ');
|
|
42
67
|
|
|
43
68
|
if (scheme.toLowerCase() !== 'bearer') {
|
|
44
|
-
throw new HttpError.Unauthorized();
|
|
69
|
+
throw new HttpError.Unauthorized('bearer');
|
|
45
70
|
}
|
|
46
71
|
|
|
47
72
|
return this.verify(token);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jayfong/x-server",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.10",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "lib/_cjs/index.js",
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"bootstrap": "tyn --frozen-lockfile",
|
|
17
17
|
"build": "haoma compile",
|
|
18
|
+
"build_test_pkg": "tyn build && rm -rf ./lib_test && mkdir -p ./lib_test && cp -r ./lib ./lib_test/lib && cp ./package.json ./lib_test/package.json && cd ./tests/app && tyn add file:../../lib_test",
|
|
18
19
|
"dev": "rm -rf lib && tsc -w -p ./tsconfig.build.json",
|
|
19
20
|
"release": "source proxy-use-trojan.sh && tyn test && standard-version -a && tyn build && npm publish && haoma run ./scripts/publish_client_helper_package.ts && git push --follow-tags origin master",
|
|
20
|
-
"test": "tsc --noEmit && jest",
|
|
21
|
+
"test": "tsc --noEmit -p ./tsconfig.build.json && jest \"$(pwd)/src/\"",
|
|
22
|
+
"test_all": "tsc --noEmit -p ./tsconfig.build.json && jest",
|
|
21
23
|
"updeps": "tnpx npm-check-updates --target minor --upgrade"
|
|
22
24
|
},
|
|
23
25
|
"husky": {
|
|
@@ -58,6 +60,7 @@
|
|
|
58
60
|
"http-errors": "^2.0.0",
|
|
59
61
|
"ioredis": "^5.3.2",
|
|
60
62
|
"jsonwebtoken": "^8.5.1",
|
|
63
|
+
"lru-cache": "^10.0.0",
|
|
61
64
|
"lz-string": "^1.4.4",
|
|
62
65
|
"mini-svg-data-uri": "^1.4.4",
|
|
63
66
|
"mint-filter": "^3.0.1",
|
|
@@ -71,7 +74,7 @@
|
|
|
71
74
|
"ts-morph": "^12.2.0",
|
|
72
75
|
"utf-8-validate": "^5.0.9",
|
|
73
76
|
"vscode-generate-index-standalone": "^1.7.1",
|
|
74
|
-
"vtils": "^4.
|
|
77
|
+
"vtils": "^4.85.2",
|
|
75
78
|
"yargs": "^17.4.1"
|
|
76
79
|
},
|
|
77
80
|
"devDependencies": {
|
|
@@ -86,7 +89,9 @@
|
|
|
86
89
|
"husky": "^4.3.8",
|
|
87
90
|
"ioredis-mock": "^8.7.0",
|
|
88
91
|
"jest": "^27.5.1",
|
|
92
|
+
"json-xml-parse": "^1.2.4",
|
|
89
93
|
"lint-staged": "^10.5.4",
|
|
94
|
+
"node-fetch": "^3.3.1",
|
|
90
95
|
"npm-check-updates": "^12.5.9",
|
|
91
96
|
"prettier": "^2.8.8",
|
|
92
97
|
"standard-version": "^9.3.2",
|