feat: 增加 cert:generatearduino:install 脚本

This commit is contained in:
王立帮
2025-05-08 23:18:05 +08:00
parent a7bc967378
commit c79fcd89dc
31 changed files with 1270 additions and 194 deletions

View File

@@ -1,7 +1,7 @@
import fs from 'node:fs';
import path from 'node:path';
import MString from './mstring';
import { ARDUINO } from './config';
import MString from './mstring.js';
import { ARDUINO } from './config.js';
const Boards = {};

View File

@@ -1,11 +1,32 @@
import os from 'node:os';
import CONFIG from '../user/config.json';
import path from 'node:path';
import fsExtra from 'fs-extra';
function processConfig(data) {
for (let i in data.path) {
if (data.path[i] instanceof String) {
data.path[i] = path.resolve(process.cwd(), data.path[i]);
} else if (data.path[i] instanceof Array) {
for (let j in data.path[i]) {
if (!(data.path[i][j] instanceof String)) {
continue;
}
data.path[i][j] = path.resolve(process.cwd(), data.path[i][j]);
}
}
}
return data;
}
const CONFIG = fsExtra.readJSONSync(path.resolve(process.cwd(), 'config.json'));
export const DEBUG = CONFIG.debug;
export const ARDUINO = CONFIG.arduino;
export const MICROPYTHON = CONFIG.micropython;
export const PYTHON = CONFIG.python;
export const ARDUINO = processConfig(CONFIG.arduino);
export const MICROPYTHON = processConfig(CONFIG.micropython);
export const PYTHON = processConfig(CONFIG.python);
export const CURRENT_PLANTFORM = os.platform();
export const TEMP_PATH = CONFIG.tempPath;
export const CLIENT_PATH = CONFIG.clientPath;
export const TEMP_PATH = path.resolve(process.cwd(), CONFIG.tempPath);
export const CLIENT_PATH = path.resolve(process.cwd(), CONFIG.clientPath);
export const CERTS_PATH = path.resolve(process.cwd(), 'certs');
export const PORT = CONFIG.port;
export const MODE = CONFIG.mode;

View File

@@ -1,4 +1,4 @@
import { DEBUG } from './config';
import { DEBUG } from './config.js';
const Debug = {};

View File

