aws-runtime-bridge 1.9.184 → 1.9.185

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/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ files 白名单),供调度中心「查看本次更新内容」弹窗按 `##
5
5
  展示。发布新版本时须在仓库中先写好 `## v<version>` 段(prepack-guard 校验缺段
6
6
  即阻断发布);Bridge 自更新成功后的运行时追加仅作为包内缺段时的兜底。
7
7
 
8
+ ## v1.9.185
9
+
10
+ _发布日期:2026-11-04_
11
+
12
+ ### 修复:已配对机器重启不再自毁配对(面板实例消失的根因)
13
+
14
+ 已配对机器(machineToken 自持凭据)优雅关闭时曾无条件调用 `/api/instances/unregister`
15
+ 注销实例,而 server 端该路径会整行删除登记行——`machineToken` 的 hash 就存在这一行上,
16
+ 行被删掉配对即被永久摧毁:重启后机器凭据注册被拒(invalid or revoked),面板上的实例
17
+ 也随之消失。本次两端同修:
18
+
19
+ - Bridge:注销时识别机器凭据目标(machineToken / credentialType=MACHINE_TOKEN),
20
+ **跳过自删登记行**——配对身份必须跨重启存活;Agent 离线由隧道断开与服务端重启同步兜底,
21
+ 真正下线机器请用管理页删除(Bearer 路径,带租户/负责人校验);
22
+ - Server:runtime token 自注销路径拒绝删除 MACHINE_TOKEN 行并返回明确错误
23
+ (兼容尚未升级的旧版 bridge,防止其重启时再毁配对);token 无效时不提前泄露
24
+ 实例的存在性与凭据类型,仍按既有路径走登录态校验。
25
+
26
+ ### 修复:票据里填写的实例名写回不再被旧主机名顶掉
27
+
28
+ server 配对响应的实例名以票据建议名为权威,但 bridge 写回配置用的是
29
+ `target.instanceName = target.instanceName || instanceName`——本机已有同址旧 target
30
+ (instanceName 为历史主机名,如此前用 API Key 注册过)时票据名永远写不进本地配置;
31
+ 下次注册(配对后立即重注册或重启)机器上报旧主机名,server 又按请求名覆盖登记行,
32
+ 用户在票据里填写的实例名就丢了。本次改为**无条件写回 server 响应名**,票据名在
33
+ 本地配置与面板登记行之间保持一致。
34
+
8
35
  ## v1.9.184
9
36
 
10
37
  _发布日期:2026-11-03_
