@16x/webphone-sdk 3.1.10 → 3.8.1

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.
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../SharedWorkerProtocol-39dch6xL.cjs"),t=require("../CCBarClient-z-TFUjTB.cjs");require("../createJsSipFactory-Dr8HbLl-.cjs");var n=class extends Error{code=`LEGACY_METHOD_DEPRECATED`;constructor(e,t){super(`${e} 已废弃:${t}`),this.name=`DeprecatedError`}},r=class{client;warnedMethods=new Set;unsubscribeIncoming;currentCall;constructor(e){this.client=new t.t(e),this.unsubscribeIncoming=this.client.on(`call.incoming`,({callId:e})=>{this.currentCall=this.client.getCalls().find(t=>t.id===e)})}getToken(...e){return this.warn(`getToken`,`请改用 client.connect()`),this.client.connect()}getAccount(...e){return this.warn(`getAccount`,`请改用 client.connect()`),this.client.connect()}login(...e){return this.warn(`login`,`请改用 client.connect()`),this.client.connect()}async call(e,...t){this.warn(`call`,`请改用 client.dial({ destination })`);let n=await this.client.dial({destination:String(e)});return this.currentCall=n,n}async insideCall(e,...t){this.warn(`insideCall`,`请改用 client.dial({ destination, type: 'extension' })`);let n=await this.client.dial({destination:String(e),type:`extension`});return this.currentCall=n,n}answer(...e){this.warn(`answer`,`请改用 call.answer()`);let t=this.requireCurrentCall();return this.client.answer(t.id)}async hangup(...e){this.warn(`hangup`,`请改用 call.hangup()`);let t=this.requireCurrentCall();try{await t.hangup()}finally{this.currentCall===t&&(this.currentCall=void 0)}}holdCall(...e){return this.warn(`holdCall`,`请改用 call.hold()`),this.requireCurrentCall().hold()}unholdCall(...e){return this.warn(`unholdCall`,`请改用 call.resume()`),this.requireCurrentCall().resume()}transSo(e,...t){return this.warn(`transSo`,`请改用 call.transfer({ target, type: 'blind' })`),this.requireCurrentCall().transfer({target:String(e),type:`blind`})}async signOut(...e){this.warn(`signOut`,`请改用 client.disconnect() 和 client.dispose()`);let t;try{await this.client.disconnect()}catch(e){t=e}try{await this.client.dispose()}catch(e){t??=e}if(this.unsubscribeIncoming(),this.currentCall=void 0,t!==void 0)throw t}setId(...e){return this.warn(`setId`,`请改用 client.setAgentStatus('available')`),this.client.setAgentStatus(`available`)}setBu(...e){throw this.warn(`setBu`,`busy由通话状态或服务端状态策略控制,浏览器不得伪造`),new n(`setBu()`,`busy由通话状态或服务端状态策略控制,浏览器不得伪造`)}setRe(...e){return this.warn(`setRe`,`请改用 client.setAgentStatus('break')`),this.client.setAgentStatus(`break`)}requireCurrentCall(){let t=this.client.getActiveCall();if(t!==void 0&&(this.currentCall=t),this.currentCall===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1);return this.currentCall}warn(e,t){i()&&!this.warnedMethods.has(e)&&(this.warnedMethods.add(e),console.warn(`[CCBarSDK] ${e}() 已废弃。${t}`))}};function i(){return!1}var a=`/openapi/token/v1`,o=`/seat/account/get`,s=`/seats/set-status`,c=`/api/fs/sip-ws`,l=7443,u=3478,d=600,f=600,p=180,m=60,h=5e3,g=2e4,_=[`outbound`,`inbound`,`mute`,`dtmf`,`hold`,`blind_transfer`],v={available:{status:`Available`,reason:`空闲`},break:{status:`On Break`,reason:`休息`},offline:{status:`Logged Out`,reason:``}};function y(n){let r=b(n.host),i=x(n.pathPrefix??a),g=`${r}${i}${S(n.accountPath??o)}`,y=`${r}${i}${S(n.statusPath??s)}`,D=S(n.sipWsPath??c),O={...n.aesKey?{key:n.aesKey}:{},...n.aesIv?{iv:n.aesIv}:{}},k=Math.max(0,n.refreshBufferSeconds??p),A=n.fetchImpl??globalThis.fetch,j,M,N=``;async function P(){if(n.getToken!==void 0)return n.getToken();if(n.tokenUrl!==void 0){let t=n.tokenMethod??`POST`,r={method:t,headers:{Accept:`application/json`,...n.tokenHeaders??{}},credentials:`include`};t===`POST`&&(r.headers={"Content-Type":`application/json`,...r.headers},r.body=JSON.stringify(n.tokenBody??{}));let i=await E(A,n.tokenUrl,r,`取 token`),a=await i.text();try{return JSON.parse(a)}catch{throw new e.i(`AUTH_TOKEN_UNAVAILABLE`,`auth`,!0,{status:i.status,cause:`取 token 的接口返回了非 JSON 响应(HTTP ${i.status}):${a.trim().slice(0,120)}`})}}throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`createLegacySessionProvider 需要 getToken 或 tokenUrl;坐席状态也可以直接用会话软电话地址里的 token(setAgentStatus 的 context.wssUrl),但这次调用没有会话可用`})}async function F(){if(j&&j.expiresAtMs-Date.now()>h)return j.token;let t;try{t=await P()}catch(t){throw t instanceof e.i?t:new e.i(`AUTH_TOKEN_UNAVAILABLE`,`auth`,!0,{cause:t})}let n=T(t);if(!n.token)throw new e.i(`AUTH_TOKEN_UNAVAILABLE`,`auth`,!0,{cause:`取 token 的返回里没有 token(支持 {token}、{accessToken}、{data:{token}} 或裸字符串)`});let r=w(n.expires,3600);return j={token:n.token,expiresAtMs:Date.now()+r*1e3},j.token}function I(e){if(!e)return``;try{return String(new URL(e).searchParams.get(`token`)??``).trim()}catch{return``}}async function L(e){let t=I(e?.wssUrl);return t?(N=t,t):N||F()}async function R(t){let n=t||await F(),r=await E(A,g,{method:`POST`,headers:{Authorization:n,"Content-Type":`application/json`,Accept:`application/json`},body:`{}`},`取坐席账号`),i=await r.text(),a;try{a=JSON.parse(i)}catch{throw new e.i(`LEGACY_PLATFORM_UNREACHABLE`,`network`,!0,{status:r.status,cause:`${g} 返回了非 JSON 响应(HTTP ${r.status});请确认 host 填的是接口网关(不是文档站)`})}let o=Number(a.code??NaN);if(!r.ok||o!==0)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,o===50,{status:r.status,serverCode:Number.isFinite(o)?String(o):void 0,cause:a.message||`取坐席账号失败(HTTP ${r.status})`});if(!a.data)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号接口没有返回 data`});return M=a.data,M}let z=e=>t.i(e,O);function B(t,i){let a=Number(t.wssPort)||l,o=String(t.domain??``).trim(),s=String(n.sipWsUrl??``).trim(),c;if(s)c=new URL(s,r),c.protocol===`http:`&&(c.protocol=`ws:`),c.protocol===`https:`&&(c.protocol=`wss:`);else{if(!o)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 domain,无法拼软电话地址;可用 sipWsUrl 显式指定`});let t=a===443?``:`:${a}`;c=new URL(`wss://${o}${t}${D}`)}return(n.attachTokenToWss??!0)&&i&&c.searchParams.set(`token`,i),c.toString()}function V(e){let t=(Array.isArray(e.iceServers)?e.iceServers:[]).map(e=>{let t=(Array.isArray(e?.urls)?e.urls:typeof e?.urls==`string`?[e.urls]:[]).map(e=>String(e??``).trim()).filter(Boolean);if(t.length!==0)return{urls:t,...e?.username?{username:String(e.username)}:{},...e?.credential?{credential:String(e.credential)}:{}}}).filter(e=>e!==void 0);if(t.length>0)return t;let n=String(e.turnIp??``).trim();return n?[{urls:[`stun:${n}:${Number(e.turnPort)||u}`]}]:[]}async function H(){let t=await F(),i=await R(),a=String(i.username??i.account??``).trim();if(!a)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 username`});let o=String(i.registerPassword??i.password??``),s=o?await z(o):``;if(!s)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 password/registerPassword,或解密后为空`});let c=w(i.expiresIn??i.expires_in,f),l=Math.max(0,Math.round((j.expiresAtMs-Date.now())/1e3)),u=Math.max(m,Math.min(l||c,c)-k),p=String(i.domain??``).trim()||C(r),h=B(i,t);return t&&(N=t),{sessionId:`legacy-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,expiresAt:Math.floor(Date.now()/1e3)+u,agent:{id:a,externalUserId:a,displayName:a,extension:a,status:`Available`},sip:{uri:`sip:${a}@${p}`,registrar:p,registerTicket:s,registerExpires:Number(n.registerExpires)>0?Number(n.registerExpires):d,ticketExpiresIn:u},transport:{wssUrl:h,ticket:``,ticketExpiresIn:u},iceServers:V(i),policy:{maxConcurrentCalls:Number(n.maxConcurrentCalls)>0?Number(n.maxConcurrentCalls):2,incomingEnabled:n.incomingEnabled??!0,mobileIncomingEnabled:n.mobileIncomingEnabled??!0,backgroundCallingSupported:!1},capabilities:[...n.capabilities??_]}}return{createSession:H,refreshSession:H,setAgentStatus:async({status:t,reason:n},r)=>{let i=await L(r),a=M??await R(i),o=String(a.username??a.account??``).trim();if(!o)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 username`});let s=v[t],c=await E(A,y,{method:`POST`,headers:{Authorization:i,"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({extension:o,status:s.status,reason:n||s.reason})},`设置坐席状态`),l=await c.text(),u;try{u=JSON.parse(l)}catch{throw new e.i(`LEGACY_PLATFORM_UNREACHABLE`,`network`,!0,{status:c.status,cause:`${y} 返回了非 JSON 响应(HTTP ${c.status})`})}let d=Number(u.code??NaN);if(!c.ok||d!==0)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,d===50,{status:c.status,serverCode:Number.isFinite(d)?String(d):void 0,cause:u.message||`设置坐席状态失败(HTTP ${c.status})`})},invalidateToken:()=>{j=void 0,N=``},getSeatAccount:async()=>M??R()}}function b(t){let n=String(t??``).trim().replace(/\/+$/,``);if(!n)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`createLegacySessionProvider 需要 host`});return/^https?:\/\//i.test(n)?n:`https://${n}`}function x(e){let t=String(e??``).trim();return!t||t===`/`?``:`/${t.replace(/^\/+|\/+$/g,``)}`}function S(e){let t=String(e??``).trim();return t.startsWith(`/`)?t:`/${t}`}function C(e){try{return new URL(e).hostname}catch{return``}}function w(e,t){let n=Number(e);return!Number.isFinite(n)||n<=0?t:(n>86400&&(n/=1e3),Math.min(Math.max(Math.floor(n),m),86400))}function T(e){if(typeof e==`string`)return{token:e.trim()};let t=e??{},n=typeof t.data==`object`&&t.data!==null?t.data:void 0;for(let e of[t,n]){if(e===void 0)continue;let t=e.token??e.accessToken;if(typeof t==`string`&&t.trim()){let n=Number(e.expires??e.expiresIn??e.expires_at);return{token:t.trim(),...Number.isFinite(n)&&n>0?{expires:n}:{}}}}return{token:``}}async function E(t,n,r,i){let a=new AbortController,o=setTimeout(()=>a.abort(),g);try{return await t(n,{...r,signal:a.signal})}catch(t){let r=a.signal.aborted;throw new e.i(r?`NETWORK_TIMEOUT`:`LEGACY_PLATFORM_UNREACHABLE`,`network`,!0,{cause:r?`${i}超时(${g/1e3} 秒):POST ${n}`:`${i}失败:无法请求 ${n}(${t instanceof Error?t.message:String(t)})`})}finally{clearTimeout(o)}}var D=`0.1.0`;typeof window<`u`&&(window.CCBarSDK=r),exports.CCBarSDK=r,exports.DeprecatedError=n,exports.createLegacySessionProvider=y,exports.decryptSipPassword=t.i,exports.legacyVersion=D;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../SharedWorkerProtocol-39dch6xL.cjs"),t=require("../CCBarClient-BJryiSYT.cjs");require("../createJsSipFactory-Dr8HbLl-.cjs");var n=class extends Error{code=`LEGACY_METHOD_DEPRECATED`;constructor(e,t){super(`${e} 已废弃:${t}`),this.name=`DeprecatedError`}},r=class{client;warnedMethods=new Set;unsubscribeIncoming;currentCall;constructor(e){this.client=new t.t(e),this.unsubscribeIncoming=this.client.on(`call.incoming`,({callId:e})=>{this.currentCall=this.client.getCalls().find(t=>t.id===e)})}getToken(...e){return this.warn(`getToken`,`请改用 client.connect()`),this.client.connect()}getAccount(...e){return this.warn(`getAccount`,`请改用 client.connect()`),this.client.connect()}login(...e){return this.warn(`login`,`请改用 client.connect()`),this.client.connect()}async call(e,...t){this.warn(`call`,`请改用 client.dial({ destination })`);let n=await this.client.dial({destination:String(e)});return this.currentCall=n,n}async insideCall(e,...t){this.warn(`insideCall`,`请改用 client.dial({ destination, type: 'extension' })`);let n=await this.client.dial({destination:String(e),type:`extension`});return this.currentCall=n,n}answer(...e){this.warn(`answer`,`请改用 call.answer()`);let t=this.requireCurrentCall();return this.client.answer(t.id)}async hangup(...e){this.warn(`hangup`,`请改用 call.hangup()`);let t=this.requireCurrentCall();try{await t.hangup()}finally{this.currentCall===t&&(this.currentCall=void 0)}}holdCall(...e){return this.warn(`holdCall`,`请改用 call.hold()`),this.requireCurrentCall().hold()}unholdCall(...e){return this.warn(`unholdCall`,`请改用 call.resume()`),this.requireCurrentCall().resume()}transSo(e,...t){return this.warn(`transSo`,`请改用 call.transfer({ target, type: 'blind' })`),this.requireCurrentCall().transfer({target:String(e),type:`blind`})}async signOut(...e){this.warn(`signOut`,`请改用 client.disconnect() 和 client.dispose()`);let t;try{await this.client.disconnect()}catch(e){t=e}try{await this.client.dispose()}catch(e){t??=e}if(this.unsubscribeIncoming(),this.currentCall=void 0,t!==void 0)throw t}setId(...e){return this.warn(`setId`,`请改用 client.setAgentStatus('available')`),this.client.setAgentStatus(`available`)}setBu(...e){throw this.warn(`setBu`,`busy由通话状态或服务端状态策略控制,浏览器不得伪造`),new n(`setBu()`,`busy由通话状态或服务端状态策略控制,浏览器不得伪造`)}setRe(...e){return this.warn(`setRe`,`请改用 client.setAgentStatus('break')`),this.client.setAgentStatus(`break`)}requireCurrentCall(){let t=this.client.getActiveCall();if(t!==void 0&&(this.currentCall=t),this.currentCall===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1);return this.currentCall}warn(e,t){i()&&!this.warnedMethods.has(e)&&(this.warnedMethods.add(e),console.warn(`[CCBarSDK] ${e}() 已废弃。${t}`))}};function i(){return!1}var a=`q7X4p6MvK1z8Lb3A`,o=`W9e2T4mN0aQ7Ru6C`;async function s(t,n={}){let r=String(t??``).replace(/\s+/g,``);if(!r)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`解密的密文为空:坐席账号里没有 password/registerPassword`});let i=n.subtle??globalThis.crypto?.subtle;if(i===void 0)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`需要 WebCrypto 才能解 SIP 密码:请在安全上下文(https / localhost)或 Node 18+ 里运行`});let s;try{let e=atob(r);s=new Uint8Array(new ArrayBuffer(e.length));for(let t=0;t<e.length;t+=1)s[t]=e.charCodeAt(t)}catch{throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`密文不是合法的 Base64:确认取的是 password/registerPassword 原值,没有被截断或转义`})}let l=await i.importKey(`raw`,c(n.key??a),`AES-CBC`,!1,[`decrypt`]);try{let e=await i.decrypt({name:`AES-CBC`,iv:c(n.iv??o)},l,s);return new TextDecoder(`utf-8`).decode(e).trim()}catch(t){throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`SIP 密码解密失败(检查 key/iv 与该环境是否一致):${t instanceof Error?t.message:String(t)}`})}}function c(e){let t=new TextEncoder().encode(e),n=new Uint8Array(new ArrayBuffer(t.byteLength));return n.set(t),n}var l=`/openapi/token/v1`,u=`/seat/account/get`,d=`/seats/set-status`,f=`/api/fs/sip-ws`,p=7443,m=3478,h=600,g=600,_=180,v=60,y=5e3,b=2e4,x=[`outbound`,`inbound`,`mute`,`dtmf`,`hold`,`blind_transfer`],S={available:{status:`Available`,reason:`空闲`},break:{status:`On Break`,reason:`休息`},offline:{status:`Logged Out`,reason:``}};function C(t){let n=w(t.host),r=T(t.pathPrefix??l),i=`${n}${r}${E(t.accountPath??u)}`,a=`${n}${r}${E(t.statusPath??d)}`,o=E(t.sipWsPath??f),c={...t.aesKey?{key:t.aesKey}:{},...t.aesIv?{iv:t.aesIv}:{}},b=Math.max(0,t.refreshBufferSeconds??_),C=t.fetchImpl??globalThis.fetch,j,M,N=``;async function P(){if(t.getToken!==void 0)return t.getToken();if(t.tokenUrl!==void 0){let n=t.tokenMethod??`POST`,r={method:n,headers:{Accept:`application/json`,...t.tokenHeaders??{}},credentials:`include`};n===`POST`&&(r.headers={"Content-Type":`application/json`,...r.headers},r.body=JSON.stringify(t.tokenBody??{}));let i=await A(C,t.tokenUrl,r,`取 token`),a=await i.text();try{return JSON.parse(a)}catch{throw new e.i(`AUTH_TOKEN_UNAVAILABLE`,`auth`,!0,{status:i.status,cause:`取 token 的接口返回了非 JSON 响应(HTTP ${i.status}):${a.trim().slice(0,120)}`})}}throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`createLegacySessionProvider 需要 getToken 或 tokenUrl;坐席状态也可以直接用会话软电话地址里的 token(setAgentStatus 的 context.wssUrl),但这次调用没有会话可用`})}async function F(){if(j&&j.expiresAtMs-Date.now()>y)return j.token;let t;try{t=await P()}catch(t){throw t instanceof e.i?t:new e.i(`AUTH_TOKEN_UNAVAILABLE`,`auth`,!0,{cause:t})}let n=k(t);if(!n.token)throw new e.i(`AUTH_TOKEN_UNAVAILABLE`,`auth`,!0,{cause:`取 token 的返回里没有 token(支持 {token}、{accessToken}、{data:{token}} 或裸字符串)`});let r=O(n.expires,3600);return j={token:n.token,expiresAtMs:Date.now()+r*1e3},j.token}function I(e){if(!e)return``;try{return String(new URL(e).searchParams.get(`token`)??``).trim()}catch{return``}}async function L(e){let t=I(e?.wssUrl);return t?(N=t,t):N||F()}async function R(t){let n=t||await F(),r=await A(C,i,{method:`POST`,headers:{Authorization:n,"Content-Type":`application/json`,Accept:`application/json`},body:`{}`},`取坐席账号`),a=await r.text(),o;try{o=JSON.parse(a)}catch{throw new e.i(`LEGACY_PLATFORM_UNREACHABLE`,`network`,!0,{status:r.status,cause:`${i} 返回了非 JSON 响应(HTTP ${r.status});请确认 host 填的是接口网关(不是文档站)`})}let s=Number(o.code??NaN);if(!r.ok||s!==0)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,s===50,{status:r.status,serverCode:Number.isFinite(s)?String(s):void 0,cause:o.message||`取坐席账号失败(HTTP ${r.status})`});if(!o.data)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号接口没有返回 data`});return M=o.data,M}let z=e=>s(e,c);function B(r,i){let a=Number(r.wssPort)||p,s=String(r.domain??``).trim(),c=String(t.sipWsUrl??``).trim(),l;if(c)l=new URL(c,n),l.protocol===`http:`&&(l.protocol=`ws:`),l.protocol===`https:`&&(l.protocol=`wss:`);else{if(!s)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 domain,无法拼软电话地址;可用 sipWsUrl 显式指定`});let t=a===443?``:`:${a}`;l=new URL(`wss://${s}${t}${o}`)}return(t.attachTokenToWss??!0)&&i&&l.searchParams.set(`token`,i),l.toString()}function V(e){let t=(Array.isArray(e.iceServers)?e.iceServers:[]).map(e=>{let t=(Array.isArray(e?.urls)?e.urls:typeof e?.urls==`string`?[e.urls]:[]).map(e=>String(e??``).trim()).filter(Boolean);if(t.length!==0)return{urls:t,...e?.username?{username:String(e.username)}:{},...e?.credential?{credential:String(e.credential)}:{}}}).filter(e=>e!==void 0);if(t.length>0)return t;let n=String(e.turnIp??``).trim();return n?[{urls:[`stun:${n}:${Number(e.turnPort)||m}`]}]:[]}async function H(){let r=await F(),i=await R(),a=String(i.username??i.account??``).trim();if(!a)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 username`});let o=String(i.registerPassword??i.password??``),s=o?await z(o):``;if(!s)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 password/registerPassword,或解密后为空`});let c=O(i.expiresIn??i.expires_in,g),l=Math.max(0,Math.round((j.expiresAtMs-Date.now())/1e3)),u=Math.max(v,Math.min(l||c,c)-b),d=String(i.domain??``).trim()||D(n),f=B(i,r);return r&&(N=r),{sessionId:`legacy-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,expiresAt:Math.floor(Date.now()/1e3)+u,agent:{id:a,externalUserId:a,displayName:a,extension:a,status:`Available`},sip:{uri:`sip:${a}@${d}`,registrar:d,registerTicket:s,registerExpires:Number(t.registerExpires)>0?Number(t.registerExpires):h,ticketExpiresIn:u},transport:{wssUrl:f,ticket:``,ticketExpiresIn:u},iceServers:V(i),policy:{maxConcurrentCalls:Number(t.maxConcurrentCalls)>0?Number(t.maxConcurrentCalls):2,incomingEnabled:t.incomingEnabled??!0,mobileIncomingEnabled:t.mobileIncomingEnabled??!0,backgroundCallingSupported:!1},capabilities:[...t.capabilities??x]}}return{createSession:H,refreshSession:H,setAgentStatus:async({status:t,reason:n},r)=>{let i=await L(r),o=M??await R(i),s=String(o.username??o.account??``).trim();if(!s)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`坐席账号里没有 username`});let c=S[t],l=await A(C,a,{method:`POST`,headers:{Authorization:i,"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({extension:s,status:c.status,reason:n||c.reason})},`设置坐席状态`),u=await l.text(),d;try{d=JSON.parse(u)}catch{throw new e.i(`LEGACY_PLATFORM_UNREACHABLE`,`network`,!0,{status:l.status,cause:`${a} 返回了非 JSON 响应(HTTP ${l.status})`})}let f=Number(d.code??NaN);if(!l.ok||f!==0)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,f===50,{status:l.status,serverCode:Number.isFinite(f)?String(f):void 0,cause:d.message||`设置坐席状态失败(HTTP ${l.status})`})},invalidateToken:()=>{j=void 0,N=``},getSeatAccount:async()=>M??R()}}function w(t){let n=String(t??``).trim().replace(/\/+$/,``);if(!n)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`createLegacySessionProvider 需要 host`});return/^https?:\/\//i.test(n)?n:`https://${n}`}function T(e){let t=String(e??``).trim();return!t||t===`/`?``:`/${t.replace(/^\/+|\/+$/g,``)}`}function E(e){let t=String(e??``).trim();return t.startsWith(`/`)?t:`/${t}`}function D(e){try{return new URL(e).hostname}catch{return``}}function O(e,t){let n=Number(e);return!Number.isFinite(n)||n<=0?t:(n>86400&&(n/=1e3),Math.min(Math.max(Math.floor(n),v),86400))}function k(e){if(typeof e==`string`)return{token:e.trim()};let t=e??{},n=typeof t.data==`object`&&t.data!==null?t.data:void 0;for(let e of[t,n]){if(e===void 0)continue;let t=e.token??e.accessToken;if(typeof t==`string`&&t.trim()){let n=Number(e.expires??e.expiresIn??e.expires_at);return{token:t.trim(),...Number.isFinite(n)&&n>0?{expires:n}:{}}}}return{token:``}}async function A(t,n,r,i){let a=new AbortController,o=setTimeout(()=>a.abort(),b);try{return await t(n,{...r,signal:a.signal})}catch(t){let r=a.signal.aborted;throw new e.i(r?`NETWORK_TIMEOUT`:`LEGACY_PLATFORM_UNREACHABLE`,`network`,!0,{cause:r?`${i}超时(${b/1e3} 秒):POST ${n}`:`${i}失败:无法请求 ${n}(${t instanceof Error?t.message:String(t)})`})}finally{clearTimeout(o)}}var j=`0.1.0`;typeof window<`u`&&(window.CCBarSDK=r),exports.CCBarSDK=r,exports.DeprecatedError=n,exports.createLegacySessionProvider=C,exports.decryptSipPassword=s,exports.legacyVersion=j;
@@ -1,18 +1,18 @@
1
1
  import { i as e } from "../SharedWorkerProtocol-DKVQ5-po.js";
