@16x/webphone-sdk 3.1.9 → 3.1.10
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 +15 -0
- package/dist/{CCBarClient-CfHT0tl2.js → CCBarClient-Sr_zlDBu.js} +189 -120
- package/dist/CCBarClient-z-TFUjTB.cjs +1 -0
- package/dist/{Diagnostics-CfbmMp-b.js → Diagnostics-WkQagE6_.js} +1 -1
- package/dist/Diagnostics-x4G0ho6W.cjs +1 -0
- package/dist/core/CCBarClient.d.ts +5 -1
- package/dist/diagnostics/index.cjs +1 -1
- package/dist/diagnostics/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +3 -3
- package/dist/index.umd.js +17 -17
- package/dist/legacy/index.cjs +1 -1
- package/dist/legacy/index.js +74 -105
- package/dist/legacy/legacyAes.d.ts +4 -26
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/CCBarClient-B6WqgloY.cjs +0 -1
- package/dist/Diagnostics-DkKlZQnY.cjs +0 -1
package/dist/legacy/index.cjs
CHANGED
|
@@ -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-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;
|
package/dist/legacy/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { i as e } from "../SharedWorkerProtocol-DKVQ5-po.js";
|
|
2
|
-
import { t } from "../CCBarClient-
|
|
2
|
+
import { i as t, t as n } from "../CCBarClient-Sr_zlDBu.js";
|
|
3
3
|
//#region src/legacy/CCBarSDK.ts
|
|
4
|
-
var
|
|
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
|
-
},
|
|
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
|
|
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
|
|
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
|
-
|
|
97
|
+
a() && !this.warnedMethods.has(e) && (this.warnedMethods.add(e), console.warn(`[CCBarSDK] ${e}() 已废弃。${t}`));
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
|
-
function
|
|
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
|
|
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 = [
|
|
137
106
|
"outbound",
|
|
138
107
|
"inbound",
|
|
139
108
|
"mute",
|
|
140
109
|
"dtmf",
|
|
141
110
|
"hold",
|
|
142
111
|
"blind_transfer"
|
|
143
|
-
],
|
|
112
|
+
], y = {
|
|
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
|
|
158
|
-
let
|
|
159
|
-
...
|
|
160
|
-
...
|
|
161
|
-
},
|
|
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 = "";
|
|
162
131
|
async function P() {
|
|
163
|
-
if (
|
|
164
|
-
if (
|
|
165
|
-
let
|
|
166
|
-
method:
|
|
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
|
-
...
|
|
138
|
+
...n.tokenHeaders ?? {}
|
|
170
139
|
},
|
|
171
140
|
credentials: "include"
|
|
172
141
|
};
|
|
173
|
-
|
|
142
|
+
t === "POST" && (r.headers = {
|
|
174
143
|
"Content-Type": "application/json",
|
|
175
144
|
...r.headers
|
|
176
|
-
}, r.body = JSON.stringify(
|
|
177
|
-
let i = await A
|
|
145
|
+
}, r.body = JSON.stringify(n.tokenBody ?? {}));
|
|
146
|
+
let i = await D(A, n.tokenUrl, r, "取 token"), a = await i.text();
|
|
178
147
|
try {
|
|
179
148
|
return JSON.parse(a);
|
|
180
149
|
} catch {
|
|
@@ -187,16 +156,16 @@ function C(t) {
|
|
|
187
156
|
throw new e("CONFIG_INVALID", "configuration", !1, { cause: "createLegacySessionProvider 需要 getToken 或 tokenUrl;坐席状态也可以直接用会话软电话地址里的 token(setAgentStatus 的 context.wssUrl),但这次调用没有会话可用" });
|
|
188
157
|
}
|
|
189
158
|
async function F() {
|
|
190
|
-
if (j && j.expiresAtMs - Date.now() >
|
|
159
|
+
if (j && j.expiresAtMs - Date.now() > g) return j.token;
|
|
191
160
|
let t;
|
|
192
161
|
try {
|
|
193
162
|
t = await P();
|
|
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 =
|
|
166
|
+
let n = E(t);
|
|
198
167
|
if (!n.token) throw new e("AUTH_TOKEN_UNAVAILABLE", "auth", !0, { cause: "取 token 的返回里没有 token(支持 {token}、{accessToken}、{data:{token}} 或裸字符串)" });
|
|
199
|
-
let r =
|
|
168
|
+
let r = T(n.expires, 3600);
|
|
200
169
|
return j = {
|
|
201
170
|
token: n.token,
|
|
202
171
|
expiresAtMs: Date.now() + r * 1e3
|
|
@@ -215,7 +184,7 @@ function C(t) {
|
|
|
215
184
|
return t ? (N = t, t) : N || F();
|
|
216
185
|
}
|
|
217
186
|
async function R(t) {
|
|
218
|
-
let n = t || await F(), r = await A
|
|
187
|
+
let n = t || await F(), r = await D(A, 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
|
-
}, "取坐席账号"),
|
|
195
|
+
}, "取坐席账号"), i = await r.text(), o;
|
|
227
196
|
try {
|
|
228
|
-
o = JSON.parse(
|
|
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: `${
|
|
201
|
+
cause: `${a} 返回了非 JSON 响应(HTTP ${r.status});请确认 host 填的是接口网关(不是文档站)`
|
|
233
202
|
});
|
|
234
203
|
}
|
|
235
204
|
let s = Number(o.code ?? NaN);
|
|
@@ -241,16 +210,16 @@ function C(t) {
|
|
|
241
210
|
if (!o.data) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号接口没有返回 data" });
|
|
242
211
|
return M = o.data, M;
|
|
243
212
|
}
|
|
244
|
-
let z = (e) =>
|
|
245
|
-
function B(
|
|
246
|
-
let a = Number(
|
|
247
|
-
if (
|
|
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:");
|
|
248
217
|
else {
|
|
249
|
-
if (!
|
|
218
|
+
if (!o) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 domain,无法拼软电话地址;可用 sipWsUrl 显式指定" });
|
|
250
219
|
let t = a === 443 ? "" : `:${a}`;
|
|
251
|
-
|
|
220
|
+
c = new URL(`wss://${o}${t}${b}`);
|
|
252
221
|
}
|
|
253
|
-
return (
|
|
222
|
+
return (n.attachTokenToWss ?? !0) && i && c.searchParams.set("token", i), c.toString();
|
|
254
223
|
}
|
|
255
224
|
function V(e) {
|
|
256
225
|
let t = (Array.isArray(e.iceServers) ? e.iceServers : []).map((e) => {
|
|
@@ -263,15 +232,15 @@ function C(t) {
|
|
|
263
232
|
}).filter((e) => e !== void 0);
|
|
264
233
|
if (t.length > 0) return t;
|
|
265
234
|
let n = String(e.turnIp ?? "").trim();
|
|
266
|
-
return n ? [{ urls: [`stun:${n}:${Number(e.turnPort) ||
|
|
235
|
+
return n ? [{ urls: [`stun:${n}:${Number(e.turnPort) || d}`] }] : [];
|
|
267
236
|
}
|
|
268
237
|
async function H() {
|
|
269
|
-
let
|
|
238
|
+
let t = await F(), i = await R(), a = String(i.username ?? i.account ?? "").trim();
|
|
270
239
|
if (!a) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 username" });
|
|
271
240
|
let o = String(i.registerPassword ?? i.password ?? ""), s = o ? await z(o) : "";
|
|
272
241
|
if (!s) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 password/registerPassword,或解密后为空" });
|
|
273
|
-
let c =
|
|
274
|
-
return
|
|
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), {
|
|
275
244
|
sessionId: `legacy-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
|
|
276
245
|
expiresAt: Math.floor(Date.now() / 1e3) + u,
|
|
277
246
|
agent: {
|
|
@@ -285,31 +254,31 @@ function C(t) {
|
|
|
285
254
|
uri: `sip:${a}@${d}`,
|
|
286
255
|
registrar: d,
|
|
287
256
|
registerTicket: s,
|
|
288
|
-
registerExpires: Number(
|
|
257
|
+
registerExpires: Number(n.registerExpires) > 0 ? Number(n.registerExpires) : f,
|
|
289
258
|
ticketExpiresIn: u
|
|
290
259
|
},
|
|
291
260
|
transport: {
|
|
292
|
-
wssUrl:
|
|
261
|
+
wssUrl: m,
|
|
293
262
|
ticket: "",
|
|
294
263
|
ticketExpiresIn: u
|
|
295
264
|
},
|
|
296
265
|
iceServers: V(i),
|
|
297
266
|
policy: {
|
|
298
|
-
maxConcurrentCalls: Number(
|
|
299
|
-
incomingEnabled:
|
|
300
|
-
mobileIncomingEnabled:
|
|
267
|
+
maxConcurrentCalls: Number(n.maxConcurrentCalls) > 0 ? Number(n.maxConcurrentCalls) : 2,
|
|
268
|
+
incomingEnabled: n.incomingEnabled ?? !0,
|
|
269
|
+
mobileIncomingEnabled: n.mobileIncomingEnabled ?? !0,
|
|
301
270
|
backgroundCallingSupported: !1
|
|
302
271
|
},
|
|
303
|
-
capabilities: [...
|
|
272
|
+
capabilities: [...n.capabilities ?? v]
|
|
304
273
|
};
|
|
305
274
|
}
|
|
306
275
|
return {
|
|
307
276
|
createSession: H,
|
|
308
277
|
refreshSession: H,
|
|
309
278
|
setAgentStatus: async ({ status: t, reason: n }, r) => {
|
|
310
|
-
let i = await L(r),
|
|
311
|
-
if (!
|
|
312
|
-
let
|
|
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, _, {
|
|
313
282
|
method: "POST",
|
|
314
283
|
headers: {
|
|
315
284
|
Authorization: i,
|
|
@@ -317,24 +286,24 @@ function C(t) {
|
|
|
317
286
|
Accept: "application/json"
|
|
318
287
|
},
|
|
319
288
|
body: JSON.stringify({
|
|
320
|
-
extension:
|
|
321
|
-
status:
|
|
322
|
-
reason: n ||
|
|
289
|
+
extension: o,
|
|
290
|
+
status: s.status,
|
|
291
|
+
reason: n || s.reason
|
|
323
292
|
})
|
|
324
|
-
}, "设置坐席状态"),
|
|
293
|
+
}, "设置坐席状态"), l = await c.text(), u;
|
|
325
294
|
try {
|
|
326
|
-
|
|
295
|
+
u = JSON.parse(l);
|
|
327
296
|
} catch {
|
|
328
297
|
throw new e("LEGACY_PLATFORM_UNREACHABLE", "network", !0, {
|
|
329
|
-
status:
|
|
330
|
-
cause: `${
|
|
298
|
+
status: c.status,
|
|
299
|
+
cause: `${_} 返回了非 JSON 响应(HTTP ${c.status})`
|
|
331
300
|
});
|
|
332
301
|
}
|
|
333
|
-
let
|
|
334
|
-
if (!
|
|
335
|
-
status:
|
|
336
|
-
serverCode: Number.isFinite(
|
|
337
|
-
cause:
|
|
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})`
|
|
338
307
|
});
|
|
339
308
|
},
|
|
340
309
|
invalidateToken: () => {
|
|
@@ -343,31 +312,31 @@ function C(t) {
|
|
|
343
312
|
getSeatAccount: async () => M ?? R()
|
|
344
313
|
};
|
|
345
314
|
}
|
|
346
|
-
function
|
|
315
|
+
function x(t) {
|
|
347
316
|
let n = String(t ?? "").trim().replace(/\/+$/, "");
|
|
348
317
|
if (!n) throw new e("CONFIG_INVALID", "configuration", !1, { cause: "createLegacySessionProvider 需要 host" });
|
|
349
318
|
return /^https?:\/\//i.test(n) ? n : `https://${n}`;
|
|
350
319
|
}
|
|
351
|
-
function
|
|
320
|
+
function S(e) {
|
|
352
321
|
let t = String(e ?? "").trim();
|
|
353
322
|
return !t || t === "/" ? "" : `/${t.replace(/^\/+|\/+$/g, "")}`;
|
|
354
323
|
}
|
|
355
|
-
function
|
|
324
|
+
function C(e) {
|
|
356
325
|
let t = String(e ?? "").trim();
|
|
357
326
|
return t.startsWith("/") ? t : `/${t}`;
|
|
358
327
|
}
|
|
359
|
-
function
|
|
328
|
+
function w(e) {
|
|
360
329
|
try {
|
|
361
330
|
return new URL(e).hostname;
|
|
362
331
|
} catch {
|
|
363
332
|
return "";
|
|
364
333
|
}
|
|
365
334
|
}
|
|
366
|
-
function
|
|
335
|
+
function T(e, t) {
|
|
367
336
|
let n = Number(e);
|
|
368
|
-
return !Number.isFinite(n) || n <= 0 ? t : (n > 86400 && (n /= 1e3), Math.min(Math.max(Math.floor(n),
|
|
337
|
+
return !Number.isFinite(n) || n <= 0 ? t : (n > 86400 && (n /= 1e3), Math.min(Math.max(Math.floor(n), h), 86400));
|
|
369
338
|
}
|
|
370
|
-
function
|
|
339
|
+
function E(e) {
|
|
371
340
|
if (typeof e == "string") return { token: e.trim() };
|
|
372
341
|
let t = e ?? {}, n = typeof t.data == "object" && t.data !== null ? t.data : void 0;
|
|
373
342
|
for (let e of [t, n]) {
|
|
@@ -383,8 +352,8 @@ function k(e) {
|
|
|
383
352
|
}
|
|
384
353
|
return { token: "" };
|
|
385
354
|
}
|
|
386
|
-
async function
|
|
387
|
-
let a = new AbortController(), o = setTimeout(() => a.abort(),
|
|
355
|
+
async function D(t, n, r, i) {
|
|
356
|
+
let a = new AbortController(), o = setTimeout(() => a.abort(), _);
|
|
388
357
|
try {
|
|
389
358
|
return await t(n, {
|
|
390
359
|
...r,
|
|
@@ -392,14 +361,14 @@ async function A(t, n, r, i) {
|
|
|
392
361
|
});
|
|
393
362
|
} catch (t) {
|
|
394
363
|
let r = a.signal.aborted;
|
|
395
|
-
throw new e(r ? "NETWORK_TIMEOUT" : "LEGACY_PLATFORM_UNREACHABLE", "network", !0, { cause: r ? `${i}超时(${
|
|
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)})` });
|
|
396
365
|
} finally {
|
|
397
366
|
clearTimeout(o);
|
|
398
367
|
}
|
|
399
368
|
}
|
|
400
369
|
//#endregion
|
|
401
370
|
//#region src/legacy/index.ts
|
|
402
|
-
var
|
|
403
|
-
typeof window < "u" && (window.CCBarSDK =
|
|
371
|
+
var O = "0.1.0";
|
|
372
|
+
typeof window < "u" && (window.CCBarSDK = i);
|
|
404
373
|
//#endregion
|
|
405
|
-
export {
|
|
374
|
+
export { i as CCBarSDK, r as DeprecatedError, b as createLegacySessionProvider, t as decryptSipPassword, O as legacyVersion };
|
|
@@ -1,29 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* 是 **AES-128-CBC / Pkcs7 的密文,Base64 编码**,需要解密才有明文 SIP 密码。
|
|
2
|
+
* 老平台坐席密码解密的入口(`@16x/webphone-sdk/legacy` 子入口导出 `decryptSipPassword`)。
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* 实现在 `src/crypto/legacySipTicket.ts`:core 的会话入口也要用同一套 AES 参数做兜底
|
|
5
|
+
* (`tryDecryptSipTicket`),所以实现放在两边都能拿到的地方,这里只做转发,行为与以前一致。
|
|
7
6
|
*/
|
|
8
|
-
export
|
|
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';
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "3.1.
|
|
1
|
+
export declare const SDK_VERSION = "3.1.10";
|