@@ -1,2 +1,2 @@
1
- import{randomBytes as ce}from"node:crypto";import p from"node:fs";import N from"node:os";import w from"axios";import{v4 as ue}from"uuid";import{getActiveBridgeHttpPort as de,getAutoRegisterConfigFilePath as S,isDesktopAppMode as le,schedulerBaseUrl as m}from"../config.js";import{runExclusiveConfigWrite as D}from"../utils/config-write-queue.js";import{logger as a}from"../utils/logger.js";import{buildTargetKey as x,fingerprintUserKey as fe,serverUrlOfTargetKey as F}from"../utils/target-identity.js";import{clearRuntimeBinding as ge,clearScopedRuntimeAccessToken as me,getRuntimeAccessToken as G,getRuntimeBindingPublicState as pe,getScopedRuntimeAccessToken as q,listScopedRuntimeAccessTokens as ye,loadRuntimeBinding as M,normalizeSchedulerBaseUrl as T,saveRuntimeBinding as Y,saveScopedRuntimeAccessToken as H}from"./runtime-binding.js";const V={enabled:!1,serverUrl:m,preferSameLanIp:!0,maxRetries:3,retryInterval:2e3},d={registered:!1,registrations:{}};let k=[];const Ie=10*60*1e3,B=new Map;function X(){const e=Date.now();for(const[r,t]of B)t.expiresAt<=e&&B.delete(r)}function Je(){X();const e=[...k];for(const r of B.values())r.key&&!e.includes(r.key)&&e.push(r.key);return e}function qe(e){const r=String(e||"").trim();if(!r)return[];const t=K(),n=t.filter(s=>String(s.connectionKey||"").trim()===r);if(n.length>0)return n;X();const o=new Set;for(const[s,i]of B)i.key===r&&o.add(s);return o.size===0?[]:t.filter(s=>o.has(C(s)))}function Ye(){return k[0]??""}const Ae=3e4;function Q(){const e=Number(process.env.AWS_REGISTER_BACKGROUND_RETRY_INTERVAL);return Number.isFinite(e)&&e>0?e:Ae}const $=new Map;function Z(e){const r=e.serverUrl||m,t=C(e)||r;if($.has(t))return;const n=setTimeout(()=>{$.delete(t),Re(e,t)},Q());n.unref?.(),$.set(t,n)}async function Re(e,r){try{const t=K().find(n=>C(n)===r)||e;await J(t,{backgroundRetry:!0})}catch(t){a.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u5F02\u5E38: ${t.message}`),Z(e)}}function He(){for(const e of $.values())clearTimeout(e);$.clear()}function Se(e){const r=e.trim();if(r.length<8)return r;for(let t=1;t<=r.length/2;t++){if(r.length%t!==0)continue;const n=r.slice(0,t);let o=!0;for(let s=t;s<r.length;s+=t)if(r.slice(s,s+t)!==n){o=!1;break}if(o&&n.length<r.length)return n}return r}function Te(e){const r=g(e);if(!r)return r;const t=Se(r);return t!==r&&a.warn(`[AutoRegister] userKey \u7591\u4F3C\u88AB\u590D\u5236\u4E86\u4E24\u904D\uFF08\u957F\u5EA6 ${r.length} \u2192 ${t.length}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u53BB\u91CD\u3002\u8BF7\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6\u662F\u5426\u91CD\u590D\u7C98\u8D34\u3002`),t}function g(e){return e==null?void 0:String(e).trim()||void 0}function _(e){return T(e)}function ee(e){return Array.isArray(e.autoRegisterTargets)?e.autoRegisterTargets.filter(r=>!!(r&&typeof r=="object"&&!Array.isArray(r))):[]}function C(e){const r=e?.serverUrl||m;return x(r,e?.credentialId||e?.userKey)}function y(e){return e?.credentialId||e?.userKey}function P(e){if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["true","1","yes","y"].includes(r))return!0;if(["false","0","no","n"].includes(r))return!1}}function re(e){if(e==null||e==="")return;const r=Number(e);return Number.isFinite(r)?r:void 0}function O(e){const r=g(e.serverUrl)||g(e.schedulerBaseUrl),t=g(e.connectionKey)||g(e.password);return{enabled:P(e.enabled),serverUrl:r,tenantId:g(e.tenantId),userId:g(e.userId),userKey:Te(e.userKey),machineToken:g(e.machineToken),connectionKey:t,instanceName:g(e.instanceName),instanceId:g(e.instanceId),credentialId:g(e.credentialId),credentialRef:g(e.credentialRef),credentialType:g(e.credentialType),projectId:g(e.projectId),roleName:g(e.roleName),workspacePath:g(e.workspacePath),registerAddr:g(e.registerAddr),registerIp:g(e.registerIp),virtualIp:g(e.virtualIp),tunnel:P(e.tunnel),preferSameLanIp:P(e.preferSameLanIp),maxRetries:re(e.maxRetries),retryInterval:re(e.retryInterval)}}function te(){const e=S();try{if(!p.existsSync(e))return a.debug(`[AutoRegister] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;const r=p.readFileSync(e,"utf-8"),t=JSON.parse(r);return a.info(`[AutoRegister] \u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u914D\u7F6E: ${e}`),O(t)}catch(r){const t=r;return a.warn(`[AutoRegister] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${e}, error: ${t.message}`),null}}function he(){const e=S();try{if(!p.existsSync(e))return[];const r=p.readFileSync(e,"utf-8"),t=JSON.parse(r),n=O(t),o=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets:[];return o.length===0?n.userKey||n.machineToken?[n]:[]:o.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(s=>{const i=O(s);return{...n,...i,machineToken:i.machineToken||(i.userKey?void 0:n.machineToken),connectionKey:i.connectionKey}})}catch(r){const t=r;return a.warn(`[AutoRegister] \u8BFB\u53D6\u81EA\u52A8\u6CE8\u518C\u76EE\u6807\u5931\u8D25: ${e}, error: ${t.message}`),[]}}function Ve(){const e=S();if(!p.existsSync(e))return[];let r;try{r=JSON.parse(p.readFileSync(e,"utf-8"))}catch(i){return a.warn(`[AutoRegister] \u8BFB\u53D6 config.json \u5931\u8D25\uFF08targets \u6458\u8981\uFF09: ${i.message}`),[]}const t=O(r),n=Array.isArray(r.autoRegisterTargets)?r.autoRegisterTargets:[],o=n.length>0?n.filter(i=>!!(i&&typeof i=="object"&&!Array.isArray(i))).map(i=>{const c=O(i);return{...t,...c,machineToken:c.machineToken||(c.userKey?void 0:t.machineToken),connectionKey:c.connectionKey}}):t.userKey||t.machineToken?[t]:[],s=i=>{const c=String(i||"").trim();return c?c.length<=8?"****":`${c.slice(0,8)}****${c.slice(-4)}`:""};return o.map((i,c)=>({index:c,serverUrl:i.serverUrl||"",instanceName:i.instanceName||"",registerAddr:i.registerAddr||i.registerIp||i.virtualIp||"",tunnel:typeof i.tunnel=="boolean"?i.tunnel:null,userKeyMasked:s(i.userKey),machineTokenSet:!!String(i.machineToken||"").trim(),credentialType:i.credentialType||"",credentialId:i.credentialId||"",credentialRef:i.credentialRef||"",connectionKeySet:!!String(i.connectionKey||"").trim()}))}function ne(){const e={};return process.env.AWS_AUTO_REGISTER==="true"&&(e.enabled=!0),process.env.AWS_RUNTIME_SCHEDULER_BASE_URL&&(e.serverUrl=process.env.AWS_RUNTIME_SCHEDULER_BASE_URL),process.env.AWS_TENANT_ID&&(e.tenantId=process.env.AWS_TENANT_ID),process.env.AWS_USER_KEY&&(e.userKey=process.env.AWS_USER_KEY),process.env.AWS_BRIDGE_MACHINE_TOKEN&&(e.machineToken=process.env.AWS_BRIDGE_MACHINE_TOKEN),process.env.AWS_BRIDGE_CONNECTION_KEY&&(e.connectionKey=process.env.AWS_BRIDGE_CONNECTION_KEY),process.env.AWS_INSTANCE_NAME&&(e.instanceName=process.env.AWS_INSTANCE_NAME),process.env.AWS_PROJECT_NAME&&(e.projectId=process.env.AWS_PROJECT_NAME),process.env.AWS_ROLE_NAME&&(e.roleName=process.env.AWS_ROLE_NAME),process.env.AWS_WORKSPACE_PATH&&(e.workspacePath=process.env.AWS_WORKSPACE_PATH),process.env.AWS_REGISTER_ADDR&&(e.registerAddr=process.env.AWS_REGISTER_ADDR),process.env.AWS_REGISTER_IP&&(e.registerIp=process.env.AWS_REGISTER_IP),process.env.AWS_VIRTUAL_IP&&(e.virtualIp=process.env.AWS_VIRTUAL_IP),process.env.AWS_PREFER_SAME_LAN_IP&&(e.preferSameLanIp=P(process.env.AWS_PREFER_SAME_LAN_IP)??!0),process.env.AWS_REGISTER_MAX_RETRIES&&(e.maxRetries=parseInt(process.env.AWS_REGISTER_MAX_RETRIES,10)),process.env.AWS_REGISTER_RETRY_INTERVAL&&(e.retryInterval=parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL,10)),e}function W(){const e=te(),r=ne(),t={...V,...e||{},...r},n=t.instanceName||N.hostname();let o=!1;return process.env.AWS_AUTO_REGISTER!==void 0?o=process.env.AWS_AUTO_REGISTER==="true":e&&(o=!0),{enabled:o,serverUrl:t.serverUrl||m,tenantId:t.tenantId||"",userKey:t.userKey||"",machineToken:t.machineToken,connectionKey:t.connectionKey,instanceName:n,instanceId:t.instanceId,credentialId:t.credentialId,credentialRef:t.credentialRef,credentialType:t.credentialType,projectId:t.projectId,roleName:t.roleName,workspacePath:t.workspacePath,registerAddr:t.registerAddr,registerIp:t.registerIp,virtualIp:t.virtualIp,tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,preferSameLanIp:t.preferSameLanIp!==!1,maxRetries:t.maxRetries,retryInterval:t.retryInterval}}function K(){const e=he(),r=ne(),n=(e.length>0?e:[te()||{}]).map(o=>{const s={...V,...o,...r};let i=!1;return process.env.AWS_AUTO_REGISTER!==void 0?i=process.env.AWS_AUTO_REGISTER==="true":i=e.length>0||!!(s.userKey||s.machineToken),{enabled:i,serverUrl:s.serverUrl||m,tenantId:s.tenantId||"",userId:s.userId,userKey:s.userKey||"",machineToken:s.machineToken,connectionKey:s.connectionKey,instanceName:s.instanceName||N.hostname(),instanceId:s.instanceId,credentialId:s.credentialId,credentialRef:s.credentialRef,credentialType:s.credentialType,projectId:s.projectId,roleName:s.roleName,workspacePath:s.workspacePath,registerAddr:s.registerAddr,registerIp:s.registerIp,virtualIp:s.virtualIp,tunnel:typeof s.tunnel=="boolean"?s.tunnel:void 0,preferSameLanIp:s.preferSameLanIp!==!1,maxRetries:s.maxRetries,retryInterval:s.retryInterval}});return k=n.map(o=>o.connectionKey).filter(o=>!!(o&&o.trim())),n}function ve(){const e=N.networkInterfaces(),r=[];for(const t of Object.keys(e)){const n=e[t];if(n)for(const o of n)o.family==="IPv4"&&!o.internal&&r.push({address:o.address,netmask:o.netmask,name:t})}return r}function z(e){const r=e.split(".").map(Number);return(r[0]<<24)+(r[1]<<16)+(r[2]<<8)+r[3]}function Ke(e,r,t){const n=z(e),o=z(r),s=z(t);return(n&s)===(o&s)}function Ue(e){try{const r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"?"127.0.0.1":/^(\d{1,3}\.){3}\d{1,3}$/.test(r.hostname)?r.hostname:null}catch{return null}}function ke(e){return e==="127.0.0.1"}function _e(e){const r=ve();if(r.length===0)return a.warn("[AutoRegister] \u672A\u627E\u5230\u4EFB\u4F55\u975E\u5185\u90E8 IP \u5730\u5740\uFF0C\u4F7F\u7528 127.0.0.1"),"127.0.0.1";const t=Ue(e);if(t){if(ke(t))return"127.0.0.1";for(const n of r)if(Ke(n.address,t,n.netmask))return a.info(`[AutoRegister] \u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u540C\u5B50\u7F51\u7684 IP: ${n.address} (\u7F51\u5361: ${n.name}, \u5B50\u7F51\u63A9\u7801: ${n.netmask})`),n.address;a.warn(`[AutoRegister] \u672A\u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3 (${t}) \u540C\u5B50\u7F51\u7684\u672C\u673A IP\uFF0C\u4F7F\u7528 127.0.0.1`)}else a.warn("[AutoRegister] \u65E0\u6CD5\u89E3\u6790\u8C03\u5EA6\u4E2D\u5FC3 IP\uFF0C\u4F7F\u7528 127.0.0.1");return"127.0.0.1"}function Ee(e=m){return _e(e)}function se(e){const r=e||W();return!r.enabled||!r.userKey&&!r.machineToken?!1:r.tunnel===!0?!0:r.tunnel===!1?!1:!r.registerAddr&&!r.registerIp&&!r.virtualIp}function L(e){const r=de();if(se(e)){const s=e.serverUrl||m;try{const i=new URL(s);if(!e.instanceId)a.warn("[AutoRegister] \u96A7\u9053\u6A21\u5F0F\u4F46\u7F3A\u5C11 instanceId\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F");else return`${i.protocol}//${i.host}/tunnel/${e.instanceId}`}catch{a.warn("[AutoRegister] serverUrl \u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F")}}const t=le()||e.preferSameLanIp===!1?"127.0.0.1":Ee(e.serverUrl||m),n=e.registerAddr||e.registerIp||e.virtualIp||t;return n?/^https?:\/\//i.test(n)?n:/:[0-9]+$/.test(n)?`http://${n}`:`http://${n}:${r}`:`http://127.0.0.1:${r}`}function b(){return K()[0]||W()}function Xe(e){return Ne(e)?.serverUrl}function Ne(e){const r=String(e||"").trim();if(!r)return;for(const n of K()){if(!n?.serverUrl)continue;const o=q(n.serverUrl,y(n));if(o&&o===r)return{serverUrl:T(n.serverUrl)||n.serverUrl,userKey:n.userKey,identityKey:y(n),instanceId:n.instanceId};const s=ye(n.serverUrl);for(const i of s){if(i.accessToken!==r)continue;const c=fe(n.userKey)===i.userKeyFingerprint?n.userKey:void 0;return{serverUrl:T(n.serverUrl)||n.serverUrl,userKey:c,identityKey:c}}}const t=M();if(t.schedulerBaseUrl){const n=q(t.schedulerBaseUrl);if(n&&n===r)return{serverUrl:T(t.schedulerBaseUrl)||t.schedulerBaseUrl}}}function we(e){if(!e)return;const r=Object.entries(d.registrations).find(([,t])=>t===e);return r?F(r[0]):void 0}function Be(e,r){const t=T(e);if(!t)return;if(String(r||"").trim()){const o=d.registrations[x(t,r)];return o||void 0}const n=Object.entries(d.registrations).filter(([o])=>F(o)===t);return n.length===1?n[0][1]:void 0}function j(e,r){const t=we(r);if(t)return t;const n=g(e.serverUrl);if(n&&(n!==m||process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))return n;const o=M(),s=g(o.schedulerBaseUrl);return o.status==="paired"&&s?s:n||m}async function $e(e){const r=e.instanceName||N.hostname(),t=e.serverUrl||m,n={tenantId:e.tenantId,userKey:e.machineToken?void 0:e.userKey,machineToken:e.machineToken,instanceId:e.instanceId,instanceName:r,hostname:N.hostname(),virtualIp:e.registerAddr||e.registerIp||e.virtualIp,runtimeBridgeBaseUrl:L(e),connectionKey:e.connectionKey,workspacePath:e.workspacePath,projectId:e.projectId,roleName:e.roleName};return a.info(`[AutoRegister] \u6B63\u5728\u6CE8\u518C\u5B9E\u4F8B: ${r}`),a.info(`[AutoRegister] \u8C03\u5EA6\u4E2D\u5FC3: ${t}`),a.info(e.machineToken?"[AutoRegister] \u51ED\u636E: \u673A\u5668\u81EA\u6301\u51ED\u636E\uFF08machineToken\uFF09":`[AutoRegister] \u7528\u6237 Key: ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),a.info(`[AutoRegister] \u79DF\u6237 ID: ${e.tenantId||"(\u81EA\u52A8\u63A8\u5BFC)"}`),(await w.post(`${t}/api/instances/register`,n,{headers:{"Content-Type":"application/json"},timeout:1e4})).data}function Ce(e,r,t,n,o,s,i,c,u){const l=S();return D(l,()=>{if(!p.existsSync(l))return;const I=p.readFileSync(l,"utf-8"),h=JSON.parse(I),U=T(e);if(!U)return;let A=!1;const R=f=>T(String(f.serverUrl||f.schedulerBaseUrl||""))!==U?!1:String(t||"").trim()?String(f.userKey??"").trim()===String(t).trim():String(i||"").trim()?String(f.machineToken??"").trim()===String(i).trim():!0,v=f=>{R(f)&&(r&&f.instanceId!==r&&(f.instanceId=r,A=!0),n&&f.credentialId!==n&&(f.credentialId=n,A=!0),o&&f.credentialRef!==o&&(f.credentialRef=o,A=!0),s&&f.credentialType!==s&&(f.credentialType=s,A=!0),c&&f.tenantId!==c&&(f.tenantId=c,A=!0),u&&f.userId!==u&&(f.userId=u,A=!0))};if(Array.isArray(h.autoRegisterTargets))for(const f of h.autoRegisterTargets)f&&typeof f=="object"&&!Array.isArray(f)&&v(f);else v(h);A&&(p.writeFileSync(l,JSON.stringify(h,null,2),"utf-8"),a.info(`[AutoRegister] \u5DF2\u56DE\u5199 instanceId \u5230 config.json (serverUrl=${e}${t?`, userKey=****${String(t).slice(-4)}`:""})`))})}async function Oe(e,r){const t=String(r||"").trim();if(!t)return;const n=y(e),o=_(e.serverUrl);if(!n||!o)return;const s=S();try{await D(s,()=>{if(!p.existsSync(s))return;const i=p.readFileSync(s,"utf-8"),c=JSON.parse(i),l=ee(c).find(I=>_(I.serverUrl||I.schedulerBaseUrl)===o&&String(I.credentialId||I.userKey||"").trim()===n);if(!l){a.warn(`[AutoRegister] \u65E0\u6CD5\u5B9A\u4F4D connectionKey \u5BF9\u5E94 target\uFF0C\u8DF3\u8FC7\u5199\u76D8: server=${o}`);return}String(l.connectionKey??"").trim()!==t&&(l.connectionKey=t,p.writeFileSync(s,JSON.stringify(c,null,2),"utf-8"),a.info(`[AutoRegister] \u5DF2\u5199\u5165 target connectionKey \u5230 config.json: ${s}`))})}catch(i){a.warn(`[AutoRegister] \u5199\u5165 target connectionKey \u5230 config.json \u5931\u8D25: ${i.message}`)}}async function Qe(e,r){const t=String(e||"").trim();if(!t)throw new Error("connectionKey is required");const n=_(r?.serverUrl);if(!n)throw new Error("serverUrl is required to rotate a target connectionKey");const o=S();let s;const i=await D(o,()=>{if(!p.existsSync(o))return!1;const l=JSON.parse(p.readFileSync(o,"utf-8")),I=ee(l),h=String(r?.instanceId||"").trim(),U=String(r?.credentialId||"").trim(),A=I.filter(v=>{if(_(v.serverUrl||v.schedulerBaseUrl)!==n)return!1;if(h&&String(v.instanceId||"").trim()===h)return!0;if(U){const E=String(v.credentialId||"").trim(),ae=String(v.userKey||"").trim();if(E===U||ae===U)return!0}return!h&&!U&&I.filter(E=>_(E.serverUrl||E.schedulerBaseUrl)===n).length===1});if(A.length!==1)throw new Error(`\u65E0\u6CD5\u552F\u4E00\u5B9A\u4F4D connectionKey \u5BF9\u5E94 target\uFF08server=${n}, matches=${A.length}\uFF09`);const R=A[0];return String(R.connectionKey??"").trim()===t?!1:(s={targetKey:x(String(R.serverUrl??R.schedulerBaseUrl??""),R.credentialId||R.userKey),previousConnectionKey:String(R.connectionKey??"").trim()},R.connectionKey=t,String(l.connectionKey??"").trim()&&delete l.connectionKey,p.writeFileSync(o,JSON.stringify(l,null,2),"utf-8"),a.info(`[AutoRegister] \u5DF2\u8F6E\u6362 target connectionKey \u5E76\u5199\u56DE config.json: ${o}`),!0)}),c=!!process.env.AWS_BRIDGE_CONNECTION_KEY;c&&i&&(process.env.AWS_BRIDGE_CONNECTION_KEY=t,a.warn("[AutoRegister] \u68C0\u6D4B\u5230 AWS_BRIDGE_CONNECTION_KEY \u73AF\u5883\u53D8\u91CF\uFF0C\u5DF2\u540C\u6B65\u66F4\u65B0\u5F53\u524D\u8FDB\u7A0B\uFF1B\u91CD\u542F bridge \u540E\u4F1A\u56DE\u5230\u73AF\u5883\u53D8\u91CF\u4E2D\u7684\u65E7\u503C\uFF0C\u8BF7\u4E00\u5E76\u4FEE\u6539\u90E8\u7F72\u914D\u7F6E"));const u=K().map(l=>String(l.connectionKey||"").trim()).filter(l=>l.length>0);return k=i?[...new Set([t,...u])]:[...new Set(u)],i&&s&&s.previousConnectionKey!==t&&B.set(s.targetKey,{key:s.previousConnectionKey,expiresAt:Date.now()+Ie}),{envOverrideWarning:c,rotated:i}}async function ie(e){let r=0;for(const t of e)String(t.connectionKey||"").trim()||(t.connectionKey=`awsb_${ce(24).toString("base64url")}`,r+=1,k.includes(t.connectionKey)||(k=[...k,t.connectionKey]),await Oe(t,t.connectionKey));r!==0&&a.info(`[AutoRegister] ${r} \u4E2A\u76EE\u6807\u7F3A\u5C11 connectionKey\uFF0C\u5DF2\u6309 target \u72EC\u7ACB\u751F\u6210\u5E76\u5199\u5165 config.json`)}function oe(e){if(!e)return;const r=Object.entries(d.registrations).find(([,s])=>s===e);if(!r)return;const t=r[0],n=F(t),o=K().find(s=>C(s)===t);return{serverUrl:n,identityKey:o?y(o):void 0,targetKey:t}}async function be(e){const r=oe(e),t=r?.serverUrl||j(b(),e),n=G(t,r?.identityKey);if(!n)throw new Error("runtimeAccessToken is required to unregister bridge instance");return(await w.post(`${t}/api/instances/unregister`,{instanceId:e},{headers:{"Content-Type":"application/json","X-Runtime-Token":n},timeout:1e4})).data}async function Ze(e){const r=e?[{...W(),...e}]:K();await ie(r);const n=(r.length>1?await Promise.all(r.map(s=>J(s))):[await J(r[0]||W())]).every(Boolean),o=r.every(s=>!s.enabled||!s.userKey&&!s.machineToken);if(!e&&(n||o)){const{stopTunnelClientsExcept:s}=await import("./tunnel-client.js");s(r.filter(i=>!!i.serverUrl).map(i=>x(i.serverUrl,y(i))))}return n}async function J(e,r){if(!e.enabled)return a.info("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u672A\u542F\u7528"),a.info(`[AutoRegister] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${S()} \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_AUTO_REGISTER=true`),!1;if(!e.userKey&&!e.machineToken)return a.error("[AutoRegister] \u7F3A\u5C11\u6CE8\u518C\u51ED\u636E\uFF08\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E userKey \u6216 machineToken\uFF0C\u4E5F\u53EF\u7528 `awsb pair --ticket ...` \u914D\u5BF9\uFF09"),!1;String(e.connectionKey||"").trim()||await ie([e]);const t=se(e);t&&!e.instanceId&&(e.instanceId=`bridge-${ue().replace(/-/g,"").slice(0,12)}`,a.info(`[AutoRegister] \u96A7\u9053\u6A21\u5F0F\uFF1A\u5DF2\u9884\u58F0\u660E instanceId=${e.instanceId}`));const n=r?.backgroundRetry?1:e.maxRetries??3,o=e.retryInterval??2e3;for(let s=1;s<=n;s++){try{d.lastAttempt=new Date;const i=await $e(e);if(i.success){if(d.registered=!0,d.instanceId=i.instanceId,i.credentialId&&(e.credentialId=i.credentialId,e.credentialType=i.credentialType),e.credentialRef=i.credentialRef,i.tenantId&&(e.tenantId=i.tenantId),i.userId&&(e.userId=i.userId),i.instanceId&&(d.registrations[C(e)]=i.instanceId,e.instanceId=i.instanceId),d.error=void 0,a.info("[AutoRegister] \u2713 \u6CE8\u518C\u6210\u529F\uFF01"),a.info(`[AutoRegister] \u5B9E\u4F8B ID: ${i.instanceId}`),a.info(`[AutoRegister] \u6D88\u606F: ${i.message}`),a.info(`[AutoRegister] \u66F4\u65B0: ${i.isUpdate?"\u662F":"\u5426"}`),i.runtimeAccessToken)try{const c=e.serverUrl||m;Y({accessToken:i.runtimeAccessToken,instanceId:i.instanceId,userId:i.userId,schedulerBaseUrl:c,userKey:y(e)});const u=T(i.serverUrl);u&&u!==T(c)&&(H({serverBaseUrl:u,accessToken:i.runtimeAccessToken,userKey:y(e)}),a.info(`[AutoRegister] \u68C0\u6D4B\u5230 server \u4E0B\u53D1\u5730\u5740(${u})\u4E0E\u8FDE\u63A5\u5730\u5740(${c})\u4E0D\u540C\uFF0C\u5DF2\u6309\u4E24\u4E2A\u5730\u5740\u5206\u522B\u4FDD\u5B58 scoped token`)),a.info("[AutoRegister] \u5DF2\u4FDD\u5B58\u8C03\u5EA6\u4E2D\u5FC3\u4E0B\u53D1\u7684 runtime access token"),i.instanceId&&Ce(e.serverUrl||m,i.instanceId,e.userKey,i.credentialId,i.credentialRef,i.credentialType,e.machineToken,i.tenantId,i.userId).catch(l=>{a.warn(`[AutoRegister] \u56DE\u5199 instanceId \u5230 config.json \u5931\u8D25: ${l.message}`)})}catch(c){const u=c;return a.error(`[AutoRegister] \u4FDD\u5B58 runtime access token \u5931\u8D25: ${u.message}`),d.error=u.message,!1}else a.warn("[AutoRegister] \u6CE8\u518C\u54CD\u5E94\u672A\u5305\u542B runtime access token\uFF0CMCP \u5C06\u65E0\u6CD5\u8BBF\u95EE\u8C03\u5EA6\u4E2D\u5FC3\uFF0C\u8BF7\u68C0\u67E5 server \u7684 bridge \u5B9E\u4F8B token \u9881\u53D1\u903B\u8F91");if(t&&i.instanceId&&i.runtimeAccessToken){const{startTunnelClient:c}=await import("./tunnel-client.js"),u=e.serverUrl||m;c(u,i.instanceId,y(e)),a.info(`[AutoRegister] \u96A7\u9053\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8: server=${u}, instanceId=${i.instanceId}${e.userKey?`, userKey=****${e.userKey.slice(-4)}`:""}`)}return!0}else a.warn(`[AutoRegister] \u6CE8\u518C\u5931\u8D25: ${i.message}`),d.error=i.message}catch(i){const c=i,u=c.response?.data?JSON.stringify(c.response.data):c.message;a.error(`[AutoRegister] \u6CE8\u518C\u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/${n}): ${u}`),d.error=u}s<n&&(a.info(`[AutoRegister] ${o/1e3} \u79D2\u540E\u91CD\u8BD5...`),await new Promise(i=>setTimeout(i,o)))}return r?.backgroundRetry?a.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u4ECD\u672A\u6210\u529F (server=${e.serverUrl||m}): ${d.error||"\u672A\u77E5"}`):(a.error("[AutoRegister] \u2717 \u6CE8\u518C\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570"),a.error("[AutoRegister] ========================================"),a.error("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u5DF2\u542F\u7528\u4F46\u6CE8\u518C\u5931\u8D25\uFF0C\u5B9E\u4F8B\u6682\u65F6\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C"),a.error("[AutoRegister] \u8BF7\u68C0\u67E5\u4EE5\u4E0B\u914D\u7F6E\uFF1A"),a.error(`[AutoRegister] - \u7528\u6237 Key (userKey): ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),a.error(`[AutoRegister] - \u79DF\u6237 ID (tenantId): ${e.tenantId||"(\u53EF\u9009\uFF0C\u5C06\u81EA\u52A8\u63A8\u5BFC)"}`),a.error(`[AutoRegister] - \u5B9E\u4F8B\u540D (instanceName): ${e.instanceName||"(\u4F7F\u7528\u4E3B\u673A\u540D)"}`),a.error(`[AutoRegister] - \u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740: ${e.serverUrl||m}`),a.error(`[AutoRegister] - \u6700\u540E\u9519\u8BEF: ${d.error||"\u672A\u77E5"}`),a.error("[AutoRegister] ========================================"),a.error(`[AutoRegister] \u914D\u7F6E\u6765\u6E90\uFF1A${S()} \u6216\u73AF\u5883\u53D8\u91CF`),a.warn(`[AutoRegister] \u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u6CE8\u518C\uFF08\u6BCF ${Math.round(Q()/1e3)} \u79D2\uFF09\uFF0C\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5`)),Z(e),!1}async function er(){const e=b();if(!e.userKey&&!e.machineToken)return{success:!1,error:"userKey or machineToken is required for runtime token refresh"};const r=pe(),t=j(e),n=L(e);try{const o=await w.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:e.tenantId,userKey:e.machineToken?void 0:e.userKey,machineToken:e.machineToken,instanceId:r.instanceId,instanceName:e.instanceName,runtimeBridgeBaseUrl:n},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!o.data.success||!o.data.runtimeAccessToken)return{success:!1,error:o.data.message||"scheduler did not return runtimeAccessToken"};const i=G(t,y(e))!==o.data.runtimeAccessToken;return Y({accessToken:o.data.runtimeAccessToken,instanceId:r.instanceId,userId:o.data.userId||e.userKey||e.credentialId||"",schedulerBaseUrl:t,userKey:y(e)}),{success:!0,runtimeAccessToken:o.data.runtimeAccessToken,updated:i}}catch(o){const s=o;return{success:!1,error:s.response?.data?JSON.stringify(s.response.data):s.message}}}async function rr(e,r){const t=_(e);if(!t)return{success:!1,error:"serverUrl is required for runtime token refresh"};const n=K().filter(u=>_(u.serverUrl)===t),o=String(r||"").trim(),s=o?n.find(u=>String(u.userKey||"").trim()===o||String(u.credentialId||"").trim()===o):n.length===1?n[0]:void 0;if(!s)return{success:!1,error:o?"no auto-register target matches this identity":"multiple auto-register targets share this serverUrl; specify the target identity"};if(!s.userKey&&!s.machineToken)return{success:!1,error:"userKey or machineToken is required for runtime token refresh"};const i={instanceId:Be(t,y(s))},c=L(s);try{const u=await w.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:s.tenantId,userKey:s.machineToken?void 0:s.userKey,machineToken:s.machineToken,instanceId:i.instanceId,instanceName:s.instanceName,runtimeBridgeBaseUrl:c},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!u.data.success||!u.data.runtimeAccessToken)return{success:!1,error:u.data.message||"scheduler did not return runtimeAccessToken"};const I=G(t,y(s))!==u.data.runtimeAccessToken;return H({serverBaseUrl:t,accessToken:u.data.runtimeAccessToken,userKey:y(s)}),{success:!0,runtimeAccessToken:u.data.runtimeAccessToken,updated:I}}catch(u){const l=u;return{success:!1,error:l.response?.data?JSON.stringify(l.response.data):l.message}}}async function tr(){if(!d.registered||!d.instanceId)return a.info("[AutoRegister] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u65E0\u9700\u6CE8\u9500"),!0;try{const e=await be(d.instanceId);if(e.success){a.info(`[AutoRegister] \u2713 \u6CE8\u9500\u6210\u529F: ${d.instanceId}`);const r=oe(d.instanceId),t=r?.serverUrl||j(b(),d.instanceId);M().schedulerBaseUrl&&me(t,r?.identityKey),ge();try{const{stopTunnelClientForTarget:o}=await import("./tunnel-client.js");o(t,r?.identityKey??y(b()))}catch(o){a.warn(`[AutoRegister] \u6CE8\u9500\u540E\u505C\u6B62\u96A7\u9053\u5931\u8D25: ${o.message}`)}if(!r)d.registered=!1,d.instanceId=void 0;else{delete d.registrations[r.targetKey];const o=Object.entries(d.registrations);d.registered=o.length>0,d.instanceId=o[o.length-1]?.[1]}return!0}else return a.warn(`[AutoRegister] \u6CE8\u9500\u5931\u8D25: ${e.message}`),!1}catch(e){const r=e;return a.error(`[AutoRegister] \u6CE8\u9500\u8BF7\u6C42\u5931\u8D25: ${r.message}`),!1}}function nr(){return{...d}}function sr(){return d.registered}function ir(){return d.instanceId}async function or(){const e=b(),r=d.instanceId,t=j(e,r),n={};if(r&&(n.instanceId=r),e.enabled&&(n.runtimeBridgeBaseUrl=L(e)),!n.instanceId&&!n.runtimeBridgeBaseUrl)return a.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6CA1\u6709 instanceId \u6216 runtimeBridgeBaseUrl\uFF0C\u8DF3\u8FC7\u6E05\u7406"),{success:!0,agentCount:0};try{a.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3..."),a.info(`[AutoRegister] instanceId: ${n.instanceId||"(\u65E0)"}`),a.info(`[AutoRegister] runtimeBridgeBaseUrl: ${n.runtimeBridgeBaseUrl||"(\u65E0)"}`);const o=await w.post(`${t}/api/instances/bridge-restart-cleanup`,n,{headers:{"Content-Type":"application/json"},timeout:1e4});return o.data.success?(a.info(`[AutoRegister] \u2713 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF1A${o.data.message}`),a.info(`[AutoRegister] \u6E05\u7406\u4E86 ${o.data.agentCount||0} \u4E2A Agent`),{success:!0,agentCount:o.data.agentCount||0}):(a.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25\uFF1A${o.data.message}`),{success:!1,error:o.data.message})}catch(o){const s=o,i=s.response?.data?JSON.stringify(s.response.data):s.message;return a.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u8BF7\u6C42\u5931\u8D25\uFF1A${i}`),{success:!1,error:i}}}export{Ze as autoRegister,or as bridgeRestartCleanup,He as cancelBackgroundRegisterRetries,Se as collapseDuplicatedSecret,qe as findConfigsByConnectionKey,S as getAutoRegisterConfigFilePath,Je as getConfiguredConnectionKeys,Ye as getCurrentConfiguredConnectionKey,ir as getInstanceId,nr as getRegistrationState,sr as isRegistered,se as isTunnelConfig,Ve as listConfiguredTargetSummaries,W as loadConfig,K as loadConfigs,b as loadPrimaryLifecycleConfig,Qe as replaceConfiguredConnectionKey,er as requestRuntimeAccessTokenRefresh,rr as requestRuntimeAccessTokenRefreshForServer,Be as resolveInstanceIdForTarget,L as resolveRuntimeBridgeBaseUrl,Xe as resolveSchedulerBaseUrlFromToken,Ne as resolveTargetIdentityFromToken,tr as unregister};
1
+ import{randomBytes as ce}from"node:crypto";import p from"node:fs";import w from"node:os";import $ from"axios";import{v4 as ue}from"uuid";import{getActiveBridgeHttpPort as de,getAutoRegisterConfigFilePath as T,isDesktopAppMode as le,schedulerBaseUrl as m}from"../config.js";import{runExclusiveConfigWrite as D}from"../utils/config-write-queue.js";import{logger as a}from"../utils/logger.js";import{buildTargetKey as x,fingerprintUserKey as fe,serverUrlOfTargetKey as F}from"../utils/target-identity.js";import{clearRuntimeBinding as ge,clearScopedRuntimeAccessToken as me,getRuntimeAccessToken as G,getRuntimeBindingPublicState as pe,getScopedRuntimeAccessToken as Y,listScopedRuntimeAccessTokens as ye,loadRuntimeBinding as M,normalizeSchedulerBaseUrl as S,saveRuntimeBinding as H,saveScopedRuntimeAccessToken as V}from"./runtime-binding.js";const X={enabled:!1,serverUrl:m,preferSameLanIp:!0,maxRetries:3,retryInterval:2e3},d={registered:!1,registrations:{}};let k=[];const Ie=10*60*1e3,B=new Map;function Q(){const e=Date.now();for(const[r,t]of B)t.expiresAt<=e&&B.delete(r)}function Je(){Q();const e=[...k];for(const r of B.values())r.key&&!e.includes(r.key)&&e.push(r.key);return e}function qe(e){const r=String(e||"").trim();if(!r)return[];const t=h(),n=t.filter(i=>String(i.connectionKey||"").trim()===r);if(n.length>0)return n;Q();const o=new Set;for(const[i,s]of B)s.key===r&&o.add(i);return o.size===0?[]:t.filter(i=>o.has(N(i)))}function Ye(){return k[0]??""}const Ae=3e4;function Z(){const e=Number(process.env.AWS_REGISTER_BACKGROUND_RETRY_INTERVAL);return Number.isFinite(e)&&e>0?e:Ae}const C=new Map;function ee(e){const r=e.serverUrl||m,t=N(e)||r;if(C.has(t))return;const n=setTimeout(()=>{C.delete(t),Re(e,t)},Z());n.unref?.(),C.set(t,n)}async function Re(e,r){try{const t=h().find(n=>N(n)===r)||e;await q(t,{backgroundRetry:!0})}catch(t){a.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u5F02\u5E38: ${t.message}`),ee(e)}}function He(){for(const e of C.values())clearTimeout(e);C.clear()}function Te(e){const r=e.trim();if(r.length<8)return r;for(let t=1;t<=r.length/2;t++){if(r.length%t!==0)continue;const n=r.slice(0,t);let o=!0;for(let i=t;i<r.length;i+=t)if(r.slice(i,i+t)!==n){o=!1;break}if(o&&n.length<r.length)return n}return r}function Se(e){const r=g(e);if(!r)return r;const t=Te(r);return t!==r&&a.warn(`[AutoRegister] userKey \u7591\u4F3C\u88AB\u590D\u5236\u4E86\u4E24\u904D\uFF08\u957F\u5EA6 ${r.length} \u2192 ${t.length}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u53BB\u91CD\u3002\u8BF7\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6\u662F\u5426\u91CD\u590D\u7C98\u8D34\u3002`),t}function g(e){return e==null?void 0:String(e).trim()||void 0}function _(e){return S(e)}function re(e){return Array.isArray(e.autoRegisterTargets)?e.autoRegisterTargets.filter(r=>!!(r&&typeof r=="object"&&!Array.isArray(r))):[]}function N(e){const r=e?.serverUrl||m;return x(r,e?.credentialId||e?.userKey)}function y(e){return e?.credentialId||e?.userKey}function P(e){if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["true","1","yes","y"].includes(r))return!0;if(["false","0","no","n"].includes(r))return!1}}function te(e){if(e==null||e==="")return;const r=Number(e);return Number.isFinite(r)?r:void 0}function O(e){const r=g(e.serverUrl)||g(e.schedulerBaseUrl),t=g(e.connectionKey)||g(e.password);return{enabled:P(e.enabled),serverUrl:r,tenantId:g(e.tenantId),userId:g(e.userId),userKey:Se(e.userKey),machineToken:g(e.machineToken),connectionKey:t,instanceName:g(e.instanceName),instanceId:g(e.instanceId),credentialId:g(e.credentialId),credentialRef:g(e.credentialRef),credentialType:g(e.credentialType),projectId:g(e.projectId),roleName:g(e.roleName),workspacePath:g(e.workspacePath),registerAddr:g(e.registerAddr),registerIp:g(e.registerIp),virtualIp:g(e.virtualIp),tunnel:P(e.tunnel),preferSameLanIp:P(e.preferSameLanIp),maxRetries:te(e.maxRetries),retryInterval:te(e.retryInterval)}}function ne(){const e=T();try{if(!p.existsSync(e))return a.debug(`[AutoRegister] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;const r=p.readFileSync(e,"utf-8"),t=JSON.parse(r);return a.info(`[AutoRegister] \u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u914D\u7F6E: ${e}`),O(t)}catch(r){const t=r;return a.warn(`[AutoRegister] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${e}, error: ${t.message}`),null}}function he(){const e=T();try{if(!p.existsSync(e))return[];const r=p.readFileSync(e,"utf-8"),t=JSON.parse(r),n=O(t),o=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets:[];return o.length===0?n.userKey||n.machineToken?[n]:[]:o.filter(i=>!!(i&&typeof i=="object"&&!Array.isArray(i))).map(i=>{const s=O(i);return{...n,...s,machineToken:s.machineToken||(s.userKey?void 0:n.machineToken),connectionKey:s.connectionKey}})}catch(r){const t=r;return a.warn(`[AutoRegister] \u8BFB\u53D6\u81EA\u52A8\u6CE8\u518C\u76EE\u6807\u5931\u8D25: ${e}, error: ${t.message}`),[]}}function Ve(){const e=T();if(!p.existsSync(e))return[];let r;try{r=JSON.parse(p.readFileSync(e,"utf-8"))}catch(s){return a.warn(`[AutoRegister] \u8BFB\u53D6 config.json \u5931\u8D25\uFF08targets \u6458\u8981\uFF09: ${s.message}`),[]}const t=O(r),n=Array.isArray(r.autoRegisterTargets)?r.autoRegisterTargets:[],o=n.length>0?n.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(s=>{const c=O(s);return{...t,...c,machineToken:c.machineToken||(c.userKey?void 0:t.machineToken),connectionKey:c.connectionKey}}):t.userKey||t.machineToken?[t]:[],i=s=>{const c=String(s||"").trim();return c?c.length<=8?"****":`${c.slice(0,8)}****${c.slice(-4)}`:""};return o.map((s,c)=>({index:c,serverUrl:s.serverUrl||"",instanceName:s.instanceName||"",registerAddr:s.registerAddr||s.registerIp||s.virtualIp||"",tunnel:typeof s.tunnel=="boolean"?s.tunnel:null,userKeyMasked:i(s.userKey),machineTokenSet:!!String(s.machineToken||"").trim(),credentialType:s.credentialType||"",credentialId:s.credentialId||"",credentialRef:s.credentialRef||"",connectionKeySet:!!String(s.connectionKey||"").trim()}))}function se(){const e={};return process.env.AWS_AUTO_REGISTER==="true"&&(e.enabled=!0),process.env.AWS_RUNTIME_SCHEDULER_BASE_URL&&(e.serverUrl=process.env.AWS_RUNTIME_SCHEDULER_BASE_URL),process.env.AWS_TENANT_ID&&(e.tenantId=process.env.AWS_TENANT_ID),process.env.AWS_USER_KEY&&(e.userKey=process.env.AWS_USER_KEY),process.env.AWS_BRIDGE_MACHINE_TOKEN&&(e.machineToken=process.env.AWS_BRIDGE_MACHINE_TOKEN),process.env.AWS_BRIDGE_CONNECTION_KEY&&(e.connectionKey=process.env.AWS_BRIDGE_CONNECTION_KEY),process.env.AWS_INSTANCE_NAME&&(e.instanceName=process.env.AWS_INSTANCE_NAME),process.env.AWS_PROJECT_NAME&&(e.projectId=process.env.AWS_PROJECT_NAME),process.env.AWS_ROLE_NAME&&(e.roleName=process.env.AWS_ROLE_NAME),process.env.AWS_WORKSPACE_PATH&&(e.workspacePath=process.env.AWS_WORKSPACE_PATH),process.env.AWS_REGISTER_ADDR&&(e.registerAddr=process.env.AWS_REGISTER_ADDR),process.env.AWS_REGISTER_IP&&(e.registerIp=process.env.AWS_REGISTER_IP),process.env.AWS_VIRTUAL_IP&&(e.virtualIp=process.env.AWS_VIRTUAL_IP),process.env.AWS_PREFER_SAME_LAN_IP&&(e.preferSameLanIp=P(process.env.AWS_PREFER_SAME_LAN_IP)??!0),process.env.AWS_REGISTER_MAX_RETRIES&&(e.maxRetries=parseInt(process.env.AWS_REGISTER_MAX_RETRIES,10)),process.env.AWS_REGISTER_RETRY_INTERVAL&&(e.retryInterval=parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL,10)),e}function W(){const e=ne(),r=se(),t={...X,...e||{},...r},n=t.instanceName||w.hostname();let o=!1;return process.env.AWS_AUTO_REGISTER!==void 0?o=process.env.AWS_AUTO_REGISTER==="true":e&&(o=!0),{enabled:o,serverUrl:t.serverUrl||m,tenantId:t.tenantId||"",userKey:t.userKey||"",machineToken:t.machineToken,connectionKey:t.connectionKey,instanceName:n,instanceId:t.instanceId,credentialId:t.credentialId,credentialRef:t.credentialRef,credentialType:t.credentialType,projectId:t.projectId,roleName:t.roleName,workspacePath:t.workspacePath,registerAddr:t.registerAddr,registerIp:t.registerIp,virtualIp:t.virtualIp,tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,preferSameLanIp:t.preferSameLanIp!==!1,maxRetries:t.maxRetries,retryInterval:t.retryInterval}}function h(){const e=he(),r=se(),n=(e.length>0?e:[ne()||{}]).map(o=>{const i={...X,...o,...r};let s=!1;return process.env.AWS_AUTO_REGISTER!==void 0?s=process.env.AWS_AUTO_REGISTER==="true":s=e.length>0||!!(i.userKey||i.machineToken),{enabled:s,serverUrl:i.serverUrl||m,tenantId:i.tenantId||"",userId:i.userId,userKey:i.userKey||"",machineToken:i.machineToken,connectionKey:i.connectionKey,instanceName:i.instanceName||w.hostname(),instanceId:i.instanceId,credentialId:i.credentialId,credentialRef:i.credentialRef,credentialType:i.credentialType,projectId:i.projectId,roleName:i.roleName,workspacePath:i.workspacePath,registerAddr:i.registerAddr,registerIp:i.registerIp,virtualIp:i.virtualIp,tunnel:typeof i.tunnel=="boolean"?i.tunnel:void 0,preferSameLanIp:i.preferSameLanIp!==!1,maxRetries:i.maxRetries,retryInterval:i.retryInterval}});return k=n.map(o=>o.connectionKey).filter(o=>!!(o&&o.trim())),n}function ve(){const e=w.networkInterfaces(),r=[];for(const t of Object.keys(e)){const n=e[t];if(n)for(const o of n)o.family==="IPv4"&&!o.internal&&r.push({address:o.address,netmask:o.netmask,name:t})}return r}function z(e){const r=e.split(".").map(Number);return(r[0]<<24)+(r[1]<<16)+(r[2]<<8)+r[3]}function Ke(e,r,t){const n=z(e),o=z(r),i=z(t);return(n&i)===(o&i)}function Ue(e){try{const r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"?"127.0.0.1":/^(\d{1,3}\.){3}\d{1,3}$/.test(r.hostname)?r.hostname:null}catch{return null}}function ke(e){return e==="127.0.0.1"}function _e(e){const r=ve();if(r.length===0)return a.warn("[AutoRegister] \u672A\u627E\u5230\u4EFB\u4F55\u975E\u5185\u90E8 IP \u5730\u5740\uFF0C\u4F7F\u7528 127.0.0.1"),"127.0.0.1";const t=Ue(e);if(t){if(ke(t))return"127.0.0.1";for(const n of r)if(Ke(n.address,t,n.netmask))return a.info(`[AutoRegister] \u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u540C\u5B50\u7F51\u7684 IP: ${n.address} (\u7F51\u5361: ${n.name}, \u5B50\u7F51\u63A9\u7801: ${n.netmask})`),n.address;a.warn(`[AutoRegister] \u672A\u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3 (${t}) \u540C\u5B50\u7F51\u7684\u672C\u673A IP\uFF0C\u4F7F\u7528 127.0.0.1`)}else a.warn("[AutoRegister] \u65E0\u6CD5\u89E3\u6790\u8C03\u5EA6\u4E2D\u5FC3 IP\uFF0C\u4F7F\u7528 127.0.0.1");return"127.0.0.1"}function Ee(e=m){return _e(e)}function ie(e){const r=e||W();return!r.enabled||!r.userKey&&!r.machineToken?!1:r.tunnel===!0?!0:r.tunnel===!1?!1:!r.registerAddr&&!r.registerIp&&!r.virtualIp}function L(e){const r=de();if(ie(e)){const i=e.serverUrl||m;try{const s=new URL(i);if(!e.instanceId)a.warn("[AutoRegister] \u96A7\u9053\u6A21\u5F0F\u4F46\u7F3A\u5C11 instanceId\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F");else return`${s.protocol}//${s.host}/tunnel/${e.instanceId}`}catch{a.warn("[AutoRegister] serverUrl \u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F")}}const t=le()||e.preferSameLanIp===!1?"127.0.0.1":Ee(e.serverUrl||m),n=e.registerAddr||e.registerIp||e.virtualIp||t;return n?/^https?:\/\//i.test(n)?n:/:[0-9]+$/.test(n)?`http://${n}`:`http://${n}:${r}`:`http://127.0.0.1:${r}`}function b(){return h()[0]||W()}function Xe(e){return Ne(e)?.serverUrl}function Ne(e){const r=String(e||"").trim();if(!r)return;for(const n of h()){if(!n?.serverUrl)continue;const o=Y(n.serverUrl,y(n));if(o&&o===r)return{serverUrl:S(n.serverUrl)||n.serverUrl,userKey:n.userKey,identityKey:y(n),instanceId:n.instanceId};const i=ye(n.serverUrl);for(const s of i){if(s.accessToken!==r)continue;const c=fe(n.userKey)===s.userKeyFingerprint?n.userKey:void 0;return{serverUrl:S(n.serverUrl)||n.serverUrl,userKey:c,identityKey:c}}}const t=M();if(t.schedulerBaseUrl){const n=Y(t.schedulerBaseUrl);if(n&&n===r)return{serverUrl:S(t.schedulerBaseUrl)||t.schedulerBaseUrl}}}function we(e){if(!e)return;const r=Object.entries(d.registrations).find(([,t])=>t===e);return r?F(r[0]):void 0}function $e(e,r){const t=S(e);if(!t)return;if(String(r||"").trim()){const o=d.registrations[x(t,r)];return o||void 0}const n=Object.entries(d.registrations).filter(([o])=>F(o)===t);return n.length===1?n[0][1]:void 0}function j(e,r){const t=we(r);if(t)return t;const n=g(e.serverUrl);if(n&&(n!==m||process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))return n;const o=M(),i=g(o.schedulerBaseUrl);return o.status==="paired"&&i?i:n||m}async function Be(e){const r=e.instanceName||w.hostname(),t=e.serverUrl||m,n={tenantId:e.tenantId,userKey:e.machineToken?void 0:e.userKey,machineToken:e.machineToken,instanceId:e.instanceId,instanceName:r,hostname:w.hostname(),virtualIp:e.registerAddr||e.registerIp||e.virtualIp,runtimeBridgeBaseUrl:L(e),connectionKey:e.connectionKey,workspacePath:e.workspacePath,projectId:e.projectId,roleName:e.roleName};return a.info(`[AutoRegister] \u6B63\u5728\u6CE8\u518C\u5B9E\u4F8B: ${r}`),a.info(`[AutoRegister] \u8C03\u5EA6\u4E2D\u5FC3: ${t}`),a.info(e.machineToken?"[AutoRegister] \u51ED\u636E: \u673A\u5668\u81EA\u6301\u51ED\u636E\uFF08machineToken\uFF09":`[AutoRegister] \u7528\u6237 Key: ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),a.info(`[AutoRegister] \u79DF\u6237 ID: ${e.tenantId||"(\u81EA\u52A8\u63A8\u5BFC)"}`),(await $.post(`${t}/api/instances/register`,n,{headers:{"Content-Type":"application/json"},timeout:1e4})).data}function Ce(e,r,t,n,o,i,s,c,u){const l=T();return D(l,()=>{if(!p.existsSync(l))return;const I=p.readFileSync(l,"utf-8"),v=JSON.parse(I),U=S(e);if(!U)return;let A=!1;const R=f=>S(String(f.serverUrl||f.schedulerBaseUrl||""))!==U?!1:String(t||"").trim()?String(f.userKey??"").trim()===String(t).trim():String(s||"").trim()?String(f.machineToken??"").trim()===String(s).trim():!0,K=f=>{R(f)&&(r&&f.instanceId!==r&&(f.instanceId=r,A=!0),n&&f.credentialId!==n&&(f.credentialId=n,A=!0),o&&f.credentialRef!==o&&(f.credentialRef=o,A=!0),i&&f.credentialType!==i&&(f.credentialType=i,A=!0),c&&f.tenantId!==c&&(f.tenantId=c,A=!0),u&&f.userId!==u&&(f.userId=u,A=!0))};if(Array.isArray(v.autoRegisterTargets))for(const f of v.autoRegisterTargets)f&&typeof f=="object"&&!Array.isArray(f)&&K(f);else K(v);A&&(p.writeFileSync(l,JSON.stringify(v,null,2),"utf-8"),a.info(`[AutoRegister] \u5DF2\u56DE\u5199 instanceId \u5230 config.json (serverUrl=${e}${t?`, userKey=****${String(t).slice(-4)}`:""})`))})}async function Oe(e,r){const t=String(r||"").trim();if(!t)return;const n=y(e),o=_(e.serverUrl);if(!n||!o)return;const i=T();try{await D(i,()=>{if(!p.existsSync(i))return;const s=p.readFileSync(i,"utf-8"),c=JSON.parse(s),l=re(c).find(I=>_(I.serverUrl||I.schedulerBaseUrl)===o&&String(I.credentialId||I.userKey||"").trim()===n);if(!l){a.warn(`[AutoRegister] \u65E0\u6CD5\u5B9A\u4F4D connectionKey \u5BF9\u5E94 target\uFF0C\u8DF3\u8FC7\u5199\u76D8: server=${o}`);return}String(l.connectionKey??"").trim()!==t&&(l.connectionKey=t,p.writeFileSync(i,JSON.stringify(c,null,2),"utf-8"),a.info(`[AutoRegister] \u5DF2\u5199\u5165 target connectionKey \u5230 config.json: ${i}`))})}catch(s){a.warn(`[AutoRegister] \u5199\u5165 target connectionKey \u5230 config.json \u5931\u8D25: ${s.message}`)}}async function Qe(e,r){const t=String(e||"").trim();if(!t)throw new Error("connectionKey is required");const n=_(r?.serverUrl);if(!n)throw new Error("serverUrl is required to rotate a target connectionKey");const o=T();let i;const s=await D(o,()=>{if(!p.existsSync(o))return!1;const l=JSON.parse(p.readFileSync(o,"utf-8")),I=re(l),v=String(r?.instanceId||"").trim(),U=String(r?.credentialId||"").trim(),A=I.filter(K=>{if(_(K.serverUrl||K.schedulerBaseUrl)!==n)return!1;if(v&&String(K.instanceId||"").trim()===v)return!0;if(U){const E=String(K.credentialId||"").trim(),ae=String(K.userKey||"").trim();if(E===U||ae===U)return!0}return!v&&!U&&I.filter(E=>_(E.serverUrl||E.schedulerBaseUrl)===n).length===1});if(A.length!==1)throw new Error(`\u65E0\u6CD5\u552F\u4E00\u5B9A\u4F4D connectionKey \u5BF9\u5E94 target\uFF08server=${n}, matches=${A.length}\uFF09`);const R=A[0];return String(R.connectionKey??"").trim()===t?!1:(i={targetKey:x(String(R.serverUrl??R.schedulerBaseUrl??""),R.credentialId||R.userKey),previousConnectionKey:String(R.connectionKey??"").trim()},R.connectionKey=t,String(l.connectionKey??"").trim()&&delete l.connectionKey,p.writeFileSync(o,JSON.stringify(l,null,2),"utf-8"),a.info(`[AutoRegister] \u5DF2\u8F6E\u6362 target connectionKey \u5E76\u5199\u56DE config.json: ${o}`),!0)}),c=!!process.env.AWS_BRIDGE_CONNECTION_KEY;c&&s&&(process.env.AWS_BRIDGE_CONNECTION_KEY=t,a.warn("[AutoRegister] \u68C0\u6D4B\u5230 AWS_BRIDGE_CONNECTION_KEY \u73AF\u5883\u53D8\u91CF\uFF0C\u5DF2\u540C\u6B65\u66F4\u65B0\u5F53\u524D\u8FDB\u7A0B\uFF1B\u91CD\u542F bridge \u540E\u4F1A\u56DE\u5230\u73AF\u5883\u53D8\u91CF\u4E2D\u7684\u65E7\u503C\uFF0C\u8BF7\u4E00\u5E76\u4FEE\u6539\u90E8\u7F72\u914D\u7F6E"));const u=h().map(l=>String(l.connectionKey||"").trim()).filter(l=>l.length>0);return k=s?[...new Set([t,...u])]:[...new Set(u)],s&&i&&i.previousConnectionKey!==t&&B.set(i.targetKey,{key:i.previousConnectionKey,expiresAt:Date.now()+Ie}),{envOverrideWarning:c,rotated:s}}async function oe(e){let r=0;for(const t of e)String(t.connectionKey||"").trim()||(t.connectionKey=`awsb_${ce(24).toString("base64url")}`,r+=1,k.includes(t.connectionKey)||(k=[...k,t.connectionKey]),await Oe(t,t.connectionKey));r!==0&&a.info(`[AutoRegister] ${r} \u4E2A\u76EE\u6807\u7F3A\u5C11 connectionKey\uFF0C\u5DF2\u6309 target \u72EC\u7ACB\u751F\u6210\u5E76\u5199\u5165 config.json`)}function J(e){if(!e)return;const r=Object.entries(d.registrations).find(([,i])=>i===e);if(!r)return;const t=r[0],n=F(t),o=h().find(i=>N(i)===t);return{serverUrl:n,identityKey:o?y(o):void 0,targetKey:t}}async function be(e){const r=J(e),t=r?.serverUrl||j(b(),e),n=G(t,r?.identityKey);if(!n)throw new Error("runtimeAccessToken is required to unregister bridge instance");return(await $.post(`${t}/api/instances/unregister`,{instanceId:e},{headers:{"Content-Type":"application/json","X-Runtime-Token":n},timeout:1e4})).data}async function Ze(e){const r=e?[{...W(),...e}]:h();await oe(r);const n=(r.length>1?await Promise.all(r.map(i=>q(i))):[await q(r[0]||W())]).every(Boolean),o=r.every(i=>!i.enabled||!i.userKey&&!i.machineToken);if(!e&&(n||o)){const{stopTunnelClientsExcept:i}=await import("./tunnel-client.js");i(r.filter(s=>!!s.serverUrl).map(s=>x(s.serverUrl,y(s))))}return n}async function q(e,r){if(!e.enabled)return a.info("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u672A\u542F\u7528"),a.info(`[AutoRegister] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${T()} \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_AUTO_REGISTER=true`),!1;if(!e.userKey&&!e.machineToken)return a.error("[AutoRegister] \u7F3A\u5C11\u6CE8\u518C\u51ED\u636E\uFF08\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E userKey \u6216 machineToken\uFF0C\u4E5F\u53EF\u7528 `awsb pair --ticket ...` \u914D\u5BF9\uFF09"),!1;String(e.connectionKey||"").trim()||await oe([e]);const t=ie(e);t&&!e.instanceId&&(e.instanceId=`bridge-${ue().replace(/-/g,"").slice(0,12)}`,a.info(`[AutoRegister] \u96A7\u9053\u6A21\u5F0F\uFF1A\u5DF2\u9884\u58F0\u660E instanceId=${e.instanceId}`));const n=r?.backgroundRetry?1:e.maxRetries??3,o=e.retryInterval??2e3;for(let i=1;i<=n;i++){try{d.lastAttempt=new Date;const s=await Be(e);if(s.success){if(d.registered=!0,d.instanceId=s.instanceId,s.credentialId&&(e.credentialId=s.credentialId,e.credentialType=s.credentialType),e.credentialRef=s.credentialRef,s.tenantId&&(e.tenantId=s.tenantId),s.userId&&(e.userId=s.userId),s.instanceId&&(d.registrations[N(e)]=s.instanceId,e.instanceId=s.instanceId),d.error=void 0,a.info("[AutoRegister] \u2713 \u6CE8\u518C\u6210\u529F\uFF01"),a.info(`[AutoRegister] \u5B9E\u4F8B ID: ${s.instanceId}`),a.info(`[AutoRegister] \u6D88\u606F: ${s.message}`),a.info(`[AutoRegister] \u66F4\u65B0: ${s.isUpdate?"\u662F":"\u5426"}`),s.runtimeAccessToken)try{const c=e.serverUrl||m;H({accessToken:s.runtimeAccessToken,instanceId:s.instanceId,userId:s.userId,schedulerBaseUrl:c,userKey:y(e)});const u=S(s.serverUrl);u&&u!==S(c)&&(V({serverBaseUrl:u,accessToken:s.runtimeAccessToken,userKey:y(e)}),a.info(`[AutoRegister] \u68C0\u6D4B\u5230 server \u4E0B\u53D1\u5730\u5740(${u})\u4E0E\u8FDE\u63A5\u5730\u5740(${c})\u4E0D\u540C\uFF0C\u5DF2\u6309\u4E24\u4E2A\u5730\u5740\u5206\u522B\u4FDD\u5B58 scoped token`)),a.info("[AutoRegister] \u5DF2\u4FDD\u5B58\u8C03\u5EA6\u4E2D\u5FC3\u4E0B\u53D1\u7684 runtime access token"),s.instanceId&&Ce(e.serverUrl||m,s.instanceId,e.userKey,s.credentialId,s.credentialRef,s.credentialType,e.machineToken,s.tenantId,s.userId).catch(l=>{a.warn(`[AutoRegister] \u56DE\u5199 instanceId \u5230 config.json \u5931\u8D25: ${l.message}`)})}catch(c){const u=c;return a.error(`[AutoRegister] \u4FDD\u5B58 runtime access token \u5931\u8D25: ${u.message}`),d.error=u.message,!1}else a.warn("[AutoRegister] \u6CE8\u518C\u54CD\u5E94\u672A\u5305\u542B runtime access token\uFF0CMCP \u5C06\u65E0\u6CD5\u8BBF\u95EE\u8C03\u5EA6\u4E2D\u5FC3\uFF0C\u8BF7\u68C0\u67E5 server \u7684 bridge \u5B9E\u4F8B token \u9881\u53D1\u903B\u8F91");if(t&&s.instanceId&&s.runtimeAccessToken){const{startTunnelClient:c}=await import("./tunnel-client.js"),u=e.serverUrl||m;c(u,s.instanceId,y(e)),a.info(`[AutoRegister] \u96A7\u9053\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8: server=${u}, instanceId=${s.instanceId}${e.userKey?`, userKey=****${e.userKey.slice(-4)}`:""}`)}return!0}else a.warn(`[AutoRegister] \u6CE8\u518C\u5931\u8D25: ${s.message}`),d.error=s.message}catch(s){const c=s,u=c.response?.data?JSON.stringify(c.response.data):c.message;a.error(`[AutoRegister] \u6CE8\u518C\u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${i}/${n}): ${u}`),d.error=u}i<n&&(a.info(`[AutoRegister] ${o/1e3} \u79D2\u540E\u91CD\u8BD5...`),await new Promise(s=>setTimeout(s,o)))}return r?.backgroundRetry?a.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u4ECD\u672A\u6210\u529F (server=${e.serverUrl||m}): ${d.error||"\u672A\u77E5"}`):(a.error("[AutoRegister] \u2717 \u6CE8\u518C\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570"),a.error("[AutoRegister] ========================================"),a.error("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u5DF2\u542F\u7528\u4F46\u6CE8\u518C\u5931\u8D25\uFF0C\u5B9E\u4F8B\u6682\u65F6\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C"),a.error("[AutoRegister] \u8BF7\u68C0\u67E5\u4EE5\u4E0B\u914D\u7F6E\uFF1A"),a.error(`[AutoRegister] - \u7528\u6237 Key (userKey): ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),a.error(`[AutoRegister] - \u79DF\u6237 ID (tenantId): ${e.tenantId||"(\u53EF\u9009\uFF0C\u5C06\u81EA\u52A8\u63A8\u5BFC)"}`),a.error(`[AutoRegister] - \u5B9E\u4F8B\u540D (instanceName): ${e.instanceName||"(\u4F7F\u7528\u4E3B\u673A\u540D)"}`),a.error(`[AutoRegister] - \u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740: ${e.serverUrl||m}`),a.error(`[AutoRegister] - \u6700\u540E\u9519\u8BEF: ${d.error||"\u672A\u77E5"}`),a.error("[AutoRegister] ========================================"),a.error(`[AutoRegister] \u914D\u7F6E\u6765\u6E90\uFF1A${T()} \u6216\u73AF\u5883\u53D8\u91CF`),a.warn(`[AutoRegister] \u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u6CE8\u518C\uFF08\u6BCF ${Math.round(Z()/1e3)} \u79D2\uFF09\uFF0C\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5`)),ee(e),!1}async function er(){const e=b();if(!e.userKey&&!e.machineToken)return{success:!1,error:"userKey or machineToken is required for runtime token refresh"};const r=pe(),t=j(e),n=L(e);try{const o=await $.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:e.tenantId,userKey:e.machineToken?void 0:e.userKey,machineToken:e.machineToken,instanceId:r.instanceId,instanceName:e.instanceName,runtimeBridgeBaseUrl:n},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!o.data.success||!o.data.runtimeAccessToken)return{success:!1,error:o.data.message||"scheduler did not return runtimeAccessToken"};const s=G(t,y(e))!==o.data.runtimeAccessToken;return H({accessToken:o.data.runtimeAccessToken,instanceId:r.instanceId,userId:o.data.userId||e.userKey||e.credentialId||"",schedulerBaseUrl:t,userKey:y(e)}),{success:!0,runtimeAccessToken:o.data.runtimeAccessToken,updated:s}}catch(o){const i=o;return{success:!1,error:i.response?.data?JSON.stringify(i.response.data):i.message}}}async function rr(e,r){const t=_(e);if(!t)return{success:!1,error:"serverUrl is required for runtime token refresh"};const n=h().filter(u=>_(u.serverUrl)===t),o=String(r||"").trim(),i=o?n.find(u=>String(u.userKey||"").trim()===o||String(u.credentialId||"").trim()===o):n.length===1?n[0]:void 0;if(!i)return{success:!1,error:o?"no auto-register target matches this identity":"multiple auto-register targets share this serverUrl; specify the target identity"};if(!i.userKey&&!i.machineToken)return{success:!1,error:"userKey or machineToken is required for runtime token refresh"};const s={instanceId:$e(t,y(i))},c=L(i);try{const u=await $.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:i.tenantId,userKey:i.machineToken?void 0:i.userKey,machineToken:i.machineToken,instanceId:s.instanceId,instanceName:i.instanceName,runtimeBridgeBaseUrl:c},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!u.data.success||!u.data.runtimeAccessToken)return{success:!1,error:u.data.message||"scheduler did not return runtimeAccessToken"};const I=G(t,y(i))!==u.data.runtimeAccessToken;return V({serverBaseUrl:t,accessToken:u.data.runtimeAccessToken,userKey:y(i)}),{success:!0,runtimeAccessToken:u.data.runtimeAccessToken,updated:I}}catch(u){const l=u;return{success:!1,error:l.response?.data?JSON.stringify(l.response.data):l.message}}}async function tr(){if(!d.registered||!d.instanceId)return a.info("[AutoRegister] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u65E0\u9700\u6CE8\u9500"),!0;const e=J(d.instanceId),r=e?h().find(t=>N(t)===e.targetKey):void 0;if(r&&(String(r.machineToken||"").trim()||r.credentialType==="MACHINE_TOKEN"))return a.info(`[AutoRegister] \u673A\u5668\u51ED\u636E\u76EE\u6807\uFF08instanceId=${d.instanceId}\uFF09\u8DF3\u8FC7\u6CE8\u9500\uFF1A\u914D\u5BF9\u8EAB\u4EFD\u5FC5\u987B\u8DE8\u91CD\u542F\u5B58\u6D3B\uFF0C\u4E0D\u5220\u9664\u8C03\u5EA6\u4E2D\u5FC3\u767B\u8BB0\u884C`),!0;try{const t=await be(d.instanceId);if(t.success){a.info(`[AutoRegister] \u2713 \u6CE8\u9500\u6210\u529F: ${d.instanceId}`);const n=J(d.instanceId),o=n?.serverUrl||j(b(),d.instanceId);M().schedulerBaseUrl&&me(o,n?.identityKey),ge();try{const{stopTunnelClientForTarget:s}=await import("./tunnel-client.js");s(o,n?.identityKey??y(b()))}catch(s){a.warn(`[AutoRegister] \u6CE8\u9500\u540E\u505C\u6B62\u96A7\u9053\u5931\u8D25: ${s.message}`)}if(!n)d.registered=!1,d.instanceId=void 0;else{delete d.registrations[n.targetKey];const s=Object.entries(d.registrations);d.registered=s.length>0,d.instanceId=s[s.length-1]?.[1]}return!0}else return a.warn(`[AutoRegister] \u6CE8\u9500\u5931\u8D25: ${t.message}`),!1}catch(t){const n=t;return a.error(`[AutoRegister] \u6CE8\u9500\u8BF7\u6C42\u5931\u8D25: ${n.message}`),!1}}function nr(){return{...d}}function sr(){return d.registered}function ir(){return d.instanceId}async function or(){const e=b(),r=d.instanceId,t=j(e,r),n={};if(r&&(n.instanceId=r),e.enabled&&(n.runtimeBridgeBaseUrl=L(e)),!n.instanceId&&!n.runtimeBridgeBaseUrl)return a.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6CA1\u6709 instanceId \u6216 runtimeBridgeBaseUrl\uFF0C\u8DF3\u8FC7\u6E05\u7406"),{success:!0,agentCount:0};try{a.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3..."),a.info(`[AutoRegister] instanceId: ${n.instanceId||"(\u65E0)"}`),a.info(`[AutoRegister] runtimeBridgeBaseUrl: ${n.runtimeBridgeBaseUrl||"(\u65E0)"}`);const o=await $.post(`${t}/api/instances/bridge-restart-cleanup`,n,{headers:{"Content-Type":"application/json"},timeout:1e4});return o.data.success?(a.info(`[AutoRegister] \u2713 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF1A${o.data.message}`),a.info(`[AutoRegister] \u6E05\u7406\u4E86 ${o.data.agentCount||0} \u4E2A Agent`),{success:!0,agentCount:o.data.agentCount||0}):(a.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25\uFF1A${o.data.message}`),{success:!1,error:o.data.message})}catch(o){const i=o,s=i.response?.data?JSON.stringify(i.response.data):i.message;return a.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u8BF7\u6C42\u5931\u8D25\uFF1A${s}`),{success:!1,error:s}}}export{Ze as autoRegister,or as bridgeRestartCleanup,He as cancelBackgroundRegisterRetries,Te as collapseDuplicatedSecret,qe as findConfigsByConnectionKey,T as getAutoRegisterConfigFilePath,Je as getConfiguredConnectionKeys,Ye as getCurrentConfiguredConnectionKey,ir as getInstanceId,nr as getRegistrationState,sr as isRegistered,ie as isTunnelConfig,Ve as listConfiguredTargetSummaries,W as loadConfig,h as loadConfigs,b as loadPrimaryLifecycleConfig,Qe as replaceConfiguredConnectionKey,er as requestRuntimeAccessTokenRefresh,rr as requestRuntimeAccessTokenRefreshForServer,$e as resolveInstanceIdForTarget,L as resolveRuntimeBridgeBaseUrl,Xe as resolveSchedulerBaseUrlFromToken,Ne as resolveTargetIdentityFromToken,tr as unregister};
2
2
 
@@ -1,2 +1,2 @@
1
- import{randomBytes as E}from"node:crypto";import{existsSync as N,mkdirSync as P,readFileSync as S,writeFileSync as x}from"node:fs";import A from"node:os";import _ from"node:path";import w from"axios";import{getActiveBridgeHttpPort as K,getAutoRegisterConfigFilePath as k,getBridgeRuntimePropertiesFilePath as b,schedulerBaseUrl as F}from"../config.js";import{runExclusiveConfigWrite as O}from"../utils/config-write-queue.js";import{logger as R}from"../utils/logger.js";import{normalizeTargetServerUrl as h}from"../utils/target-identity.js";const C="awsp_";function B(r){if(!N(r))return{};try{return JSON.parse(S(r,"utf-8"))}catch(n){throw new Error(`\u65E0\u6CD5\u89E3\u6790\u914D\u7F6E\u6587\u4EF6 ${r}: ${n.message}`)}}function $(r){return Array.isArray(r.autoRegisterTargets)?r.autoRegisterTargets.filter(n=>!!(n&&typeof n=="object"&&!Array.isArray(n))):[]}function M(){return`bridge-${E(6).toString("hex")}`}function j(r,n){return/^https?:\/\//i.test(r)?r:/:[0-9]+$/.test(r)?`http://${r}`:`http://${r}:${n}`}function q(r,n){const s=$(r),l=n.serverUrl?.trim(),e=l?h(l):"",f=String(n.instanceId||"").trim(),y=String(n.targetIdentity||"").trim();let i=-1,c=r,g=!1;if(s.length>0){const d=s.map((o,U)=>({item:o,itemIndex:U})).filter(({item:o})=>!e||h(o.serverUrl||o.schedulerBaseUrl)===e);let m=d;if(f){const o=d.filter(({item:U})=>String(U.instanceId||"").trim()===f);if(o.length>1)throw new Error(`\u5339\u914D\u5230\u591A\u4E2A instanceId=${f} \u7684\u914D\u5BF9\u76EE\u6807\uFF0C\u8BF7\u68C0\u67E5 config.json`);o.length===1?m=o:(m=[],g=!0)}else if(y){if(m=d.filter(({item:o})=>String(o.credentialId||o.userKey||"").trim()===y),m.length>1)throw new Error("\u5339\u914D\u5230\u591A\u4E2A\u914D\u5BF9\u76EE\u6807\uFF0C\u8BF7\u7528 --instance-id \u6216 --target-identity \u7CBE\u786E\u6307\u5B9A");if(m.length===0)throw new Error("\u6307\u5B9A targetIdentity \u7684\u914D\u5BF9\u76EE\u6807\u4E0D\u5B58\u5728")}else if(d.length>1)throw new Error("\u5B58\u5728\u591A\u4E2A\u6CE8\u518C\u76EE\u6807\uFF0C\u8BF7\u7528 --server-url \u642D\u914D --instance-id / --target-identity \u6307\u5B9A\u672C\u6B21\u914D\u5BF9\u76EE\u6807");if(g)i=s.length;else if(i=m[0]?.itemIndex??-1,i<0){if(!e)throw new Error("\u65E0\u6CD5\u786E\u5B9A\u914D\u5BF9\u76EE\u6807\uFF0C\u8BF7\u7528 --server-url \u6307\u5B9A");c={serverUrl:l},i=s.length,g=!0}else c=s[i]||{}}const p=h(l||c.serverUrl||c.schedulerBaseUrl||F);if(!p)throw new Error("\u65E0\u6CD5\u786E\u5B9A\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\uFF0C\u8BF7\u7528 --server-url \u6307\u5B9A");const a=n.registerAddr||String(c.registerAddr||c.registerIp||c.virtualIp||"").trim(),u=c.tunnel===!0?!0:c.tunnel===!1?!1:!a;let t=f||String(c.instanceId||"").trim()||void 0,I;if(u){t||(t=M());const d=new URL(p);I=`${d.protocol}//${d.host}/tunnel/${t}`}else I=j(a,K());const v=String(c.connectionKey||"").trim(),T=n.instanceName?.trim()||String(c.instanceName||"").trim()||A.hostname();return{index:i,target:c,serverUrl:p,tunnel:u,instanceId:t,connectionKey:v,instanceName:T,runtimeBridgeBaseUrl:I,isNewTarget:g}}async function G(r,n){return(await w.post(r,n,{headers:{"Content-Type":"application/json"},timeout:15e3})).data}const Y=2500,D=1e3;function z(){try{const r=b();if(!N(r))return null;const s=S(r,"utf-8").split(/\r?\n/).find(e=>/^port\s*[=:]/.test(e.trim()));if(!s)return null;const l=Number(s.split(/[=:]/)[1]?.trim());return Number.isInteger(l)&&l>=1&&l<=65535?l:null}catch{return null}}async function re(){const r=z();if(!r)return!1;const n=`http://127.0.0.1:${r}/runtime/pair-applied`;for(let s=1;s<=2;s+=1)try{return(await w.post(n,{},{timeout:Y})).data?.ok===!0}catch(l){if(l.response?.status===404)return!1;s<2&&await new Promise(f=>setTimeout(f,D))}return!1}async function te(r){const n=String(r.ticket||"").trim();if(!n.startsWith(C))return{success:!1,error:"\u914D\u5BF9\u7968\u636E\u683C\u5F0F\u4E0D\u6B63\u786E\uFF08\u5E94\u4EE5 awsp_ \u5F00\u5934\uFF09\uFF0C\u8BF7\u4ECE\u7BA1\u7406\u9875\u91CD\u65B0\u590D\u5236"};const s=r.configPath||k(),l=B(s);let e;try{e=q(l,r)}catch(a){return{success:!1,error:a.message}}const f={pairingTicket:n,instanceName:e.instanceName,runtimeBridgeBaseUrl:e.runtimeBridgeBaseUrl};e.instanceId&&(f.instanceId=e.instanceId);const y=r.postPair||G;let i;try{i=await y(`${e.serverUrl}/api/instances/pair`,f)}catch(a){const u=a;return{success:!1,error:u.response?.data?.message||u.message||"\u914D\u5BF9\u8BF7\u6C42\u5931\u8D25"}}if(!i?.success||!i.machineToken||!i.instanceId)return{success:!1,error:i?.message||"\u8C03\u5EA6\u4E2D\u5FC3\u672A\u8FD4\u56DE\u673A\u5668\u51ED\u636E"};const c=String(i.connectionKey||"").trim();if(!c)return{success:!1,error:"\u8C03\u5EA6\u4E2D\u5FC3\u672A\u8FD4\u56DE\u8FDE\u63A5\u5BC6\u94A5\uFF08server \u7248\u672C\u8FC7\u65E7\uFF1F\uFF09\uFF0C\u8BF7\u5347\u7EA7 server \u540E\u91CD\u8BD5"};const g=i.instanceId,p=i.instanceName||e.instanceName;try{await O(s,()=>{const a=B(s),u=$(a);let t;if(Array.isArray(a.autoRegisterTargets)&&u.length>0){const I=u.filter(o=>h(o.serverUrl||o.schedulerBaseUrl)===h(e.serverUrl)),v=String(e.target.userKey||"").trim(),T=e.instanceId?I.filter(o=>String(o.instanceId||"").trim()===e.instanceId):[],d=v?I.filter(o=>String(o.userKey||"").trim()===v):[];if(T.length>1||d.length>1)throw new Error(`\u914D\u5BF9\u5199\u56DE\u5931\u8D25\uFF1A\u5339\u914D\u5230\u591A\u4E2A\u76EE\u6807\uFF08server=${e.serverUrl}\uFF09\uFF0C\u8BF7\u7528 instanceId / target identity \u7CBE\u786E\u6307\u5B9A`);const m=T[0]||d[0]||(I.length===1&&!e.isNewTarget?I[0]:void 0);m?t=m:!e.isNewTarget&&e.index>=0&&u[e.index]?t=u[e.index]:(t={serverUrl:e.serverUrl},u.push(t),a.autoRegisterTargets=u)}else t=a;t.serverUrl=t.serverUrl||e.serverUrl,t.instanceName=t.instanceName||p,t.instanceId=g,t.credentialId=g,delete t.credentialRef,t.credentialType=i.credentialType||"MACHINE_TOKEN",t.machineToken=i.machineToken,t.connectionKey=c,i.tenantId&&(t.tenantId=i.tenantId),i.userId&&(t.userId=i.userId),Array.isArray(a.autoRegisterTargets)&&a.autoRegisterTargets.length>0&&String(a.connectionKey||"").trim()&&delete a.connectionKey,P(_.dirname(s),{recursive:!0}),x(s,JSON.stringify(a,null,2),"utf-8")})}catch(a){return{success:!1,error:a.message}}return e.instanceId&&e.instanceId!==g&&R.info(`[Pair] server \u5DF2\u6309\u7968\u636E\u786E\u5B9A\u5B9E\u4F8B id\uFF1A${g}\uFF08\u672C\u5730\u6B64\u524D\u4E3A ${e.instanceId}\uFF09\uFF0Cconfig.json \u5DF2\u5199\u56DE\u65B0 id`),R.info(`[Pair] \u914D\u5BF9\u6210\u529F: server=${e.serverUrl}, instanceId=${g}, machineToken \u5DF2\u5199\u5165 ${s}`),{success:!0,instanceId:g,serverUrl:e.serverUrl}}export{re as notifyRunningBridgeAfterPair,te as pairBridge,z as readRunningBridgePort,q as resolvePairTarget};
1
+ import{randomBytes as E}from"node:crypto";import{existsSync as S,mkdirSync as P,readFileSync as w,writeFileSync as x}from"node:fs";import A from"node:os";import _ from"node:path";import N from"axios";import{getActiveBridgeHttpPort as K,getAutoRegisterConfigFilePath as k,getBridgeRuntimePropertiesFilePath as b,schedulerBaseUrl as F}from"../config.js";import{runExclusiveConfigWrite as O}from"../utils/config-write-queue.js";import{logger as R}from"../utils/logger.js";import{normalizeTargetServerUrl as h}from"../utils/target-identity.js";const C="awsp_";function B(r){if(!S(r))return{};try{return JSON.parse(w(r,"utf-8"))}catch(n){throw new Error(`\u65E0\u6CD5\u89E3\u6790\u914D\u7F6E\u6587\u4EF6 ${r}: ${n.message}`)}}function $(r){return Array.isArray(r.autoRegisterTargets)?r.autoRegisterTargets.filter(n=>!!(n&&typeof n=="object"&&!Array.isArray(n))):[]}function M(){return`bridge-${E(6).toString("hex")}`}function j(r,n){return/^https?:\/\//i.test(r)?r:/:[0-9]+$/.test(r)?`http://${r}`:`http://${r}:${n}`}function q(r,n){const s=$(r),l=n.serverUrl?.trim(),e=l?h(l):"",f=String(n.instanceId||"").trim(),y=String(n.targetIdentity||"").trim();let i=-1,c=r,g=!1;if(s.length>0){const d=s.map((o,U)=>({item:o,itemIndex:U})).filter(({item:o})=>!e||h(o.serverUrl||o.schedulerBaseUrl)===e);let m=d;if(f){const o=d.filter(({item:U})=>String(U.instanceId||"").trim()===f);if(o.length>1)throw new Error(`\u5339\u914D\u5230\u591A\u4E2A instanceId=${f} \u7684\u914D\u5BF9\u76EE\u6807\uFF0C\u8BF7\u68C0\u67E5 config.json`);o.length===1?m=o:(m=[],g=!0)}else if(y){if(m=d.filter(({item:o})=>String(o.credentialId||o.userKey||"").trim()===y),m.length>1)throw new Error("\u5339\u914D\u5230\u591A\u4E2A\u914D\u5BF9\u76EE\u6807\uFF0C\u8BF7\u7528 --instance-id \u6216 --target-identity \u7CBE\u786E\u6307\u5B9A");if(m.length===0)throw new Error("\u6307\u5B9A targetIdentity \u7684\u914D\u5BF9\u76EE\u6807\u4E0D\u5B58\u5728")}else if(d.length>1)throw new Error("\u5B58\u5728\u591A\u4E2A\u6CE8\u518C\u76EE\u6807\uFF0C\u8BF7\u7528 --server-url \u642D\u914D --instance-id / --target-identity \u6307\u5B9A\u672C\u6B21\u914D\u5BF9\u76EE\u6807");if(g)i=s.length;else if(i=m[0]?.itemIndex??-1,i<0){if(!e)throw new Error("\u65E0\u6CD5\u786E\u5B9A\u914D\u5BF9\u76EE\u6807\uFF0C\u8BF7\u7528 --server-url \u6307\u5B9A");c={serverUrl:l},i=s.length,g=!0}else c=s[i]||{}}const p=h(l||c.serverUrl||c.schedulerBaseUrl||F);if(!p)throw new Error("\u65E0\u6CD5\u786E\u5B9A\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\uFF0C\u8BF7\u7528 --server-url \u6307\u5B9A");const a=n.registerAddr||String(c.registerAddr||c.registerIp||c.virtualIp||"").trim(),u=c.tunnel===!0?!0:c.tunnel===!1?!1:!a;let t=f||String(c.instanceId||"").trim()||void 0,I;if(u){t||(t=M());const d=new URL(p);I=`${d.protocol}//${d.host}/tunnel/${t}`}else I=j(a,K());const v=String(c.connectionKey||"").trim(),T=n.instanceName?.trim()||String(c.instanceName||"").trim()||A.hostname();return{index:i,target:c,serverUrl:p,tunnel:u,instanceId:t,connectionKey:v,instanceName:T,runtimeBridgeBaseUrl:I,isNewTarget:g}}async function G(r,n){return(await N.post(r,n,{headers:{"Content-Type":"application/json"},timeout:15e3})).data}const Y=2500,D=1e3;function z(){try{const r=b();if(!S(r))return null;const s=w(r,"utf-8").split(/\r?\n/).find(e=>/^port\s*[=:]/.test(e.trim()));if(!s)return null;const l=Number(s.split(/[=:]/)[1]?.trim());return Number.isInteger(l)&&l>=1&&l<=65535?l:null}catch{return null}}async function re(){const r=z();if(!r)return!1;const n=`http://127.0.0.1:${r}/runtime/pair-applied`;for(let s=1;s<=2;s+=1)try{return(await N.post(n,{},{timeout:Y})).data?.ok===!0}catch(l){if(l.response?.status===404)return!1;s<2&&await new Promise(f=>setTimeout(f,D))}return!1}async function te(r){const n=String(r.ticket||"").trim();if(!n.startsWith(C))return{success:!1,error:"\u914D\u5BF9\u7968\u636E\u683C\u5F0F\u4E0D\u6B63\u786E\uFF08\u5E94\u4EE5 awsp_ \u5F00\u5934\uFF09\uFF0C\u8BF7\u4ECE\u7BA1\u7406\u9875\u91CD\u65B0\u590D\u5236"};const s=r.configPath||k(),l=B(s);let e;try{e=q(l,r)}catch(a){return{success:!1,error:a.message}}const f={pairingTicket:n,instanceName:e.instanceName,runtimeBridgeBaseUrl:e.runtimeBridgeBaseUrl};e.instanceId&&(f.instanceId=e.instanceId);const y=r.postPair||G;let i;try{i=await y(`${e.serverUrl}/api/instances/pair`,f)}catch(a){const u=a;return{success:!1,error:u.response?.data?.message||u.message||"\u914D\u5BF9\u8BF7\u6C42\u5931\u8D25"}}if(!i?.success||!i.machineToken||!i.instanceId)return{success:!1,error:i?.message||"\u8C03\u5EA6\u4E2D\u5FC3\u672A\u8FD4\u56DE\u673A\u5668\u51ED\u636E"};const c=String(i.connectionKey||"").trim();if(!c)return{success:!1,error:"\u8C03\u5EA6\u4E2D\u5FC3\u672A\u8FD4\u56DE\u8FDE\u63A5\u5BC6\u94A5\uFF08server \u7248\u672C\u8FC7\u65E7\uFF1F\uFF09\uFF0C\u8BF7\u5347\u7EA7 server \u540E\u91CD\u8BD5"};const g=i.instanceId,p=i.instanceName||e.instanceName;try{await O(s,()=>{const a=B(s),u=$(a);let t;if(Array.isArray(a.autoRegisterTargets)&&u.length>0){const I=u.filter(o=>h(o.serverUrl||o.schedulerBaseUrl)===h(e.serverUrl)),v=String(e.target.userKey||"").trim(),T=e.instanceId?I.filter(o=>String(o.instanceId||"").trim()===e.instanceId):[],d=v?I.filter(o=>String(o.userKey||"").trim()===v):[];if(T.length>1||d.length>1)throw new Error(`\u914D\u5BF9\u5199\u56DE\u5931\u8D25\uFF1A\u5339\u914D\u5230\u591A\u4E2A\u76EE\u6807\uFF08server=${e.serverUrl}\uFF09\uFF0C\u8BF7\u7528 instanceId / target identity \u7CBE\u786E\u6307\u5B9A`);const m=T[0]||d[0]||(I.length===1&&!e.isNewTarget?I[0]:void 0);m?t=m:!e.isNewTarget&&e.index>=0&&u[e.index]?t=u[e.index]:(t={serverUrl:e.serverUrl},u.push(t),a.autoRegisterTargets=u)}else t=a;t.serverUrl=t.serverUrl||e.serverUrl,t.instanceName=p,t.instanceId=g,t.credentialId=g,delete t.credentialRef,t.credentialType=i.credentialType||"MACHINE_TOKEN",t.machineToken=i.machineToken,t.connectionKey=c,i.tenantId&&(t.tenantId=i.tenantId),i.userId&&(t.userId=i.userId),Array.isArray(a.autoRegisterTargets)&&a.autoRegisterTargets.length>0&&String(a.connectionKey||"").trim()&&delete a.connectionKey,P(_.dirname(s),{recursive:!0}),x(s,JSON.stringify(a,null,2),"utf-8")})}catch(a){return{success:!1,error:a.message}}return e.instanceId&&e.instanceId!==g&&R.info(`[Pair] server \u5DF2\u6309\u7968\u636E\u786E\u5B9A\u5B9E\u4F8B id\uFF1A${g}\uFF08\u672C\u5730\u6B64\u524D\u4E3A ${e.instanceId}\uFF09\uFF0Cconfig.json \u5DF2\u5199\u56DE\u65B0 id`),R.info(`[Pair] \u914D\u5BF9\u6210\u529F: server=${e.serverUrl}, instanceId=${g}, machineToken \u5DF2\u5199\u5165 ${s}`),{success:!0,instanceId:g,serverUrl:e.serverUrl}}export{re as notifyRunningBridgeAfterPair,te as pairBridge,z as readRunningBridgePort,q as resolvePairTarget};
2
2
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-runtime-bridge",
3
- "version": "1.9.184",
3
+ "version": "1.9.185",
4
4
  "description": "AgentsWorkStudio runtime bridge service for machine-level agent runtime integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",