2
- import { i as t, t as n } from "../CCBarClient-Sr_zlDBu.js";
2
+ import { t } from "../CCBarClient-CbkMKzEw.js";
3
3
  //#region src/legacy/CCBarSDK.ts
4
- var r = class extends Error {
4
+ var n = class extends Error {
5
5
  code = "LEGACY_METHOD_DEPRECATED";
6
6
  constructor(e, t) {
7
7
  super(`${e} 已废弃:${t}`), this.name = "DeprecatedError";
8
8
  }
9
- }, i = class {
9
+ }, r = class {
10
10
  client;
11
11
  warnedMethods = /* @__PURE__ */ new Set();
12
12
  unsubscribeIncoming;
13
13
  currentCall;
14
14
  constructor(e) {
15
- this.client = new n(e), this.unsubscribeIncoming = this.client.on("call.incoming", ({ callId: e }) => {
15
+ this.client = new t(e), this.unsubscribeIncoming = this.client.on("call.incoming", ({ callId: e }) => {
16
16
  this.currentCall = this.client.getCalls().find((t) => t.id === e);
17
17
  });
18
18
  }
@@ -83,7 +83,7 @@ var r = class extends Error {
83
83
  return this.warn("setId", "请改用 client.setAgentStatus('available')"), this.client.setAgentStatus("available");
84
84
  }
85
85
  setBu(...e) {
86
- throw this.warn("setBu", "busy由通话状态或服务端状态策略控制,浏览器不得伪造"), new r("setBu()", "busy由通话状态或服务端状态策略控制,浏览器不得伪造");
86
+ throw this.warn("setBu", "busy由通话状态或服务端状态策略控制,浏览器不得伪造"), new n("setBu()", "busy由通话状态或服务端状态策略控制,浏览器不得伪造");
87
87
  }
88
88
  setRe(...e) {
89
89
  return this.warn("setRe", "请改用 client.setAgentStatus('break')"), this.client.setAgentStatus("break");
@@ -94,22 +94,53 @@ var r = class extends Error {
94
94
  return this.currentCall;
95
95
  }
96
96
  warn(e, t) {
97
- a() && !this.warnedMethods.has(e) && (this.warnedMethods.add(e), console.warn(`[CCBarSDK] ${e}() 已废弃。${t}`));
97
+ i() && !this.warnedMethods.has(e) && (this.warnedMethods.add(e), console.warn(`[CCBarSDK] ${e}() 已废弃。${t}`));
98
98
  }
99
99
  };
100
- function a() {
100
+ function i() {
101
101
  return !1;
102
102
  }
103
103
  //#endregion
104
+ //#region src/legacy/legacyAes.ts
105
+ var a = "q7X4p6MvK1z8Lb3A", o = "W9e2T4mN0aQ7Ru6C";
106
+ async function s(t, n = {}) {
107
+ let r = String(t ?? "").replace(/\s+/g, "");
108
+ if (!r) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "解密的密文为空:坐席账号里没有 password/registerPassword" });
109
+ let i = n.subtle ?? globalThis.crypto?.subtle;
110
+ if (i === void 0) throw new e("CONFIG_INVALID", "configuration", !1, { cause: "需要 WebCrypto 才能解 SIP 密码:请在安全上下文(https / localhost)或 Node 18+ 里运行" });
111
+ let s;
112
+ try {
113
+ let e = atob(r);
114
+ s = new Uint8Array(new ArrayBuffer(e.length));
115
+ for (let t = 0; t < e.length; t += 1) s[t] = e.charCodeAt(t);
116
+ } catch {
117
+ throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "密文不是合法的 Base64:确认取的是 password/registerPassword 原值,没有被截断或转义" });
118
+ }
119
+ let l = await i.importKey("raw", c(n.key ?? a), "AES-CBC", !1, ["decrypt"]);
120
+ try {
121
+ let e = await i.decrypt({
122
+ name: "AES-CBC",
123
+ iv: c(n.iv ?? o)
124
+ }, l, s);
125
+ return new TextDecoder("utf-8").decode(e).trim();
126
+ } catch (t) {
127
+ throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: `SIP 密码解密失败(检查 key/iv 与该环境是否一致):${t instanceof Error ? t.message : String(t)}` });
128
+ }
129
+ }
130
+ function c(e) {
131
+ let t = new TextEncoder().encode(e), n = new Uint8Array(new ArrayBuffer(t.byteLength));
132
+ return n.set(t), n;
133
+ }
134
+ //#endregion
104
135
  //#region src/legacy/legacySessionProvider.ts
