@linkfox-web/api-user-center 0.3.3 → 0.3.5

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/README.md CHANGED
@@ -56,7 +56,7 @@ const session = await startThirdPartySso({
56
56
  // 退出仅清除当前应用会话:clearThirdPartySsoSession(clientId)。
57
57
  ```
58
58
 
59
- 登录成功后 SDK 用 `@linkfox-web/http` 的 `setSession()` 保存会话(附带 `ssoClientId`,有效期取 JWT 的 `exp`),`@linkfox-web/ai-tools` 等服务会自动把 accessToken 放进 `Authorization`。这会替换当前站点的 http 会话,在主站域名下使用时请先 `configure({ cookieKey: 'LINKFOX_SSO_TOKEN' })` 之类的独立键,避免覆盖主站登录。`readThirdPartySsoSession(clientId)` 只认同一 clientId 写入的会话,过期或损坏时会清掉;`clearThirdPartySsoSession(clientId)` 不动其他来源的会话。无法保存或 token 缺少有效 exp 时登录失败。解码 exp 只用于本地过期判断,不代替服务端验签;前端 cookie 不具备 HttpOnly。
59
+ 登录成功后 SDK 用 `@linkfox-web/http` 的 `setSession()` 保存会话(附带 `ssoClientId`,有效期取 JWT 的 `exp`),`@linkfox-web/ai-tools` 等服务会自动把 accessToken 放进 `Authorization`。调用任一第三方 SSO 会话接口时,SDK 会把 http 会话切到 `` configure({ cookieKey: `LINKFOX_SSO_${clientId}_TOKEN`, storage: 'local' }) ``:每个应用存在自己的 localStorage 键,不写共享根域 cookie,同一域名下部署多个应用互不覆盖,也不会覆盖主站登录;因此同一页面不要混用主站登录与第三方 SSO。`readThirdPartySsoSession(clientId)` 只认同一 clientId 写入的会话,过期或损坏时会清掉;`clearThirdPartySsoSession(clientId)` 不动其他来源的会话。无法保存或 token 缺少有效 exp 时登录失败。解码 exp 只用于本地过期判断,不代替服务端验签;前端 cookie 不具备 HttpOnly。
60
60
 
61
61
  `getThirdPartyApplication(clientId, { redirectUri, signal })` 和 `loginThirdPartyApplication(params, { signal })` 可独立调用;后者会保存应用会话。SSO 接口本身均为匿名请求,不向 SSO 服务发送已有 token,不调用主站刷新接口;HTTP 200 中的 `{ error: { code, message } }` 也会作为异常抛出。
62
62
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var Ee=Object.create;var x=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var be=Object.getPrototypeOf,ke=Object.prototype.hasOwnProperty;var Le=(e,r)=>{for(var t in r)x(e,t,{get:r[t],enumerable:!0})},q=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Ae(r))!ke.call(e,i)&&i!==t&&x(e,i,{get:()=>r[i],enumerable:!(n=Re(r,i))||n.enumerable});return e};var C=(e,r,t)=>(t=e!=null?Ee(be(e)):{},q(r||!e||!e.__esModule?x(t,"default",{value:e,enumerable:!0}):t,e)),ve=e=>q(x({},"__esModule",{value:!0}),e);var We={};Le(We,{clearThirdPartySsoSession:()=>ue,completeThirdPartySsoRedirect:()=>Ce,getImageVerifyCode:()=>ne,getPersonalKey:()=>N,getThirdPartyApplication:()=>k,getUserInfo:()=>w,getVerifyCode:()=>oe,getWechatQrCode:()=>ae,getWechatQrCodeStatus:()=>ce,handleThirdPartySsoCallback:()=>we,loginByCode:()=>se,loginByPassword:()=>ie,loginByWechat:()=>de,loginThirdPartyApplication:()=>L,logout:()=>X,readThirdPartySsoSession:()=>M,redirectToThirdPartySso:()=>xe,resolveCurrentTeam:()=>S,startThirdPartySso:()=>Se,switchTeam:()=>J,syncApiKey:()=>H,syncCurrentTeam:()=>y});module.exports=ve(We);var T=require("@linkfox-web/http");var I=require("@linkfox-web/http");var B={baseURL:"https://api.linkfox.com",aesKey:"AR7x7zfje4nkim4t",source:"ai-linkfox-web",systemId:"LinkFoxAgent",clientChannel:"LinkFoxAI"};var Oe=new Set(["30003","30009","30011","30015","30017","30019"]),Q="LINKFOX_CLIENT_ID";function U(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function _(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let r=Math.random()*16|0;return(e==="x"?r:r&3|8).toString(16)})}function _e(){try{let e=localStorage.getItem(Q);return e||(e=_(),localStorage.setItem(Q,e)),e}catch{return""}}function Ne(e){try{return btoa(JSON.stringify({a_id:_e(),d_id:e}))}catch{return""}}var s=(0,I.defineService)({name:"user-center",defaults:B,baseHeaders:e=>({source:e.config.source,uid:Ne(e.session?.userId??"")}),authorize:e=>e.session?{authorization:e.session.accessToken}:{},isUnauthorized:(e,r)=>e.status===401||U(r)&&r.success!==!0&&Oe.has(String(r.code??"")),refreshOnUnauthorized:!1,unwrap:(e,r)=>{if(U(r)&&(r.code==="OK"&&r.success!==!1||r.code===200&&r.success!==!1||r.success===!0)&&e.ok)return r.data;throw new I.LinkfoxHttpError({service:"user-center",status:e.status,code:U(r)?r.code:void 0,message:U(r)&&(r.message||r.msg)||e.statusText||`HTTP ${e.status}`,body:r})}});var p=require("@linkfox-web/http");var l=require("@linkfox-web/http");async function N(e){return(await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/api-credential/getPersonalKey",body:{teamId:e||await De()}}))?.credentials??[]}async function De(){let e=(0,l.getCurrentTeam)()?.teamId;if(e)return e;let{teamList:r}=await w(),t=(S(r)??r.find(n=>n.isSelect===1)??r[0])?.teamId;if(!t)throw new l.LinkfoxHttpError({service:"user-center",status:200,code:"TEAM_REQUIRED",message:"当前账号没有可用团队"});return t}async function H(e){let r=await N(e),t=r.find(n=>n.credentialType==="USER_PRIMARY"&&n.credential)??r.find(n=>n.credential);if(!t)throw new l.LinkfoxHttpError({service:"user-center",status:200,code:"API_KEY_NOT_FOUND",message:"当前账号没有可用的 API Key"});return D(t.credential),t.credential}function D(e){(0,l.configure)({services:{"ai-tools":{apiKey:e}}})}function w(){return j(!1)}function j(e){return s.request({method:"POST",path:"/linkFoxApp/api/userCenter/userInfo",body:{},skipRecovery:e})}function S(e){if(!e?.length)return;let r=e.find(n=>n.isSelect===1);if(r?.agentMemberId)return r;let t=e.find(n=>n.teamType===1);return t?.agentMemberId?t:e.find(n=>n.agentMemberId)}function Y(e){return e.aiTeamId?{id:e.aiTeamId,teamId:e.teamId,name:e.teamName,type:e.teamType,logo:e.logo??"",ownerId:e.ownerId}:null}async function y(e){let r=await j(e?.skipRecovery??!1),t=S(r.teamList),n=t?Y(t):null;return n?((0,p.setTeam)(n),!0):!1}async function J(e){await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/team/switchTeam",body:{targetTeamId:e}});let r=await w(),t=r.teamList.find(i=>i.teamId===e),n=t?Y(t):null;return n?(0,p.setTeam)(n):(0,p.clearTeam)(),r}function X(){(0,p.clearSession)(),D(void 0)}async function Ve(e){let r=await s.request({method:"POST",path:"/cp/v1/user/refresh",auth:"none",skipRecovery:!0,headers:{authorization:e.refreshToken??""}});if(!r?.accessToken)throw new Error("REFRESH_TOKEN_EXPIRED");(0,T.updateSession)({accessToken:r.accessToken,refreshToken:r.refreshToken,expireAt:r.expireAt})}function $(){(0,T.registerCapability)("refresh",Ve),(0,T.registerCapability)("resolveTeam",()=>y({skipRecovery:!0}))}var E=require("@linkfox-web/http");var G=C(require("crypto-js/aes"),1),Z=C(require("crypto-js/enc-utf8"),1),ee=C(require("crypto-js/mode-ecb"),1),re=C(require("crypto-js/pad-zeropadding"),1);function te(e,r){return G.default.encrypt(e,Z.default.parse(r),{mode:ee.default,padding:re.default}).toString()}function V(e){return e?.sourceUrl??(typeof location<"u"?location.href:"")}async function z(e){if(!e?.accessToken)throw new E.LinkfoxHttpError({service:"user-center",status:200,code:"INVALID_LOGIN_RESPONSE",message:"登录响应缺少 accessToken",body:e});(0,E.setSession)(e);try{await y()}catch{}return e}function R(e,r){return s.request({method:"POST",path:e,body:r,auth:"none"})}async function ne(){let e=_(),r=await s.request({path:"/user/v1/sendMessageCode.jpg",query:{uuid:e},auth:"none",responseType:"blob"}),t=await new Promise((n,i)=>{let o=new FileReader;o.onloadend=()=>n(String(o.result??"")),o.onerror=()=>i(o.error),o.readAsDataURL(r)});return{uuid:e,imageBase64:t}}async function ie(e,r){let t=s.config(),n=await R("/user/v2/web/login",{type:"smsPwd",method:"login",sourceUrl:V(r),data:{authPhone:e.authPhone,auth:te(e.password,t.aesKey),uuid:e.uuid,imageCode:e.imageCode,systemId:t.systemId}});return z(n)}async function oe(e){await R("/user/v3/web/login",{type:"sms",method:"getVerifyCode",data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",...e.uuid?{uuid:e.uuid}:{},...e.imageCode?{imageCode:e.imageCode}:{},clientChannel:s.config().clientChannel}})}async function se(e,r){let t=await R("/user/v3/web/login",{type:"sms",method:"login",sourceUrl:V(r),data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",authCode:e.authCode,sourceChannel:e.sourceChannel??""}});return z(t)}function ae(){return s.request({method:"POST",path:"/user/v1/web/login/wechat/qr_url",body:{type:"1"},auth:"none"})}function ce(e){return s.request({path:"/user/v1/web/login/wechat",query:{sessionId:e},auth:"none"})}async function de(e,r){let t=await R("/user/v2/web/login",{type:"wechatQR",method:"login",sourceUrl:V(r),data:{sessionId:e.sessionId,...e.authPhone?{authPhone:e.authPhone}:{},...e.authCode?{authCode:e.authCode}:{},sourceChannel:e.sourceChannel??""}});return z(t)}var A=require("@linkfox-web/http"),b=(0,A.defineService)({name:"third-party-sso",defaults:{baseURL:""},refreshOnUnauthorized:!1,unwrap:(e,r)=>{let t=r&&typeof r=="object"?r:void 0,n=t?.error&&typeof t.error=="object"?t.error:void 0;if(e.ok&&t&&!t.error)return t;throw new A.LinkfoxHttpError({service:"third-party-sso",status:e.status,code:typeof n?.code=="string"||typeof n?.code=="number"?n.code:e.status,message:typeof n?.message=="string"?n.message:`SSO 请求失败(HTTP ${e.status})`})}});var u=require("@linkfox-web/http");function K(e){if(!e.trim())throw new Error("缺少 SSO clientId")}function ue(e){K(e),(0,u.getSession)()?.ssoClientId===e&&(0,u.clearSession)()}function M(e){K(e);let r=(0,u.getSession)();if(!r||r.ssoClientId!==e)return null;try{if(typeof r.sub!="string"||!r.sub||typeof r.id!="string"||!r.id||typeof r.name!="string"||typeof r.expireAt!="number"||r.expireAt<=Date.now()||fe(r.accessToken)!==r.expireAt)throw new Error("无效会话")}catch{return(0,u.clearSession)(),null}return{accessToken:r.accessToken,sub:r.sub,id:r.id,name:r.name,...typeof r.picture=="string"?{picture:r.picture}:{},expireAt:r.expireAt}}function fe(e){try{let r=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),{exp:t}=JSON.parse(atob(r.padEnd(Math.ceil(r.length/4)*4,"=")));if(typeof t=="number"&&Number.isFinite(t)&&t*1e3>Date.now()&&t*1e3<=864e13)return t*1e3}catch{}throw new Error("SSO token 无效或已过期,请重新登录")}function ge(e,r){K(e);let t=r;if(!t||typeof t.accessToken!="string"||!t.accessToken||typeof t.sub!="string"||!t.sub||typeof t.id!="string"||!t.id||typeof t.name!="string")throw new Error("SSO 登录响应缺少用户信息或 accessToken");let n={accessToken:t.accessToken,sub:t.sub,id:t.id,name:t.name,...typeof t.picture=="string"?{picture:t.picture}:{},expireAt:fe(t.accessToken)};if((0,u.setSession)({...n,userId:n.sub,ssoClientId:e}),M(e)?.accessToken!==n.accessToken)throw new Error("浏览器禁止保存登录信息,请允许本站 cookie 与本地存储后重试");return n}var le="linkfox:sso:callback",ze=["code","state","error","error_description"],pe="linkfox:sso:redirect:",Ke=6e5;function he(e){if(!e.trim())throw new Error("缺少 SSO clientId");if(!b.config().baseURL)throw new Error("请配置 third-party-sso 的 baseURL")}async function k(e,r={}){he(e);let t=await b.request({method:"POST",path:"/thirdPartyApplication/get",body:{clientId:e,...r.redirectUri?{redirectUri:r.redirectUri}:{}},auth:"none",signal:r.signal});if(!["redirectUri","authorizationUrl","codeVerifier","appName"].every(n=>typeof t[n]=="string"&&t[n]))throw new Error("SSO 应用配置响应不完整");return t}async function L(e,r={}){if(he(e.clientId),![e.code,e.codeVerifier,e.redirectUri,e.appName].every(g=>typeof g=="string"&&g.trim()))throw new Error("SSO 换取 token 的参数不完整");r.signal?.throwIfAborted();let{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:f}=e,a=await b.request({method:"POST",path:"/thirdPartyApplication/login",body:{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:f},auth:"none",signal:r.signal});return r.signal?.throwIfAborted(),ge(t,a)}function me(e,r){let t=new URL(e.redirectUri);if(t.origin!==window.location.origin||t.username||t.password||t.hash||!["http:","https:"].includes(t.protocol))throw new Error(`SSO redirectUri 为 ${t.origin}${t.pathname},请在该地址打开应用或修改服务端注册配置`);if(t.href!==new URL(r).href)throw new Error("SSO 返回的 redirectUri 与请求不一致");let n=new URL(e.authorizationUrl);if(n.protocol!=="https:"||n.username||n.password)throw new Error("SSO authorizationUrl 必须是 HTTPS 地址");if(n.searchParams.get("redirect_uri")!==e.redirectUri||n.searchParams.get("code_challenge_method")!=="S256"||!n.searchParams.get("code_challenge"))throw new Error("SSO 授权地址缺少匹配的 redirect_uri 或 PKCE S256 参数");return{redirect:t,authorization:n}}function ye(e,r,t){if(e.origin!==r.origin||e.pathname!==r.pathname)throw new Error("SSO 回调地址与 redirectUri 不一致");for(let[i,o]of r.searchParams)if(e.searchParams.get(i)!==o)throw new Error("SSO 回调参数与 redirectUri 不一致");if(e.searchParams.getAll("state").length!==1||e.searchParams.get("state")!==t)throw new Error("SSO 回调 state 不匹配,请重新登录");if(e.searchParams.has("error"))throw new Error("授权未完成或已被拒绝,请重新登录");let n=e.searchParams.get("code");if(!n||e.searchParams.getAll("code").length!==1)throw new Error("SSO 回调缺少唯一 code");return n}function we(){if(typeof window>"u"||window.parent===window)return!1;let e=new URL(window.location.href);if(!e.searchParams.has("code")&&!e.searchParams.has("error"))return!1;window.parent.postMessage({type:le,url:e.href},e.origin);for(let r of["code","state","error","error_description"])e.searchParams.delete(r);return window.history.replaceState(null,"",e.href),!0}function Se(e){if(typeof window>"u")return Promise.reject(new Error("SSO iframe 登录只能在浏览器中启动"));let r=new AbortController,t=r.signal;return new Promise((n,i)=>{let o=!1,f=!1,a,g,v="",P=e.timeoutMs??3e5;if(!Number.isFinite(P)||P<=0||P>2147483647){i(new Error("SSO 超时配置无效"));return}let W=()=>{clearTimeout(Ue),window.removeEventListener("message",F),e.signal?.removeEventListener("abort",O),a=void 0},h=d=>{o||(o=!0,W(),r.abort(),i(d))},O=()=>h(new DOMException("登录已取消","AbortError")),F=d=>{if(o||f||!a||!g||d.origin!==g.origin||!d.source||d.source!==e.getFrameWindow())return;let c=d.data;if(!(!c||c.type!==le||typeof c.url!="string"))try{let m=ye(new URL(c.url),g,v);f=!0,L({clientId:e.clientId,redirectUri:a.redirectUri,codeVerifier:a.codeVerifier,appName:a.appName,code:m},{signal:t}).then(Ie=>{o||(o=!0,W(),n(Ie))},h)}catch(m){h(m)}},Ue=setTimeout(()=>h(new Error("登录超时,请重试;若授权页无法显示,请检查其 iframe 嵌入策略")),P);if(e.signal?.addEventListener("abort",O,{once:!0}),e.signal?.aborted){O();return}window.addEventListener("message",F),k(e.clientId,{redirectUri:e.redirectUri??window.location.origin,signal:t}).then(d=>{if(!o)try{a=d;let c=me(a,e.redirectUri??window.location.origin);g=c.redirect;let m=c.authorization;v=crypto.randomUUID(),m.searchParams.set("state",v),e.onAuthorization({authorizationUrl:m.href,appName:a.appName})}catch(c){h(c)}},h)})}function Te(){try{return window.sessionStorage}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}}function Pe(e){if(e)try{let r=new URL(e,window.location.href);return r.origin===window.location.origin?r.href:void 0}catch{return}}function Me(e){let r=Te(),t=pe+e,n=r.getItem(t);if(r.removeItem(t),!n)return null;try{let i=JSON.parse(n);return!["state","codeVerifier","redirectUri","appName","returnTo"].every(o=>typeof i[o]=="string"&&i[o])||typeof i.createdAt!="number"?null:i}catch{return null}}async function xe(e){if(typeof window>"u")throw new Error("SSO 跳转登录只能在浏览器中启动");let r=Te(),t=e.redirectUri??window.location.origin,n=await k(e.clientId,{redirectUri:t,signal:e.signal}),{authorization:i}=me(n,t),o=crypto.randomUUID();i.searchParams.set("state",o);let f={state:o,codeVerifier:n.codeVerifier,redirectUri:n.redirectUri,appName:n.appName,returnTo:Pe(e.returnTo??window.location.href)??n.redirectUri,createdAt:Date.now()};e.signal?.throwIfAborted();try{r.setItem(pe+e.clientId,JSON.stringify(f))}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}window.location.assign(i.href)}async function Ce(e,r={}){if(typeof window>"u")return null;let t=new URL(window.location.href);if(!t.searchParams.has("state")||!t.searchParams.has("code")&&!t.searchParams.has("error"))return null;let n=new URL(t.href);for(let a of ze)n.searchParams.delete(a);window.history.replaceState(window.history.state,"",n.href);let i=Me(e);if(!i)throw new Error("登录请求已失效,请重新登录");if(Date.now()-i.createdAt>Ke)throw new Error("登录超时,请重新登录");let o=ye(t,new URL(i.redirectUri),i.state);return{session:await L({clientId:e,redirectUri:i.redirectUri,codeVerifier:i.codeVerifier,appName:i.appName,code:o},r),returnTo:Pe(i.returnTo)??i.redirectUri}}$();
1
+ "use strict";var Ee=Object.create;var x=Object.defineProperty;var Ae=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var be=Object.getPrototypeOf,ke=Object.prototype.hasOwnProperty;var Le=(e,r)=>{for(var t in r)x(e,t,{get:r[t],enumerable:!0})},q=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Re(r))!ke.call(e,i)&&i!==t&&x(e,i,{get:()=>r[i],enumerable:!(n=Ae(r,i))||n.enumerable});return e};var C=(e,r,t)=>(t=e!=null?Ee(be(e)):{},q(r||!e||!e.__esModule?x(t,"default",{value:e,enumerable:!0}):t,e)),ve=e=>q(x({},"__esModule",{value:!0}),e);var We={};Le(We,{clearThirdPartySsoSession:()=>ue,completeThirdPartySsoRedirect:()=>Ce,getImageVerifyCode:()=>ne,getPersonalKey:()=>N,getThirdPartyApplication:()=>k,getUserInfo:()=>w,getVerifyCode:()=>oe,getWechatQrCode:()=>ae,getWechatQrCodeStatus:()=>ce,handleThirdPartySsoCallback:()=>we,loginByCode:()=>se,loginByPassword:()=>ie,loginByWechat:()=>de,loginThirdPartyApplication:()=>L,logout:()=>$,readThirdPartySsoSession:()=>M,redirectToThirdPartySso:()=>xe,resolveCurrentTeam:()=>S,startThirdPartySso:()=>Se,switchTeam:()=>Y,syncApiKey:()=>H,syncCurrentTeam:()=>y});module.exports=ve(We);var T=require("@linkfox-web/http");var I=require("@linkfox-web/http");var B={baseURL:"https://api.linkfox.com",aesKey:"AR7x7zfje4nkim4t",source:"ai-linkfox-web",systemId:"LinkFoxAgent",clientChannel:"LinkFoxAI"};var Oe=new Set(["30003","30009","30011","30015","30017","30019"]),Q="LINKFOX_CLIENT_ID";function U(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function _(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let r=Math.random()*16|0;return(e==="x"?r:r&3|8).toString(16)})}function _e(){try{let e=localStorage.getItem(Q);return e||(e=_(),localStorage.setItem(Q,e)),e}catch{return""}}function Ne(e){try{return btoa(JSON.stringify({a_id:_e(),d_id:e}))}catch{return""}}var s=(0,I.defineService)({name:"user-center",defaults:B,baseHeaders:e=>({source:e.config.source,uid:Ne(e.session?.userId??"")}),authorize:e=>e.session?{authorization:e.session.accessToken}:{},isUnauthorized:(e,r)=>e.status===401||U(r)&&r.success!==!0&&Oe.has(String(r.code??"")),refreshOnUnauthorized:!1,unwrap:(e,r)=>{if(U(r)&&(r.code==="OK"&&r.success!==!1||r.code===200&&r.success!==!1||r.success===!0)&&e.ok)return r.data;throw new I.LinkfoxHttpError({service:"user-center",status:e.status,code:U(r)?r.code:void 0,message:U(r)&&(r.message||r.msg)||e.statusText||`HTTP ${e.status}`,body:r})}});var p=require("@linkfox-web/http");var l=require("@linkfox-web/http");async function N(e){return(await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/api-credential/getPersonalKey",body:{teamId:e||await De()}}))?.credentials??[]}async function De(){let e=(0,l.getCurrentTeam)()?.teamId;if(e)return e;let{teamList:r}=await w(),t=(S(r)??r.find(n=>n.isSelect===1)??r[0])?.teamId;if(!t)throw new l.LinkfoxHttpError({service:"user-center",status:200,code:"TEAM_REQUIRED",message:"当前账号没有可用团队"});return t}async function H(e){let r=await N(e),t=r.find(n=>n.credentialType==="USER_PRIMARY"&&n.credential)??r.find(n=>n.credential);if(!t)throw new l.LinkfoxHttpError({service:"user-center",status:200,code:"API_KEY_NOT_FOUND",message:"当前账号没有可用的 API Key"});return D(t.credential),t.credential}function D(e){(0,l.configure)({services:{"ai-tools":{apiKey:e}}})}function w(){return j(!1)}function j(e){return s.request({method:"POST",path:"/linkFoxApp/api/userCenter/userInfo",body:{},skipRecovery:e})}function S(e){if(!e?.length)return;let r=e.find(n=>n.isSelect===1);if(r?.agentMemberId)return r;let t=e.find(n=>n.teamType===1);return t?.agentMemberId?t:e.find(n=>n.agentMemberId)}function X(e){return e.aiTeamId?{id:e.aiTeamId,teamId:e.teamId,name:e.teamName,type:e.teamType,logo:e.logo??"",ownerId:e.ownerId}:null}async function y(e){let r=await j(e?.skipRecovery??!1),t=S(r.teamList),n=t?X(t):null;return n?((0,p.setTeam)(n),!0):!1}async function Y(e){await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/team/switchTeam",body:{targetTeamId:e}});let r=await w(),t=r.teamList.find(i=>i.teamId===e),n=t?X(t):null;return n?(0,p.setTeam)(n):(0,p.clearTeam)(),r}function $(){(0,p.clearSession)(),D(void 0)}async function Ke(e){let r=await s.request({method:"POST",path:"/cp/v1/user/refresh",auth:"none",skipRecovery:!0,headers:{authorization:e.refreshToken??""}});if(!r?.accessToken)throw new Error("REFRESH_TOKEN_EXPIRED");(0,T.updateSession)({accessToken:r.accessToken,refreshToken:r.refreshToken,expireAt:r.expireAt})}function J(){(0,T.registerCapability)("refresh",Ke),(0,T.registerCapability)("resolveTeam",()=>y({skipRecovery:!0}))}var E=require("@linkfox-web/http");var G=C(require("crypto-js/aes"),1),Z=C(require("crypto-js/enc-utf8"),1),ee=C(require("crypto-js/mode-ecb"),1),re=C(require("crypto-js/pad-zeropadding"),1);function te(e,r){return G.default.encrypt(e,Z.default.parse(r),{mode:ee.default,padding:re.default}).toString()}function K(e){return e?.sourceUrl??(typeof location<"u"?location.href:"")}async function V(e){if(!e?.accessToken)throw new E.LinkfoxHttpError({service:"user-center",status:200,code:"INVALID_LOGIN_RESPONSE",message:"登录响应缺少 accessToken",body:e});(0,E.setSession)(e);try{await y()}catch{}return e}function A(e,r){return s.request({method:"POST",path:e,body:r,auth:"none"})}async function ne(){let e=_(),r=await s.request({path:"/user/v1/sendMessageCode.jpg",query:{uuid:e},auth:"none",responseType:"blob"}),t=await new Promise((n,i)=>{let o=new FileReader;o.onloadend=()=>n(String(o.result??"")),o.onerror=()=>i(o.error),o.readAsDataURL(r)});return{uuid:e,imageBase64:t}}async function ie(e,r){let t=s.config(),n=await A("/user/v2/web/login",{type:"smsPwd",method:"login",sourceUrl:K(r),data:{authPhone:e.authPhone,auth:te(e.password,t.aesKey),uuid:e.uuid,imageCode:e.imageCode,systemId:t.systemId}});return V(n)}async function oe(e){await A("/user/v3/web/login",{type:"sms",method:"getVerifyCode",data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",...e.uuid?{uuid:e.uuid}:{},...e.imageCode?{imageCode:e.imageCode}:{},clientChannel:s.config().clientChannel}})}async function se(e,r){let t=await A("/user/v3/web/login",{type:"sms",method:"login",sourceUrl:K(r),data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",authCode:e.authCode,sourceChannel:e.sourceChannel??""}});return V(t)}function ae(){return s.request({method:"POST",path:"/user/v1/web/login/wechat/qr_url",body:{type:"1"},auth:"none"})}function ce(e){return s.request({path:"/user/v1/web/login/wechat",query:{sessionId:e},auth:"none"})}async function de(e,r){let t=await A("/user/v2/web/login",{type:"wechatQR",method:"login",sourceUrl:K(r),data:{sessionId:e.sessionId,...e.authPhone?{authPhone:e.authPhone}:{},...e.authCode?{authCode:e.authCode}:{},sourceChannel:e.sourceChannel??""}});return V(t)}var R=require("@linkfox-web/http"),b=(0,R.defineService)({name:"third-party-sso",defaults:{baseURL:""},refreshOnUnauthorized:!1,unwrap:(e,r)=>{let t=r&&typeof r=="object"?r:void 0,n=t?.error&&typeof t.error=="object"?t.error:void 0;if(e.ok&&t&&!t.error)return t;throw new R.LinkfoxHttpError({service:"third-party-sso",status:e.status,code:typeof n?.code=="string"||typeof n?.code=="number"?n.code:e.status,message:typeof n?.message=="string"?n.message:`SSO 请求失败(HTTP ${e.status})`})}});var c=require("@linkfox-web/http");function z(e){if(!e.trim())throw new Error("缺少 SSO clientId");(0,c.configure)({cookieKey:`LINKFOX_SSO_${e}_TOKEN`,storage:"local"})}function ue(e){z(e),(0,c.getSession)()?.ssoClientId===e&&(0,c.clearSession)()}function M(e){z(e);let r=(0,c.getSession)();if(!r||r.ssoClientId!==e)return null;try{if(typeof r.sub!="string"||!r.sub||typeof r.id!="string"||!r.id||typeof r.name!="string"||typeof r.expireAt!="number"||r.expireAt<=Date.now()||fe(r.accessToken)!==r.expireAt)throw new Error("无效会话")}catch{return(0,c.clearSession)(),null}return{accessToken:r.accessToken,sub:r.sub,id:r.id,name:r.name,...typeof r.picture=="string"?{picture:r.picture}:{},expireAt:r.expireAt}}function fe(e){try{let r=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),{exp:t}=JSON.parse(atob(r.padEnd(Math.ceil(r.length/4)*4,"=")));if(typeof t=="number"&&Number.isFinite(t)&&t*1e3>Date.now()&&t*1e3<=864e13)return t*1e3}catch{}throw new Error("SSO token 无效或已过期,请重新登录")}function ge(e,r){z(e);let t=r;if(!t||typeof t.accessToken!="string"||!t.accessToken||typeof t.sub!="string"||!t.sub||typeof t.id!="string"||!t.id||typeof t.name!="string")throw new Error("SSO 登录响应缺少用户信息或 accessToken");let n={accessToken:t.accessToken,sub:t.sub,id:t.id,name:t.name,...typeof t.picture=="string"?{picture:t.picture}:{},expireAt:fe(t.accessToken)};if((0,c.setSession)({...n,userId:n.sub,ssoClientId:e}),M(e)?.accessToken!==n.accessToken)throw new Error("浏览器禁止保存登录信息,请允许本站 cookie 与本地存储后重试");return n}var le="linkfox:sso:callback",Ve=["code","state","error","error_description"],pe="linkfox:sso:redirect:",ze=6e5;function he(e){if(!e.trim())throw new Error("缺少 SSO clientId");if(!b.config().baseURL)throw new Error("请配置 third-party-sso 的 baseURL")}async function k(e,r={}){he(e);let t=await b.request({method:"POST",path:"/thirdPartyApplication/get",body:{clientId:e,...r.redirectUri?{redirectUri:r.redirectUri}:{}},auth:"none",signal:r.signal});if(!["redirectUri","authorizationUrl","codeVerifier","appName"].every(n=>typeof t[n]=="string"&&t[n]))throw new Error("SSO 应用配置响应不完整");return t}async function L(e,r={}){if(he(e.clientId),![e.code,e.codeVerifier,e.redirectUri,e.appName].every(g=>typeof g=="string"&&g.trim()))throw new Error("SSO 换取 token 的参数不完整");r.signal?.throwIfAborted();let{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:f}=e,a=await b.request({method:"POST",path:"/thirdPartyApplication/login",body:{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:f},auth:"none",signal:r.signal});return r.signal?.throwIfAborted(),ge(t,a)}function me(e,r){let t=new URL(e.redirectUri);if(t.origin!==window.location.origin||t.username||t.password||t.hash||!["http:","https:"].includes(t.protocol))throw new Error(`SSO redirectUri 为 ${t.origin}${t.pathname},请在该地址打开应用或修改服务端注册配置`);if(t.href!==new URL(r).href)throw new Error("SSO 返回的 redirectUri 与请求不一致");let n=new URL(e.authorizationUrl);if(n.protocol!=="https:"||n.username||n.password)throw new Error("SSO authorizationUrl 必须是 HTTPS 地址");if(n.searchParams.get("redirect_uri")!==e.redirectUri||n.searchParams.get("code_challenge_method")!=="S256"||!n.searchParams.get("code_challenge"))throw new Error("SSO 授权地址缺少匹配的 redirect_uri 或 PKCE S256 参数");return{redirect:t,authorization:n}}function ye(e,r,t){if(e.origin!==r.origin||e.pathname!==r.pathname)throw new Error("SSO 回调地址与 redirectUri 不一致");for(let[i,o]of r.searchParams)if(e.searchParams.get(i)!==o)throw new Error("SSO 回调参数与 redirectUri 不一致");if(e.searchParams.getAll("state").length!==1||e.searchParams.get("state")!==t)throw new Error("SSO 回调 state 不匹配,请重新登录");if(e.searchParams.has("error"))throw new Error("授权未完成或已被拒绝,请重新登录");let n=e.searchParams.get("code");if(!n||e.searchParams.getAll("code").length!==1)throw new Error("SSO 回调缺少唯一 code");return n}function we(){if(typeof window>"u"||window.parent===window)return!1;let e=new URL(window.location.href);if(!e.searchParams.has("code")&&!e.searchParams.has("error"))return!1;window.parent.postMessage({type:le,url:e.href},e.origin);for(let r of["code","state","error","error_description"])e.searchParams.delete(r);return window.history.replaceState(null,"",e.href),!0}function Se(e){if(typeof window>"u")return Promise.reject(new Error("SSO iframe 登录只能在浏览器中启动"));let r=new AbortController,t=r.signal;return new Promise((n,i)=>{let o=!1,f=!1,a,g,v="",P=e.timeoutMs??3e5;if(!Number.isFinite(P)||P<=0||P>2147483647){i(new Error("SSO 超时配置无效"));return}let W=()=>{clearTimeout(Ue),window.removeEventListener("message",F),e.signal?.removeEventListener("abort",O),a=void 0},h=u=>{o||(o=!0,W(),r.abort(),i(u))},O=()=>h(new DOMException("登录已取消","AbortError")),F=u=>{if(o||f||!a||!g||u.origin!==g.origin||!u.source||u.source!==e.getFrameWindow())return;let d=u.data;if(!(!d||d.type!==le||typeof d.url!="string"))try{let m=ye(new URL(d.url),g,v);f=!0,L({clientId:e.clientId,redirectUri:a.redirectUri,codeVerifier:a.codeVerifier,appName:a.appName,code:m},{signal:t}).then(Ie=>{o||(o=!0,W(),n(Ie))},h)}catch(m){h(m)}},Ue=setTimeout(()=>h(new Error("登录超时,请重试;若授权页无法显示,请检查其 iframe 嵌入策略")),P);if(e.signal?.addEventListener("abort",O,{once:!0}),e.signal?.aborted){O();return}window.addEventListener("message",F),k(e.clientId,{redirectUri:e.redirectUri??window.location.origin,signal:t}).then(u=>{if(!o)try{a=u;let d=me(a,e.redirectUri??window.location.origin);g=d.redirect;let m=d.authorization;v=crypto.randomUUID(),m.searchParams.set("state",v),e.onAuthorization({authorizationUrl:m.href,appName:a.appName})}catch(d){h(d)}},h)})}function Te(){try{return window.sessionStorage}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}}function Pe(e){if(e)try{let r=new URL(e,window.location.href);return r.origin===window.location.origin?r.href:void 0}catch{return}}function Me(e){let r=Te(),t=pe+e,n=r.getItem(t);if(r.removeItem(t),!n)return null;try{let i=JSON.parse(n);return!["state","codeVerifier","redirectUri","appName","returnTo"].every(o=>typeof i[o]=="string"&&i[o])||typeof i.createdAt!="number"?null:i}catch{return null}}async function xe(e){if(typeof window>"u")throw new Error("SSO 跳转登录只能在浏览器中启动");let r=Te(),t=e.redirectUri??window.location.origin,n=await k(e.clientId,{redirectUri:t,signal:e.signal}),{authorization:i}=me(n,t),o=crypto.randomUUID();i.searchParams.set("state",o);let f={state:o,codeVerifier:n.codeVerifier,redirectUri:n.redirectUri,appName:n.appName,returnTo:Pe(e.returnTo??window.location.href)??n.redirectUri,createdAt:Date.now()};e.signal?.throwIfAborted();try{r.setItem(pe+e.clientId,JSON.stringify(f))}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}window.location.assign(i.href)}async function Ce(e,r={}){if(typeof window>"u")return null;let t=new URL(window.location.href);if(!t.searchParams.has("state")||!t.searchParams.has("code")&&!t.searchParams.has("error"))return null;let n=new URL(t.href);for(let a of Ve)n.searchParams.delete(a);window.history.replaceState(window.history.state,"",n.href);let i=Me(e);if(!i)throw new Error("登录请求已失效,请重新登录");if(Date.now()-i.createdAt>ze)throw new Error("登录超时,请重新登录");let o=ye(t,new URL(i.redirectUri),i.state);return{session:await L({clientId:e,redirectUri:i.redirectUri,codeVerifier:i.codeVerifier,appName:i.appName,code:o},r),returnTo:Pe(i.returnTo)??i.redirectUri}}J();
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{registerCapability as K,updateSession as he}from"@linkfox-web/http";import{defineService as te,LinkfoxHttpError as ne}from"@linkfox-web/http";var v={baseURL:"https://api.linkfox.com",aesKey:"AR7x7zfje4nkim4t",source:"ai-linkfox-web",systemId:"LinkFoxAgent",clientChannel:"LinkFoxAI"};var ie=new Set(["30003","30009","30011","30015","30017","30019"]),O="LINKFOX_CLIENT_ID";function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function C(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let r=Math.random()*16|0;return(e==="x"?r:r&3|8).toString(16)})}function oe(){try{let e=localStorage.getItem(O);return e||(e=C(),localStorage.setItem(O,e)),e}catch{return""}}function se(e){try{return btoa(JSON.stringify({a_id:oe(),d_id:e}))}catch{return""}}var s=te({name:"user-center",defaults:v,baseHeaders:e=>({source:e.config.source,uid:se(e.session?.userId??"")}),authorize:e=>e.session?{authorization:e.session.accessToken}:{},isUnauthorized:(e,r)=>e.status===401||m(r)&&r.success!==!0&&ie.has(String(r.code??"")),refreshOnUnauthorized:!1,unwrap:(e,r)=>{if(m(r)&&(r.code==="OK"&&r.success!==!1||r.code===200&&r.success!==!1||r.success===!0)&&e.ok)return r.data;throw new ne({service:"user-center",status:e.status,code:m(r)?r.code:void 0,message:m(r)&&(r.message||r.msg)||e.statusText||`HTTP ${e.status}`,body:r})}});import{clearSession as fe,clearTeam as ge,setTeam as D}from"@linkfox-web/http";import{configure as ae,getCurrentTeam as ce,LinkfoxHttpError as _}from"@linkfox-web/http";async function N(e){return(await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/api-credential/getPersonalKey",body:{teamId:e||await de()}}))?.credentials??[]}async function de(){let e=ce()?.teamId;if(e)return e;let{teamList:r}=await y(),t=(w(r)??r.find(n=>n.isSelect===1)??r[0])?.teamId;if(!t)throw new _({service:"user-center",status:200,code:"TEAM_REQUIRED",message:"当前账号没有可用团队"});return t}async function ue(e){let r=await N(e),t=r.find(n=>n.credentialType==="USER_PRIMARY"&&n.credential)??r.find(n=>n.credential);if(!t)throw new _({service:"user-center",status:200,code:"API_KEY_NOT_FOUND",message:"当前账号没有可用的 API Key"});return U(t.credential),t.credential}function U(e){ae({services:{"ai-tools":{apiKey:e}}})}function y(){return V(!1)}function V(e){return s.request({method:"POST",path:"/linkFoxApp/api/userCenter/userInfo",body:{},skipRecovery:e})}function w(e){if(!e?.length)return;let r=e.find(n=>n.isSelect===1);if(r?.agentMemberId)return r;let t=e.find(n=>n.teamType===1);return t?.agentMemberId?t:e.find(n=>n.agentMemberId)}function z(e){return e.aiTeamId?{id:e.aiTeamId,teamId:e.teamId,name:e.teamName,type:e.teamType,logo:e.logo??"",ownerId:e.ownerId}:null}async function p(e){let r=await V(e?.skipRecovery??!1),t=w(r.teamList),n=t?z(t):null;return n?(D(n),!0):!1}async function le(e){await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/team/switchTeam",body:{targetTeamId:e}});let r=await y(),t=r.teamList.find(i=>i.teamId===e),n=t?z(t):null;return n?D(n):ge(),r}function pe(){fe(),U(void 0)}async function me(e){let r=await s.request({method:"POST",path:"/cp/v1/user/refresh",auth:"none",skipRecovery:!0,headers:{authorization:e.refreshToken??""}});if(!r?.accessToken)throw new Error("REFRESH_TOKEN_EXPIRED");he({accessToken:r.accessToken,refreshToken:r.refreshToken,expireAt:r.expireAt})}function M(){K("refresh",me),K("resolveTeam",()=>p({skipRecovery:!0}))}import{LinkfoxHttpError as Pe,setSession as xe}from"@linkfox-web/http";import ye from"crypto-js/aes";import we from"crypto-js/enc-utf8";import Se from"crypto-js/mode-ecb";import Te from"crypto-js/pad-zeropadding";function W(e,r){return ye.encrypt(e,we.parse(r),{mode:Se,padding:Te}).toString()}function I(e){return e?.sourceUrl??(typeof location<"u"?location.href:"")}async function E(e){if(!e?.accessToken)throw new Pe({service:"user-center",status:200,code:"INVALID_LOGIN_RESPONSE",message:"登录响应缺少 accessToken",body:e});xe(e);try{await p()}catch{}return e}function S(e,r){return s.request({method:"POST",path:e,body:r,auth:"none"})}async function Ce(){let e=C(),r=await s.request({path:"/user/v1/sendMessageCode.jpg",query:{uuid:e},auth:"none",responseType:"blob"}),t=await new Promise((n,i)=>{let o=new FileReader;o.onloadend=()=>n(String(o.result??"")),o.onerror=()=>i(o.error),o.readAsDataURL(r)});return{uuid:e,imageBase64:t}}async function Ue(e,r){let t=s.config(),n=await S("/user/v2/web/login",{type:"smsPwd",method:"login",sourceUrl:I(r),data:{authPhone:e.authPhone,auth:W(e.password,t.aesKey),uuid:e.uuid,imageCode:e.imageCode,systemId:t.systemId}});return E(n)}async function Ie(e){await S("/user/v3/web/login",{type:"sms",method:"getVerifyCode",data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",...e.uuid?{uuid:e.uuid}:{},...e.imageCode?{imageCode:e.imageCode}:{},clientChannel:s.config().clientChannel}})}async function Ee(e,r){let t=await S("/user/v3/web/login",{type:"sms",method:"login",sourceUrl:I(r),data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",authCode:e.authCode,sourceChannel:e.sourceChannel??""}});return E(t)}function Re(){return s.request({method:"POST",path:"/user/v1/web/login/wechat/qr_url",body:{type:"1"},auth:"none"})}function Ae(e){return s.request({path:"/user/v1/web/login/wechat",query:{sessionId:e},auth:"none"})}async function be(e,r){let t=await S("/user/v2/web/login",{type:"wechatQR",method:"login",sourceUrl:I(r),data:{sessionId:e.sessionId,...e.authPhone?{authPhone:e.authPhone}:{},...e.authCode?{authCode:e.authCode}:{},sourceChannel:e.sourceChannel??""}});return E(t)}import{defineService as ke,LinkfoxHttpError as Le}from"@linkfox-web/http";var T=ke({name:"third-party-sso",defaults:{baseURL:""},refreshOnUnauthorized:!1,unwrap:(e,r)=>{let t=r&&typeof r=="object"?r:void 0,n=t?.error&&typeof t.error=="object"?t.error:void 0;if(e.ok&&t&&!t.error)return t;throw new Le({service:"third-party-sso",status:e.status,code:typeof n?.code=="string"||typeof n?.code=="number"?n.code:e.status,message:typeof n?.message=="string"?n.message:`SSO 请求失败(HTTP ${e.status})`})}});import{clearSession as F,getSession as q,setSession as ve}from"@linkfox-web/http";function R(e){if(!e.trim())throw new Error("缺少 SSO clientId")}function Oe(e){R(e),q()?.ssoClientId===e&&F()}function B(e){R(e);let r=q();if(!r||r.ssoClientId!==e)return null;try{if(typeof r.sub!="string"||!r.sub||typeof r.id!="string"||!r.id||typeof r.name!="string"||typeof r.expireAt!="number"||r.expireAt<=Date.now()||Q(r.accessToken)!==r.expireAt)throw new Error("无效会话")}catch{return F(),null}return{accessToken:r.accessToken,sub:r.sub,id:r.id,name:r.name,...typeof r.picture=="string"?{picture:r.picture}:{},expireAt:r.expireAt}}function Q(e){try{let r=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),{exp:t}=JSON.parse(atob(r.padEnd(Math.ceil(r.length/4)*4,"=")));if(typeof t=="number"&&Number.isFinite(t)&&t*1e3>Date.now()&&t*1e3<=864e13)return t*1e3}catch{}throw new Error("SSO token 无效或已过期,请重新登录")}function H(e,r){R(e);let t=r;if(!t||typeof t.accessToken!="string"||!t.accessToken||typeof t.sub!="string"||!t.sub||typeof t.id!="string"||!t.id||typeof t.name!="string")throw new Error("SSO 登录响应缺少用户信息或 accessToken");let n={accessToken:t.accessToken,sub:t.sub,id:t.id,name:t.name,...typeof t.picture=="string"?{picture:t.picture}:{},expireAt:Q(t.accessToken)};if(ve({...n,userId:n.sub,ssoClientId:e}),B(e)?.accessToken!==n.accessToken)throw new Error("浏览器禁止保存登录信息,请允许本站 cookie 与本地存储后重试");return n}var j="linkfox:sso:callback",_e=["code","state","error","error_description"],Y="linkfox:sso:redirect:",Ne=6e5;function J(e){if(!e.trim())throw new Error("缺少 SSO clientId");if(!T.config().baseURL)throw new Error("请配置 third-party-sso 的 baseURL")}async function A(e,r={}){J(e);let t=await T.request({method:"POST",path:"/thirdPartyApplication/get",body:{clientId:e,...r.redirectUri?{redirectUri:r.redirectUri}:{}},auth:"none",signal:r.signal});if(!["redirectUri","authorizationUrl","codeVerifier","appName"].every(n=>typeof t[n]=="string"&&t[n]))throw new Error("SSO 应用配置响应不完整");return t}async function b(e,r={}){if(J(e.clientId),![e.code,e.codeVerifier,e.redirectUri,e.appName].every(f=>typeof f=="string"&&f.trim()))throw new Error("SSO 换取 token 的参数不完整");r.signal?.throwIfAborted();let{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:u}=e,a=await T.request({method:"POST",path:"/thirdPartyApplication/login",body:{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:u},auth:"none",signal:r.signal});return r.signal?.throwIfAborted(),H(t,a)}function X(e,r){let t=new URL(e.redirectUri);if(t.origin!==window.location.origin||t.username||t.password||t.hash||!["http:","https:"].includes(t.protocol))throw new Error(`SSO redirectUri 为 ${t.origin}${t.pathname},请在该地址打开应用或修改服务端注册配置`);if(t.href!==new URL(r).href)throw new Error("SSO 返回的 redirectUri 与请求不一致");let n=new URL(e.authorizationUrl);if(n.protocol!=="https:"||n.username||n.password)throw new Error("SSO authorizationUrl 必须是 HTTPS 地址");if(n.searchParams.get("redirect_uri")!==e.redirectUri||n.searchParams.get("code_challenge_method")!=="S256"||!n.searchParams.get("code_challenge"))throw new Error("SSO 授权地址缺少匹配的 redirect_uri 或 PKCE S256 参数");return{redirect:t,authorization:n}}function $(e,r,t){if(e.origin!==r.origin||e.pathname!==r.pathname)throw new Error("SSO 回调地址与 redirectUri 不一致");for(let[i,o]of r.searchParams)if(e.searchParams.get(i)!==o)throw new Error("SSO 回调参数与 redirectUri 不一致");if(e.searchParams.getAll("state").length!==1||e.searchParams.get("state")!==t)throw new Error("SSO 回调 state 不匹配,请重新登录");if(e.searchParams.has("error"))throw new Error("授权未完成或已被拒绝,请重新登录");let n=e.searchParams.get("code");if(!n||e.searchParams.getAll("code").length!==1)throw new Error("SSO 回调缺少唯一 code");return n}function De(){if(typeof window>"u"||window.parent===window)return!1;let e=new URL(window.location.href);if(!e.searchParams.has("code")&&!e.searchParams.has("error"))return!1;window.parent.postMessage({type:j,url:e.href},e.origin);for(let r of["code","state","error","error_description"])e.searchParams.delete(r);return window.history.replaceState(null,"",e.href),!0}function Ve(e){if(typeof window>"u")return Promise.reject(new Error("SSO iframe 登录只能在浏览器中启动"));let r=new AbortController,t=r.signal;return new Promise((n,i)=>{let o=!1,u=!1,a,f,P="",h=e.timeoutMs??3e5;if(!Number.isFinite(h)||h<=0||h>2147483647){i(new Error("SSO 超时配置无效"));return}let k=()=>{clearTimeout(ee),window.removeEventListener("message",L),e.signal?.removeEventListener("abort",x),a=void 0},g=d=>{o||(o=!0,k(),r.abort(),i(d))},x=()=>g(new DOMException("登录已取消","AbortError")),L=d=>{if(o||u||!a||!f||d.origin!==f.origin||!d.source||d.source!==e.getFrameWindow())return;let c=d.data;if(!(!c||c.type!==j||typeof c.url!="string"))try{let l=$(new URL(c.url),f,P);u=!0,b({clientId:e.clientId,redirectUri:a.redirectUri,codeVerifier:a.codeVerifier,appName:a.appName,code:l},{signal:t}).then(re=>{o||(o=!0,k(),n(re))},g)}catch(l){g(l)}},ee=setTimeout(()=>g(new Error("登录超时,请重试;若授权页无法显示,请检查其 iframe 嵌入策略")),h);if(e.signal?.addEventListener("abort",x,{once:!0}),e.signal?.aborted){x();return}window.addEventListener("message",L),A(e.clientId,{redirectUri:e.redirectUri??window.location.origin,signal:t}).then(d=>{if(!o)try{a=d;let c=X(a,e.redirectUri??window.location.origin);f=c.redirect;let l=c.authorization;P=crypto.randomUUID(),l.searchParams.set("state",P),e.onAuthorization({authorizationUrl:l.href,appName:a.appName})}catch(c){g(c)}},g)})}function G(){try{return window.sessionStorage}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}}function Z(e){if(e)try{let r=new URL(e,window.location.href);return r.origin===window.location.origin?r.href:void 0}catch{return}}function ze(e){let r=G(),t=Y+e,n=r.getItem(t);if(r.removeItem(t),!n)return null;try{let i=JSON.parse(n);return!["state","codeVerifier","redirectUri","appName","returnTo"].every(o=>typeof i[o]=="string"&&i[o])||typeof i.createdAt!="number"?null:i}catch{return null}}async function Ke(e){if(typeof window>"u")throw new Error("SSO 跳转登录只能在浏览器中启动");let r=G(),t=e.redirectUri??window.location.origin,n=await A(e.clientId,{redirectUri:t,signal:e.signal}),{authorization:i}=X(n,t),o=crypto.randomUUID();i.searchParams.set("state",o);let u={state:o,codeVerifier:n.codeVerifier,redirectUri:n.redirectUri,appName:n.appName,returnTo:Z(e.returnTo??window.location.href)??n.redirectUri,createdAt:Date.now()};e.signal?.throwIfAborted();try{r.setItem(Y+e.clientId,JSON.stringify(u))}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}window.location.assign(i.href)}async function Me(e,r={}){if(typeof window>"u")return null;let t=new URL(window.location.href);if(!t.searchParams.has("state")||!t.searchParams.has("code")&&!t.searchParams.has("error"))return null;let n=new URL(t.href);for(let a of _e)n.searchParams.delete(a);window.history.replaceState(window.history.state,"",n.href);let i=ze(e);if(!i)throw new Error("登录请求已失效,请重新登录");if(Date.now()-i.createdAt>Ne)throw new Error("登录超时,请重新登录");let o=$(t,new URL(i.redirectUri),i.state);return{session:await b({clientId:e,redirectUri:i.redirectUri,codeVerifier:i.codeVerifier,appName:i.appName,code:o},r),returnTo:Z(i.returnTo)??i.redirectUri}}M();export{Oe as clearThirdPartySsoSession,Me as completeThirdPartySsoRedirect,Ce as getImageVerifyCode,N as getPersonalKey,A as getThirdPartyApplication,y as getUserInfo,Ie as getVerifyCode,Re as getWechatQrCode,Ae as getWechatQrCodeStatus,De as handleThirdPartySsoCallback,Ee as loginByCode,Ue as loginByPassword,be as loginByWechat,b as loginThirdPartyApplication,pe as logout,B as readThirdPartySsoSession,Ke as redirectToThirdPartySso,w as resolveCurrentTeam,Ve as startThirdPartySso,le as switchTeam,ue as syncApiKey,p as syncCurrentTeam};
1
+ import{registerCapability as z,updateSession as he}from"@linkfox-web/http";import{defineService as te,LinkfoxHttpError as ne}from"@linkfox-web/http";var v={baseURL:"https://api.linkfox.com",aesKey:"AR7x7zfje4nkim4t",source:"ai-linkfox-web",systemId:"LinkFoxAgent",clientChannel:"LinkFoxAI"};var ie=new Set(["30003","30009","30011","30015","30017","30019"]),O="LINKFOX_CLIENT_ID";function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function C(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let r=Math.random()*16|0;return(e==="x"?r:r&3|8).toString(16)})}function oe(){try{let e=localStorage.getItem(O);return e||(e=C(),localStorage.setItem(O,e)),e}catch{return""}}function se(e){try{return btoa(JSON.stringify({a_id:oe(),d_id:e}))}catch{return""}}var s=te({name:"user-center",defaults:v,baseHeaders:e=>({source:e.config.source,uid:se(e.session?.userId??"")}),authorize:e=>e.session?{authorization:e.session.accessToken}:{},isUnauthorized:(e,r)=>e.status===401||m(r)&&r.success!==!0&&ie.has(String(r.code??"")),refreshOnUnauthorized:!1,unwrap:(e,r)=>{if(m(r)&&(r.code==="OK"&&r.success!==!1||r.code===200&&r.success!==!1||r.success===!0)&&e.ok)return r.data;throw new ne({service:"user-center",status:e.status,code:m(r)?r.code:void 0,message:m(r)&&(r.message||r.msg)||e.statusText||`HTTP ${e.status}`,body:r})}});import{clearSession as fe,clearTeam as ge,setTeam as D}from"@linkfox-web/http";import{configure as ae,getCurrentTeam as ce,LinkfoxHttpError as _}from"@linkfox-web/http";async function N(e){return(await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/api-credential/getPersonalKey",body:{teamId:e||await de()}}))?.credentials??[]}async function de(){let e=ce()?.teamId;if(e)return e;let{teamList:r}=await y(),t=(w(r)??r.find(n=>n.isSelect===1)??r[0])?.teamId;if(!t)throw new _({service:"user-center",status:200,code:"TEAM_REQUIRED",message:"当前账号没有可用团队"});return t}async function ue(e){let r=await N(e),t=r.find(n=>n.credentialType==="USER_PRIMARY"&&n.credential)??r.find(n=>n.credential);if(!t)throw new _({service:"user-center",status:200,code:"API_KEY_NOT_FOUND",message:"当前账号没有可用的 API Key"});return U(t.credential),t.credential}function U(e){ae({services:{"ai-tools":{apiKey:e}}})}function y(){return K(!1)}function K(e){return s.request({method:"POST",path:"/linkFoxApp/api/userCenter/userInfo",body:{},skipRecovery:e})}function w(e){if(!e?.length)return;let r=e.find(n=>n.isSelect===1);if(r?.agentMemberId)return r;let t=e.find(n=>n.teamType===1);return t?.agentMemberId?t:e.find(n=>n.agentMemberId)}function V(e){return e.aiTeamId?{id:e.aiTeamId,teamId:e.teamId,name:e.teamName,type:e.teamType,logo:e.logo??"",ownerId:e.ownerId}:null}async function p(e){let r=await K(e?.skipRecovery??!1),t=w(r.teamList),n=t?V(t):null;return n?(D(n),!0):!1}async function le(e){await s.request({method:"POST",path:"/linkFoxApp/api/userCenter/team/switchTeam",body:{targetTeamId:e}});let r=await y(),t=r.teamList.find(i=>i.teamId===e),n=t?V(t):null;return n?D(n):ge(),r}function pe(){fe(),U(void 0)}async function me(e){let r=await s.request({method:"POST",path:"/cp/v1/user/refresh",auth:"none",skipRecovery:!0,headers:{authorization:e.refreshToken??""}});if(!r?.accessToken)throw new Error("REFRESH_TOKEN_EXPIRED");he({accessToken:r.accessToken,refreshToken:r.refreshToken,expireAt:r.expireAt})}function M(){z("refresh",me),z("resolveTeam",()=>p({skipRecovery:!0}))}import{LinkfoxHttpError as Pe,setSession as xe}from"@linkfox-web/http";import ye from"crypto-js/aes";import we from"crypto-js/enc-utf8";import Se from"crypto-js/mode-ecb";import Te from"crypto-js/pad-zeropadding";function W(e,r){return ye.encrypt(e,we.parse(r),{mode:Se,padding:Te}).toString()}function I(e){return e?.sourceUrl??(typeof location<"u"?location.href:"")}async function E(e){if(!e?.accessToken)throw new Pe({service:"user-center",status:200,code:"INVALID_LOGIN_RESPONSE",message:"登录响应缺少 accessToken",body:e});xe(e);try{await p()}catch{}return e}function S(e,r){return s.request({method:"POST",path:e,body:r,auth:"none"})}async function Ce(){let e=C(),r=await s.request({path:"/user/v1/sendMessageCode.jpg",query:{uuid:e},auth:"none",responseType:"blob"}),t=await new Promise((n,i)=>{let o=new FileReader;o.onloadend=()=>n(String(o.result??"")),o.onerror=()=>i(o.error),o.readAsDataURL(r)});return{uuid:e,imageBase64:t}}async function Ue(e,r){let t=s.config(),n=await S("/user/v2/web/login",{type:"smsPwd",method:"login",sourceUrl:I(r),data:{authPhone:e.authPhone,auth:W(e.password,t.aesKey),uuid:e.uuid,imageCode:e.imageCode,systemId:t.systemId}});return E(n)}async function Ie(e){await S("/user/v3/web/login",{type:"sms",method:"getVerifyCode",data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",...e.uuid?{uuid:e.uuid}:{},...e.imageCode?{imageCode:e.imageCode}:{},clientChannel:s.config().clientChannel}})}async function Ee(e,r){let t=await S("/user/v3/web/login",{type:"sms",method:"login",sourceUrl:I(r),data:{authPhone:e.authPhone,areaCode:e.areaCode??"+86",authCode:e.authCode,sourceChannel:e.sourceChannel??""}});return E(t)}function Ae(){return s.request({method:"POST",path:"/user/v1/web/login/wechat/qr_url",body:{type:"1"},auth:"none"})}function Re(e){return s.request({path:"/user/v1/web/login/wechat",query:{sessionId:e},auth:"none"})}async function be(e,r){let t=await S("/user/v2/web/login",{type:"wechatQR",method:"login",sourceUrl:I(r),data:{sessionId:e.sessionId,...e.authPhone?{authPhone:e.authPhone}:{},...e.authCode?{authCode:e.authCode}:{},sourceChannel:e.sourceChannel??""}});return E(t)}import{defineService as ke,LinkfoxHttpError as Le}from"@linkfox-web/http";var T=ke({name:"third-party-sso",defaults:{baseURL:""},refreshOnUnauthorized:!1,unwrap:(e,r)=>{let t=r&&typeof r=="object"?r:void 0,n=t?.error&&typeof t.error=="object"?t.error:void 0;if(e.ok&&t&&!t.error)return t;throw new Le({service:"third-party-sso",status:e.status,code:typeof n?.code=="string"||typeof n?.code=="number"?n.code:e.status,message:typeof n?.message=="string"?n.message:`SSO 请求失败(HTTP ${e.status})`})}});import{clearSession as F,configure as ve,getSession as q,setSession as Oe}from"@linkfox-web/http";function A(e){if(!e.trim())throw new Error("缺少 SSO clientId");ve({cookieKey:`LINKFOX_SSO_${e}_TOKEN`,storage:"local"})}function _e(e){A(e),q()?.ssoClientId===e&&F()}function B(e){A(e);let r=q();if(!r||r.ssoClientId!==e)return null;try{if(typeof r.sub!="string"||!r.sub||typeof r.id!="string"||!r.id||typeof r.name!="string"||typeof r.expireAt!="number"||r.expireAt<=Date.now()||Q(r.accessToken)!==r.expireAt)throw new Error("无效会话")}catch{return F(),null}return{accessToken:r.accessToken,sub:r.sub,id:r.id,name:r.name,...typeof r.picture=="string"?{picture:r.picture}:{},expireAt:r.expireAt}}function Q(e){try{let r=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),{exp:t}=JSON.parse(atob(r.padEnd(Math.ceil(r.length/4)*4,"=")));if(typeof t=="number"&&Number.isFinite(t)&&t*1e3>Date.now()&&t*1e3<=864e13)return t*1e3}catch{}throw new Error("SSO token 无效或已过期,请重新登录")}function H(e,r){A(e);let t=r;if(!t||typeof t.accessToken!="string"||!t.accessToken||typeof t.sub!="string"||!t.sub||typeof t.id!="string"||!t.id||typeof t.name!="string")throw new Error("SSO 登录响应缺少用户信息或 accessToken");let n={accessToken:t.accessToken,sub:t.sub,id:t.id,name:t.name,...typeof t.picture=="string"?{picture:t.picture}:{},expireAt:Q(t.accessToken)};if(Oe({...n,userId:n.sub,ssoClientId:e}),B(e)?.accessToken!==n.accessToken)throw new Error("浏览器禁止保存登录信息,请允许本站 cookie 与本地存储后重试");return n}var j="linkfox:sso:callback",Ne=["code","state","error","error_description"],X="linkfox:sso:redirect:",De=6e5;function Y(e){if(!e.trim())throw new Error("缺少 SSO clientId");if(!T.config().baseURL)throw new Error("请配置 third-party-sso 的 baseURL")}async function R(e,r={}){Y(e);let t=await T.request({method:"POST",path:"/thirdPartyApplication/get",body:{clientId:e,...r.redirectUri?{redirectUri:r.redirectUri}:{}},auth:"none",signal:r.signal});if(!["redirectUri","authorizationUrl","codeVerifier","appName"].every(n=>typeof t[n]=="string"&&t[n]))throw new Error("SSO 应用配置响应不完整");return t}async function b(e,r={}){if(Y(e.clientId),![e.code,e.codeVerifier,e.redirectUri,e.appName].every(f=>typeof f=="string"&&f.trim()))throw new Error("SSO 换取 token 的参数不完整");r.signal?.throwIfAborted();let{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:u}=e,a=await T.request({method:"POST",path:"/thirdPartyApplication/login",body:{clientId:t,redirectUri:n,codeVerifier:i,appName:o,code:u},auth:"none",signal:r.signal});return r.signal?.throwIfAborted(),H(t,a)}function $(e,r){let t=new URL(e.redirectUri);if(t.origin!==window.location.origin||t.username||t.password||t.hash||!["http:","https:"].includes(t.protocol))throw new Error(`SSO redirectUri 为 ${t.origin}${t.pathname},请在该地址打开应用或修改服务端注册配置`);if(t.href!==new URL(r).href)throw new Error("SSO 返回的 redirectUri 与请求不一致");let n=new URL(e.authorizationUrl);if(n.protocol!=="https:"||n.username||n.password)throw new Error("SSO authorizationUrl 必须是 HTTPS 地址");if(n.searchParams.get("redirect_uri")!==e.redirectUri||n.searchParams.get("code_challenge_method")!=="S256"||!n.searchParams.get("code_challenge"))throw new Error("SSO 授权地址缺少匹配的 redirect_uri 或 PKCE S256 参数");return{redirect:t,authorization:n}}function J(e,r,t){if(e.origin!==r.origin||e.pathname!==r.pathname)throw new Error("SSO 回调地址与 redirectUri 不一致");for(let[i,o]of r.searchParams)if(e.searchParams.get(i)!==o)throw new Error("SSO 回调参数与 redirectUri 不一致");if(e.searchParams.getAll("state").length!==1||e.searchParams.get("state")!==t)throw new Error("SSO 回调 state 不匹配,请重新登录");if(e.searchParams.has("error"))throw new Error("授权未完成或已被拒绝,请重新登录");let n=e.searchParams.get("code");if(!n||e.searchParams.getAll("code").length!==1)throw new Error("SSO 回调缺少唯一 code");return n}function Ke(){if(typeof window>"u"||window.parent===window)return!1;let e=new URL(window.location.href);if(!e.searchParams.has("code")&&!e.searchParams.has("error"))return!1;window.parent.postMessage({type:j,url:e.href},e.origin);for(let r of["code","state","error","error_description"])e.searchParams.delete(r);return window.history.replaceState(null,"",e.href),!0}function Ve(e){if(typeof window>"u")return Promise.reject(new Error("SSO iframe 登录只能在浏览器中启动"));let r=new AbortController,t=r.signal;return new Promise((n,i)=>{let o=!1,u=!1,a,f,P="",h=e.timeoutMs??3e5;if(!Number.isFinite(h)||h<=0||h>2147483647){i(new Error("SSO 超时配置无效"));return}let k=()=>{clearTimeout(ee),window.removeEventListener("message",L),e.signal?.removeEventListener("abort",x),a=void 0},g=d=>{o||(o=!0,k(),r.abort(),i(d))},x=()=>g(new DOMException("登录已取消","AbortError")),L=d=>{if(o||u||!a||!f||d.origin!==f.origin||!d.source||d.source!==e.getFrameWindow())return;let c=d.data;if(!(!c||c.type!==j||typeof c.url!="string"))try{let l=J(new URL(c.url),f,P);u=!0,b({clientId:e.clientId,redirectUri:a.redirectUri,codeVerifier:a.codeVerifier,appName:a.appName,code:l},{signal:t}).then(re=>{o||(o=!0,k(),n(re))},g)}catch(l){g(l)}},ee=setTimeout(()=>g(new Error("登录超时,请重试;若授权页无法显示,请检查其 iframe 嵌入策略")),h);if(e.signal?.addEventListener("abort",x,{once:!0}),e.signal?.aborted){x();return}window.addEventListener("message",L),R(e.clientId,{redirectUri:e.redirectUri??window.location.origin,signal:t}).then(d=>{if(!o)try{a=d;let c=$(a,e.redirectUri??window.location.origin);f=c.redirect;let l=c.authorization;P=crypto.randomUUID(),l.searchParams.set("state",P),e.onAuthorization({authorizationUrl:l.href,appName:a.appName})}catch(c){g(c)}},g)})}function G(){try{return window.sessionStorage}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}}function Z(e){if(e)try{let r=new URL(e,window.location.href);return r.origin===window.location.origin?r.href:void 0}catch{return}}function ze(e){let r=G(),t=X+e,n=r.getItem(t);if(r.removeItem(t),!n)return null;try{let i=JSON.parse(n);return!["state","codeVerifier","redirectUri","appName","returnTo"].every(o=>typeof i[o]=="string"&&i[o])||typeof i.createdAt!="number"?null:i}catch{return null}}async function Me(e){if(typeof window>"u")throw new Error("SSO 跳转登录只能在浏览器中启动");let r=G(),t=e.redirectUri??window.location.origin,n=await R(e.clientId,{redirectUri:t,signal:e.signal}),{authorization:i}=$(n,t),o=crypto.randomUUID();i.searchParams.set("state",o);let u={state:o,codeVerifier:n.codeVerifier,redirectUri:n.redirectUri,appName:n.appName,returnTo:Z(e.returnTo??window.location.href)??n.redirectUri,createdAt:Date.now()};e.signal?.throwIfAborted();try{r.setItem(X+e.clientId,JSON.stringify(u))}catch{throw new Error("浏览器禁止本地存储,无法跳转登录,请允许本站存储后重试")}window.location.assign(i.href)}async function We(e,r={}){if(typeof window>"u")return null;let t=new URL(window.location.href);if(!t.searchParams.has("state")||!t.searchParams.has("code")&&!t.searchParams.has("error"))return null;let n=new URL(t.href);for(let a of Ne)n.searchParams.delete(a);window.history.replaceState(window.history.state,"",n.href);let i=ze(e);if(!i)throw new Error("登录请求已失效,请重新登录");if(Date.now()-i.createdAt>De)throw new Error("登录超时,请重新登录");let o=J(t,new URL(i.redirectUri),i.state);return{session:await b({clientId:e,redirectUri:i.redirectUri,codeVerifier:i.codeVerifier,appName:i.appName,code:o},r),returnTo:Z(i.returnTo)??i.redirectUri}}M();export{_e as clearThirdPartySsoSession,We as completeThirdPartySsoRedirect,Ce as getImageVerifyCode,N as getPersonalKey,R as getThirdPartyApplication,y as getUserInfo,Ie as getVerifyCode,Ae as getWechatQrCode,Re as getWechatQrCodeStatus,Ke as handleThirdPartySsoCallback,Ee as loginByCode,Ue as loginByPassword,be as loginByWechat,b as loginThirdPartyApplication,pe as logout,B as readThirdPartySsoSession,Me as redirectToThirdPartySso,w as resolveCurrentTeam,Ve as startThirdPartySso,le as switchTeam,ue as syncApiKey,p as syncCurrentTeam};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linkfox-web/api-user-center",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "LinkFox 用户中心接口:登录、刷新、用户信息、切换团队",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,14 +31,14 @@
31
31
  "./dist/index.cjs"
32
32
  ],
33
33
  "peerDependencies": {
34
- "@linkfox-web/http": "^0.3.3"
34
+ "@linkfox-web/http": "^0.3.5"
35
35
  },
36
36
  "dependencies": {
37
37
  "crypto-js": "4.2.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/crypto-js": "4.2.2",
41
- "@linkfox-web/http": "0.3.3"
41
+ "@linkfox-web/http": "0.3.5"
42
42
  },
43
43
  "publishConfig": {
44
44
  "access": "public"