style: 完成所有文件的lint

This commit is contained in:
claude-code-best
2026-05-01 21:39:30 +08:00
parent d136872cc9
commit 6182015005
1333 changed files with 68255 additions and 77882 deletions

View File

@@ -2,27 +2,27 @@
* Self-signed certificate generation for HTTPS support
*/
import { X509Certificate } from "node:crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { homedir, networkInterfaces } from "node:os";
import { join } from "node:path";
import { generate } from "selfsigned";
import { X509Certificate } from 'node:crypto'
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { homedir, networkInterfaces } from 'node:os'
import { join } from 'node:path'
import { generate } from 'selfsigned'
/**
* Get all LAN IPv4 addresses
*/
export function getLanIPs(): string[] {
const ips: string[] = [];
const nets = networkInterfaces();
const ips: string[] = []
const nets = networkInterfaces()
for (const name of Object.keys(nets)) {
for (const net of nets[name] || []) {
// Skip internal (loopback) and non-IPv4 addresses
if (!net.internal && net.family === "IPv4") {
ips.push(net.address);
if (!net.internal && net.family === 'IPv4') {
ips.push(net.address)
}
}
}
return ips;
return ips
}
/**
@@ -30,31 +30,31 @@ export function getLanIPs(): string[] {
* SAN format: "IP Address:192.168.1.100, IP Address:127.0.0.1, DNS:localhost"
*/
function extractSanIPs(x509: X509Certificate): string[] {
const san = x509.subjectAltName;
if (!san) return [];
const san = x509.subjectAltName
if (!san) return []
const ips: string[] = [];
const ips: string[] = []
// Parse "IP Address:x.x.x.x" entries from SAN string
const parts = san.split(", ");
const parts = san.split(', ')
for (const part of parts) {
const match = part.match(/^IP Address:(.+)$/);
const match = part.match(/^IP Address:(.+)$/)
if (match && match[1]) {
ips.push(match[1]);
ips.push(match[1])
}
}
return ips;
return ips
}
const CERT_DIR = join(homedir(), ".acp-proxy");
const KEY_PATH = join(CERT_DIR, "key.pem");
const CERT_PATH = join(CERT_DIR, "cert.pem");
const CERT_DIR = join(homedir(), '.acp-proxy')
const KEY_PATH = join(CERT_DIR, 'key.pem')
const CERT_PATH = join(CERT_DIR, 'cert.pem')
// Certificate validity in days
const CERT_VALIDITY_DAYS = 365;
const CERT_VALIDITY_DAYS = 365
export interface TlsOptions {
key: string;
cert: string;
key: string
cert: string
}
/**
@@ -64,111 +64,119 @@ export interface TlsOptions {
export async function getOrCreateCertificate(): Promise<TlsOptions> {
// Ensure directory exists
if (!existsSync(CERT_DIR)) {
mkdirSync(CERT_DIR, { recursive: true });
mkdirSync(CERT_DIR, { recursive: true })
}
// Check if certificates already exist and are still valid
if (existsSync(KEY_PATH) && existsSync(CERT_PATH)) {
const certPem = readFileSync(CERT_PATH, "utf-8");
const keyPem = readFileSync(KEY_PATH, "utf-8");
const certPem = readFileSync(CERT_PATH, 'utf-8')
const keyPem = readFileSync(KEY_PATH, 'utf-8')
try {
const x509 = new X509Certificate(certPem);
const validTo = new Date(x509.validTo);
const now = new Date();
const x509 = new X509Certificate(certPem)
const validTo = new Date(x509.validTo)
const now = new Date()
// Check if cert is expired or will expire within 7 days
const daysUntilExpiry = Math.floor((validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
const daysUntilExpiry = Math.floor(
(validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),
)
if (daysUntilExpiry <= 7) {
// Certificate expired or expiring soon
console.log(`⚠️ Certificate ${daysUntilExpiry <= 0 ? "expired" : `expires in ${daysUntilExpiry} days`}, regenerating...`);
console.log(
`⚠️ Certificate ${daysUntilExpiry <= 0 ? 'expired' : `expires in ${daysUntilExpiry} days`}, regenerating...`,
)
} else {
// Check if current LAN IPs are in the certificate's SAN
const currentLanIPs = getLanIPs();
const certSanIPs = extractSanIPs(x509);
const currentLanIPs = getLanIPs()
const certSanIPs = extractSanIPs(x509)
// Check if all current LAN IPs are covered by the certificate
const missingIPs = currentLanIPs.filter(ip => !certSanIPs.includes(ip));
const missingIPs = currentLanIPs.filter(ip => !certSanIPs.includes(ip))
if (missingIPs.length === 0) {
console.log(`🔐 Using existing certificate from ${CERT_DIR}`);
console.log(` Valid for ${daysUntilExpiry} more days`);
return { key: keyPem, cert: certPem };
console.log(`🔐 Using existing certificate from ${CERT_DIR}`)
console.log(` Valid for ${daysUntilExpiry} more days`)
return { key: keyPem, cert: certPem }
}
// LAN IP changed, regenerate
console.log(`⚠️ LAN IP changed (missing: ${missingIPs.join(", ")}), regenerating certificate...`);
console.log(
`⚠️ LAN IP changed (missing: ${missingIPs.join(', ')}), regenerating certificate...`,
)
}
} catch {
// Failed to parse certificate, regenerate
console.log(`⚠️ Invalid certificate, regenerating...`);
console.log(`⚠️ Invalid certificate, regenerating...`)
}
}
// Generate new self-signed certificate
console.log(`🔐 Generating self-signed certificate...`);
console.log(`🔐 Generating self-signed certificate...`)
const attrs = [{ name: "commonName", value: "ACP Proxy Server" }];
const attrs = [{ name: 'commonName', value: 'ACP Proxy Server' }]
// Calculate expiry date
const notAfterDate = new Date();
notAfterDate.setDate(notAfterDate.getDate() + CERT_VALIDITY_DAYS);
const notAfterDate = new Date()
notAfterDate.setDate(notAfterDate.getDate() + CERT_VALIDITY_DAYS)
// Build altNames: localhost + loopback + all LAN IPs
const altNames: Array<{ type: 1 | 2 | 6 | 7; value?: string; ip?: string }> = [
{ type: 2, value: "localhost" },
{ type: 7, ip: "127.0.0.1" },
{ type: 7, ip: "::1" },
];
const altNames: Array<{ type: 1 | 2 | 6 | 7; value?: string; ip?: string }> =
[
{ type: 2, value: 'localhost' },
{ type: 7, ip: '127.0.0.1' },
{ type: 7, ip: '::1' },
]
// Add all current LAN IPs
const lanIPs = getLanIPs();
const lanIPs = getLanIPs()
for (const ip of lanIPs) {
altNames.push({ type: 7, ip });
altNames.push({ type: 7, ip })
}
if (lanIPs.length > 0) {
console.log(` Including LAN IPs: ${lanIPs.join(", ")}`);
console.log(` Including LAN IPs: ${lanIPs.join(', ')}`)
}
const pems = await generate(attrs, {
keySize: 2048,
notAfterDate,
algorithm: "sha256",
algorithm: 'sha256',
extensions: [
{
name: "basicConstraints",
name: 'basicConstraints',
cA: true,
},
{
name: "keyUsage",
name: 'keyUsage',
keyCertSign: true,
digitalSignature: true,
keyEncipherment: true,
},
{
name: "extKeyUsage",
name: 'extKeyUsage',
serverAuth: true,
},
{
name: "subjectAltName",
name: 'subjectAltName',
altNames,
},
],
});
})
// Save certificates
writeFileSync(KEY_PATH, pems.private);
writeFileSync(CERT_PATH, pems.cert);
writeFileSync(KEY_PATH, pems.private)
writeFileSync(CERT_PATH, pems.cert)
console.log(`✅ Certificate saved to ${CERT_DIR}`);
console.log(` Valid for ${CERT_VALIDITY_DAYS} days`);
console.log(` ⚠️ First access will show a security warning - click "Advanced" → "Proceed"`);
console.log(`✅ Certificate saved to ${CERT_DIR}`)
console.log(` Valid for ${CERT_VALIDITY_DAYS} days`)
console.log(
` ⚠️ First access will show a security warning - click "Advanced" → "Proceed"`,
)
return {
key: pems.private,
cert: pems.cert,
};
}
}