@16x/webphone-sdk 3.1.9 → 3.1.11

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