105
- var o = "/openapi/token/v1", s = "/seat/account/get", c = "/seats/set-status", l = "/api/fs/sip-ws", u = 7443, d = 3478, f = 600, p = 600, m = 180, h = 60, g = 5e3, _ = 2e4, v = [
136
+ var l = "/openapi/token/v1", u = "/seat/account/get", d = "/seats/set-status", f = "/api/fs/sip-ws", p = 7443, m = 3478, h = 600, g = 600, _ = 180, v = 60, y = 5e3, b = 2e4, x = [
106
137
  "outbound",
107
138
  "inbound",
108
139
  "mute",
109
140
  "dtmf",
110
141
  "hold",
111
142
  "blind_transfer"
112
- ], y = {
143
+ ], S = {
113
144
  available: {
114
145
  status: "Available",
115
146
  reason: "空闲"
@@ -123,27 +154,27 @@ var o = "/openapi/token/v1", s = "/seat/account/get", c = "/seats/set-status", l
123
154
  reason: ""
124
155
  }
125
156
  };
126
- function b(n) {
127
- let r = x(n.host), i = S(n.pathPrefix ?? o), a = `${r}${i}${C(n.accountPath ?? s)}`, _ = `${r}${i}${C(n.statusPath ?? c)}`, b = C(n.sipWsPath ?? l), O = {
128
- ...n.aesKey ? { key: n.aesKey } : {},
129
- ...n.aesIv ? { iv: n.aesIv } : {}
130
- }, k = Math.max(0, n.refreshBufferSeconds ?? m), A = n.fetchImpl ?? globalThis.fetch, j, M, N = "";
157
+ function C(t) {
158
+ let n = w(t.host), r = T(t.pathPrefix ?? l), i = `${n}${r}${E(t.accountPath ?? u)}`, a = `${n}${r}${E(t.statusPath ?? d)}`, o = E(t.sipWsPath ?? f), c = {
159
+ ...t.aesKey ? { key: t.aesKey } : {},
160
+ ...t.aesIv ? { iv: t.aesIv } : {}
161
+ }, b = Math.max(0, t.refreshBufferSeconds ?? _), C = t.fetchImpl ?? globalThis.fetch, j, M, N = "";
131
162
  async function P() {
132
- if (n.getToken !== void 0) return n.getToken();
133
- if (n.tokenUrl !== void 0) {
134
- let t = n.tokenMethod ?? "POST", r = {
135
- method: t,
163
+ if (t.getToken !== void 0) return t.getToken();
164
+ if (t.tokenUrl !== void 0) {
165
+ let n = t.tokenMethod ?? "POST", r = {
166
+ method: n,
136
167
  headers: {
137
168
  Accept: "application/json",
138
- ...n.tokenHeaders ?? {}
169
+ ...t.tokenHeaders ?? {}
139
170
  },
140
171
  credentials: "include"
141
172
  };
142
- t === "POST" && (r.headers = {
173
+ n === "POST" && (r.headers = {
143
174
  "Content-Type": "application/json",
144
175
  ...r.headers
145
- }, r.body = JSON.stringify(n.tokenBody ?? {}));
146
- let i = await D(A, n.tokenUrl, r, "取 token"), a = await i.text();
176
+ }, r.body = JSON.stringify(t.tokenBody ?? {}));
177
+ let i = await A(C, t.tokenUrl, r, "取 token"), a = await i.text();
147
178
  try {
148
179
  return JSON.parse(a);
149
180
  } catch {
@@ -156,16 +187,16 @@ function b(n) {
156
187
  throw new e("CONFIG_INVALID", "configuration", !1, { cause: "createLegacySessionProvider 需要 getToken 或 tokenUrl;坐席状态也可以直接用会话软电话地址里的 token(setAgentStatus 的 context.wssUrl),但这次调用没有会话可用" });
157
188
  }
158
189
  async function F() {
159
- if (j && j.expiresAtMs - Date.now() > g) return j.token;
190
+ if (j && j.expiresAtMs - Date.now() > y) return j.token;
160
191
  let t;
161
192
  try {
162
193
  t = await P();
163
194
  } catch (t) {
164
195
  throw t instanceof e ? t : new e("AUTH_TOKEN_UNAVAILABLE", "auth", !0, { cause: t });
165
196
  }
166
- let n = E(t);
197
+ let n = k(t);
167
198
  if (!n.token) throw new e("AUTH_TOKEN_UNAVAILABLE", "auth", !0, { cause: "取 token 的返回里没有 token(支持 {token}、{accessToken}、{data:{token}} 或裸字符串)" });
168
- let r = T(n.expires, 3600);
199
+ let r = O(n.expires, 3600);
169
200
  return j = {
170
201
  token: n.token,
171
202
  expiresAtMs: Date.now() + r * 1e3
@@ -184,7 +215,7 @@ function b(n) {
184
215
  return t ? (N = t, t) : N || F();
185
216
  }
186
217
  async function R(t) {
187
- let n = t || await F(), r = await D(A, a, {
218
+ let n = t || await F(), r = await A(C, i, {
188
219
  method: "POST",
189
220
  headers: {
190
221
  Authorization: n,
@@ -192,13 +223,13 @@ function b(n) {
192
223
  Accept: "application/json"
193
224
  },
194
225
  body: "{}"
195
- }, "取坐席账号"), i = await r.text(), o;
226
+ }, "取坐席账号"), a = await r.text(), o;
196
227
  try {
197
- o = JSON.parse(i);
228
+ o = JSON.parse(a);
198
229
  } catch {
199
230
  throw new e("LEGACY_PLATFORM_UNREACHABLE", "network", !0, {
200
231
  status: r.status,
201
- cause: `${a} 返回了非 JSON 响应(HTTP ${r.status});请确认 host 填的是接口网关(不是文档站)`
232
+ cause: `${i} 返回了非 JSON 响应(HTTP ${r.status});请确认 host 填的是接口网关(不是文档站)`
202
233
  });
203
234
  }
204
235
  let s = Number(o.code ?? NaN);
@@ -210,16 +241,16 @@ function b(n) {
210
241
  if (!o.data) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号接口没有返回 data" });
211
242
  return M = o.data, M;
212
243
  }
213
- let z = (e) => t(e, O);
214
- function B(t, i) {
215
- let a = Number(t.wssPort) || u, o = String(t.domain ?? "").trim(), s = String(n.sipWsUrl ?? "").trim(), c;
216
- if (s) c = new URL(s, r), c.protocol === "http:" && (c.protocol = "ws:"), c.protocol === "https:" && (c.protocol = "wss:");
244
+ let z = (e) => s(e, c);
245
+ function B(r, i) {
246
+ let a = Number(r.wssPort) || p, s = String(r.domain ?? "").trim(), c = String(t.sipWsUrl ?? "").trim(), l;
247
+ if (c) l = new URL(c, n), l.protocol === "http:" && (l.protocol = "ws:"), l.protocol === "https:" && (l.protocol = "wss:");
217
248
  else {
218
- if (!o) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 domain,无法拼软电话地址;可用 sipWsUrl 显式指定" });
249
+ if (!s) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 domain,无法拼软电话地址;可用 sipWsUrl 显式指定" });
219
250
  let t = a === 443 ? "" : `:${a}`;
220
- c = new URL(`wss://${o}${t}${b}`);
251
+ l = new URL(`wss://${s}${t}${o}`);
221
252
  }
222
- return (n.attachTokenToWss ?? !0) && i && c.searchParams.set("token", i), c.toString();
253
+ return (t.attachTokenToWss ?? !0) && i && l.searchParams.set("token", i), l.toString();
223
254
  }
224
255
  function V(e) {
225
256
  let t = (Array.isArray(e.iceServers) ? e.iceServers : []).map((e) => {
@@ -232,15 +263,15 @@ function b(n) {
232
263
  }).filter((e) => e !== void 0);
233
264
  if (t.length > 0) return t;
234
265
  let n = String(e.turnIp ?? "").trim();
235
- return n ? [{ urls: [`stun:${n}:${Number(e.turnPort) || d}`] }] : [];
266
+ return n ? [{ urls: [`stun:${n}:${Number(e.turnPort) || m}`] }] : [];
236
267
  }
237
268
  async function H() {
238
- let t = await F(), i = await R(), a = String(i.username ?? i.account ?? "").trim();
269
+ let r = await F(), i = await R(), a = String(i.username ?? i.account ?? "").trim();
239
270
  if (!a) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 username" });
240
271
  let o = String(i.registerPassword ?? i.password ?? ""), s = o ? await z(o) : "";
241
272
  if (!s) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 password/registerPassword,或解密后为空" });
242
- let c = T(i.expiresIn ?? i.expires_in, p), l = Math.max(0, Math.round((j.expiresAtMs - Date.now()) / 1e3)), u = Math.max(h, Math.min(l || c, c) - k), d = String(i.domain ?? "").trim() || w(r), m = B(i, t);
243
- return t && (N = t), {
273
+ let c = O(i.expiresIn ?? i.expires_in, g), l = Math.max(0, Math.round((j.expiresAtMs - Date.now()) / 1e3)), u = Math.max(v, Math.min(l || c, c) - b), d = String(i.domain ?? "").trim() || D(n), f = B(i, r);
274
+ return r && (N = r), {
244
275
  sessionId: `legacy-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
245
276
  expiresAt: Math.floor(Date.now() / 1e3) + u,
246
277
  agent: {
@@ -254,31 +285,31 @@ function b(n) {
254
285
  uri: `sip:${a}@${d}`,
255
286
  registrar: d,
256
287
  registerTicket: s,
257
- registerExpires: Number(n.registerExpires) > 0 ? Number(n.registerExpires) : f,
288
+ registerExpires: Number(t.registerExpires) > 0 ? Number(t.registerExpires) : h,
258
289
  ticketExpiresIn: u
259
290
  },
260
291
  transport: {
261
- wssUrl: m,
292
+ wssUrl: f,
262
293
  ticket: "",
263
294
  ticketExpiresIn: u
264
295
  },
265
296
  iceServers: V(i),
266
297
  policy: {
267
- maxConcurrentCalls: Number(n.maxConcurrentCalls) > 0 ? Number(n.maxConcurrentCalls) : 2,
268
- incomingEnabled: n.incomingEnabled ?? !0,
269
- mobileIncomingEnabled: n.mobileIncomingEnabled ?? !0,
298
+ maxConcurrentCalls: Number(t.maxConcurrentCalls) > 0 ? Number(t.maxConcurrentCalls) : 2,
299
+ incomingEnabled: t.incomingEnabled ?? !0,
300
+ mobileIncomingEnabled: t.mobileIncomingEnabled ?? !0,
270
301
  backgroundCallingSupported: !1
271
302
  },
272
- capabilities: [...n.capabilities ?? v]
303
+ capabilities: [...t.capabilities ?? x]
273
304
  };
274
305
  }
275
306
  return {
276
307
  createSession: H,
277
308
  refreshSession: H,
278
309
  setAgentStatus: async ({ status: t, reason: n }, r) => {
279
- let i = await L(r), a = M ?? await R(i), o = String(a.username ?? a.account ?? "").trim();
280
- if (!o) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 username" });
281
- let s = y[t], c = await D(A, _, {
310
+ let i = await L(r), o = M ?? await R(i), s = String(o.username ?? o.account ?? "").trim();
311
+ if (!s) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 username" });
312
+ let c = S[t], l = await A(C, a, {
282
313
  method: "POST",
283
314
  headers: {
284
315
  Authorization: i,
@@ -286,24 +317,24 @@ function b(n) {
286
317
  Accept: "application/json"
287
318
  },
288
319
  body: JSON.stringify({
289
- extension: o,
290
- status: s.status,
291
- reason: n || s.reason
320
+ extension: s,
321
+ status: c.status,
322
+ reason: n || c.reason
292
323
  })
293
- }, "设置坐席状态"), l = await c.text(), u;
324
+ }, "设置坐席状态"), u = await l.text(), d;
294
325
  try {
295
- u = JSON.parse(l);
326
+ d = JSON.parse(u);
296
327
  } catch {
297
328
  throw new e("LEGACY_PLATFORM_UNREACHABLE", "network", !0, {
298
- status: c.status,
299
- cause: `${_} 返回了非 JSON 响应(HTTP ${c.status})`
329
+ status: l.status,
330
+ cause: `${a} 返回了非 JSON 响应(HTTP ${l.status})`
300
331
  });
301
332
  }
302
- let d = Number(u.code ?? NaN);
303
- if (!c.ok || d !== 0) throw new e("LEGACY_PLATFORM_REJECTED", "auth", d === 50, {
304
- status: c.status,
305
- serverCode: Number.isFinite(d) ? String(d) : void 0,
306
- cause: u.message || `设置坐席状态失败(HTTP ${c.status})`
333
+ let f = Number(d.code ?? NaN);
334
+ if (!l.ok || f !== 0) throw new e("LEGACY_PLATFORM_REJECTED", "auth", f === 50, {
335
+ status: l.status,
336
+ serverCode: Number.isFinite(f) ? String(f) : void 0,
337
+ cause: d.message || `设置坐席状态失败(HTTP ${l.status})`
307
338
  });
308
339
  },
309
340
  invalidateToken: () => {
@@ -312,31 +343,31 @@ function b(n) {
312
343
  getSeatAccount: async () => M ?? R()
313
344
  };
314
345
  }
315
- function x(t) {
346
+ function w(t) {
316
347
  let n = String(t ?? "").trim().replace(/\/+$/, "");
317
348
  if (!n) throw new e("CONFIG_INVALID", "configuration", !1, { cause: "createLegacySessionProvider 需要 host" });
318
349
  return /^https?:\/\//i.test(n) ? n : `https://${n}`;
319
350
  }
320
- function S(e) {
351
+ function T(e) {
321
352
  let t = String(e ?? "").trim();
322
353
  return !t || t === "/" ? "" : `/${t.replace(/^\/+|\/+$/g, "")}`;
323
354
  }
324
- function C(e) {
355
+ function E(e) {
325
356
  let t = String(e ?? "").trim();
326
357
  return t.startsWith("/") ? t : `/${t}`;
327
358
  }
328
- function w(e) {
359
+ function D(e) {
329
360
  try {
330
361
  return new URL(e).hostname;
331
362
  } catch {
332
363
  return "";
333
364
  }
334
365
  }
335
- function T(e, t) {
366
+ function O(e, t) {
336
367
  let n = Number(e);
337
- return !Number.isFinite(n) || n <= 0 ? t : (n > 86400 && (n /= 1e3), Math.min(Math.max(Math.floor(n), h), 86400));
368
+ return !Number.isFinite(n) || n <= 0 ? t : (n > 86400 && (n /= 1e3), Math.min(Math.max(Math.floor(n), v), 86400));
338
369
  }
339
- function E(e) {
370
+ function k(e) {
340
371
  if (typeof e == "string") return { token: e.trim() };
341
372
  let t = e ?? {}, n = typeof t.data == "object" && t.data !== null ? t.data : void 0;
342
373
  for (let e of [t, n]) {
@@ -352,8 +383,8 @@ function E(e) {
352
383
  }
353
384
  return { token: "" };
354
385
  }
355
- async function D(t, n, r, i) {
356
- let a = new AbortController(), o = setTimeout(() => a.abort(), _);
386
+ async function A(t, n, r, i) {
387
+ let a = new AbortController(), o = setTimeout(() => a.abort(), b);
357
388
  try {
358
389
  return await t(n, {
359
390
  ...r,
@@ -361,14 +392,14 @@ async function D(t, n, r, i) {
361
392
  });
362
393
  } catch (t) {
363
394
  let r = a.signal.aborted;
364
- throw new e(r ? "NETWORK_TIMEOUT" : "LEGACY_PLATFORM_UNREACHABLE", "network", !0, { cause: r ? `${i}超时(${_ / 1e3} 秒):POST ${n}` : `${i}失败:无法请求 ${n}(${t instanceof Error ? t.message : String(t)})` });
395
+ throw new e(r ? "NETWORK_TIMEOUT" : "LEGACY_PLATFORM_UNREACHABLE", "network", !0, { cause: r ? `${i}超时(${b / 1e3} 秒):POST ${n}` : `${i}失败:无法请求 ${n}(${t instanceof Error ? t.message : String(t)})` });
365
396
  } finally {
366
397
  clearTimeout(o);
367
398
  }
368
399
  }
369
400
  //#endregion
370
401
  //#region src/legacy/index.ts
371
- var O = "0.1.0";
372
- typeof window < "u" && (window.CCBarSDK = i);
402
+ var j = "0.1.0";
403
+ typeof window < "u" && (window.CCBarSDK = r);
373
404
  //#endregion
374
- export { i as CCBarSDK, r as DeprecatedError, b as createLegacySessionProvider, t as decryptSipPassword, O as legacyVersion };
405
+ export { r as CCBarSDK, n as DeprecatedError, C as createLegacySessionProvider, s as decryptSipPassword, j as legacyVersion };
@@ -1,7 +1,29 @@
1
1
  /**
2
- * 老平台坐席密码解密的入口(`@16x/webphone-sdk/legacy` 子入口导出 `decryptSipPassword`)。
2
+ * 老平台坐席密码的解密:`seat/account/get` 返回的 `password`(或 `registerPassword`)
3
+ * 是 **AES-128-CBC / Pkcs7 的密文,Base64 编码**,需要解密才有明文 SIP 密码。
3
4
  *
4
- * 实现在 `src/crypto/legacySipTicket.ts`:core 的会话入口也要用同一套 AES 参数做兜底
5
- * (`tryDecryptSipTicket`),所以实现放在两边都能拿到的地方,这里只做转发,行为与以前一致。
5
+ * key/iv 各 16 字节,老平台是固定值(旧版 `ccbar.js` 里同样是硬编码),可用 options 覆盖。
6
+ * 在浏览器与 Node 里都能用(走 WebCrypto,无需额外依赖;需要安全上下文或 Node 18+)。
6
7
  */
7
- export { decryptSipPassword, type DecryptSipPasswordOptions } from '../crypto/legacySipTicket.js';
8
+ export interface DecryptSipPasswordOptions {
9
+ /** AES key(16 字节,UTF-8),默认用老平台内置值 */
10
+ key?: string;
11
+ /** AES iv(16 字节,UTF-8),默认用老平台内置值 */
12
+ iv?: string;
13
+ /** 解密实现所用的 WebCrypto(测试可注入),默认全局 crypto.subtle */
14
+ subtle?: SubtleCrypto;
15
+ }
16
+ /**
17
+ * 解出 SIP 密码明文。
18
+ *
19
+ * ```ts
20
+ * import { decryptSipPassword } from '@16x/webphone-sdk/legacy';
21
+ *
22
+ * const res = await fetch(`${host}/openapi/token/v1/seat/account/get`, { method: 'POST', headers: { Authorization: token }, body: '{}' });
23
+ * const { data } = await res.json();
24
+ * const password = await decryptSipPassword(data.password); // 明文 SIP 密码
25
+ * ```
26
+ *
27
+ * 失败时抛 `CCBarError`:可读原因在 `error.cause` 上(密文为空 / 不是合法 Base64 / 解密失败)。
28
+ */
29
+ export declare function decryptSipPassword(cipherText: string, options?: DecryptSipPasswordOptions): Promise<string>;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "3.1.10";
1
+ export declare const SDK_VERSION = "3.8.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@16x/webphone-sdk",
3
- "version": "3.1.10",
3
+ "version": "3.8.1",
4
4
  "homepage": "https://www.npmjs.com/package/@16x/webphone-sdk",
5
5
  "private": false,
6
6
  "license": "UNLICENSED",