const fs = require('fs'); const os = require('os'); const path = require('path'); const { pathToFileURL } = require('url'); const REPOSITORY_ROOT = path.resolve(__dirname, '../../..'); const SETUP_MODULE_PATH = path.join(REPOSITORY_ROOT, 'scripts', 'setup-remote.mjs'); const RESTART_MARKER_PATH = path.join(REPOSITORY_ROOT, '.remote-access', 'restart-requested.json'); const DEFAULT_BOOTSTRAP_ENDPOINT = 'https://ck.yydd.ai:8443/v1/enroll'; function normalizeEndpoint(value) { const endpoint = new URL(String(value || DEFAULT_BOOTSTRAP_ENDPOINT).trim()); if (endpoint.protocol !== 'https:' || endpoint.username || endpoint.password) { throw new Error('配置请求地址必须是没有内嵌账号密码的 HTTPS 地址'); } return endpoint.toString(); } async function enrollRemoteInstallation(input = {}) { const endpoint = normalizeEndpoint(input.endpoint); const apiKey = String(input.apiKey || '').trim(); const label = String(input.label || os.hostname()).trim(); if (!apiKey) throw new Error('请输入部署 Key'); if (!label || label.length > 80) throw new Error('设备名称必须为 1 到 80 个字符'); const setupModule = await import(pathToFileURL(SETUP_MODULE_PATH).href); const { enrollment, connection } = await setupModule.configureRemoteAccess({ endpoint, key: apiKey, label, replace: false, }); return { installationId: enrollment.installation_id, certificateValidUntil: enrollment.ssh.valid_until, systemDatabase: { host: '127.0.0.1', port: connection.localDatabasePort, database: enrollment.database.name, }, redis: { host: enrollment.redis.host, port: Number(enrollment.redis.port), tls: true, }, adminUsername: enrollment.application_admin.username, adminPassword: enrollment.application_admin.password, }; } function scheduleRemoteRestart() { fs.mkdirSync(path.dirname(RESTART_MARKER_PATH), { recursive: true, mode: 0o700 }); fs.writeFileSync( RESTART_MARKER_PATH, `${JSON.stringify({ requestedAt: new Date().toISOString() })}\n`, { mode: 0o600 } ); fs.chmodSync(RESTART_MARKER_PATH, 0o600); } module.exports = { DEFAULT_BOOTSTRAP_ENDPOINT, enrollRemoteInstallation, normalizeEndpoint, scheduleRemoteRestart, };