feat: 更新sign的模块
This commit is contained in:
parent
780d744a16
commit
926c0a09cd
5
.gitignore
vendored
5
.gitignore
vendored
@ -3,4 +3,7 @@ src/app.config.json5
|
|||||||
dist
|
dist
|
||||||
.npmrc
|
.npmrc
|
||||||
|
|
||||||
.turbo
|
.turbo
|
||||||
|
|
||||||
|
https-cert.pem
|
||||||
|
https-key.pem
|
35
demo/simple/src/apps-https/app.ts
Normal file
35
demo/simple/src/apps-https/app.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Route, App } from '@kevisual/router';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
const app = new App({
|
||||||
|
serverOptions: {
|
||||||
|
cors: {},
|
||||||
|
isHTTPS: true,
|
||||||
|
httpsKey: readFileSync('https-key.pem', 'utf8'),
|
||||||
|
httpsCert: readFileSync('https-cert.pem', 'utf-8'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
app.listen(4003, '0.0.0.0', () => {
|
||||||
|
console.log(`http://localhost:4003/api/router?path=demo&key=02`);
|
||||||
|
console.log(`http://localhost:4003/api/router?path=demo&key=01`);
|
||||||
|
console.log(`https://192.168.31.220:4003/api/router?path=demo&key=01`);
|
||||||
|
});
|
||||||
|
const route01 = new Route('demo', '01');
|
||||||
|
route01.run = async (ctx) => {
|
||||||
|
ctx.body = '01';
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
app.use(
|
||||||
|
'demo',
|
||||||
|
async (ctx) => {
|
||||||
|
ctx.body = '01';
|
||||||
|
return ctx;
|
||||||
|
},
|
||||||
|
{ key: '01' },
|
||||||
|
);
|
||||||
|
|
||||||
|
const route02 = new Route('demo', '02');
|
||||||
|
route02.run = async (ctx) => {
|
||||||
|
ctx.body = '02';
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
app.addRoute(route02);
|
6
demo/simple/src/apps-https/create-sign.ts
Normal file
6
demo/simple/src/apps-https/create-sign.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { createCert } from '@kevisual/router/sign';
|
||||||
|
import { writeFileSync } from 'fs';
|
||||||
|
const { key, cert } = createCert();
|
||||||
|
|
||||||
|
writeFileSync('https-key.pem', key);
|
||||||
|
writeFileSync('https-cert.pem', cert);
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "@kevisual/router",
|
"name": "@kevisual/router",
|
||||||
"version": "0.0.4-alpha-8",
|
"version": "0.0.4",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"module": "dist/index.js",
|
"module": "dist/index.js",
|
||||||
@ -41,6 +41,7 @@
|
|||||||
"url": "git+https://github.com/abearxiong/kevisual-router.git"
|
"url": "git+https://github.com/abearxiong/kevisual-router.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"selfsigned": "^2.4.1",
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
@ -54,6 +55,10 @@
|
|||||||
"./browser": {
|
"./browser": {
|
||||||
"import": "./dist/router-browser.js",
|
"import": "./dist/router-browser.js",
|
||||||
"require": "./dist/router-browser.js"
|
"require": "./dist/router-browser.js"
|
||||||
|
},
|
||||||
|
"./sign": {
|
||||||
|
"import": "./dist/router-sign.js",
|
||||||
|
"require": "./dist/router-sign.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -51,4 +51,26 @@ export default [
|
|||||||
},
|
},
|
||||||
plugins: [dts()],
|
plugins: [dts()],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: 'src/sign.ts',
|
||||||
|
output: {
|
||||||
|
file: 'dist/router-sign.js',
|
||||||
|
format: 'es',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
resolve({
|
||||||
|
browser: false,
|
||||||
|
}),
|
||||||
|
commonjs(),
|
||||||
|
typescript(),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 'src/sign.ts',
|
||||||
|
output: {
|
||||||
|
file: 'dist/router-sign.d.ts',
|
||||||
|
format: 'es',
|
||||||
|
},
|
||||||
|
plugins: [dts()],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
@ -14,6 +14,9 @@ type AppOptions<T = {}> = {
|
|||||||
path?: string;
|
path?: string;
|
||||||
cors?: Cors;
|
cors?: Cors;
|
||||||
handle?: any;
|
handle?: any;
|
||||||
|
isHTTPS?: boolean;
|
||||||
|
httpsKey?: string;
|
||||||
|
httpsCert?: string;
|
||||||
};
|
};
|
||||||
io?: boolean;
|
io?: boolean;
|
||||||
ioOpts?: { routerHandle?: RouterHandle; routerContext?: RouteContext<T>; path?: string };
|
ioOpts?: { routerHandle?: RouterHandle; routerContext?: RouteContext<T>; path?: string };
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import http, { IncomingMessage, ServerResponse } from 'http';
|
import http, { IncomingMessage, ServerResponse } from 'http';
|
||||||
|
import https from 'https';
|
||||||
import { handleServer } from './handle-server.ts';
|
import { handleServer } from './handle-server.ts';
|
||||||
|
|
||||||
export type Listener = (...args: any[]) => void;
|
export type Listener = (...args: any[]) => void;
|
||||||
|
|
||||||
export type Cors = {
|
export type Cors = {
|
||||||
@ -9,12 +9,15 @@ export type Cors = {
|
|||||||
*/
|
*/
|
||||||
origin?: string | undefined;
|
origin?: string | undefined;
|
||||||
};
|
};
|
||||||
type ServerOpts = {
|
export type ServerOpts = {
|
||||||
/**path default `/api/router` */
|
/**path default `/api/router` */
|
||||||
path?: string;
|
path?: string;
|
||||||
/**handle Fn */
|
/**handle Fn */
|
||||||
handle?: (msg?: { path: string; key?: string; [key: string]: any }) => any;
|
handle?: (msg?: { path: string; key?: string; [key: string]: any }) => any;
|
||||||
cors?: Cors;
|
cors?: Cors;
|
||||||
|
isHTTPS?: boolean;
|
||||||
|
httpsKey?: string;
|
||||||
|
httpsCert?: string;
|
||||||
};
|
};
|
||||||
export const resultError = (error: string, code = 500) => {
|
export const resultError = (error: string, code = 500) => {
|
||||||
const r = {
|
const r = {
|
||||||
@ -31,10 +34,20 @@ export class Server {
|
|||||||
private _callback: any;
|
private _callback: any;
|
||||||
private cors: Cors;
|
private cors: Cors;
|
||||||
private hasOn = false;
|
private hasOn = false;
|
||||||
|
private isHTTPS = false;
|
||||||
|
private options = {
|
||||||
|
key: '',
|
||||||
|
cert: '',
|
||||||
|
};
|
||||||
constructor(opts?: ServerOpts) {
|
constructor(opts?: ServerOpts) {
|
||||||
this.path = opts?.path || '/api/router';
|
this.path = opts?.path || '/api/router';
|
||||||
this.handle = opts?.handle;
|
this.handle = opts?.handle;
|
||||||
this.cors = opts?.cors;
|
this.cors = opts?.cors;
|
||||||
|
this.isHTTPS = opts?.isHTTPS || false;
|
||||||
|
this.options = {
|
||||||
|
key: opts?.httpsKey || '',
|
||||||
|
cert: opts?.httpsCert || '',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
||||||
@ -45,11 +58,29 @@ export class Server {
|
|||||||
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
||||||
listen(handle: any, listeningListener?: () => void): void;
|
listen(handle: any, listeningListener?: () => void): void;
|
||||||
listen(...args: any[]) {
|
listen(...args: any[]) {
|
||||||
this._server = http.createServer();
|
this._server = this.createServer();
|
||||||
const callback = this.createCallback();
|
const callback = this.createCallback();
|
||||||
this._server.on('request', callback);
|
this._server.on('request', callback);
|
||||||
this._server.listen(...args);
|
this._server.listen(...args);
|
||||||
}
|
}
|
||||||
|
createServer() {
|
||||||
|
let server: http.Server | https.Server;
|
||||||
|
if (this.isHTTPS) {
|
||||||
|
if (this.options.key && this.options.cert) {
|
||||||
|
server = https.createServer({
|
||||||
|
key: this.options.key,
|
||||||
|
cert: this.options.cert,
|
||||||
|
});
|
||||||
|
console.log('https server');
|
||||||
|
return server;
|
||||||
|
} else {
|
||||||
|
console.error('https key and cert is required');
|
||||||
|
console.log('downgrade to http');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server = http.createServer();
|
||||||
|
return server;
|
||||||
|
}
|
||||||
setHandle(handle?: any) {
|
setHandle(handle?: any) {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
}
|
}
|
||||||
@ -65,7 +96,7 @@ export class Server {
|
|||||||
if (req.url === '/favicon.ico') {
|
if (req.url === '/favicon.ico') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.headersSent) {
|
if (res.headersSent) {
|
||||||
// 程序已经在其他地方响应了
|
// 程序已经在其他地方响应了
|
||||||
return;
|
return;
|
||||||
@ -130,7 +161,7 @@ export class Server {
|
|||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*/
|
||||||
on(listener: Listener | Listener[]) {
|
on(listener: Listener | Listener[]) {
|
||||||
this._server = this._server || http.createServer();
|
this._server = this._server || this.createServer();
|
||||||
this._server.removeAllListeners('request');
|
this._server.removeAllListeners('request');
|
||||||
this.hasOn = true;
|
this.hasOn = true;
|
||||||
if (Array.isArray(listener)) {
|
if (Array.isArray(listener)) {
|
||||||
|
46
src/sign.ts
Normal file
46
src/sign.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { generate } from 'selfsigned';
|
||||||
|
|
||||||
|
type Attributes = {
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
type AltNames = {
|
||||||
|
type: number;
|
||||||
|
value?: string;
|
||||||
|
ip?: string;
|
||||||
|
};
|
||||||
|
export const createCert = (attrs: Attributes[] = [], altNames: AltNames[] = []) => {
|
||||||
|
let attributes = [
|
||||||
|
{ name: 'commonName', value: '*' }, // 通配符域名
|
||||||
|
{ name: 'countryName', value: 'CN' }, // 国家代码
|
||||||
|
{ name: 'stateOrProvinceName', value: 'ZheJiang' }, // 州名
|
||||||
|
{ name: 'localityName', value: 'Hangzhou' }, // 城市名
|
||||||
|
{ name: 'organizationName', value: 'Envision' }, // 组织名
|
||||||
|
{ name: 'organizationalUnitName', value: 'IT' }, // 组织单位
|
||||||
|
...attrs,
|
||||||
|
];
|
||||||
|
// attribute 根据name去重复, 后面的覆盖前面的
|
||||||
|
attributes = attributes.filter((item, index, self) => {
|
||||||
|
return self.findIndex((t) => t.name === item.name) === index;
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
days: 365, // 证书有效期(天)
|
||||||
|
extensions: [
|
||||||
|
{
|
||||||
|
name: 'subjectAltName',
|
||||||
|
altNames: [
|
||||||
|
{ type: 2, value: '*' }, // DNS 名称
|
||||||
|
{ type: 2, value: 'localhost' }, // DNS
|
||||||
|
{ type: 7, ip: '127.0.0.1' }, // IP 地址
|
||||||
|
...altNames,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const pems = generate(attributes, options);
|
||||||
|
return {
|
||||||
|
key: pems.private,
|
||||||
|
cert: pems.cert,
|
||||||
|
};
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user