@@ -1,4 +1,4 @@
import Events from './events';
import Events from './events.js';
export default class EventsBase {

View File

@@ -1,8 +1,7 @@
// import mitt from 'mitt';
import _ from 'lodash';
import shortid from 'shortid';
import Debug from './debug';
import Registry from './registry';
import Debug from './debug.js';
import Registry from './registry.js';
export default class Events {

View File

@@ -1,4 +1,4 @@
import Debug from './debug';
import Debug from './debug.js';
export default class Registry {

View File

@@ -5,8 +5,8 @@ import {
ByteLengthParser
} from 'serialport';
import _ from 'lodash';
import EventsBase from './events-base';
import { CURRENT_PLANTFORM } from './config';
import EventsBase from './events-base.js';
import { CURRENT_PLANTFORM } from './config.js';
export default class Serial extends EventsBase {

View File

@@ -1,6 +1,6 @@
import mustache from 'mustache';
import Shell from './shell';
import { MICROPYTHON, PYTHON } from './config';
import Shell from './shell.js';
import { MICROPYTHON, PYTHON } from './config.js';
export default class ShellAmpy extends Shell {

View File

@@ -1,6 +1,6 @@
import _ from 'lodash';
import Shell from './shell';
import { ARDUINO } from './config';
import Shell from './shell.js';
import { ARDUINO } from './config.js';
export default class ShellArduino extends Shell {

View File

@@ -1,7 +1,7 @@
import path from 'node:path';
import Shell from './shell';
import MString from './mstring';
import { MICROPYTHON, PYTHON, CLIENT_PATH } from './config';
import Shell from './shell.js';
import MString from './mstring.js';
import { MICROPYTHON, PYTHON, CLIENT_PATH } from './config.js';
export default class ShellMicroPython extends Shell {

View File

@@ -1,6 +1,6 @@
import { execFile, exec } from 'node:child_process';
import EventsBase from './events-base';
import { CURRENT_PLANTFORM } from './config';
import EventsBase from './events-base.js';
import { CURRENT_PLANTFORM } from './config.js';
export default class Shell extends EventsBase {

View File

@@ -1,17 +1,17 @@
import { Server } from 'socket.io';
import to from 'await-to-js';
import { to } from 'await-to-js';
import { usb } from 'usb';
import path from 'node:path';
import fsExtra from 'fs-extra';
import Serial from './serial';
import Debug from './debug';
import Registry from './registry';
import ShellArduino from './shell-arduino';
import ShellMicroPython from './shell-micropython';
import ShellAmpy from './shell-ampy';
import MString from './mstring';
import Boards from './boards';
import { TEMP_PATH, CLIENT_PATH } from './config';
import Serial from './serial.js';
import Debug from './debug.js';
import Registry from './registry.js';
import ShellArduino from './shell-arduino.js';
import ShellMicroPython from './shell-micropython.js';
import ShellAmpy from './shell-ampy.js';
import MString from './mstring.js';
import Boards from './boards.js';
import { TEMP_PATH, CLIENT_PATH } from './config.js';
export default class Socket {
@@ -213,7 +213,6 @@ export default class Socket {
});
socket.on('arduino.compile', async (config, callback) => {
console.log(config)
const shell = this.#shellArduino_.getItem(socket.id);
config.path = config?.path ?? {};
config.path.build = path.resolve(TEMP_PATH, socket.id, 'build');

76
src/common/utils.js Normal file
View File

@@ -0,0 +1,76 @@
import os from 'node:os';
import path from 'node:path';
import fsExtra from 'fs-extra';
import fsPlus from 'fs-plus';
import forge from 'node-forge';
import shell from 'shelljs';
import _ from 'lodash';
import { CERTS_PATH } from './config.js';
export function getDefaultHosts() {
const interfaceDict = os.networkInterfaces();
const addresses = [];
for (const key in interfaceDict) {
const interfaces = interfaceDict[key];
if (interfaces) {
for (const item of interfaces) {
const family = item.family;
if (family === 'IPv4') {
addresses.push(item.address);
}
}
}
}
return ['localhost', ...addresses];
}
function generateCertificate() {
fsExtra.ensureDirSync(CERTS_PATH);
shell.cd(CERTS_PATH);
shell.exec(`mkcert -key-file server.key -cert-file server.crt ${getDefaultHosts().join(' ')}`);
console.log('new certificate generated successfully!');
const certPem = fsExtra.readFileSync(path.resolve(CERTS_PATH, 'server.crt'));
const keyPem = fsExtra.readFileSync(path.resolve(CERTS_PATH, 'server.key'));
return {
key: keyPem,
cert: certPem
};
}
export function getCertificate() {
const crtPath = path.resolve(CERTS_PATH, 'server.crt');
const keyPath = path.resolve(CERTS_PATH, 'server.key');
let data = {};
if (!fsPlus.isFileSync(crtPath) || !fsPlus.isFileSync(keyPath)) {
data = generateCertificate();
} else {
data.cert = fsExtra.readFileSync(crtPath);
data.key = fsExtra.readFileSync(keyPath);
}
const cert = forge.pki.certificateFromPem(data.cert);
const now = new Date();
const notBefore = cert.validity.notBefore;
const notAfter = cert.validity.notAfter;
if (now < notBefore || now > notAfter) {
data = generateCertificate();
}
const sanExt = cert.extensions.find(ext => ext.name === 'subjectAltName');
if (sanExt && sanExt.altNames) {
const hosts = [];
for (let item of sanExt.altNames) {
if (item.type === 2) {
hosts.push(item.value);
} else if (item.type === 7) {
hosts.push(item.ip);
}
}
const currentHosts = getDefaultHosts();
if (_.xor(currentHosts, hosts).length !== 0) {
data = generateCertificate();
}
} else {
data = generateCertificate();
}
return data;
}

View File

@@ -1,44 +1,72 @@
import express from 'express';
import path from 'node:path';
import * as url from 'node:url';
import { readFileSync } from 'node:fs';
import { createServer } from 'node:https';
import Socket from './common/socket';
import path from 'node:path';
import fsExtra from 'fs-extra';
import express from 'express';
import Socket from './common/socket.js';
import { getCertificate } from './common/utils.js';
import { CLIENT_PATH, PORT, MODE } from './common/config.js';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const __dirname = path.dirname(url.fileURLToPath(new URL(import.meta.url)));
const app = express();
const httpsServer = createServer({
key: readFileSync(path.resolve(__dirname, '../certs/server.key')),
cert: readFileSync(path.resolve(__dirname, '../certs/server.crt'))
}, app);
if (CLIENT_PATH) {
app.use(express.static(CLIENT_PATH));
}
const httpsServer = createServer(getCertificate(), app);
const socket = new Socket(httpsServer, {
path: '/mixly-socket/',
maxHttpBufferSize: 1e8,
cors: {
origin: '*',
methods: ['GET', 'POST'],
transports: ['websocket', 'polling', 'flashsocket'],
credentials: true
}
});
if (MODE !== 'static') {
const socket = new Socket(httpsServer, {
path: '/mixly-socket/',
maxHttpBufferSize: 1e8,
cors: {
origin: '*',
methods: ['GET', 'POST'],
transports: ['websocket', 'polling', 'flashsocket'],
credentials: true
}
});
const io = socket.getIO();
const io = socket.getIO();
function close() {
io.close(() => {
console.log('Socket服务已关闭');
process.exit(0);
process.on('SIGINT', () => {
io.close(() => {
console.log('Socket服务已关闭');
process.exit(0);
});
});
process.on('SIGTERM', () => {
io.close(() => {
console.log('Socket服务已关闭');
process.exit(0);
});
});
}
process.on('SIGINT', () => {
close();
const mixlyConfigPath = path.resolve(CLIENT_PATH, 'sw-config.json');
const mixlyConfig = fsExtra.readJSONSync(mixlyConfigPath);
if (MODE === 'web-compiler') {
mixlyConfig['webCompiler']['enabled'] = true;
mixlyConfig['webCompiler']['url'] = `wss://127.0.0.1:${PORT}`;
mixlyConfig['webSocket']['enabled'] = false;
} else if (MODE === 'web-socket') {
mixlyConfig['webCompiler']['enabled'] = false;
mixlyConfig['webSocket']['url'] = `wss://127.0.0.1:${PORT}`;
mixlyConfig['webSocket']['enabled'] = true;
} else {
mixlyConfig['webCompiler']['enabled'] = false;
mixlyConfig['webSocket']['enabled'] = false;
}
fsExtra.writeJSONSync(mixlyConfigPath, mixlyConfig, {
spaces: ' '
});
process.on('SIGTERM', () => {
close();
});
httpsServer.listen(4000);
httpsServer.listen(PORT);
if (CLIENT_PATH) {
console.log(`Static服务器正在运行: https://127.0.0.1:${PORT}`);
}
if (MODE !== 'static') {
console.log(`Socket.io服务器正在运行: wss://127.0.0.1:${PORT}/mixly-socket`);
}

View File

@@ -1,27 +0,0 @@
{
"debug": true,
"arduino": {
"path": {
"folder": "D:/gitee/arduino-cli-win32/arduino-cli",
"cli": "D:/gitee/arduino-cli-win32/arduino-cli/arduino-cli.exe",
"libraries": [
"D:/gitee/arduino-cli-win32/arduino-cli/libraries"
],
"cache": "D:/gitee/arduino-cli-win32/arduino-cli/cache",
"config": "D:/gitee/arduino-cli-win32/arduino-cli/arduino-cli.json"
}
},
"micropython": {
"path": {
"ampy": "D:/gitee/mixly3.0-win32-x64/resources/app/src/tools/python/ampy_main.py",
"esptool": "D:/gitee/mixly3.0-win32-x64/resources/app/src/tools/python/esptool_main.py"
}
},
"python": {
"path": {
"cli": "D:/gitee/mixly3.0-win32-x64/mixpyBuild/win_python3/python3.exe"
}
},
"tempPath": "D:/gitee/mixly3-server/temp",
"clientPath": "D:/gitee/mixly3.0-win32-x64/resources/app/src"
}