hono 1.0.0 → 1.2.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/README.md +189 -125
- package/dist/compose.d.ts +2 -2
- package/dist/compose.js +20 -8
- package/dist/context.d.ts +4 -5
- package/dist/context.js +5 -17
- package/dist/hono.d.ts +51 -25
- package/dist/hono.js +106 -49
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/middleware/basic-auth/index.js +11 -10
- package/dist/middleware/body-parse/index.d.ts +5 -0
- package/dist/middleware/cookie/index.d.ts +1 -3
- package/dist/middleware/graphql-server/parse-body.d.ts +1 -3
- package/dist/middleware/jwt/index.d.ts +6 -0
- package/dist/middleware/jwt/index.js +49 -0
- package/dist/middleware/logger/index.js +3 -5
- package/dist/middleware/mustache/index.js +3 -9
- package/dist/router/reg-exp-router/node.d.ts +3 -0
- package/dist/router/reg-exp-router/node.js +13 -7
- package/dist/router/reg-exp-router/router.d.ts +21 -2
- package/dist/router/reg-exp-router/router.js +300 -80
- package/dist/router/reg-exp-router/trie.d.ts +4 -0
- package/dist/router/reg-exp-router/trie.js +2 -2
- package/dist/router/trie-router/node.d.ts +4 -3
- package/dist/router/trie-router/node.js +123 -55
- package/dist/router/trie-router/router.d.ts +1 -1
- package/dist/router.d.ts +4 -3
- package/dist/router.js +5 -4
- package/dist/utils/body.js +2 -2
- package/dist/utils/buffer.d.ts +1 -0
- package/dist/utils/buffer.js +9 -1
- package/dist/utils/crypto.d.ts +0 -2
- package/dist/utils/crypto.js +1 -51
- package/dist/utils/encode.d.ts +7 -0
- package/dist/utils/encode.js +105 -0
- package/dist/utils/jwt/index.d.ts +1 -0
- package/dist/utils/jwt/index.js +27 -0
- package/dist/utils/jwt/jwt.d.ts +7 -0
- package/dist/utils/jwt/jwt.js +98 -0
- package/dist/utils/jwt/types.d.ts +20 -0
- package/dist/utils/jwt/types.js +44 -0
- package/dist/utils/url.js +4 -4
- package/package.json +29 -21
|
@@ -3,96 +3,164 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Node = void 0;
|
|
4
4
|
const router_1 = require("../../router");
|
|
5
5
|
const url_1 = require("../../utils/url");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
function findParam(node, name) {
|
|
7
|
+
for (let i = 0, len = node.patterns.length; i < len; i++) {
|
|
8
|
+
if (typeof node.patterns[i] === 'object' && node.patterns[i][1] === name) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const nodes = Object.values(node.children);
|
|
13
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
14
|
+
if (findParam(nodes[i], name)) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
9
20
|
class Node {
|
|
10
21
|
constructor(method, handler, children) {
|
|
11
22
|
this.children = children || {};
|
|
12
|
-
this.
|
|
23
|
+
this.methods = [];
|
|
13
24
|
if (method && handler) {
|
|
14
|
-
|
|
25
|
+
const m = {};
|
|
26
|
+
m[method] = handler;
|
|
27
|
+
this.methods = [m];
|
|
15
28
|
}
|
|
16
|
-
this.middlewares = [];
|
|
17
29
|
this.patterns = [];
|
|
18
30
|
}
|
|
19
31
|
insert(method, path, handler) {
|
|
20
32
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
21
33
|
let curNode = this;
|
|
22
34
|
const parts = (0, url_1.splitPath)(path);
|
|
35
|
+
const parentPatterns = [];
|
|
36
|
+
const errorMessage = (name) => {
|
|
37
|
+
return `Duplicate param name, use another name instead of '${name}' - ${method} ${path} <--- '${name}'`;
|
|
38
|
+
};
|
|
23
39
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
24
40
|
const p = parts[i];
|
|
25
41
|
if (Object.keys(curNode.children).includes(p)) {
|
|
42
|
+
parentPatterns.push(...curNode.patterns);
|
|
26
43
|
curNode = curNode.children[p];
|
|
27
44
|
continue;
|
|
28
45
|
}
|
|
29
46
|
curNode.children[p] = new Node();
|
|
30
47
|
const pattern = (0, url_1.getPattern)(p);
|
|
31
48
|
if (pattern) {
|
|
49
|
+
if (typeof pattern === 'object') {
|
|
50
|
+
for (let j = 0, len = parentPatterns.length; j < len; j++) {
|
|
51
|
+
if (typeof parentPatterns[j] === 'object' && parentPatterns[j][1] === pattern[1]) {
|
|
52
|
+
throw new Error(errorMessage(pattern[1]));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (Object.values(curNode.children).some((n) => findParam(n, pattern[1]))) {
|
|
56
|
+
throw new Error(errorMessage(pattern[1]));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
32
59
|
curNode.patterns.push(pattern);
|
|
60
|
+
parentPatterns.push(...curNode.patterns);
|
|
33
61
|
}
|
|
62
|
+
parentPatterns.push(...curNode.patterns);
|
|
34
63
|
curNode = curNode.children[p];
|
|
35
64
|
}
|
|
36
|
-
curNode.
|
|
65
|
+
if (!curNode.methods.length) {
|
|
66
|
+
curNode.methods = [];
|
|
67
|
+
}
|
|
68
|
+
const m = {};
|
|
69
|
+
m[method] = handler;
|
|
70
|
+
curNode.methods.push(m);
|
|
37
71
|
return curNode;
|
|
38
72
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// '*' => match any path
|
|
47
|
-
// /api/* => default wildcard match
|
|
48
|
-
if (curNode.children['*'] && !curNode.children[p]) {
|
|
49
|
-
const astNode = curNode.children['*'];
|
|
50
|
-
if (Object.keys(astNode.children).length === 0) {
|
|
51
|
-
curNode = astNode;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
73
|
+
getHandlers(node, method) {
|
|
74
|
+
const handlers = [];
|
|
75
|
+
node.methods.map((m) => {
|
|
76
|
+
let handler = m[method];
|
|
77
|
+
if (handler !== undefined) {
|
|
78
|
+
handlers.push(handler);
|
|
79
|
+
return;
|
|
54
80
|
}
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
81
|
+
handler = m[router_1.METHOD_NAME_ALL];
|
|
82
|
+
if (handler !== undefined) {
|
|
83
|
+
handlers.push(handler);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
return handlers;
|
|
88
|
+
}
|
|
89
|
+
next(node, part, method, isLast) {
|
|
90
|
+
const handlers = [];
|
|
91
|
+
const nextNodes = [];
|
|
92
|
+
const params = {};
|
|
93
|
+
for (let j = 0, len = node.patterns.length; j < len; j++) {
|
|
94
|
+
const pattern = node.patterns[j];
|
|
95
|
+
// Wildcard
|
|
96
|
+
// '/hello/*/foo' => match /hello/bar/foo
|
|
97
|
+
if (pattern === '*') {
|
|
98
|
+
const astNode = node.children['*'];
|
|
99
|
+
if (astNode) {
|
|
100
|
+
handlers.push(...this.getHandlers(astNode, method));
|
|
101
|
+
nextNodes.push(astNode);
|
|
61
102
|
}
|
|
62
103
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
104
|
+
if (part === '')
|
|
105
|
+
continue;
|
|
106
|
+
// Named match
|
|
107
|
+
// `/posts/:id` => match /posts/123
|
|
108
|
+
const [key, name, matcher] = pattern;
|
|
109
|
+
if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) {
|
|
110
|
+
if (typeof key === 'string') {
|
|
111
|
+
if (isLast === true) {
|
|
112
|
+
handlers.push(...this.getHandlers(node.children[key], method));
|
|
113
|
+
}
|
|
114
|
+
nextNodes.push(node.children[key]);
|
|
73
115
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (p !== '' && (matcher === true || matcher.test(p))) {
|
|
77
|
-
params[name] = p;
|
|
78
|
-
curNode = curNode.children[key];
|
|
79
|
-
isParamMatch = true;
|
|
80
|
-
break;
|
|
116
|
+
if (typeof name === 'string') {
|
|
117
|
+
params[name] = part;
|
|
81
118
|
}
|
|
82
|
-
return noRoute();
|
|
83
|
-
}
|
|
84
|
-
if (isWildcard && i === len - 1) {
|
|
85
|
-
break;
|
|
86
119
|
}
|
|
87
|
-
|
|
88
|
-
|
|
120
|
+
}
|
|
121
|
+
const nextNode = node.children[part];
|
|
122
|
+
if (nextNode) {
|
|
123
|
+
if (isLast === true) {
|
|
124
|
+
// '/hello/*' => match '/hello'
|
|
125
|
+
if (nextNode.children['*'] !== undefined) {
|
|
126
|
+
handlers.push(...this.getHandlers(nextNode.children['*'], method));
|
|
127
|
+
}
|
|
128
|
+
handlers.push(...this.getHandlers(nextNode, method));
|
|
89
129
|
}
|
|
130
|
+
nextNodes.push(nextNode);
|
|
90
131
|
}
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
132
|
+
const next = {
|
|
133
|
+
nodes: nextNodes,
|
|
134
|
+
handlers: handlers,
|
|
135
|
+
params: params,
|
|
136
|
+
};
|
|
137
|
+
return next;
|
|
138
|
+
}
|
|
139
|
+
search(method, path) {
|
|
140
|
+
const handlers = [];
|
|
141
|
+
let params = {};
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
143
|
+
const curNode = this;
|
|
144
|
+
let curNodes = [curNode];
|
|
145
|
+
const parts = (0, url_1.splitPath)(path);
|
|
146
|
+
for (let i = 0, len = parts.length; i < len; i++) {
|
|
147
|
+
const p = parts[i];
|
|
148
|
+
const isLast = i === len - 1;
|
|
149
|
+
const tempNodes = [];
|
|
150
|
+
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
|
151
|
+
const res = this.next(curNodes[j], p, method, isLast);
|
|
152
|
+
if (res.nodes.length === 0) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
handlers.push(...res.handlers);
|
|
156
|
+
params = Object.assign(params, res.params);
|
|
157
|
+
tempNodes.push(...res.nodes);
|
|
158
|
+
}
|
|
159
|
+
curNodes = tempNodes;
|
|
94
160
|
}
|
|
95
|
-
|
|
161
|
+
if (handlers.length <= 0)
|
|
162
|
+
return null;
|
|
163
|
+
return new router_1.Result(handlers, params);
|
|
96
164
|
}
|
|
97
165
|
}
|
|
98
166
|
exports.Node = Node;
|
package/dist/router.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const METHOD_NAME_ALL: "ALL";
|
|
2
|
+
export declare const METHOD_NAME_ALL_LOWERCASE: "all";
|
|
2
3
|
export declare abstract class Router<T> {
|
|
3
4
|
abstract add(method: string, path: string, handler: T): void;
|
|
4
5
|
abstract match(method: string, path: string): Result<T> | null;
|
|
5
6
|
}
|
|
6
7
|
export declare class Result<T> {
|
|
7
|
-
|
|
8
|
+
handlers: T[];
|
|
8
9
|
params: Record<string, string>;
|
|
9
|
-
constructor(
|
|
10
|
+
constructor(handlers: T[], params: Record<string, string>);
|
|
10
11
|
}
|
package/dist/router.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Result = exports.Router = exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.Result = exports.Router = exports.METHOD_NAME_ALL_LOWERCASE = exports.METHOD_NAME_ALL = void 0;
|
|
4
|
+
exports.METHOD_NAME_ALL = 'ALL';
|
|
5
|
+
exports.METHOD_NAME_ALL_LOWERCASE = 'all';
|
|
5
6
|
class Router {
|
|
6
7
|
}
|
|
7
8
|
exports.Router = Router;
|
|
8
9
|
class Result {
|
|
9
|
-
constructor(
|
|
10
|
-
this.
|
|
10
|
+
constructor(handlers, params) {
|
|
11
|
+
this.handlers = handlers;
|
|
11
12
|
this.params = params;
|
|
12
13
|
}
|
|
13
14
|
}
|
package/dist/utils/body.js
CHANGED
|
@@ -7,10 +7,10 @@ const parseBody = async (r) => {
|
|
|
7
7
|
return await r.json();
|
|
8
8
|
}
|
|
9
9
|
else if (contentType.includes('application/text')) {
|
|
10
|
-
return r.text();
|
|
10
|
+
return await r.text();
|
|
11
11
|
}
|
|
12
12
|
else if (contentType.startsWith('text')) {
|
|
13
|
-
return r.text();
|
|
13
|
+
return await r.text();
|
|
14
14
|
}
|
|
15
15
|
else if (contentType.includes('form')) {
|
|
16
16
|
const form = {};
|
package/dist/utils/buffer.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export declare const equal: (a: ArrayBuffer, b: ArrayBuffer) => boolean;
|
|
2
2
|
export declare const timingSafeEqual: (a: string | object | boolean, b: string | object | boolean, hashFunction?: Function) => Promise<boolean>;
|
|
3
|
+
export declare const bufferToString: (buffer: ArrayBuffer) => string;
|
package/dist/utils/buffer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.timingSafeEqual = exports.equal = void 0;
|
|
3
|
+
exports.bufferToString = exports.timingSafeEqual = exports.equal = void 0;
|
|
4
4
|
const crypto_1 = require("../utils/crypto");
|
|
5
5
|
const equal = (a, b) => {
|
|
6
6
|
if (a === b) {
|
|
@@ -29,3 +29,11 @@ const timingSafeEqual = async (a, b, hashFunction) => {
|
|
|
29
29
|
return sa === sb && a === b;
|
|
30
30
|
};
|
|
31
31
|
exports.timingSafeEqual = timingSafeEqual;
|
|
32
|
+
const bufferToString = (buffer) => {
|
|
33
|
+
if (buffer instanceof ArrayBuffer) {
|
|
34
|
+
const enc = new TextDecoder('utf-8');
|
|
35
|
+
return enc.decode(buffer);
|
|
36
|
+
}
|
|
37
|
+
return buffer;
|
|
38
|
+
};
|
|
39
|
+
exports.bufferToString = bufferToString;
|
package/dist/utils/crypto.d.ts
CHANGED
|
@@ -6,6 +6,4 @@ declare type Data = string | object | boolean;
|
|
|
6
6
|
export declare const sha256: (data: Data) => Promise<string>;
|
|
7
7
|
export declare const sha1: (data: Data) => Promise<string>;
|
|
8
8
|
export declare const createHash: (data: Data, algorithm: Algorithm) => Promise<string>;
|
|
9
|
-
export declare const encodeBase64: (str: string) => string;
|
|
10
|
-
export declare const decodeBase64: (str: string) => string;
|
|
11
9
|
export {};
|
package/dist/utils/crypto.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.createHash = exports.sha1 = exports.sha256 = void 0;
|
|
4
4
|
const sha256 = async (data) => {
|
|
5
5
|
const algorithm = { name: 'SHA-256', alias: 'sha256' };
|
|
6
6
|
const hash = await (0, exports.createHash)(data, algorithm);
|
|
@@ -34,53 +34,3 @@ const createHash = async (data, algorithm) => {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
exports.createHash = createHash;
|
|
37
|
-
const encodeBase64 = (str) => {
|
|
38
|
-
if (str === null) {
|
|
39
|
-
throw new TypeError('1st argument of "encodeBase64" should not be null.');
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
const encoder = new TextEncoder();
|
|
43
|
-
const bytes = encoder.encode(str);
|
|
44
|
-
const length = bytes.byteLength;
|
|
45
|
-
let binary = '';
|
|
46
|
-
for (let i = 0; i < length; i++) {
|
|
47
|
-
binary += String.fromCharCode(bytes[i]);
|
|
48
|
-
}
|
|
49
|
-
return btoa(binary);
|
|
50
|
-
}
|
|
51
|
-
catch (_a) { }
|
|
52
|
-
try {
|
|
53
|
-
const { Buffer } = require('buffer');
|
|
54
|
-
return Buffer.from(str).toString('base64');
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
console.error('If you want to do "encodeBase64", polyfill "buffer" module.');
|
|
58
|
-
throw e;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
exports.encodeBase64 = encodeBase64;
|
|
62
|
-
const decodeBase64 = (str) => {
|
|
63
|
-
if (str === null) {
|
|
64
|
-
throw new TypeError('1st argument of "decodeBase64" should not be null.');
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
const text = atob(str);
|
|
68
|
-
const length = text.length;
|
|
69
|
-
const bytes = new Uint8Array(length);
|
|
70
|
-
for (let i = 0; i < length; i++) {
|
|
71
|
-
bytes[i] = text.charCodeAt(i);
|
|
72
|
-
}
|
|
73
|
-
const decoder = new TextDecoder();
|
|
74
|
-
return decoder.decode(bytes);
|
|
75
|
-
}
|
|
76
|
-
catch (_a) { }
|
|
77
|
-
try {
|
|
78
|
-
const { Buffer } = require('buffer');
|
|
79
|
-
return Buffer.from(str, 'base64').toString();
|
|
80
|
-
}
|
|
81
|
-
catch (e) {
|
|
82
|
-
console.error('If you want to do "decodeBase64", polyfill "buffer" module.');
|
|
83
|
-
throw e;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
exports.decodeBase64 = decodeBase64;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const encodeBase64: (str: string) => string;
|
|
2
|
+
export declare const decodeBase64: (str: string) => string;
|
|
3
|
+
export declare const encodeBase64URL: (str: string) => string;
|
|
4
|
+
export declare const decodeBase64URL: (str: string) => string;
|
|
5
|
+
export declare const utf8ToUint8Array: (str: string) => Uint8Array;
|
|
6
|
+
export declare const arrayBufferToBase64: (buf: ArrayBuffer) => Promise<string>;
|
|
7
|
+
export declare const arrayBufferToBase64URL: (buf: ArrayBuffer) => Promise<string>;
|
|
@@ -0,0 +1,105 @@
|
|
|
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 (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.arrayBufferToBase64URL = exports.arrayBufferToBase64 = exports.utf8ToUint8Array = exports.decodeBase64URL = exports.encodeBase64URL = exports.decodeBase64 = exports.encodeBase64 = void 0;
|
|
27
|
+
const encodeBase64 = (str) => {
|
|
28
|
+
if (str === null) {
|
|
29
|
+
throw new TypeError('1st argument of "encodeBase64" should not be null.');
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const encoder = new TextEncoder();
|
|
33
|
+
const bytes = encoder.encode(str);
|
|
34
|
+
return btoa(String.fromCharCode(...bytes));
|
|
35
|
+
}
|
|
36
|
+
catch (_a) { }
|
|
37
|
+
try {
|
|
38
|
+
const { Buffer } = require('buffer');
|
|
39
|
+
return Buffer.from(str).toString('base64');
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
console.error('If you want to do "encodeBase64", polyfill "buffer" module.');
|
|
43
|
+
throw e;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.encodeBase64 = encodeBase64;
|
|
47
|
+
const decodeBase64 = (str) => {
|
|
48
|
+
if (str === null) {
|
|
49
|
+
throw new TypeError('1st argument of "decodeBase64" should not be null.');
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const text = atob(str);
|
|
53
|
+
const bytes = new Uint8Array(text.split('').map((c) => c.charCodeAt(0)));
|
|
54
|
+
const decoder = new TextDecoder();
|
|
55
|
+
return decoder.decode(bytes);
|
|
56
|
+
}
|
|
57
|
+
catch (_a) { }
|
|
58
|
+
try {
|
|
59
|
+
const { Buffer } = require('buffer');
|
|
60
|
+
return Buffer.from(str, 'base64').toString();
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
console.error('If you want to do "decodeBase64", polyfill "buffer" module.');
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.decodeBase64 = decodeBase64;
|
|
68
|
+
const encodeBase64URL = (str) => {
|
|
69
|
+
return (0, exports.encodeBase64)(str).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
70
|
+
};
|
|
71
|
+
exports.encodeBase64URL = encodeBase64URL;
|
|
72
|
+
const decodeBase64URL = (str) => {
|
|
73
|
+
const pad = (s) => {
|
|
74
|
+
const diff = s.length % 4;
|
|
75
|
+
if (diff === 2) {
|
|
76
|
+
return `${s}==`;
|
|
77
|
+
}
|
|
78
|
+
if (diff === 3) {
|
|
79
|
+
return `${s}=`;
|
|
80
|
+
}
|
|
81
|
+
return s;
|
|
82
|
+
};
|
|
83
|
+
return (0, exports.decodeBase64)(pad(str).replace(/-/g, '+').replace('_', '/'));
|
|
84
|
+
};
|
|
85
|
+
exports.decodeBase64URL = decodeBase64URL;
|
|
86
|
+
const utf8ToUint8Array = (str) => {
|
|
87
|
+
const encoder = new TextEncoder();
|
|
88
|
+
return encoder.encode(str);
|
|
89
|
+
};
|
|
90
|
+
exports.utf8ToUint8Array = utf8ToUint8Array;
|
|
91
|
+
const arrayBufferToBase64 = async (buf) => {
|
|
92
|
+
if (typeof btoa === 'function') {
|
|
93
|
+
return btoa(String.fromCharCode(...new Uint8Array(buf)));
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const { Buffer } = await Promise.resolve().then(() => __importStar(require('buffer')));
|
|
97
|
+
return Buffer.from(String.fromCharCode(...new Uint8Array(buf))).toString('base64');
|
|
98
|
+
}
|
|
99
|
+
catch (e) { }
|
|
100
|
+
};
|
|
101
|
+
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
102
|
+
const arrayBufferToBase64URL = async (buf) => {
|
|
103
|
+
return (await (0, exports.arrayBufferToBase64)(buf)).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
104
|
+
};
|
|
105
|
+
exports.arrayBufferToBase64URL = arrayBufferToBase64URL;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Jwt from './jwt';
|
|
@@ -0,0 +1,27 @@
|
|
|
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 (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Jwt = void 0;
|
|
27
|
+
exports.Jwt = __importStar(require("./jwt"));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AlgorithmTypes } from './types';
|
|
2
|
+
export declare const sign: (payload: unknown, secret: string, alg?: AlgorithmTypes) => Promise<string>;
|
|
3
|
+
export declare const verify: (token: string, secret: string, alg?: AlgorithmTypes) => Promise<boolean>;
|
|
4
|
+
export declare const decode: (token: string) => {
|
|
5
|
+
header: any;
|
|
6
|
+
payload: any;
|
|
7
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decode = exports.verify = exports.sign = void 0;
|
|
4
|
+
const encode_1 = require("../../utils/encode");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
const types_2 = require("./types");
|
|
7
|
+
var CryptoKeyFormat;
|
|
8
|
+
(function (CryptoKeyFormat) {
|
|
9
|
+
CryptoKeyFormat["RAW"] = "raw";
|
|
10
|
+
CryptoKeyFormat["PKCS8"] = "pkcs8";
|
|
11
|
+
CryptoKeyFormat["SPKI"] = "spki";
|
|
12
|
+
CryptoKeyFormat["JWK"] = "jwk";
|
|
13
|
+
})(CryptoKeyFormat || (CryptoKeyFormat = {}));
|
|
14
|
+
var CryptoKeyUsage;
|
|
15
|
+
(function (CryptoKeyUsage) {
|
|
16
|
+
CryptoKeyUsage["Ecrypt"] = "encrypt";
|
|
17
|
+
CryptoKeyUsage["Decrypt"] = "decrypt";
|
|
18
|
+
CryptoKeyUsage["Sign"] = "sign";
|
|
19
|
+
CryptoKeyUsage["Verify"] = "verify";
|
|
20
|
+
CryptoKeyUsage["Deriverkey"] = "deriveKey";
|
|
21
|
+
CryptoKeyUsage["DeriveBits"] = "deriveBits";
|
|
22
|
+
CryptoKeyUsage["WrapKey"] = "wrapKey";
|
|
23
|
+
CryptoKeyUsage["UnwrapKey"] = "unwrapKey";
|
|
24
|
+
})(CryptoKeyUsage || (CryptoKeyUsage = {}));
|
|
25
|
+
const param = (name) => {
|
|
26
|
+
switch (name.toUpperCase()) {
|
|
27
|
+
case 'HS256':
|
|
28
|
+
return {
|
|
29
|
+
name: 'HMAC',
|
|
30
|
+
hash: {
|
|
31
|
+
name: 'SHA-256',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
case 'HS384':
|
|
35
|
+
return {
|
|
36
|
+
name: 'HMAC',
|
|
37
|
+
hash: {
|
|
38
|
+
name: 'SHA-384',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
case 'HS512':
|
|
42
|
+
return {
|
|
43
|
+
name: 'HMAC',
|
|
44
|
+
hash: {
|
|
45
|
+
name: 'SHA-512',
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
default:
|
|
49
|
+
throw new types_2.JwtAlorithmNotImplemented(name);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const signing = async (data, secret, alg = types_1.AlgorithmTypes.HS256) => {
|
|
53
|
+
const cryptoKey = await crypto.subtle.importKey(CryptoKeyFormat.RAW, (0, encode_1.utf8ToUint8Array)(secret), param(alg), false, [CryptoKeyUsage.Sign]);
|
|
54
|
+
return await crypto.subtle.sign(param(alg), cryptoKey, (0, encode_1.utf8ToUint8Array)(data));
|
|
55
|
+
};
|
|
56
|
+
const sign = async (payload, secret, alg = types_1.AlgorithmTypes.HS256) => {
|
|
57
|
+
const encodedPayload = await (0, encode_1.encodeBase64URL)(JSON.stringify(payload));
|
|
58
|
+
const encodedHeader = await (0, encode_1.encodeBase64URL)(JSON.stringify({ alg, typ: 'JWT' }));
|
|
59
|
+
const partialToken = `${encodedHeader}.${encodedPayload}`;
|
|
60
|
+
const signature = await (0, encode_1.arrayBufferToBase64URL)(await signing(partialToken, secret, alg));
|
|
61
|
+
return `${partialToken}.${signature}`;
|
|
62
|
+
};
|
|
63
|
+
exports.sign = sign;
|
|
64
|
+
const verify = async (token, secret, alg = types_1.AlgorithmTypes.HS256) => {
|
|
65
|
+
const tokenParts = token.split('.');
|
|
66
|
+
if (tokenParts.length !== 3) {
|
|
67
|
+
throw new types_2.JwtTokenInvalid(token);
|
|
68
|
+
}
|
|
69
|
+
const { payload } = (0, exports.decode)(token);
|
|
70
|
+
if (payload.nbf && payload.nbf > Math.floor(Date.now() / 1000)) {
|
|
71
|
+
throw new types_2.JwtTokenNotBefore(token);
|
|
72
|
+
}
|
|
73
|
+
if (payload.exp && payload.exp <= Math.floor(Date.now() / 1000)) {
|
|
74
|
+
throw new types_2.JwtTokenExpired(token);
|
|
75
|
+
}
|
|
76
|
+
const signature = await (0, encode_1.arrayBufferToBase64URL)(await signing(tokenParts.slice(0, 2).join('.'), secret, alg));
|
|
77
|
+
if (signature !== tokenParts[2]) {
|
|
78
|
+
throw new types_2.JwtTokenSignatureMismatched(token);
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
};
|
|
82
|
+
exports.verify = verify;
|
|
83
|
+
// eslint-disable-next-line
|
|
84
|
+
const decode = (token) => {
|
|
85
|
+
try {
|
|
86
|
+
const [h, p] = token.split('.');
|
|
87
|
+
const header = JSON.parse((0, encode_1.decodeBase64URL)(h));
|
|
88
|
+
const payload = JSON.parse((0, encode_1.decodeBase64URL)(p));
|
|
89
|
+
return {
|
|
90
|
+
header,
|
|
91
|
+
payload,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
throw new types_2.JwtTokenInvalid(token);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
exports.decode = decode;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare class JwtAlorithmNotImplemented extends Error {
|
|
2
|
+
constructor(token: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class JwtTokenInvalid extends Error {
|
|
5
|
+
constructor(token: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class JwtTokenNotBefore extends Error {
|
|
8
|
+
constructor(token: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class JwtTokenExpired extends Error {
|
|
11
|
+
constructor(token: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class JwtTokenSignatureMismatched extends Error {
|
|
14
|
+
constructor(token: string);
|
|
15
|
+
}
|
|
16
|
+
export declare enum AlgorithmTypes {
|
|
17
|
+
HS256 = "HS256",
|
|
18
|
+
HS384 = "HS384",
|
|
19
|
+
HS512 = "HS512"
|
|
20
|
+
}
|