iboot-http-client 1.0.1 → 1.0.3
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/dist/iboot-http-client.cjs.js +1 -1
- package/dist/iboot-http-client.cjs.js.map +1 -1
- package/dist/iboot-http-client.es.js +420 -83
- package/dist/iboot-http-client.es.js.map +1 -1
- package/dist/iboot-http-client.umd.js +1 -1
- package/dist/iboot-http-client.umd.js.map +1 -1
- package/dist/types/http-client.d.ts +1 -1
- package/package.json +3 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("js-md5");require("crypto-js");require("pino");const T={GENERAL:0,PHONE:1,EMAIL:2},h={TYPE_MGT:0,TYPE_C:1,TYPE_B:2},S={FROM_WEB:1,FROM_PC:2,FROM_WX_MINI_PRO:3,FROM_WX_PLU:4,FROM_WX_E:5,FROM_APP:6,FROM_DEVICE:7},w={unknown:0,male:1,female:2},R="zh-CN",_="_device_id_key",I="_current_website_key",g="Get request error!",E="Post request error!",c={"Device-Id":"Device-Id",Lang:"Lang","Website-Id":"Website-Id","Website-No":"Website-No"},i={IBOOT_DEVICE_ID:"IBOOT_DEVICE_ID",IBOOT_LOCALE:"IBOOT_LOCALE",IBOOT_WEBSITE_ID:"IBOOT_WEBSITE_ID",IBOOT_WEBSITE_NO:"IBOOT_WEBSITE_NO"},u=()=>{const s=localStorage.getItem(_)??"",e=localStorage.getItem(I),t=e!=null?JSON.parse(e):null,n={};return s.length>0&&(n["Device-Id"]=s),t&&(n.Lang=t.language,t.websiteId&&(n["Website-Id"]=t.websiteId),t.websiteNo&&(n["Website-No"]=t.websiteNo)),n},C=(s,e)=>{localStorage.setItem(_,s),e&&localStorage.setItem(I,JSON.stringify(e))},f=async(s,e)=>{if(e?.data){const o=new URLSearchParams(e.data);s.indexOf("?")!=-1?s+=`&${o}`:s+=`?${o}`}const t=u(),n=e?.heads;if(n)for(const o in n){const a=n[o];a&&(t[o]=a)}const r=await fetch(s,{method:"GET",headers:t,cache:e?.useCache?"force-cache":"default"});return r.ok?await r.json():{code:r.status,success:!1,msg:r.statusText}},P=async(s,e)=>{const t=await f(s,e);if(t.success)return t.data;if(e?.showError){e.showError(t.msg??g);return}throw Error(t.msg??g)},d=async(s,e)=>{const t=e?.data??{},n=e?.heads;let r;const o=new Headers(u());if(t instanceof FormData?r=t:(r=JSON.stringify(t),o.set("Content-Type","application/json")),n)for(let O in n){const l=n[O];l&&o.set(O,l)}const a=await fetch(s,{method:"POST",headers:o,body:r});return a.ok?await a.json():{code:a.status,success:!1,msg:a.statusText}},N=async(s,e)=>{const t=await d(s,e);if(t.success)return t.data;if(e?.showError){e.showError(t.msg??E);return}throw Error(t.msg??E)},D=async(s,e)=>{const t=await d(s,e);return t.success?(e?.showSuccess&&e.showSuccess(t.msg??"SUCCESS"),!0):(e?.showError&&e.showError(t.msg??E),!1)},b=s=>{const e=s.headers.get(c["Device-Id"]),t=s.headers.get(c.Lang),n=s.headers.get(c["Website-Id"]),r=s.headers.get(c["Website-No"]),o={};return e&&e.length>0&&(o.deviceId=e),t&&t.length>0&&(o.lang=t),n&&n.length>0&&(o.websiteId=n),r&&r.length>0&&(o.websiteNo=r),o},B=s=>{const e={},t=s.get(i.IBOOT_DEVICE_ID)?.value,n=s.get(i.IBOOT_LOCALE)?.value,r=s.get(i.IBOOT_WEBSITE_ID)?.value,o=s.get(i.IBOOT_WEBSITE_NO)?.value;return t&&t.length>0&&(e.deviceId=t),n&&n.length>0&&(e.lang=n),r&&r.length>0&&(e.websiteId=r),o&&o.length>0&&(e.websiteNo=o),e};exports.ACCOUNT_TYPE_MAP=T;exports.CURRENT_WEBSITE_KEY=I;exports.DEFAULT_LOCALE=R;exports.DEVICE_ID_KEY=_;exports.USER_FORM_MAP=S;exports.USER_SEX_MAP=w;exports.USER_TYPE_MAP=h;exports.get=f;exports.getHttpClientOpts=b;exports.getHttpClientOptsByCookie=B;exports.iGet=P;exports.iPost=N;exports.iPostSuccess=D;exports.post=d;exports.setDefaultRequestHeader=C;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("js-md5"),g=require("crypto-js"),U=require("pino"),D={GENERAL:0,PHONE:1,EMAIL:2},S={TYPE_MGT:0,TYPE_C:1,TYPE_B:2},k={FROM_WEB:1,FROM_PC:2,FROM_WX_MINI_PRO:3,FROM_WX_PLU:4,FROM_WX_E:5,FROM_APP:6,FROM_DEVICE:7},B={unknown:0,male:1,female:2},T=o=>Array.isArray(o)||typeof o=="object"&&Object.prototype.toString.call(o)==="[object Array]",w=o=>{const t=o,e="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",r=e.length;let s="";for(let n=0;n<t;n++)s+=e.charAt(Math.floor(Math.random()*r));return s},L=(o,t)=>{const e={};return o.split("&").forEach(s=>{const n=s.split("=");n[1]&&(e[n[0]]=n[1])}),e},y=o=>o==null||o==""||o.length==0?"":encodeURIComponent(o).replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/\'/g,"%27").replace(/\!/g,"%21").replace(/\~/g,"%7E"),v="zh-CN",_="_device_id_key",I="_current_website_key",O="Get request error!",E="Post request error!",m={"Device-Id":"Device-Id",Lang:"Lang","Website-Id":"Website-Id","Website-No":"Website-No"},h={IBOOT_DEVICE_ID:"IBOOT_DEVICE_ID",IBOOT_LOCALE:"IBOOT_LOCALE",IBOOT_WEBSITE_ID:"IBOOT_WEBSITE_ID",IBOOT_WEBSITE_NO:"IBOOT_WEBSITE_NO",token:"token",user:"user"},P=()=>{const o=localStorage.getItem(_)??"",t=localStorage.getItem(I),e=t!=null?JSON.parse(t):null,r={};return o.length>0&&(r["Device-Id"]=o),e&&(r.Lang=e.language,e.websiteId&&(r["Website-Id"]=e.websiteId),e.websiteNo&&(r["Website-No"]=e.websiteNo)),r},M=(o,t)=>{localStorage.setItem(_,o),t&&localStorage.setItem(I,JSON.stringify(t))},C=async(o,t)=>{if(t?.data){const n=new URLSearchParams(t.data);o.indexOf("?")!=-1?o+=`&${n}`:o+=`?${n}`}const e=P(),r=t?.heads;if(r)for(const n in r){const a=r[n];a&&(e[n]=a)}const s=await fetch(o,{method:"GET",headers:e,cache:t?.useCache?"force-cache":"default"});return s.ok?await s.json():{code:s.status,success:!1,msg:s.statusText}},W=async(o,t)=>{const e=await C(o,t);if(e.success)return e.data;if(t?.showError){t.showError(e.msg??O);return}throw Error(e.msg??O)},b=async(o,t)=>{const e=t?.data??{},r=t?.heads;let s;const n=new Headers(P());if(e instanceof FormData?s=e:(s=JSON.stringify(e),n.set("Content-Type","application/json")),r)for(let l in r){const i=r[l];i&&n.set(l,i)}const a=await fetch(o,{method:"POST",headers:n,body:s});return a.ok?await a.json():{code:a.status,success:!1,msg:a.statusText}},$=async(o,t)=>{const e=await b(o,t);if(e.success)return e.data;if(t?.showError){t.showError(e.msg??E);return}throw Error(e.msg??E)},j=async(o,t)=>{const e=await b(o,t);return e.success?(t?.showSuccess&&t.showSuccess(e.msg??"SUCCESS"),!0):(t?.showError&&t.showError(e.msg??E),!1)},x=o=>{const t=o.headers.get(m["Device-Id"]),e=o.headers.get(m.Lang),r=o.headers.get(m["Website-Id"]),s=o.headers.get(m["Website-No"]),n={};return t&&t.length>0&&(n.deviceId=t),e&&e.length>0&&(n.lang=e),r&&r.length>0&&(n.websiteId=r),s&&s.length>0&&(n.websiteNo=s),n},H=o=>{const t={},e=o.get(h.IBOOT_DEVICE_ID)?.value,r=o.get(h.IBOOT_LOCALE)?.value,s=o.get(h.IBOOT_WEBSITE_ID)?.value,n=o.get(h.IBOOT_WEBSITE_NO)?.value;return e&&e.length>0&&(t.deviceId=e),r&&r.length>0&&(t.lang=r),s&&s.length>0&&(t.websiteId=s),n&&n.length>0&&(t.websiteNo=n),t};class K{baseUrl;apiKey;userType;userFrom;deviceId;version="1";lang;websiteId;websiteNo;_isDebug;logger;constructor({deviceId:t,lang:e,websiteId:r,websiteNo:s,userType:n}){this.baseUrl=process.env.BASE_URL??"",this.apiKey=process.env.API_KEY??"",this.userType=n??S.TYPE_MGT,this.userFrom=process.env.USER_FROM||"1",this.deviceId=t??w(10),this.lang=e??v,this.websiteId=r,this.websiteNo=s,this._isDebug=process.env.NODE_ENV!="production",this.logger=U({name:"iboot",level:this._isDebug?"debug":"info",nestedKey:"payload"})}isDebug(){return this._isDebug}encrypt(t){const e=g.enc.Utf8.parse(this.apiKey);return g.AES.encrypt(t,e).toString()}decrypt(t){const e=g.enc.Utf8.parse(this.apiKey);return g.AES.decrypt(t,e,{mode:g.mode.ECB}).toString(g.enc.Utf8)}getDeviceId(){return this.deviceId}convertUrlParameter(t){const e=[];for(const r in t){let s=t[r];if(s&&typeof s=="string")s=s.trim();else if(s&&typeof s=="object"){if(T(s)){if(s.length===0)continue;for(let n=0;n<s.length;n++){const a=s[n];for(const l in a){const i=a[l]??void 0;if(i){if(typeof i=="object")T(i)&&i.forEach((c,f)=>{if(c)for(const d in c){const u=c[d];if(u&&u.toString().length>0){const p=`[${n.toString()}].${l+`[${f.toString()}].${d}`}=${y(u)}`;e.push(r+p)}}});else if(i.toString().length>0){const c=`[${n.toString()}].${l}=${y(i.toString())}`;e.push(r+c)}}}}}else for(const n in s){const a=s[n];if(a!=null&&a!=""&&a.length!=0){const l=`.${n}=${y(a)}`;e.push(r+l)}}continue}else s&&typeof s=="function"&&(s=null);s!=null&&s!=""&&s.length!=0&&e.push(r+"="+y(s))}return e&&e.join("&")}async sign(t){const e="&key="+await this.helloIboot(),r=[];for(const i in t)r.push(i);r.sort((i,c)=>i.toLowerCase().localeCompare(c.toLowerCase()));const s=[];r.forEach(i=>{let c=t[i];typeof c=="object"&&(c=JSON.stringify(c)),s.push(i+"="+c)});const n=s.join("&"),a=N.md5((n+e).toLocaleUpperCase()),l={params:n,md5:a};return this.logger.debug(l),a}assemblyParameter(t,e){const r=t??{};return r.timestamp=Date.now()+"",r.echostr=w(10),r.version=this.version,r.deviceId=this.deviceId,r.webid=this.websiteId,r.apiKey=this.apiKey,e&&e.length>0&&(r.username=e),r}async assemblyHeader({urlParams:t,token:e}){const r={"Content-Type":"application/x-www-form-urlencoded","Res-Type":"json","Device-Id":this.deviceId,Lang:this.lang,"User-Type":e?.utype.toString()??this.userType.toString(),"User-From":this.userFrom,"Api-Key":this.apiKey};this.websiteId&&this.websiteId.length>0&&(r["Web-Id"]=this.websiteId),this.websiteNo&&this.websiteNo.length>0&&(r["Web-No"]=this.websiteNo),e&&(e.token&&e.token.length>0&&e.username&&e.username.length>0&&(r.Authorization=e.token,r.Username=e.username),e.xcsrf&&(r[e.xcsrf.csrfHeader]=e.xcsrf.csrfToken));const s=L(t),n=await this.sign(s);return r.Sign=n,r}async helloIboot(){const t=process.env.HELLO_URL??"";if(t.length===0)return this.apiKey;const e=this.getApiUrl(t),r={"Content-Type":"application/x-www-form-urlencoded","Res-Type":"json","Api-Key":this.apiKey},s=await fetch(e,{method:"GET",headers:r,credentials:"include",cache:"force-cache"});if(s.ok)return(await s.json()).data;throw new Error("hello iBoot error!")}getApiUrl(t){return`${this.baseUrl}/${t}`}async get({url:t,data:e,token:r}){const s=this.assemblyParameter(e),n=this.convertUrlParameter(s),a=await this.assemblyHeader({urlParams:n,token:r}),l=`${this.getApiUrl(t)}?${n.toString()}`,i={method:"GET",url:l,headers:a};this.logger.info(i);try{const c=await fetch(l,{method:"GET",headers:a,credentials:"include",cache:"force-cache"});return c.ok?await c.json():{code:c.status,success:!1,msg:c.statusText}}catch(c){return{code:500,success:!1,msg:c?.toString()??"Server exception!"}}}async csrf(){const t=await this.get({url:"guest/csrf"});if(t.success){const e=t.data;if(e)return e.csrfToken.toString()}}async post({url:t,data:e,token:r}){e=e?{...e}:{};const s=e.buffer??void 0,n=e.boundary??void 0;s&&delete e.buffer,n&&delete e.boundary;const a=this.assemblyParameter(e),l=this.convertUrlParameter(a),i=await this.assemblyHeader({urlParams:l,token:r});s&&n&&(i["Content-Type"]=`multipart/form-data; boundary=${n}`);const c=this.getApiUrl(t),f={method:"POST",url:c,headers:i};this.logger.info(f);try{const d=s?`${c}?${l}`:c,u=await fetch(d,{method:"POST",headers:i,body:s||l.toString(),credentials:"include"});return u.ok?await u.json():{code:u.status,success:!1,msg:u.statusText}}catch(d){return{code:500,success:!1,msg:d?.toString()??"Server exception!"}}}async stream({url:t,data:e,token:r}){e=e?{...e}:{};const s=e.buffer??void 0,n=e.boundary??void 0;s&&delete e.buffer,n&&delete e.boundary;const a=this.assemblyParameter(e),l=this.convertUrlParameter(a),i=await this.assemblyHeader({urlParams:l,token:r});s&&n&&(i["Content-Type"]=`multipart/form-data; boundary=${n}`),i.Connection="keep-alive",i["X-Accel-Buffering"]="no",i["Cache-Control"]="no-cache";const c=this.getApiUrl(t);try{const f=s?`${c}?${l}`:c,d={method:"POST",url:c,headers:i};this.logger.info(d);const u=await fetch(f,{method:"POST",headers:i,body:s||l.toString(),credentials:"include"});if(!u.ok)throw new Error(`HTTP error! status: ${u.status}`);if(!u.body)throw new Error("No response body");return new Response(u.body,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}catch(f){throw f}}getUserInfo(t){const e=t.get(h.user)?.value;return e&&e.length>0?JSON.parse(e):null}getToken(t){const e=t.get("user")?.value;let r="",s=this.userType;if(e&&e.length>0){const n=JSON.parse(e);r=n.username,s=n.userType.toString()}return{username:r,utype:s,token:t.get(h.token)?.value??""}}getTokenByCookies=t=>{const e=t.get("user")?.value;let r="",s=this.userType;if(e&&e.length>0){const n=JSON.parse(e);r=n.username,s=n.userType.toString()}return{username:r,utype:s,token:t.get(h.token)?.value??""}};setToken(t,e){const{id:r,name:s,username:n,nickname:a,sex:l,headImg:i,token:c,lastLoginTime:f,tokenExpired:d,deviceId:u,userType:p,mustChangePwd:A}=t,R={id:r,name:s,username:n,nickname:a,sex:l,headImg:i,lastLoginTime:f,tokenExpired:d,deviceId:u,userType:p,status:0,accountType:0,enabled:!1,userFrom:1,needToReview:!1,socketOnline:!1,createTime:"",mustChangePwd:A};return e.cookies.set(h.token,c,{httpOnly:!0,secure:!this._isDebug,sameSite:"strict",path:"/"}),e.cookies.set(h.user,JSON.stringify(R)),e}cleanToken(t){return t.cookies.set(h.token,"",{maxAge:-1,httpOnly:!0,path:"/"}),t.cookies.set(h.user,"",{maxAge:-1,httpOnly:!0,path:"/"}),t.cookies.delete(h.token),t.cookies.delete(h.user),t}}exports.ACCOUNT_TYPE_MAP=D;exports.CURRENT_WEBSITE_KEY=I;exports.DEFAULT_LOCALE=v;exports.DEVICE_ID_KEY=_;exports.HttpClient=K;exports.USER_FORM_MAP=k;exports.USER_SEX_MAP=B;exports.USER_TYPE_MAP=S;exports.get=C;exports.getHttpClientOpts=x;exports.getHttpClientOptsByCookie=H;exports.iGet=W;exports.iPost=$;exports.iPostSuccess=j;exports.post=b;exports.setDefaultRequestHeader=M;
|
|
2
2
|
//# sourceMappingURL=iboot-http-client.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iboot-http-client.cjs.js","sources":["../src/types/user.ts","../src/http-client.ts"],"sourcesContent":["export const ACCOUNT_TYPE_MAP = {\r\n GENERAL : 0,\r\n PHONE : 1,\r\n EMAIL : 2\r\n}\r\n\r\nexport const USER_TYPE_MAP = {\r\n TYPE_MGT : 0,\r\n TYPE_C : 1,\r\n TYPE_B : 2\r\n}\r\n\r\nexport const USER_FORM_MAP = {\r\n FROM_WEB : 1,\r\n FROM_PC : 2,\r\n FROM_WX_MINI_PRO : 3,\r\n FROM_WX_PLU : 4,\r\n FROM_WX_E : 5,\r\n FROM_APP : 6,\r\n FROM_DEVICE : 7\r\n}\r\n\r\nexport const USER_SEX_MAP = {\r\n unknown:0,\r\n male:1,\r\n female:2,\r\n}\r\n\r\nexport type ACCOUNT_TYPE = typeof ACCOUNT_TYPE_MAP[keyof typeof ACCOUNT_TYPE_MAP];\r\nexport type USER_TYPE = typeof USER_TYPE_MAP[keyof typeof USER_TYPE_MAP];\r\nexport type USER_FORM = typeof USER_FORM_MAP[keyof typeof USER_FORM_MAP];\r\nexport type USER_SEX = typeof USER_SEX_MAP[keyof typeof USER_SEX_MAP];\r\n\r\n// User interface\r\nexport interface User {\r\n id: string;\r\n name: string;\r\n username: string;\r\n nickname: string;\r\n sex: USER_SEX;\r\n headImg: string;\r\n lastLoginTime: string;\r\n tokenExpired: string;\r\n deviceId: string;\r\n userType: USER_TYPE;\r\n status: number;\r\n accountType: number;\r\n enabled: boolean;\r\n userFrom: USER_FORM;\r\n needToReview: boolean;\r\n socketOnline: boolean;\r\n createTime: string;\r\n mustChangePwd: boolean;\r\n}","import md5 from \"js-md5\";\r\nimport CryptoJS from 'crypto-js';\r\nimport { isArray, randomString, urlEncode, urlParamToJson } from \"./utils\";\r\nimport pino from \"pino\";\r\nimport { \r\n ClientGetParams, \r\n ClientPostParams, \r\n CookieNames, \r\n CSRFToken, \r\n CurWebsite, \r\n HttpClientOpts, \r\n HttpHeaderNames, \r\n HttpHeaders, \r\n HttpToken, \r\n IbootCookieStore, \r\n IbootReadonlyCookies, \r\n IbootWritableCookie, \r\n ResultModel \r\n} from \"./types/http\";\r\nimport { User, USER_TYPE, USER_TYPE_MAP } from \"./types/user\";\r\n\r\nexport const DEFAULT_LOCALE = 'zh-CN';\r\nexport const DEVICE_ID_KEY = \"_device_id_key\";\r\nexport const CURRENT_WEBSITE_KEY = \"_current_website_key\"\r\n\r\nconst _GET_ERROR = \"Get request error!\"\r\nconst _POST_ERROR = \"Post request error!\";\r\n\r\nconst HEADER_NAMES: Record<HttpHeaderNames, HttpHeaderNames> = {\r\n \"Device-Id\": \"Device-Id\",\r\n \"Lang\": \"Lang\",\r\n \"Website-Id\": \"Website-Id\",\r\n \"Website-No\": \"Website-No\",\r\n}\r\n\r\nconst COOKIE_NAMES: Record<CookieNames, CookieNames> = {\r\n \"IBOOT_DEVICE_ID\": \"IBOOT_DEVICE_ID\",\r\n \"IBOOT_LOCALE\": \"IBOOT_LOCALE\",\r\n \"IBOOT_WEBSITE_ID\": \"IBOOT_WEBSITE_ID\",\r\n \"IBOOT_WEBSITE_NO\": \"IBOOT_WEBSITE_NO\",\r\n \"token\": \"token\",\r\n \"user\": \"user\"\r\n}\r\n\r\nconst getDefaultRequestHeader = (): HttpHeaders => {\r\n const devideId = localStorage.getItem(DEVICE_ID_KEY) ?? ''\r\n const json = localStorage.getItem(CURRENT_WEBSITE_KEY);\r\n const curWebsite: CurWebsite | null = json != null ? JSON.parse(json) : null;\r\n const header: HttpHeaders = {}\r\n if (devideId.length > 0) {\r\n header['Device-Id'] = devideId\r\n }\r\n if (curWebsite) {\r\n header['Lang'] = curWebsite.language;\r\n if (curWebsite.websiteId) {\r\n header['Website-Id'] = curWebsite.websiteId;\r\n }\r\n if (curWebsite.websiteNo) {\r\n header['Website-No'] = curWebsite.websiteNo\r\n }\r\n }\r\n return header;\r\n};\r\n\r\nexport const setDefaultRequestHeader = (deviceId: string, website?: CurWebsite): void => {\r\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\r\n if (website) {\r\n localStorage.setItem(CURRENT_WEBSITE_KEY, JSON.stringify(website));\r\n }\r\n}\r\n\r\nexport const get = async <T>(url: string, opts?: ClientGetParams): Promise<ResultModel<T>> => {\r\n if (opts?.data) {\r\n const params = new URLSearchParams(opts.data);\r\n if (url.indexOf(\"?\") != -1) {\r\n url += `&${params}`\r\n } else {\r\n url += `?${params}`\r\n }\r\n }\r\n const headers: Record<string, string> = getDefaultRequestHeader();\r\n const heads = opts?.heads;\r\n if (heads) {\r\n for (const field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n headers[field] = value;\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: headers,\r\n cache: opts?.useCache ? 'force-cache' : 'default'\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText\r\n }\r\n}\r\n\r\nexport const iGet = async <T>(url: string, opts?: ClientGetParams): Promise<T | undefined> => {\r\n const res = await get<T>(url, opts);\r\n if (res.success) {\r\n return res.data as T;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _GET_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _GET_ERROR)\r\n}\r\n\r\nexport const post = async <T>(url: string, opts?: ClientPostParams): Promise<ResultModel<T>> => {\r\n const data = opts?.data ?? {};\r\n const heads = opts?.heads;\r\n let body: string | FormData;\r\n const proxyHeaders = new Headers(getDefaultRequestHeader());\r\n if (!(data instanceof FormData)) {\r\n body = JSON.stringify(data);\r\n proxyHeaders.set('Content-Type', 'application/json');\r\n } else {\r\n body = data;\r\n }\r\n if (heads) {\r\n for (let field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n proxyHeaders.set(field, value);\r\n }\r\n }\r\n }\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: proxyHeaders,\r\n body: body,\r\n });\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText,\r\n }\r\n}\r\n\r\nexport const iPost = async <T>(url: string, opts?: ClientPostParams): Promise<T | undefined> => {\r\n const res = await post<T>(url, opts);\r\n if (res.success) {\r\n return res.data;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _POST_ERROR)\r\n}\r\n\r\nexport const iPostSuccess = async (url: string, opts?: ClientPostParams): Promise<boolean> => {\r\n const res = await post(url, opts);\r\n if (res.success) {\r\n if (opts?.showSuccess) {\r\n opts.showSuccess(res.msg ?? 'SUCCESS')\r\n }\r\n return true;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport const getHttpClientOpts = (request: Request): HttpClientOpts => {\r\n const deviceId = request.headers.get(HEADER_NAMES[\"Device-Id\"]);\r\n const lang = request.headers.get(HEADER_NAMES.Lang);\r\n const websiteId = request.headers.get(HEADER_NAMES[\"Website-Id\"]);\r\n const websiteNo = request.headers.get(HEADER_NAMES[\"Website-No\"]);\r\n const result: HttpClientOpts = {}\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport const getHttpClientOptsByCookie = (cookie: IbootReadonlyCookies): HttpClientOpts => {\r\n const result: HttpClientOpts = {}\r\n const deviceId = cookie.get(COOKIE_NAMES.IBOOT_DEVICE_ID)?.value;\r\n const lang = cookie.get(COOKIE_NAMES.IBOOT_LOCALE)?.value;\r\n const websiteId = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_ID)?.value;\r\n const websiteNo = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_NO)?.value;\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport default class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly apiKey: string;\r\n private readonly userType: USER_TYPE;\r\n private readonly userFrom: string;\r\n private readonly deviceId: string;\r\n private readonly version: string = '1';\r\n private readonly lang: string;\r\n private readonly websiteId?: string;\r\n private readonly websiteNo?: string;\r\n private readonly _isDebug: boolean;\r\n private readonly logger: pino.Logger;\r\n constructor({ deviceId, lang, websiteId, websiteNo, userType }: Readonly<HttpClientOpts>) {\r\n this.baseUrl = process.env.BASE_URL ?? '';\r\n this.apiKey = process.env.API_KEY ?? '';\r\n this.userType = userType ?? USER_TYPE_MAP.TYPE_MGT;\r\n this.userFrom = process.env.USER_FROM || '1';\r\n this.deviceId = deviceId ?? randomString(10);\r\n this.lang = lang ?? DEFAULT_LOCALE;\r\n this.websiteId = websiteId\r\n this.websiteNo = websiteNo\r\n this._isDebug = process.env.NODE_ENV != 'production';\r\n this.logger = pino({\r\n name: 'iboot',\r\n level: this._isDebug ? 'debug' : 'info',\r\n nestedKey: 'payload'\r\n })\r\n }\r\n\r\n isDebug() {\r\n return this._isDebug;\r\n }\r\n\r\n encrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.encrypt(data, key).toString();\r\n }\r\n\r\n decrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.decrypt(data, key, {\r\n mode: CryptoJS.mode.ECB,\r\n }).toString(CryptoJS.enc.Utf8);\r\n }\r\n\r\n getDeviceId() {\r\n return this.deviceId;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private convertUrlParameter(data: Record<string, any>): string {\r\n const p: string[] = [];\r\n for (const o in data) {\r\n let v = data[o];\r\n if (v && typeof v === \"string\") {\r\n v = v.trim();\r\n } else if (v && typeof v === \"object\") {\r\n if (isArray(v)) {\r\n if (v.length === 0) {\r\n continue;\r\n }\r\n for (let i = 0; i < v.length; i++) {\r\n const arr_item = v[i];\r\n for (const item_field in arr_item) {\r\n const item_field_value = arr_item[item_field] ?? undefined;\r\n if (item_field_value) {\r\n if (typeof item_field_value === \"object\") {\r\n if (isArray(item_field_value)) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n item_field_value.forEach((item1: any, index: number) => {\r\n if (item1) {\r\n for (const f in item1) {\r\n const v = item1[f];\r\n if (v && v.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field + `[${index.toString()}].${f}`}=${urlEncode(v)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } else if (item_field_value.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field}=${urlEncode(item_field_value.toString())}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n for (const obj in v) {\r\n const oValue = v[obj];\r\n if (oValue != null && oValue != \"\" && oValue.length != 0) {\r\n const s = `.${obj}=${urlEncode(oValue)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n continue;\r\n } else if (v && typeof v === \"function\") {\r\n v = null;\r\n }\r\n\r\n if (v != null && v != \"\" && v.length != 0) {\r\n p.push(o + \"=\" + urlEncode(v));\r\n }\r\n }\r\n return (p && p.join(\"&\"));\r\n }\r\n\r\n private async sign(data: Record<string, object | string>): Promise<string> {\r\n //由后台分配\r\n const _apiKey = \"&key=\" + (await this.helloIboot());\r\n const arr: string[] = [];\r\n for (const o in data) {\r\n arr.push(o);\r\n }\r\n arr.sort((a: string, b: string) => {\r\n return a.toLowerCase().localeCompare(b.toLowerCase());\r\n });\r\n const res: string[] = [];\r\n arr.forEach((v: string) => {\r\n let value: object | string = data[v];\r\n if (typeof value === \"object\") {\r\n value = JSON.stringify(value);\r\n }\r\n res.push(v + \"=\" + value);\r\n });\r\n const paramsStr: string = res.join(\"&\");\r\n const str = md5.md5((paramsStr + _apiKey).toLocaleUpperCase());\r\n const logInfo = {\r\n params: paramsStr,\r\n md5: str\r\n }\r\n this.logger.debug(logInfo)\r\n return str;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private assemblyParameter(data?: Record<string, any>, username?: string): Record<string, any> {\r\n const params = data ?? {};\r\n params['timestamp'] = Date.now() + '';\r\n params['echostr'] = randomString(10);\r\n params['version'] = this.version;\r\n params['deviceId'] = this.deviceId;\r\n params['webid'] = this.websiteId;\r\n params['apiKey'] = this.apiKey;\r\n if (username && username.length > 0) {\r\n params['username'] = username;\r\n }\r\n return params;\r\n }\r\n\r\n private async assemblyHeader({ urlParams, token }: Readonly<{ urlParams: string, token?: Readonly<HttpToken> }>) {\r\n const h: Record<string, string> = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Device-Id': this.deviceId,\r\n 'Lang': this.lang,\r\n 'User-Type': token?.utype.toString() ?? this.userType.toString(),\r\n 'User-From': this.userFrom,\r\n 'Api-Key': this.apiKey\r\n }\r\n if (this.websiteId && this.websiteId.length > 0) {\r\n h['Web-Id'] = this.websiteId\r\n }\r\n if (this.websiteNo && this.websiteNo.length > 0) {\r\n h['Web-No'] = this.websiteNo\r\n }\r\n if (token) {\r\n if (token.token && token.token.length > 0 && token.username && token.username.length > 0) {\r\n h['Authorization'] = token.token;\r\n h['Username'] = token.username;\r\n }\r\n if (token.xcsrf) {\r\n h[token.xcsrf.csrfHeader] = token.xcsrf.csrfToken;\r\n }\r\n }\r\n const data = urlParamToJson(urlParams);\r\n const sign = await this.sign(data);\r\n h['Sign'] = sign\r\n return h;\r\n }\r\n\r\n private async helloIboot(): Promise<string> {\r\n const helloUrl = process.env.HELLO_URL ?? '';\r\n if (helloUrl.length === 0) {\r\n return this.apiKey;\r\n }\r\n const api = this.getApiUrl(helloUrl);\r\n const h = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Api-Key': this.apiKey\r\n }\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: h,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result.data;\r\n }\r\n throw new Error('hello iBoot error!')\r\n }\r\n\r\n private getApiUrl(url: string): string {\r\n return `${this.baseUrl}/${url}`;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async get<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n const api = `${this.getApiUrl(url)}?${urlParams.toString()}`\r\n const logInfo = {\r\n \"method\": \"GET\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: headers,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n async csrf(): Promise<string | undefined> {\r\n const res = await this.get<CSRFToken>({\r\n url: 'guest/csrf'\r\n });\r\n if (res.success) {\r\n const data = res.data;\r\n if (data) {\r\n return data[\"csrfToken\"].toString();\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async post<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n const api = this.getApiUrl(url);\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async stream({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<Response> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params); //new URLSearchParams(params);\r\n\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n headers['Connection'] = 'keep-alive';\r\n headers['X-Accel-Buffering'] = 'no'; //防止 Nginx 缓存\r\n headers['Cache-Control'] = 'no-cache';\r\n const api = this.getApiUrl(url)\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers,\r\n\r\n }\r\n this.logger.info(logInfo);\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP error! status: ${res.status}`);\r\n }\r\n if (!res.body) {\r\n throw new Error('No response body');\r\n }\r\n return new Response(res.body, {\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive'\r\n }\r\n });\r\n } catch (e) {\r\n throw e;\r\n }\r\n }\r\n\r\n getUserInfo(cookies: IbootCookieStore): User | null {\r\n const userjson = cookies.get(COOKIE_NAMES.user)?.value;\r\n if (userjson && userjson.length > 0) {\r\n return JSON.parse(userjson);\r\n }\r\n return null;\r\n }\r\n\r\n getToken(cookies: IbootCookieStore): HttpToken {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n getTokenByCookies = (cookies: IbootReadonlyCookies): HttpToken => {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n setToken(data: User & { token: string, extFields: Record<string, any> }, response: { cookies: IbootWritableCookie }) {\r\n const { id, name, username, nickname, sex, headImg, token, lastLoginTime, tokenExpired, deviceId, userType, mustChangePwd } = data;\r\n const loginUser: User = {\r\n id: id,\r\n name: name,\r\n username: username,\r\n nickname: nickname,\r\n sex: sex,\r\n headImg: headImg,\r\n lastLoginTime: lastLoginTime,\r\n tokenExpired: tokenExpired,\r\n deviceId: deviceId,\r\n userType: userType,\r\n status: 0,\r\n accountType: 0,\r\n enabled: false,\r\n userFrom: 1,\r\n needToReview: false,\r\n socketOnline: false,\r\n createTime: \"\",\r\n mustChangePwd: mustChangePwd\r\n };\r\n response.cookies.set(COOKIE_NAMES.token, token, {\r\n httpOnly: true,\r\n secure: !this._isDebug, // 在生产环境中启用Secure\r\n sameSite: 'strict', // 防止 CSRF 攻击\r\n path: '/', // Cookie 的路径\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, JSON.stringify(loginUser));\r\n return response;\r\n }\r\n\r\n cleanToken(response: { cookies: IbootWritableCookie }) {\r\n response.cookies.set(COOKIE_NAMES.token, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.delete(COOKIE_NAMES.token);\r\n response.cookies.delete(COOKIE_NAMES.user)\r\n return response;\r\n }\r\n}"],"names":["ACCOUNT_TYPE_MAP","USER_TYPE_MAP","USER_FORM_MAP","USER_SEX_MAP","DEFAULT_LOCALE","DEVICE_ID_KEY","CURRENT_WEBSITE_KEY","_GET_ERROR","_POST_ERROR","HEADER_NAMES","COOKIE_NAMES","getDefaultRequestHeader","devideId","json","curWebsite","header","setDefaultRequestHeader","deviceId","website","get","url","opts","params","headers","heads","field","value","response","iGet","res","post","data","body","proxyHeaders","iPost","iPostSuccess","getHttpClientOpts","request","lang","websiteId","websiteNo","result","getHttpClientOptsByCookie","cookie"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"iboot-http-client.cjs.js","sources":["../src/types/user.ts","../src/utils.ts","../src/http-client.ts"],"sourcesContent":["export const ACCOUNT_TYPE_MAP = {\r\n GENERAL : 0,\r\n PHONE : 1,\r\n EMAIL : 2\r\n}\r\n\r\nexport const USER_TYPE_MAP = {\r\n TYPE_MGT : 0,\r\n TYPE_C : 1,\r\n TYPE_B : 2\r\n}\r\n\r\nexport const USER_FORM_MAP = {\r\n FROM_WEB : 1,\r\n FROM_PC : 2,\r\n FROM_WX_MINI_PRO : 3,\r\n FROM_WX_PLU : 4,\r\n FROM_WX_E : 5,\r\n FROM_APP : 6,\r\n FROM_DEVICE : 7\r\n}\r\n\r\nexport const USER_SEX_MAP = {\r\n unknown:0,\r\n male:1,\r\n female:2,\r\n}\r\n\r\nexport type ACCOUNT_TYPE = typeof ACCOUNT_TYPE_MAP[keyof typeof ACCOUNT_TYPE_MAP];\r\nexport type USER_TYPE = typeof USER_TYPE_MAP[keyof typeof USER_TYPE_MAP];\r\nexport type USER_FORM = typeof USER_FORM_MAP[keyof typeof USER_FORM_MAP];\r\nexport type USER_SEX = typeof USER_SEX_MAP[keyof typeof USER_SEX_MAP];\r\n\r\n// User interface\r\nexport interface User {\r\n id: string;\r\n name: string;\r\n username: string;\r\n nickname: string;\r\n sex: USER_SEX;\r\n headImg: string;\r\n lastLoginTime: string;\r\n tokenExpired: string;\r\n deviceId: string;\r\n userType: USER_TYPE;\r\n status: number;\r\n accountType: number;\r\n enabled: boolean;\r\n userFrom: USER_FORM;\r\n needToReview: boolean;\r\n socketOnline: boolean;\r\n createTime: string;\r\n mustChangePwd: boolean;\r\n}","export const isArray = (obj: unknown) => {\r\n return (\r\n Array.isArray(obj) ||\r\n (typeof obj === \"object\" &&\r\n Object.prototype.toString.call(obj) === \"[object Array]\")\r\n );\r\n};\r\n\r\n/**\r\n * 生成指定长度的随机串\r\n * @param {Object} len\r\n */\r\nexport const randomString = (len: number) => {\r\n const l = len || 32;\r\n const $chars = \"ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678\";\r\n const maxPos = $chars.length;\r\n let pwd = \"\";\r\n for (let i = 0; i < l; i++) {\r\n pwd += $chars.charAt(Math.floor(Math.random() * maxPos));\r\n }\r\n return pwd;\r\n};\r\n\r\nexport const urlParamToJson = (urlQueryParams: string, exclude?: string[]): Record<string, string> => {\r\n const result: Record<string, string> = {};\r\n const strs = urlQueryParams.split(\"&\");\r\n strs.forEach((item) => {\r\n const arr = item.split(\"=\");\r\n if (arr[1]) {\r\n if (!exclude || exclude.indexOf(arr[0]) == -1) {\r\n result[arr[0]] = arr[1];\r\n }\r\n }\r\n });\r\n return result;\r\n};\r\n\r\nexport const urlEncode = (value: string | null | undefined): string => {\r\n if (value == null || value == \"\" || value.length == 0) {\r\n return \"\";\r\n }\r\n return (\r\n encodeURIComponent(value)\r\n // .replace(/%20/g, '+')\r\n // .replace(/%2B/g, '\\\\+')\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\'/g, \"%27\")\r\n .replace(/\\!/g, \"%21\")\r\n .replace(/\\~/g, \"%7E\")\r\n );\r\n};\r\n","import md5 from \"js-md5\";\r\nimport CryptoJS from 'crypto-js';\r\nimport { isArray, randomString, urlEncode, urlParamToJson } from \"./utils\";\r\nimport pino from \"pino\";\r\nimport { \r\n ClientGetParams, \r\n ClientPostParams, \r\n CookieNames, \r\n CSRFToken, \r\n CurWebsite, \r\n HttpClientOpts, \r\n HttpHeaderNames, \r\n HttpHeaders, \r\n HttpToken, \r\n IbootCookieStore, \r\n IbootReadonlyCookies, \r\n IbootWritableCookie, \r\n ResultModel \r\n} from \"./types/http\";\r\nimport { User, USER_TYPE, USER_TYPE_MAP } from \"./types/user\";\r\n\r\nexport const DEFAULT_LOCALE = 'zh-CN';\r\nexport const DEVICE_ID_KEY = \"_device_id_key\";\r\nexport const CURRENT_WEBSITE_KEY = \"_current_website_key\"\r\n\r\nconst _GET_ERROR = \"Get request error!\"\r\nconst _POST_ERROR = \"Post request error!\";\r\n\r\nconst HEADER_NAMES: Record<HttpHeaderNames, HttpHeaderNames> = {\r\n \"Device-Id\": \"Device-Id\",\r\n \"Lang\": \"Lang\",\r\n \"Website-Id\": \"Website-Id\",\r\n \"Website-No\": \"Website-No\",\r\n}\r\n\r\nconst COOKIE_NAMES: Record<CookieNames, CookieNames> = {\r\n \"IBOOT_DEVICE_ID\": \"IBOOT_DEVICE_ID\",\r\n \"IBOOT_LOCALE\": \"IBOOT_LOCALE\",\r\n \"IBOOT_WEBSITE_ID\": \"IBOOT_WEBSITE_ID\",\r\n \"IBOOT_WEBSITE_NO\": \"IBOOT_WEBSITE_NO\",\r\n \"token\": \"token\",\r\n \"user\": \"user\"\r\n}\r\n\r\nconst getDefaultRequestHeader = (): HttpHeaders => {\r\n const devideId = localStorage.getItem(DEVICE_ID_KEY) ?? ''\r\n const json = localStorage.getItem(CURRENT_WEBSITE_KEY);\r\n const curWebsite: CurWebsite | null = json != null ? JSON.parse(json) : null;\r\n const header: HttpHeaders = {}\r\n if (devideId.length > 0) {\r\n header['Device-Id'] = devideId\r\n }\r\n if (curWebsite) {\r\n header['Lang'] = curWebsite.language;\r\n if (curWebsite.websiteId) {\r\n header['Website-Id'] = curWebsite.websiteId;\r\n }\r\n if (curWebsite.websiteNo) {\r\n header['Website-No'] = curWebsite.websiteNo\r\n }\r\n }\r\n return header;\r\n};\r\n\r\nexport const setDefaultRequestHeader = (deviceId: string, website?: CurWebsite): void => {\r\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\r\n if (website) {\r\n localStorage.setItem(CURRENT_WEBSITE_KEY, JSON.stringify(website));\r\n }\r\n}\r\n\r\nexport const get = async <T>(url: string, opts?: ClientGetParams): Promise<ResultModel<T>> => {\r\n if (opts?.data) {\r\n const params = new URLSearchParams(opts.data);\r\n if (url.indexOf(\"?\") != -1) {\r\n url += `&${params}`\r\n } else {\r\n url += `?${params}`\r\n }\r\n }\r\n const headers: Record<string, string> = getDefaultRequestHeader();\r\n const heads = opts?.heads;\r\n if (heads) {\r\n for (const field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n headers[field] = value;\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: headers,\r\n cache: opts?.useCache ? 'force-cache' : 'default'\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText\r\n }\r\n}\r\n\r\nexport const iGet = async <T>(url: string, opts?: ClientGetParams): Promise<T | undefined> => {\r\n const res = await get<T>(url, opts);\r\n if (res.success) {\r\n return res.data as T;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _GET_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _GET_ERROR)\r\n}\r\n\r\nexport const post = async <T>(url: string, opts?: ClientPostParams): Promise<ResultModel<T>> => {\r\n const data = opts?.data ?? {};\r\n const heads = opts?.heads;\r\n let body: string | FormData;\r\n const proxyHeaders = new Headers(getDefaultRequestHeader());\r\n if (!(data instanceof FormData)) {\r\n body = JSON.stringify(data);\r\n proxyHeaders.set('Content-Type', 'application/json');\r\n } else {\r\n body = data;\r\n }\r\n if (heads) {\r\n for (let field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n proxyHeaders.set(field, value);\r\n }\r\n }\r\n }\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: proxyHeaders,\r\n body: body,\r\n });\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText,\r\n }\r\n}\r\n\r\nexport const iPost = async <T>(url: string, opts?: ClientPostParams): Promise<T | undefined> => {\r\n const res = await post<T>(url, opts);\r\n if (res.success) {\r\n return res.data;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _POST_ERROR)\r\n}\r\n\r\nexport const iPostSuccess = async (url: string, opts?: ClientPostParams): Promise<boolean> => {\r\n const res = await post(url, opts);\r\n if (res.success) {\r\n if (opts?.showSuccess) {\r\n opts.showSuccess(res.msg ?? 'SUCCESS')\r\n }\r\n return true;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport const getHttpClientOpts = (request: Request): HttpClientOpts => {\r\n const deviceId = request.headers.get(HEADER_NAMES[\"Device-Id\"]);\r\n const lang = request.headers.get(HEADER_NAMES.Lang);\r\n const websiteId = request.headers.get(HEADER_NAMES[\"Website-Id\"]);\r\n const websiteNo = request.headers.get(HEADER_NAMES[\"Website-No\"]);\r\n const result: HttpClientOpts = {}\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport const getHttpClientOptsByCookie = (cookie: IbootReadonlyCookies): HttpClientOpts => {\r\n const result: HttpClientOpts = {}\r\n const deviceId = cookie.get(COOKIE_NAMES.IBOOT_DEVICE_ID)?.value;\r\n const lang = cookie.get(COOKIE_NAMES.IBOOT_LOCALE)?.value;\r\n const websiteId = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_ID)?.value;\r\n const websiteNo = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_NO)?.value;\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly apiKey: string;\r\n private readonly userType: USER_TYPE;\r\n private readonly userFrom: string;\r\n private readonly deviceId: string;\r\n private readonly version: string = '1';\r\n private readonly lang: string;\r\n private readonly websiteId?: string;\r\n private readonly websiteNo?: string;\r\n private readonly _isDebug: boolean;\r\n private readonly logger: pino.Logger;\r\n constructor({ deviceId, lang, websiteId, websiteNo, userType }: Readonly<HttpClientOpts>) {\r\n this.baseUrl = process.env.BASE_URL ?? '';\r\n this.apiKey = process.env.API_KEY ?? '';\r\n this.userType = userType ?? USER_TYPE_MAP.TYPE_MGT;\r\n this.userFrom = process.env.USER_FROM || '1';\r\n this.deviceId = deviceId ?? randomString(10);\r\n this.lang = lang ?? DEFAULT_LOCALE;\r\n this.websiteId = websiteId\r\n this.websiteNo = websiteNo\r\n this._isDebug = process.env.NODE_ENV != 'production';\r\n this.logger = pino({\r\n name: 'iboot',\r\n level: this._isDebug ? 'debug' : 'info',\r\n nestedKey: 'payload'\r\n })\r\n }\r\n\r\n isDebug() {\r\n return this._isDebug;\r\n }\r\n\r\n encrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.encrypt(data, key).toString();\r\n }\r\n\r\n decrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.decrypt(data, key, {\r\n mode: CryptoJS.mode.ECB,\r\n }).toString(CryptoJS.enc.Utf8);\r\n }\r\n\r\n getDeviceId() {\r\n return this.deviceId;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private convertUrlParameter(data: Record<string, any>): string {\r\n const p: string[] = [];\r\n for (const o in data) {\r\n let v = data[o];\r\n if (v && typeof v === \"string\") {\r\n v = v.trim();\r\n } else if (v && typeof v === \"object\") {\r\n if (isArray(v)) {\r\n if (v.length === 0) {\r\n continue;\r\n }\r\n for (let i = 0; i < v.length; i++) {\r\n const arr_item = v[i];\r\n for (const item_field in arr_item) {\r\n const item_field_value = arr_item[item_field] ?? undefined;\r\n if (item_field_value) {\r\n if (typeof item_field_value === \"object\") {\r\n if (isArray(item_field_value)) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n item_field_value.forEach((item1: any, index: number) => {\r\n if (item1) {\r\n for (const f in item1) {\r\n const v = item1[f];\r\n if (v && v.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field + `[${index.toString()}].${f}`}=${urlEncode(v)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } else if (item_field_value.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field}=${urlEncode(item_field_value.toString())}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n for (const obj in v) {\r\n const oValue = v[obj];\r\n if (oValue != null && oValue != \"\" && oValue.length != 0) {\r\n const s = `.${obj}=${urlEncode(oValue)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n continue;\r\n } else if (v && typeof v === \"function\") {\r\n v = null;\r\n }\r\n\r\n if (v != null && v != \"\" && v.length != 0) {\r\n p.push(o + \"=\" + urlEncode(v));\r\n }\r\n }\r\n return (p && p.join(\"&\"));\r\n }\r\n\r\n private async sign(data: Record<string, object | string>): Promise<string> {\r\n //由后台分配\r\n const _apiKey = \"&key=\" + (await this.helloIboot());\r\n const arr: string[] = [];\r\n for (const o in data) {\r\n arr.push(o);\r\n }\r\n arr.sort((a: string, b: string) => {\r\n return a.toLowerCase().localeCompare(b.toLowerCase());\r\n });\r\n const res: string[] = [];\r\n arr.forEach((v: string) => {\r\n let value: object | string = data[v];\r\n if (typeof value === \"object\") {\r\n value = JSON.stringify(value);\r\n }\r\n res.push(v + \"=\" + value);\r\n });\r\n const paramsStr: string = res.join(\"&\");\r\n const str = md5.md5((paramsStr + _apiKey).toLocaleUpperCase());\r\n const logInfo = {\r\n params: paramsStr,\r\n md5: str\r\n }\r\n this.logger.debug(logInfo)\r\n return str;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private assemblyParameter(data?: Record<string, any>, username?: string): Record<string, any> {\r\n const params = data ?? {};\r\n params['timestamp'] = Date.now() + '';\r\n params['echostr'] = randomString(10);\r\n params['version'] = this.version;\r\n params['deviceId'] = this.deviceId;\r\n params['webid'] = this.websiteId;\r\n params['apiKey'] = this.apiKey;\r\n if (username && username.length > 0) {\r\n params['username'] = username;\r\n }\r\n return params;\r\n }\r\n\r\n private async assemblyHeader({ urlParams, token }: Readonly<{ urlParams: string, token?: Readonly<HttpToken> }>) {\r\n const h: Record<string, string> = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Device-Id': this.deviceId,\r\n 'Lang': this.lang,\r\n 'User-Type': token?.utype.toString() ?? this.userType.toString(),\r\n 'User-From': this.userFrom,\r\n 'Api-Key': this.apiKey\r\n }\r\n if (this.websiteId && this.websiteId.length > 0) {\r\n h['Web-Id'] = this.websiteId\r\n }\r\n if (this.websiteNo && this.websiteNo.length > 0) {\r\n h['Web-No'] = this.websiteNo\r\n }\r\n if (token) {\r\n if (token.token && token.token.length > 0 && token.username && token.username.length > 0) {\r\n h['Authorization'] = token.token;\r\n h['Username'] = token.username;\r\n }\r\n if (token.xcsrf) {\r\n h[token.xcsrf.csrfHeader] = token.xcsrf.csrfToken;\r\n }\r\n }\r\n const data = urlParamToJson(urlParams);\r\n const sign = await this.sign(data);\r\n h['Sign'] = sign\r\n return h;\r\n }\r\n\r\n private async helloIboot(): Promise<string> {\r\n const helloUrl = process.env.HELLO_URL ?? '';\r\n if (helloUrl.length === 0) {\r\n return this.apiKey;\r\n }\r\n const api = this.getApiUrl(helloUrl);\r\n const h = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Api-Key': this.apiKey\r\n }\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: h,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result.data;\r\n }\r\n throw new Error('hello iBoot error!')\r\n }\r\n\r\n private getApiUrl(url: string): string {\r\n return `${this.baseUrl}/${url}`;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async get<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n const api = `${this.getApiUrl(url)}?${urlParams.toString()}`\r\n const logInfo = {\r\n \"method\": \"GET\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: headers,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n async csrf(): Promise<string | undefined> {\r\n const res = await this.get<CSRFToken>({\r\n url: 'guest/csrf'\r\n });\r\n if (res.success) {\r\n const data = res.data;\r\n if (data) {\r\n return data[\"csrfToken\"].toString();\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async post<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n const api = this.getApiUrl(url);\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async stream({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<Response> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params); //new URLSearchParams(params);\r\n\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n headers['Connection'] = 'keep-alive';\r\n headers['X-Accel-Buffering'] = 'no'; //防止 Nginx 缓存\r\n headers['Cache-Control'] = 'no-cache';\r\n const api = this.getApiUrl(url)\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers,\r\n\r\n }\r\n this.logger.info(logInfo);\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP error! status: ${res.status}`);\r\n }\r\n if (!res.body) {\r\n throw new Error('No response body');\r\n }\r\n return new Response(res.body, {\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive'\r\n }\r\n });\r\n } catch (e) {\r\n throw e;\r\n }\r\n }\r\n\r\n getUserInfo(cookies: IbootCookieStore): User | null {\r\n const userjson = cookies.get(COOKIE_NAMES.user)?.value;\r\n if (userjson && userjson.length > 0) {\r\n return JSON.parse(userjson);\r\n }\r\n return null;\r\n }\r\n\r\n getToken(cookies: IbootCookieStore): HttpToken {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n getTokenByCookies = (cookies: IbootReadonlyCookies): HttpToken => {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n setToken(data: User & { token: string, extFields: Record<string, any> }, response: { cookies: IbootWritableCookie }) {\r\n const { id, name, username, nickname, sex, headImg, token, lastLoginTime, tokenExpired, deviceId, userType, mustChangePwd } = data;\r\n const loginUser: User = {\r\n id: id,\r\n name: name,\r\n username: username,\r\n nickname: nickname,\r\n sex: sex,\r\n headImg: headImg,\r\n lastLoginTime: lastLoginTime,\r\n tokenExpired: tokenExpired,\r\n deviceId: deviceId,\r\n userType: userType,\r\n status: 0,\r\n accountType: 0,\r\n enabled: false,\r\n userFrom: 1,\r\n needToReview: false,\r\n socketOnline: false,\r\n createTime: \"\",\r\n mustChangePwd: mustChangePwd\r\n };\r\n response.cookies.set(COOKIE_NAMES.token, token, {\r\n httpOnly: true,\r\n secure: !this._isDebug, // 在生产环境中启用Secure\r\n sameSite: 'strict', // 防止 CSRF 攻击\r\n path: '/', // Cookie 的路径\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, JSON.stringify(loginUser));\r\n return response;\r\n }\r\n\r\n cleanToken(response: { cookies: IbootWritableCookie }) {\r\n response.cookies.set(COOKIE_NAMES.token, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.delete(COOKIE_NAMES.token);\r\n response.cookies.delete(COOKIE_NAMES.user)\r\n return response;\r\n }\r\n}"],"names":["ACCOUNT_TYPE_MAP","USER_TYPE_MAP","USER_FORM_MAP","USER_SEX_MAP","isArray","obj","randomString","len","l","$chars","maxPos","pwd","i","urlParamToJson","urlQueryParams","exclude","result","item","arr","urlEncode","value","DEFAULT_LOCALE","DEVICE_ID_KEY","CURRENT_WEBSITE_KEY","_GET_ERROR","_POST_ERROR","HEADER_NAMES","COOKIE_NAMES","getDefaultRequestHeader","devideId","json","curWebsite","header","setDefaultRequestHeader","deviceId","website","get","url","opts","params","headers","heads","field","response","iGet","res","post","data","body","proxyHeaders","iPost","iPostSuccess","getHttpClientOpts","request","lang","websiteId","websiteNo","getHttpClientOptsByCookie","cookie","HttpClient","userType","pino","key","CryptoJS","p","o","v","arr_item","item_field","item_field_value","item1","index","f","s","oValue","_apiKey","a","b","paramsStr","str","md5","logInfo","username","urlParams","token","h","sign","helloUrl","api","e","buffer","boundary","cookies","userjson","utype","user","id","name","nickname","sex","headImg","lastLoginTime","tokenExpired","mustChangePwd","loginUser"],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import "js-md5";
|
|
2
|
-
import "crypto-js";
|
|
3
|
-
import "pino";
|
|
4
|
-
const
|
|
1
|
+
import C from "js-md5";
|
|
2
|
+
import g from "crypto-js";
|
|
3
|
+
import N from "pino";
|
|
4
|
+
const $ = {
|
|
5
5
|
GENERAL: 0,
|
|
6
6
|
PHONE: 1,
|
|
7
7
|
EMAIL: 2
|
|
8
|
-
},
|
|
8
|
+
}, A = {
|
|
9
9
|
TYPE_MGT: 0,
|
|
10
10
|
TYPE_C: 1,
|
|
11
11
|
TYPE_B: 2
|
|
12
|
-
},
|
|
12
|
+
}, W = {
|
|
13
13
|
FROM_WEB: 1,
|
|
14
14
|
FROM_PC: 2,
|
|
15
15
|
FROM_WX_MINI_PRO: 3,
|
|
@@ -17,108 +17,445 @@ const S = {
|
|
|
17
17
|
FROM_WX_E: 5,
|
|
18
18
|
FROM_APP: 6,
|
|
19
19
|
FROM_DEVICE: 7
|
|
20
|
-
},
|
|
20
|
+
}, x = {
|
|
21
21
|
unknown: 0,
|
|
22
22
|
male: 1,
|
|
23
23
|
female: 2
|
|
24
|
-
}, b =
|
|
24
|
+
}, b = (o) => Array.isArray(o) || typeof o == "object" && Object.prototype.toString.call(o) === "[object Array]", I = (o) => {
|
|
25
|
+
const t = o, e = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678", r = e.length;
|
|
26
|
+
let s = "";
|
|
27
|
+
for (let n = 0; n < t; n++)
|
|
28
|
+
s += e.charAt(Math.floor(Math.random() * r));
|
|
29
|
+
return s;
|
|
30
|
+
}, R = (o, t) => {
|
|
31
|
+
const e = {};
|
|
32
|
+
return o.split("&").forEach((s) => {
|
|
33
|
+
const n = s.split("=");
|
|
34
|
+
n[1] && (e[n[0]] = n[1]);
|
|
35
|
+
}), e;
|
|
36
|
+
}, m = (o) => o == null || o == "" || o.length == 0 ? "" : encodeURIComponent(o).replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\'/g, "%27").replace(/\!/g, "%21").replace(/\~/g, "%7E"), U = "zh-CN", T = "_device_id_key", _ = "_current_website_key", w = "Get request error!", E = "Post request error!", y = {
|
|
25
37
|
"Device-Id": "Device-Id",
|
|
26
38
|
Lang: "Lang",
|
|
27
39
|
"Website-Id": "Website-Id",
|
|
28
40
|
"Website-No": "Website-No"
|
|
29
|
-
},
|
|
41
|
+
}, h = {
|
|
30
42
|
IBOOT_DEVICE_ID: "IBOOT_DEVICE_ID",
|
|
31
43
|
IBOOT_LOCALE: "IBOOT_LOCALE",
|
|
32
44
|
IBOOT_WEBSITE_ID: "IBOOT_WEBSITE_ID",
|
|
33
|
-
IBOOT_WEBSITE_NO: "IBOOT_WEBSITE_NO"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
IBOOT_WEBSITE_NO: "IBOOT_WEBSITE_NO",
|
|
46
|
+
token: "token",
|
|
47
|
+
user: "user"
|
|
48
|
+
}, O = () => {
|
|
49
|
+
const o = localStorage.getItem(T) ?? "", t = localStorage.getItem(_), e = t != null ? JSON.parse(t) : null, r = {};
|
|
50
|
+
return o.length > 0 && (r["Device-Id"] = o), e && (r.Lang = e.language, e.websiteId && (r["Website-Id"] = e.websiteId), e.websiteNo && (r["Website-No"] = e.websiteNo)), r;
|
|
51
|
+
}, M = (o, t) => {
|
|
52
|
+
localStorage.setItem(T, o), t && localStorage.setItem(_, JSON.stringify(t));
|
|
53
|
+
}, k = async (o, t) => {
|
|
54
|
+
if (t?.data) {
|
|
55
|
+
const n = new URLSearchParams(t.data);
|
|
56
|
+
o.indexOf("?") != -1 ? o += `&${n}` : o += `?${n}`;
|
|
57
|
+
}
|
|
58
|
+
const e = O(), r = t?.heads;
|
|
59
|
+
if (r)
|
|
60
|
+
for (const n in r) {
|
|
61
|
+
const c = r[n];
|
|
62
|
+
c && (e[n] = c);
|
|
49
63
|
}
|
|
50
|
-
const
|
|
64
|
+
const s = await fetch(o, {
|
|
51
65
|
method: "GET",
|
|
52
|
-
headers:
|
|
53
|
-
cache:
|
|
66
|
+
headers: e,
|
|
67
|
+
cache: t?.useCache ? "force-cache" : "default"
|
|
54
68
|
});
|
|
55
|
-
return
|
|
56
|
-
code:
|
|
69
|
+
return s.ok ? await s.json() : {
|
|
70
|
+
code: s.status,
|
|
57
71
|
success: !1,
|
|
58
|
-
msg:
|
|
72
|
+
msg: s.statusText
|
|
59
73
|
};
|
|
60
|
-
},
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
return
|
|
64
|
-
if (
|
|
65
|
-
|
|
74
|
+
}, j = async (o, t) => {
|
|
75
|
+
const e = await k(o, t);
|
|
76
|
+
if (e.success)
|
|
77
|
+
return e.data;
|
|
78
|
+
if (t?.showError) {
|
|
79
|
+
t.showError(e.msg ?? w);
|
|
66
80
|
return;
|
|
67
81
|
}
|
|
68
|
-
throw Error(
|
|
69
|
-
},
|
|
70
|
-
const
|
|
71
|
-
let
|
|
72
|
-
const
|
|
73
|
-
if (
|
|
74
|
-
for (let
|
|
75
|
-
const
|
|
76
|
-
|
|
82
|
+
throw Error(e.msg ?? w);
|
|
83
|
+
}, S = async (o, t) => {
|
|
84
|
+
const e = t?.data ?? {}, r = t?.heads;
|
|
85
|
+
let s;
|
|
86
|
+
const n = new Headers(O());
|
|
87
|
+
if (e instanceof FormData ? s = e : (s = JSON.stringify(e), n.set("Content-Type", "application/json")), r)
|
|
88
|
+
for (let l in r) {
|
|
89
|
+
const i = r[l];
|
|
90
|
+
i && n.set(l, i);
|
|
77
91
|
}
|
|
78
|
-
const
|
|
92
|
+
const c = await fetch(o, {
|
|
79
93
|
method: "POST",
|
|
80
|
-
headers:
|
|
81
|
-
body:
|
|
94
|
+
headers: n,
|
|
95
|
+
body: s
|
|
82
96
|
});
|
|
83
|
-
return
|
|
84
|
-
code:
|
|
97
|
+
return c.ok ? await c.json() : {
|
|
98
|
+
code: c.status,
|
|
85
99
|
success: !1,
|
|
86
|
-
msg:
|
|
100
|
+
msg: c.statusText
|
|
87
101
|
};
|
|
88
|
-
},
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
return
|
|
92
|
-
if (
|
|
93
|
-
|
|
102
|
+
}, K = async (o, t) => {
|
|
103
|
+
const e = await S(o, t);
|
|
104
|
+
if (e.success)
|
|
105
|
+
return e.data;
|
|
106
|
+
if (t?.showError) {
|
|
107
|
+
t.showError(e.msg ?? E);
|
|
94
108
|
return;
|
|
95
109
|
}
|
|
96
|
-
throw Error(
|
|
97
|
-
},
|
|
98
|
-
const
|
|
99
|
-
return
|
|
100
|
-
},
|
|
101
|
-
const
|
|
102
|
-
return
|
|
103
|
-
},
|
|
104
|
-
const
|
|
105
|
-
return
|
|
110
|
+
throw Error(e.msg ?? E);
|
|
111
|
+
}, F = async (o, t) => {
|
|
112
|
+
const e = await S(o, t);
|
|
113
|
+
return e.success ? (t?.showSuccess && t.showSuccess(e.msg ?? "SUCCESS"), !0) : (t?.showError && t.showError(e.msg ?? E), !1);
|
|
114
|
+
}, H = (o) => {
|
|
115
|
+
const t = o.headers.get(y["Device-Id"]), e = o.headers.get(y.Lang), r = o.headers.get(y["Website-Id"]), s = o.headers.get(y["Website-No"]), n = {};
|
|
116
|
+
return t && t.length > 0 && (n.deviceId = t), e && e.length > 0 && (n.lang = e), r && r.length > 0 && (n.websiteId = r), s && s.length > 0 && (n.websiteNo = s), n;
|
|
117
|
+
}, G = (o) => {
|
|
118
|
+
const t = {}, e = o.get(h.IBOOT_DEVICE_ID)?.value, r = o.get(h.IBOOT_LOCALE)?.value, s = o.get(h.IBOOT_WEBSITE_ID)?.value, n = o.get(h.IBOOT_WEBSITE_NO)?.value;
|
|
119
|
+
return e && e.length > 0 && (t.deviceId = e), r && r.length > 0 && (t.lang = r), s && s.length > 0 && (t.websiteId = s), n && n.length > 0 && (t.websiteNo = n), t;
|
|
106
120
|
};
|
|
121
|
+
class J {
|
|
122
|
+
baseUrl;
|
|
123
|
+
apiKey;
|
|
124
|
+
userType;
|
|
125
|
+
userFrom;
|
|
126
|
+
deviceId;
|
|
127
|
+
version = "1";
|
|
128
|
+
lang;
|
|
129
|
+
websiteId;
|
|
130
|
+
websiteNo;
|
|
131
|
+
_isDebug;
|
|
132
|
+
logger;
|
|
133
|
+
constructor({ deviceId: t, lang: e, websiteId: r, websiteNo: s, userType: n }) {
|
|
134
|
+
this.baseUrl = process.env.BASE_URL ?? "", this.apiKey = process.env.API_KEY ?? "", this.userType = n ?? A.TYPE_MGT, this.userFrom = process.env.USER_FROM || "1", this.deviceId = t ?? I(10), this.lang = e ?? U, this.websiteId = r, this.websiteNo = s, this._isDebug = process.env.NODE_ENV != "production", this.logger = N({
|
|
135
|
+
name: "iboot",
|
|
136
|
+
level: this._isDebug ? "debug" : "info",
|
|
137
|
+
nestedKey: "payload"
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
isDebug() {
|
|
141
|
+
return this._isDebug;
|
|
142
|
+
}
|
|
143
|
+
encrypt(t) {
|
|
144
|
+
const e = g.enc.Utf8.parse(this.apiKey);
|
|
145
|
+
return g.AES.encrypt(t, e).toString();
|
|
146
|
+
}
|
|
147
|
+
decrypt(t) {
|
|
148
|
+
const e = g.enc.Utf8.parse(this.apiKey);
|
|
149
|
+
return g.AES.decrypt(t, e, {
|
|
150
|
+
mode: g.mode.ECB
|
|
151
|
+
}).toString(g.enc.Utf8);
|
|
152
|
+
}
|
|
153
|
+
getDeviceId() {
|
|
154
|
+
return this.deviceId;
|
|
155
|
+
}
|
|
156
|
+
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
157
|
+
convertUrlParameter(t) {
|
|
158
|
+
const e = [];
|
|
159
|
+
for (const r in t) {
|
|
160
|
+
let s = t[r];
|
|
161
|
+
if (s && typeof s == "string")
|
|
162
|
+
s = s.trim();
|
|
163
|
+
else if (s && typeof s == "object") {
|
|
164
|
+
if (b(s)) {
|
|
165
|
+
if (s.length === 0)
|
|
166
|
+
continue;
|
|
167
|
+
for (let n = 0; n < s.length; n++) {
|
|
168
|
+
const c = s[n];
|
|
169
|
+
for (const l in c) {
|
|
170
|
+
const i = c[l] ?? void 0;
|
|
171
|
+
if (i) {
|
|
172
|
+
if (typeof i == "object")
|
|
173
|
+
b(i) && i.forEach((a, f) => {
|
|
174
|
+
if (a)
|
|
175
|
+
for (const d in a) {
|
|
176
|
+
const u = a[d];
|
|
177
|
+
if (u && u.toString().length > 0) {
|
|
178
|
+
const p = `[${n.toString()}].${l + `[${f.toString()}].${d}`}=${m(u)}`;
|
|
179
|
+
e.push(r + p);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
else if (i.toString().length > 0) {
|
|
184
|
+
const a = `[${n.toString()}].${l}=${m(i.toString())}`;
|
|
185
|
+
e.push(r + a);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
} else
|
|
191
|
+
for (const n in s) {
|
|
192
|
+
const c = s[n];
|
|
193
|
+
if (c != null && c != "" && c.length != 0) {
|
|
194
|
+
const l = `.${n}=${m(c)}`;
|
|
195
|
+
e.push(r + l);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
continue;
|
|
199
|
+
} else s && typeof s == "function" && (s = null);
|
|
200
|
+
s != null && s != "" && s.length != 0 && e.push(r + "=" + m(s));
|
|
201
|
+
}
|
|
202
|
+
return e && e.join("&");
|
|
203
|
+
}
|
|
204
|
+
async sign(t) {
|
|
205
|
+
const e = "&key=" + await this.helloIboot(), r = [];
|
|
206
|
+
for (const i in t)
|
|
207
|
+
r.push(i);
|
|
208
|
+
r.sort((i, a) => i.toLowerCase().localeCompare(a.toLowerCase()));
|
|
209
|
+
const s = [];
|
|
210
|
+
r.forEach((i) => {
|
|
211
|
+
let a = t[i];
|
|
212
|
+
typeof a == "object" && (a = JSON.stringify(a)), s.push(i + "=" + a);
|
|
213
|
+
});
|
|
214
|
+
const n = s.join("&"), c = C.md5((n + e).toLocaleUpperCase()), l = {
|
|
215
|
+
params: n,
|
|
216
|
+
md5: c
|
|
217
|
+
};
|
|
218
|
+
return this.logger.debug(l), c;
|
|
219
|
+
}
|
|
220
|
+
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
221
|
+
assemblyParameter(t, e) {
|
|
222
|
+
const r = t ?? {};
|
|
223
|
+
return r.timestamp = Date.now() + "", r.echostr = I(10), r.version = this.version, r.deviceId = this.deviceId, r.webid = this.websiteId, r.apiKey = this.apiKey, e && e.length > 0 && (r.username = e), r;
|
|
224
|
+
}
|
|
225
|
+
async assemblyHeader({ urlParams: t, token: e }) {
|
|
226
|
+
const r = {
|
|
227
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
228
|
+
"Res-Type": "json",
|
|
229
|
+
"Device-Id": this.deviceId,
|
|
230
|
+
Lang: this.lang,
|
|
231
|
+
"User-Type": e?.utype.toString() ?? this.userType.toString(),
|
|
232
|
+
"User-From": this.userFrom,
|
|
233
|
+
"Api-Key": this.apiKey
|
|
234
|
+
};
|
|
235
|
+
this.websiteId && this.websiteId.length > 0 && (r["Web-Id"] = this.websiteId), this.websiteNo && this.websiteNo.length > 0 && (r["Web-No"] = this.websiteNo), e && (e.token && e.token.length > 0 && e.username && e.username.length > 0 && (r.Authorization = e.token, r.Username = e.username), e.xcsrf && (r[e.xcsrf.csrfHeader] = e.xcsrf.csrfToken));
|
|
236
|
+
const s = R(t), n = await this.sign(s);
|
|
237
|
+
return r.Sign = n, r;
|
|
238
|
+
}
|
|
239
|
+
async helloIboot() {
|
|
240
|
+
const t = process.env.HELLO_URL ?? "";
|
|
241
|
+
if (t.length === 0)
|
|
242
|
+
return this.apiKey;
|
|
243
|
+
const e = this.getApiUrl(t), r = {
|
|
244
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
245
|
+
"Res-Type": "json",
|
|
246
|
+
"Api-Key": this.apiKey
|
|
247
|
+
}, s = await fetch(e, {
|
|
248
|
+
method: "GET",
|
|
249
|
+
headers: r,
|
|
250
|
+
credentials: "include",
|
|
251
|
+
cache: "force-cache"
|
|
252
|
+
});
|
|
253
|
+
if (s.ok)
|
|
254
|
+
return (await s.json()).data;
|
|
255
|
+
throw new Error("hello iBoot error!");
|
|
256
|
+
}
|
|
257
|
+
getApiUrl(t) {
|
|
258
|
+
return `${this.baseUrl}/${t}`;
|
|
259
|
+
}
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
261
|
+
async get({ url: t, data: e, token: r }) {
|
|
262
|
+
const s = this.assemblyParameter(e), n = this.convertUrlParameter(s), c = await this.assemblyHeader({ urlParams: n, token: r }), l = `${this.getApiUrl(t)}?${n.toString()}`, i = {
|
|
263
|
+
method: "GET",
|
|
264
|
+
url: l,
|
|
265
|
+
headers: c
|
|
266
|
+
};
|
|
267
|
+
this.logger.info(i);
|
|
268
|
+
try {
|
|
269
|
+
const a = await fetch(l, {
|
|
270
|
+
method: "GET",
|
|
271
|
+
headers: c,
|
|
272
|
+
credentials: "include",
|
|
273
|
+
cache: "force-cache"
|
|
274
|
+
});
|
|
275
|
+
return a.ok ? await a.json() : {
|
|
276
|
+
code: a.status,
|
|
277
|
+
success: !1,
|
|
278
|
+
msg: a.statusText
|
|
279
|
+
};
|
|
280
|
+
} catch (a) {
|
|
281
|
+
return {
|
|
282
|
+
code: 500,
|
|
283
|
+
success: !1,
|
|
284
|
+
msg: a?.toString() ?? "Server exception!"
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async csrf() {
|
|
289
|
+
const t = await this.get({
|
|
290
|
+
url: "guest/csrf"
|
|
291
|
+
});
|
|
292
|
+
if (t.success) {
|
|
293
|
+
const e = t.data;
|
|
294
|
+
if (e)
|
|
295
|
+
return e.csrfToken.toString();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
299
|
+
async post({ url: t, data: e, token: r }) {
|
|
300
|
+
e = e ? { ...e } : {};
|
|
301
|
+
const s = e.buffer ?? void 0, n = e.boundary ?? void 0;
|
|
302
|
+
s && delete e.buffer, n && delete e.boundary;
|
|
303
|
+
const c = this.assemblyParameter(e), l = this.convertUrlParameter(c), i = await this.assemblyHeader({ urlParams: l, token: r });
|
|
304
|
+
s && n && (i["Content-Type"] = `multipart/form-data; boundary=${n}`);
|
|
305
|
+
const a = this.getApiUrl(t), f = {
|
|
306
|
+
method: "POST",
|
|
307
|
+
url: a,
|
|
308
|
+
headers: i
|
|
309
|
+
};
|
|
310
|
+
this.logger.info(f);
|
|
311
|
+
try {
|
|
312
|
+
const d = s ? `${a}?${l}` : a, u = await fetch(d, {
|
|
313
|
+
method: "POST",
|
|
314
|
+
headers: i,
|
|
315
|
+
body: s || l.toString(),
|
|
316
|
+
credentials: "include"
|
|
317
|
+
});
|
|
318
|
+
return u.ok ? await u.json() : {
|
|
319
|
+
code: u.status,
|
|
320
|
+
success: !1,
|
|
321
|
+
msg: u.statusText
|
|
322
|
+
};
|
|
323
|
+
} catch (d) {
|
|
324
|
+
return {
|
|
325
|
+
code: 500,
|
|
326
|
+
success: !1,
|
|
327
|
+
msg: d?.toString() ?? "Server exception!"
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
332
|
+
async stream({ url: t, data: e, token: r }) {
|
|
333
|
+
e = e ? { ...e } : {};
|
|
334
|
+
const s = e.buffer ?? void 0, n = e.boundary ?? void 0;
|
|
335
|
+
s && delete e.buffer, n && delete e.boundary;
|
|
336
|
+
const c = this.assemblyParameter(e), l = this.convertUrlParameter(c), i = await this.assemblyHeader({ urlParams: l, token: r });
|
|
337
|
+
s && n && (i["Content-Type"] = `multipart/form-data; boundary=${n}`), i.Connection = "keep-alive", i["X-Accel-Buffering"] = "no", i["Cache-Control"] = "no-cache";
|
|
338
|
+
const a = this.getApiUrl(t);
|
|
339
|
+
try {
|
|
340
|
+
const f = s ? `${a}?${l}` : a, d = {
|
|
341
|
+
method: "POST",
|
|
342
|
+
url: a,
|
|
343
|
+
headers: i
|
|
344
|
+
};
|
|
345
|
+
this.logger.info(d);
|
|
346
|
+
const u = await fetch(f, {
|
|
347
|
+
method: "POST",
|
|
348
|
+
headers: i,
|
|
349
|
+
body: s || l.toString(),
|
|
350
|
+
credentials: "include"
|
|
351
|
+
});
|
|
352
|
+
if (!u.ok)
|
|
353
|
+
throw new Error(`HTTP error! status: ${u.status}`);
|
|
354
|
+
if (!u.body)
|
|
355
|
+
throw new Error("No response body");
|
|
356
|
+
return new Response(u.body, {
|
|
357
|
+
headers: {
|
|
358
|
+
"Content-Type": "text/event-stream",
|
|
359
|
+
"Cache-Control": "no-cache",
|
|
360
|
+
Connection: "keep-alive"
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
} catch (f) {
|
|
364
|
+
throw f;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
getUserInfo(t) {
|
|
368
|
+
const e = t.get(h.user)?.value;
|
|
369
|
+
return e && e.length > 0 ? JSON.parse(e) : null;
|
|
370
|
+
}
|
|
371
|
+
getToken(t) {
|
|
372
|
+
const e = t.get("user")?.value;
|
|
373
|
+
let r = "", s = this.userType;
|
|
374
|
+
if (e && e.length > 0) {
|
|
375
|
+
const n = JSON.parse(e);
|
|
376
|
+
r = n.username, s = n.userType.toString();
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
username: r,
|
|
380
|
+
utype: s,
|
|
381
|
+
token: t.get(h.token)?.value ?? ""
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
getTokenByCookies = (t) => {
|
|
385
|
+
const e = t.get("user")?.value;
|
|
386
|
+
let r = "", s = this.userType;
|
|
387
|
+
if (e && e.length > 0) {
|
|
388
|
+
const n = JSON.parse(e);
|
|
389
|
+
r = n.username, s = n.userType.toString();
|
|
390
|
+
}
|
|
391
|
+
return {
|
|
392
|
+
username: r,
|
|
393
|
+
utype: s,
|
|
394
|
+
token: t.get(h.token)?.value ?? ""
|
|
395
|
+
};
|
|
396
|
+
};
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
398
|
+
setToken(t, e) {
|
|
399
|
+
const { id: r, name: s, username: n, nickname: c, sex: l, headImg: i, token: a, lastLoginTime: f, tokenExpired: d, deviceId: u, userType: p, mustChangePwd: v } = t, P = {
|
|
400
|
+
id: r,
|
|
401
|
+
name: s,
|
|
402
|
+
username: n,
|
|
403
|
+
nickname: c,
|
|
404
|
+
sex: l,
|
|
405
|
+
headImg: i,
|
|
406
|
+
lastLoginTime: f,
|
|
407
|
+
tokenExpired: d,
|
|
408
|
+
deviceId: u,
|
|
409
|
+
userType: p,
|
|
410
|
+
status: 0,
|
|
411
|
+
accountType: 0,
|
|
412
|
+
enabled: !1,
|
|
413
|
+
userFrom: 1,
|
|
414
|
+
needToReview: !1,
|
|
415
|
+
socketOnline: !1,
|
|
416
|
+
createTime: "",
|
|
417
|
+
mustChangePwd: v
|
|
418
|
+
};
|
|
419
|
+
return e.cookies.set(h.token, a, {
|
|
420
|
+
httpOnly: !0,
|
|
421
|
+
secure: !this._isDebug,
|
|
422
|
+
// 在生产环境中启用Secure
|
|
423
|
+
sameSite: "strict",
|
|
424
|
+
// 防止 CSRF 攻击
|
|
425
|
+
path: "/"
|
|
426
|
+
// Cookie 的路径
|
|
427
|
+
}), e.cookies.set(h.user, JSON.stringify(P)), e;
|
|
428
|
+
}
|
|
429
|
+
cleanToken(t) {
|
|
430
|
+
return t.cookies.set(h.token, "", {
|
|
431
|
+
maxAge: -1,
|
|
432
|
+
//设置为 -1表示立即过期
|
|
433
|
+
httpOnly: !0,
|
|
434
|
+
path: "/"
|
|
435
|
+
}), t.cookies.set(h.user, "", {
|
|
436
|
+
maxAge: -1,
|
|
437
|
+
//设置为 -1表示立即过期
|
|
438
|
+
httpOnly: !0,
|
|
439
|
+
path: "/"
|
|
440
|
+
}), t.cookies.delete(h.token), t.cookies.delete(h.user), t;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
107
443
|
export {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
444
|
+
$ as ACCOUNT_TYPE_MAP,
|
|
445
|
+
_ as CURRENT_WEBSITE_KEY,
|
|
446
|
+
U as DEFAULT_LOCALE,
|
|
447
|
+
T as DEVICE_ID_KEY,
|
|
448
|
+
J as HttpClient,
|
|
449
|
+
W as USER_FORM_MAP,
|
|
450
|
+
x as USER_SEX_MAP,
|
|
451
|
+
A as USER_TYPE_MAP,
|
|
452
|
+
k as get,
|
|
453
|
+
H as getHttpClientOpts,
|
|
454
|
+
G as getHttpClientOptsByCookie,
|
|
455
|
+
j as iGet,
|
|
456
|
+
K as iPost,
|
|
457
|
+
F as iPostSuccess,
|
|
458
|
+
S as post,
|
|
459
|
+
M as setDefaultRequestHeader
|
|
123
460
|
};
|
|
124
461
|
//# sourceMappingURL=iboot-http-client.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iboot-http-client.es.js","sources":["../src/types/user.ts","../src/http-client.ts"],"sourcesContent":["export const ACCOUNT_TYPE_MAP = {\r\n GENERAL : 0,\r\n PHONE : 1,\r\n EMAIL : 2\r\n}\r\n\r\nexport const USER_TYPE_MAP = {\r\n TYPE_MGT : 0,\r\n TYPE_C : 1,\r\n TYPE_B : 2\r\n}\r\n\r\nexport const USER_FORM_MAP = {\r\n FROM_WEB : 1,\r\n FROM_PC : 2,\r\n FROM_WX_MINI_PRO : 3,\r\n FROM_WX_PLU : 4,\r\n FROM_WX_E : 5,\r\n FROM_APP : 6,\r\n FROM_DEVICE : 7\r\n}\r\n\r\nexport const USER_SEX_MAP = {\r\n unknown:0,\r\n male:1,\r\n female:2,\r\n}\r\n\r\nexport type ACCOUNT_TYPE = typeof ACCOUNT_TYPE_MAP[keyof typeof ACCOUNT_TYPE_MAP];\r\nexport type USER_TYPE = typeof USER_TYPE_MAP[keyof typeof USER_TYPE_MAP];\r\nexport type USER_FORM = typeof USER_FORM_MAP[keyof typeof USER_FORM_MAP];\r\nexport type USER_SEX = typeof USER_SEX_MAP[keyof typeof USER_SEX_MAP];\r\n\r\n// User interface\r\nexport interface User {\r\n id: string;\r\n name: string;\r\n username: string;\r\n nickname: string;\r\n sex: USER_SEX;\r\n headImg: string;\r\n lastLoginTime: string;\r\n tokenExpired: string;\r\n deviceId: string;\r\n userType: USER_TYPE;\r\n status: number;\r\n accountType: number;\r\n enabled: boolean;\r\n userFrom: USER_FORM;\r\n needToReview: boolean;\r\n socketOnline: boolean;\r\n createTime: string;\r\n mustChangePwd: boolean;\r\n}","import md5 from \"js-md5\";\r\nimport CryptoJS from 'crypto-js';\r\nimport { isArray, randomString, urlEncode, urlParamToJson } from \"./utils\";\r\nimport pino from \"pino\";\r\nimport { \r\n ClientGetParams, \r\n ClientPostParams, \r\n CookieNames, \r\n CSRFToken, \r\n CurWebsite, \r\n HttpClientOpts, \r\n HttpHeaderNames, \r\n HttpHeaders, \r\n HttpToken, \r\n IbootCookieStore, \r\n IbootReadonlyCookies, \r\n IbootWritableCookie, \r\n ResultModel \r\n} from \"./types/http\";\r\nimport { User, USER_TYPE, USER_TYPE_MAP } from \"./types/user\";\r\n\r\nexport const DEFAULT_LOCALE = 'zh-CN';\r\nexport const DEVICE_ID_KEY = \"_device_id_key\";\r\nexport const CURRENT_WEBSITE_KEY = \"_current_website_key\"\r\n\r\nconst _GET_ERROR = \"Get request error!\"\r\nconst _POST_ERROR = \"Post request error!\";\r\n\r\nconst HEADER_NAMES: Record<HttpHeaderNames, HttpHeaderNames> = {\r\n \"Device-Id\": \"Device-Id\",\r\n \"Lang\": \"Lang\",\r\n \"Website-Id\": \"Website-Id\",\r\n \"Website-No\": \"Website-No\",\r\n}\r\n\r\nconst COOKIE_NAMES: Record<CookieNames, CookieNames> = {\r\n \"IBOOT_DEVICE_ID\": \"IBOOT_DEVICE_ID\",\r\n \"IBOOT_LOCALE\": \"IBOOT_LOCALE\",\r\n \"IBOOT_WEBSITE_ID\": \"IBOOT_WEBSITE_ID\",\r\n \"IBOOT_WEBSITE_NO\": \"IBOOT_WEBSITE_NO\",\r\n \"token\": \"token\",\r\n \"user\": \"user\"\r\n}\r\n\r\nconst getDefaultRequestHeader = (): HttpHeaders => {\r\n const devideId = localStorage.getItem(DEVICE_ID_KEY) ?? ''\r\n const json = localStorage.getItem(CURRENT_WEBSITE_KEY);\r\n const curWebsite: CurWebsite | null = json != null ? JSON.parse(json) : null;\r\n const header: HttpHeaders = {}\r\n if (devideId.length > 0) {\r\n header['Device-Id'] = devideId\r\n }\r\n if (curWebsite) {\r\n header['Lang'] = curWebsite.language;\r\n if (curWebsite.websiteId) {\r\n header['Website-Id'] = curWebsite.websiteId;\r\n }\r\n if (curWebsite.websiteNo) {\r\n header['Website-No'] = curWebsite.websiteNo\r\n }\r\n }\r\n return header;\r\n};\r\n\r\nexport const setDefaultRequestHeader = (deviceId: string, website?: CurWebsite): void => {\r\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\r\n if (website) {\r\n localStorage.setItem(CURRENT_WEBSITE_KEY, JSON.stringify(website));\r\n }\r\n}\r\n\r\nexport const get = async <T>(url: string, opts?: ClientGetParams): Promise<ResultModel<T>> => {\r\n if (opts?.data) {\r\n const params = new URLSearchParams(opts.data);\r\n if (url.indexOf(\"?\") != -1) {\r\n url += `&${params}`\r\n } else {\r\n url += `?${params}`\r\n }\r\n }\r\n const headers: Record<string, string> = getDefaultRequestHeader();\r\n const heads = opts?.heads;\r\n if (heads) {\r\n for (const field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n headers[field] = value;\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: headers,\r\n cache: opts?.useCache ? 'force-cache' : 'default'\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText\r\n }\r\n}\r\n\r\nexport const iGet = async <T>(url: string, opts?: ClientGetParams): Promise<T | undefined> => {\r\n const res = await get<T>(url, opts);\r\n if (res.success) {\r\n return res.data as T;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _GET_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _GET_ERROR)\r\n}\r\n\r\nexport const post = async <T>(url: string, opts?: ClientPostParams): Promise<ResultModel<T>> => {\r\n const data = opts?.data ?? {};\r\n const heads = opts?.heads;\r\n let body: string | FormData;\r\n const proxyHeaders = new Headers(getDefaultRequestHeader());\r\n if (!(data instanceof FormData)) {\r\n body = JSON.stringify(data);\r\n proxyHeaders.set('Content-Type', 'application/json');\r\n } else {\r\n body = data;\r\n }\r\n if (heads) {\r\n for (let field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n proxyHeaders.set(field, value);\r\n }\r\n }\r\n }\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: proxyHeaders,\r\n body: body,\r\n });\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText,\r\n }\r\n}\r\n\r\nexport const iPost = async <T>(url: string, opts?: ClientPostParams): Promise<T | undefined> => {\r\n const res = await post<T>(url, opts);\r\n if (res.success) {\r\n return res.data;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _POST_ERROR)\r\n}\r\n\r\nexport const iPostSuccess = async (url: string, opts?: ClientPostParams): Promise<boolean> => {\r\n const res = await post(url, opts);\r\n if (res.success) {\r\n if (opts?.showSuccess) {\r\n opts.showSuccess(res.msg ?? 'SUCCESS')\r\n }\r\n return true;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport const getHttpClientOpts = (request: Request): HttpClientOpts => {\r\n const deviceId = request.headers.get(HEADER_NAMES[\"Device-Id\"]);\r\n const lang = request.headers.get(HEADER_NAMES.Lang);\r\n const websiteId = request.headers.get(HEADER_NAMES[\"Website-Id\"]);\r\n const websiteNo = request.headers.get(HEADER_NAMES[\"Website-No\"]);\r\n const result: HttpClientOpts = {}\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport const getHttpClientOptsByCookie = (cookie: IbootReadonlyCookies): HttpClientOpts => {\r\n const result: HttpClientOpts = {}\r\n const deviceId = cookie.get(COOKIE_NAMES.IBOOT_DEVICE_ID)?.value;\r\n const lang = cookie.get(COOKIE_NAMES.IBOOT_LOCALE)?.value;\r\n const websiteId = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_ID)?.value;\r\n const websiteNo = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_NO)?.value;\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport default class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly apiKey: string;\r\n private readonly userType: USER_TYPE;\r\n private readonly userFrom: string;\r\n private readonly deviceId: string;\r\n private readonly version: string = '1';\r\n private readonly lang: string;\r\n private readonly websiteId?: string;\r\n private readonly websiteNo?: string;\r\n private readonly _isDebug: boolean;\r\n private readonly logger: pino.Logger;\r\n constructor({ deviceId, lang, websiteId, websiteNo, userType }: Readonly<HttpClientOpts>) {\r\n this.baseUrl = process.env.BASE_URL ?? '';\r\n this.apiKey = process.env.API_KEY ?? '';\r\n this.userType = userType ?? USER_TYPE_MAP.TYPE_MGT;\r\n this.userFrom = process.env.USER_FROM || '1';\r\n this.deviceId = deviceId ?? randomString(10);\r\n this.lang = lang ?? DEFAULT_LOCALE;\r\n this.websiteId = websiteId\r\n this.websiteNo = websiteNo\r\n this._isDebug = process.env.NODE_ENV != 'production';\r\n this.logger = pino({\r\n name: 'iboot',\r\n level: this._isDebug ? 'debug' : 'info',\r\n nestedKey: 'payload'\r\n })\r\n }\r\n\r\n isDebug() {\r\n return this._isDebug;\r\n }\r\n\r\n encrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.encrypt(data, key).toString();\r\n }\r\n\r\n decrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.decrypt(data, key, {\r\n mode: CryptoJS.mode.ECB,\r\n }).toString(CryptoJS.enc.Utf8);\r\n }\r\n\r\n getDeviceId() {\r\n return this.deviceId;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private convertUrlParameter(data: Record<string, any>): string {\r\n const p: string[] = [];\r\n for (const o in data) {\r\n let v = data[o];\r\n if (v && typeof v === \"string\") {\r\n v = v.trim();\r\n } else if (v && typeof v === \"object\") {\r\n if (isArray(v)) {\r\n if (v.length === 0) {\r\n continue;\r\n }\r\n for (let i = 0; i < v.length; i++) {\r\n const arr_item = v[i];\r\n for (const item_field in arr_item) {\r\n const item_field_value = arr_item[item_field] ?? undefined;\r\n if (item_field_value) {\r\n if (typeof item_field_value === \"object\") {\r\n if (isArray(item_field_value)) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n item_field_value.forEach((item1: any, index: number) => {\r\n if (item1) {\r\n for (const f in item1) {\r\n const v = item1[f];\r\n if (v && v.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field + `[${index.toString()}].${f}`}=${urlEncode(v)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } else if (item_field_value.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field}=${urlEncode(item_field_value.toString())}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n for (const obj in v) {\r\n const oValue = v[obj];\r\n if (oValue != null && oValue != \"\" && oValue.length != 0) {\r\n const s = `.${obj}=${urlEncode(oValue)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n continue;\r\n } else if (v && typeof v === \"function\") {\r\n v = null;\r\n }\r\n\r\n if (v != null && v != \"\" && v.length != 0) {\r\n p.push(o + \"=\" + urlEncode(v));\r\n }\r\n }\r\n return (p && p.join(\"&\"));\r\n }\r\n\r\n private async sign(data: Record<string, object | string>): Promise<string> {\r\n //由后台分配\r\n const _apiKey = \"&key=\" + (await this.helloIboot());\r\n const arr: string[] = [];\r\n for (const o in data) {\r\n arr.push(o);\r\n }\r\n arr.sort((a: string, b: string) => {\r\n return a.toLowerCase().localeCompare(b.toLowerCase());\r\n });\r\n const res: string[] = [];\r\n arr.forEach((v: string) => {\r\n let value: object | string = data[v];\r\n if (typeof value === \"object\") {\r\n value = JSON.stringify(value);\r\n }\r\n res.push(v + \"=\" + value);\r\n });\r\n const paramsStr: string = res.join(\"&\");\r\n const str = md5.md5((paramsStr + _apiKey).toLocaleUpperCase());\r\n const logInfo = {\r\n params: paramsStr,\r\n md5: str\r\n }\r\n this.logger.debug(logInfo)\r\n return str;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private assemblyParameter(data?: Record<string, any>, username?: string): Record<string, any> {\r\n const params = data ?? {};\r\n params['timestamp'] = Date.now() + '';\r\n params['echostr'] = randomString(10);\r\n params['version'] = this.version;\r\n params['deviceId'] = this.deviceId;\r\n params['webid'] = this.websiteId;\r\n params['apiKey'] = this.apiKey;\r\n if (username && username.length > 0) {\r\n params['username'] = username;\r\n }\r\n return params;\r\n }\r\n\r\n private async assemblyHeader({ urlParams, token }: Readonly<{ urlParams: string, token?: Readonly<HttpToken> }>) {\r\n const h: Record<string, string> = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Device-Id': this.deviceId,\r\n 'Lang': this.lang,\r\n 'User-Type': token?.utype.toString() ?? this.userType.toString(),\r\n 'User-From': this.userFrom,\r\n 'Api-Key': this.apiKey\r\n }\r\n if (this.websiteId && this.websiteId.length > 0) {\r\n h['Web-Id'] = this.websiteId\r\n }\r\n if (this.websiteNo && this.websiteNo.length > 0) {\r\n h['Web-No'] = this.websiteNo\r\n }\r\n if (token) {\r\n if (token.token && token.token.length > 0 && token.username && token.username.length > 0) {\r\n h['Authorization'] = token.token;\r\n h['Username'] = token.username;\r\n }\r\n if (token.xcsrf) {\r\n h[token.xcsrf.csrfHeader] = token.xcsrf.csrfToken;\r\n }\r\n }\r\n const data = urlParamToJson(urlParams);\r\n const sign = await this.sign(data);\r\n h['Sign'] = sign\r\n return h;\r\n }\r\n\r\n private async helloIboot(): Promise<string> {\r\n const helloUrl = process.env.HELLO_URL ?? '';\r\n if (helloUrl.length === 0) {\r\n return this.apiKey;\r\n }\r\n const api = this.getApiUrl(helloUrl);\r\n const h = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Api-Key': this.apiKey\r\n }\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: h,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result.data;\r\n }\r\n throw new Error('hello iBoot error!')\r\n }\r\n\r\n private getApiUrl(url: string): string {\r\n return `${this.baseUrl}/${url}`;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async get<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n const api = `${this.getApiUrl(url)}?${urlParams.toString()}`\r\n const logInfo = {\r\n \"method\": \"GET\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: headers,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n async csrf(): Promise<string | undefined> {\r\n const res = await this.get<CSRFToken>({\r\n url: 'guest/csrf'\r\n });\r\n if (res.success) {\r\n const data = res.data;\r\n if (data) {\r\n return data[\"csrfToken\"].toString();\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async post<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n const api = this.getApiUrl(url);\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async stream({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<Response> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params); //new URLSearchParams(params);\r\n\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n headers['Connection'] = 'keep-alive';\r\n headers['X-Accel-Buffering'] = 'no'; //防止 Nginx 缓存\r\n headers['Cache-Control'] = 'no-cache';\r\n const api = this.getApiUrl(url)\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers,\r\n\r\n }\r\n this.logger.info(logInfo);\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP error! status: ${res.status}`);\r\n }\r\n if (!res.body) {\r\n throw new Error('No response body');\r\n }\r\n return new Response(res.body, {\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive'\r\n }\r\n });\r\n } catch (e) {\r\n throw e;\r\n }\r\n }\r\n\r\n getUserInfo(cookies: IbootCookieStore): User | null {\r\n const userjson = cookies.get(COOKIE_NAMES.user)?.value;\r\n if (userjson && userjson.length > 0) {\r\n return JSON.parse(userjson);\r\n }\r\n return null;\r\n }\r\n\r\n getToken(cookies: IbootCookieStore): HttpToken {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n getTokenByCookies = (cookies: IbootReadonlyCookies): HttpToken => {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n setToken(data: User & { token: string, extFields: Record<string, any> }, response: { cookies: IbootWritableCookie }) {\r\n const { id, name, username, nickname, sex, headImg, token, lastLoginTime, tokenExpired, deviceId, userType, mustChangePwd } = data;\r\n const loginUser: User = {\r\n id: id,\r\n name: name,\r\n username: username,\r\n nickname: nickname,\r\n sex: sex,\r\n headImg: headImg,\r\n lastLoginTime: lastLoginTime,\r\n tokenExpired: tokenExpired,\r\n deviceId: deviceId,\r\n userType: userType,\r\n status: 0,\r\n accountType: 0,\r\n enabled: false,\r\n userFrom: 1,\r\n needToReview: false,\r\n socketOnline: false,\r\n createTime: \"\",\r\n mustChangePwd: mustChangePwd\r\n };\r\n response.cookies.set(COOKIE_NAMES.token, token, {\r\n httpOnly: true,\r\n secure: !this._isDebug, // 在生产环境中启用Secure\r\n sameSite: 'strict', // 防止 CSRF 攻击\r\n path: '/', // Cookie 的路径\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, JSON.stringify(loginUser));\r\n return response;\r\n }\r\n\r\n cleanToken(response: { cookies: IbootWritableCookie }) {\r\n response.cookies.set(COOKIE_NAMES.token, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.delete(COOKIE_NAMES.token);\r\n response.cookies.delete(COOKIE_NAMES.user)\r\n return response;\r\n }\r\n}"],"names":["ACCOUNT_TYPE_MAP","USER_TYPE_MAP","USER_FORM_MAP","USER_SEX_MAP","DEFAULT_LOCALE","DEVICE_ID_KEY","CURRENT_WEBSITE_KEY","_GET_ERROR","_POST_ERROR","HEADER_NAMES","COOKIE_NAMES","getDefaultRequestHeader","devideId","json","curWebsite","header","setDefaultRequestHeader","deviceId","website","get","url","opts","params","headers","heads","field","value","response","iGet","res","post","data","body","proxyHeaders","iPost","iPostSuccess","getHttpClientOpts","request","lang","websiteId","websiteNo","result","getHttpClientOptsByCookie","cookie"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"iboot-http-client.es.js","sources":["../src/types/user.ts","../src/utils.ts","../src/http-client.ts"],"sourcesContent":["export const ACCOUNT_TYPE_MAP = {\r\n GENERAL : 0,\r\n PHONE : 1,\r\n EMAIL : 2\r\n}\r\n\r\nexport const USER_TYPE_MAP = {\r\n TYPE_MGT : 0,\r\n TYPE_C : 1,\r\n TYPE_B : 2\r\n}\r\n\r\nexport const USER_FORM_MAP = {\r\n FROM_WEB : 1,\r\n FROM_PC : 2,\r\n FROM_WX_MINI_PRO : 3,\r\n FROM_WX_PLU : 4,\r\n FROM_WX_E : 5,\r\n FROM_APP : 6,\r\n FROM_DEVICE : 7\r\n}\r\n\r\nexport const USER_SEX_MAP = {\r\n unknown:0,\r\n male:1,\r\n female:2,\r\n}\r\n\r\nexport type ACCOUNT_TYPE = typeof ACCOUNT_TYPE_MAP[keyof typeof ACCOUNT_TYPE_MAP];\r\nexport type USER_TYPE = typeof USER_TYPE_MAP[keyof typeof USER_TYPE_MAP];\r\nexport type USER_FORM = typeof USER_FORM_MAP[keyof typeof USER_FORM_MAP];\r\nexport type USER_SEX = typeof USER_SEX_MAP[keyof typeof USER_SEX_MAP];\r\n\r\n// User interface\r\nexport interface User {\r\n id: string;\r\n name: string;\r\n username: string;\r\n nickname: string;\r\n sex: USER_SEX;\r\n headImg: string;\r\n lastLoginTime: string;\r\n tokenExpired: string;\r\n deviceId: string;\r\n userType: USER_TYPE;\r\n status: number;\r\n accountType: number;\r\n enabled: boolean;\r\n userFrom: USER_FORM;\r\n needToReview: boolean;\r\n socketOnline: boolean;\r\n createTime: string;\r\n mustChangePwd: boolean;\r\n}","export const isArray = (obj: unknown) => {\r\n return (\r\n Array.isArray(obj) ||\r\n (typeof obj === \"object\" &&\r\n Object.prototype.toString.call(obj) === \"[object Array]\")\r\n );\r\n};\r\n\r\n/**\r\n * 生成指定长度的随机串\r\n * @param {Object} len\r\n */\r\nexport const randomString = (len: number) => {\r\n const l = len || 32;\r\n const $chars = \"ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678\";\r\n const maxPos = $chars.length;\r\n let pwd = \"\";\r\n for (let i = 0; i < l; i++) {\r\n pwd += $chars.charAt(Math.floor(Math.random() * maxPos));\r\n }\r\n return pwd;\r\n};\r\n\r\nexport const urlParamToJson = (urlQueryParams: string, exclude?: string[]): Record<string, string> => {\r\n const result: Record<string, string> = {};\r\n const strs = urlQueryParams.split(\"&\");\r\n strs.forEach((item) => {\r\n const arr = item.split(\"=\");\r\n if (arr[1]) {\r\n if (!exclude || exclude.indexOf(arr[0]) == -1) {\r\n result[arr[0]] = arr[1];\r\n }\r\n }\r\n });\r\n return result;\r\n};\r\n\r\nexport const urlEncode = (value: string | null | undefined): string => {\r\n if (value == null || value == \"\" || value.length == 0) {\r\n return \"\";\r\n }\r\n return (\r\n encodeURIComponent(value)\r\n // .replace(/%20/g, '+')\r\n // .replace(/%2B/g, '\\\\+')\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\'/g, \"%27\")\r\n .replace(/\\!/g, \"%21\")\r\n .replace(/\\~/g, \"%7E\")\r\n );\r\n};\r\n","import md5 from \"js-md5\";\r\nimport CryptoJS from 'crypto-js';\r\nimport { isArray, randomString, urlEncode, urlParamToJson } from \"./utils\";\r\nimport pino from \"pino\";\r\nimport { \r\n ClientGetParams, \r\n ClientPostParams, \r\n CookieNames, \r\n CSRFToken, \r\n CurWebsite, \r\n HttpClientOpts, \r\n HttpHeaderNames, \r\n HttpHeaders, \r\n HttpToken, \r\n IbootCookieStore, \r\n IbootReadonlyCookies, \r\n IbootWritableCookie, \r\n ResultModel \r\n} from \"./types/http\";\r\nimport { User, USER_TYPE, USER_TYPE_MAP } from \"./types/user\";\r\n\r\nexport const DEFAULT_LOCALE = 'zh-CN';\r\nexport const DEVICE_ID_KEY = \"_device_id_key\";\r\nexport const CURRENT_WEBSITE_KEY = \"_current_website_key\"\r\n\r\nconst _GET_ERROR = \"Get request error!\"\r\nconst _POST_ERROR = \"Post request error!\";\r\n\r\nconst HEADER_NAMES: Record<HttpHeaderNames, HttpHeaderNames> = {\r\n \"Device-Id\": \"Device-Id\",\r\n \"Lang\": \"Lang\",\r\n \"Website-Id\": \"Website-Id\",\r\n \"Website-No\": \"Website-No\",\r\n}\r\n\r\nconst COOKIE_NAMES: Record<CookieNames, CookieNames> = {\r\n \"IBOOT_DEVICE_ID\": \"IBOOT_DEVICE_ID\",\r\n \"IBOOT_LOCALE\": \"IBOOT_LOCALE\",\r\n \"IBOOT_WEBSITE_ID\": \"IBOOT_WEBSITE_ID\",\r\n \"IBOOT_WEBSITE_NO\": \"IBOOT_WEBSITE_NO\",\r\n \"token\": \"token\",\r\n \"user\": \"user\"\r\n}\r\n\r\nconst getDefaultRequestHeader = (): HttpHeaders => {\r\n const devideId = localStorage.getItem(DEVICE_ID_KEY) ?? ''\r\n const json = localStorage.getItem(CURRENT_WEBSITE_KEY);\r\n const curWebsite: CurWebsite | null = json != null ? JSON.parse(json) : null;\r\n const header: HttpHeaders = {}\r\n if (devideId.length > 0) {\r\n header['Device-Id'] = devideId\r\n }\r\n if (curWebsite) {\r\n header['Lang'] = curWebsite.language;\r\n if (curWebsite.websiteId) {\r\n header['Website-Id'] = curWebsite.websiteId;\r\n }\r\n if (curWebsite.websiteNo) {\r\n header['Website-No'] = curWebsite.websiteNo\r\n }\r\n }\r\n return header;\r\n};\r\n\r\nexport const setDefaultRequestHeader = (deviceId: string, website?: CurWebsite): void => {\r\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\r\n if (website) {\r\n localStorage.setItem(CURRENT_WEBSITE_KEY, JSON.stringify(website));\r\n }\r\n}\r\n\r\nexport const get = async <T>(url: string, opts?: ClientGetParams): Promise<ResultModel<T>> => {\r\n if (opts?.data) {\r\n const params = new URLSearchParams(opts.data);\r\n if (url.indexOf(\"?\") != -1) {\r\n url += `&${params}`\r\n } else {\r\n url += `?${params}`\r\n }\r\n }\r\n const headers: Record<string, string> = getDefaultRequestHeader();\r\n const heads = opts?.heads;\r\n if (heads) {\r\n for (const field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n headers[field] = value;\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: headers,\r\n cache: opts?.useCache ? 'force-cache' : 'default'\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText\r\n }\r\n}\r\n\r\nexport const iGet = async <T>(url: string, opts?: ClientGetParams): Promise<T | undefined> => {\r\n const res = await get<T>(url, opts);\r\n if (res.success) {\r\n return res.data as T;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _GET_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _GET_ERROR)\r\n}\r\n\r\nexport const post = async <T>(url: string, opts?: ClientPostParams): Promise<ResultModel<T>> => {\r\n const data = opts?.data ?? {};\r\n const heads = opts?.heads;\r\n let body: string | FormData;\r\n const proxyHeaders = new Headers(getDefaultRequestHeader());\r\n if (!(data instanceof FormData)) {\r\n body = JSON.stringify(data);\r\n proxyHeaders.set('Content-Type', 'application/json');\r\n } else {\r\n body = data;\r\n }\r\n if (heads) {\r\n for (let field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n proxyHeaders.set(field, value);\r\n }\r\n }\r\n }\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: proxyHeaders,\r\n body: body,\r\n });\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText,\r\n }\r\n}\r\n\r\nexport const iPost = async <T>(url: string, opts?: ClientPostParams): Promise<T | undefined> => {\r\n const res = await post<T>(url, opts);\r\n if (res.success) {\r\n return res.data;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _POST_ERROR)\r\n}\r\n\r\nexport const iPostSuccess = async (url: string, opts?: ClientPostParams): Promise<boolean> => {\r\n const res = await post(url, opts);\r\n if (res.success) {\r\n if (opts?.showSuccess) {\r\n opts.showSuccess(res.msg ?? 'SUCCESS')\r\n }\r\n return true;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport const getHttpClientOpts = (request: Request): HttpClientOpts => {\r\n const deviceId = request.headers.get(HEADER_NAMES[\"Device-Id\"]);\r\n const lang = request.headers.get(HEADER_NAMES.Lang);\r\n const websiteId = request.headers.get(HEADER_NAMES[\"Website-Id\"]);\r\n const websiteNo = request.headers.get(HEADER_NAMES[\"Website-No\"]);\r\n const result: HttpClientOpts = {}\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport const getHttpClientOptsByCookie = (cookie: IbootReadonlyCookies): HttpClientOpts => {\r\n const result: HttpClientOpts = {}\r\n const deviceId = cookie.get(COOKIE_NAMES.IBOOT_DEVICE_ID)?.value;\r\n const lang = cookie.get(COOKIE_NAMES.IBOOT_LOCALE)?.value;\r\n const websiteId = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_ID)?.value;\r\n const websiteNo = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_NO)?.value;\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly apiKey: string;\r\n private readonly userType: USER_TYPE;\r\n private readonly userFrom: string;\r\n private readonly deviceId: string;\r\n private readonly version: string = '1';\r\n private readonly lang: string;\r\n private readonly websiteId?: string;\r\n private readonly websiteNo?: string;\r\n private readonly _isDebug: boolean;\r\n private readonly logger: pino.Logger;\r\n constructor({ deviceId, lang, websiteId, websiteNo, userType }: Readonly<HttpClientOpts>) {\r\n this.baseUrl = process.env.BASE_URL ?? '';\r\n this.apiKey = process.env.API_KEY ?? '';\r\n this.userType = userType ?? USER_TYPE_MAP.TYPE_MGT;\r\n this.userFrom = process.env.USER_FROM || '1';\r\n this.deviceId = deviceId ?? randomString(10);\r\n this.lang = lang ?? DEFAULT_LOCALE;\r\n this.websiteId = websiteId\r\n this.websiteNo = websiteNo\r\n this._isDebug = process.env.NODE_ENV != 'production';\r\n this.logger = pino({\r\n name: 'iboot',\r\n level: this._isDebug ? 'debug' : 'info',\r\n nestedKey: 'payload'\r\n })\r\n }\r\n\r\n isDebug() {\r\n return this._isDebug;\r\n }\r\n\r\n encrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.encrypt(data, key).toString();\r\n }\r\n\r\n decrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.decrypt(data, key, {\r\n mode: CryptoJS.mode.ECB,\r\n }).toString(CryptoJS.enc.Utf8);\r\n }\r\n\r\n getDeviceId() {\r\n return this.deviceId;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private convertUrlParameter(data: Record<string, any>): string {\r\n const p: string[] = [];\r\n for (const o in data) {\r\n let v = data[o];\r\n if (v && typeof v === \"string\") {\r\n v = v.trim();\r\n } else if (v && typeof v === \"object\") {\r\n if (isArray(v)) {\r\n if (v.length === 0) {\r\n continue;\r\n }\r\n for (let i = 0; i < v.length; i++) {\r\n const arr_item = v[i];\r\n for (const item_field in arr_item) {\r\n const item_field_value = arr_item[item_field] ?? undefined;\r\n if (item_field_value) {\r\n if (typeof item_field_value === \"object\") {\r\n if (isArray(item_field_value)) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n item_field_value.forEach((item1: any, index: number) => {\r\n if (item1) {\r\n for (const f in item1) {\r\n const v = item1[f];\r\n if (v && v.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field + `[${index.toString()}].${f}`}=${urlEncode(v)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } else if (item_field_value.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field}=${urlEncode(item_field_value.toString())}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n for (const obj in v) {\r\n const oValue = v[obj];\r\n if (oValue != null && oValue != \"\" && oValue.length != 0) {\r\n const s = `.${obj}=${urlEncode(oValue)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n continue;\r\n } else if (v && typeof v === \"function\") {\r\n v = null;\r\n }\r\n\r\n if (v != null && v != \"\" && v.length != 0) {\r\n p.push(o + \"=\" + urlEncode(v));\r\n }\r\n }\r\n return (p && p.join(\"&\"));\r\n }\r\n\r\n private async sign(data: Record<string, object | string>): Promise<string> {\r\n //由后台分配\r\n const _apiKey = \"&key=\" + (await this.helloIboot());\r\n const arr: string[] = [];\r\n for (const o in data) {\r\n arr.push(o);\r\n }\r\n arr.sort((a: string, b: string) => {\r\n return a.toLowerCase().localeCompare(b.toLowerCase());\r\n });\r\n const res: string[] = [];\r\n arr.forEach((v: string) => {\r\n let value: object | string = data[v];\r\n if (typeof value === \"object\") {\r\n value = JSON.stringify(value);\r\n }\r\n res.push(v + \"=\" + value);\r\n });\r\n const paramsStr: string = res.join(\"&\");\r\n const str = md5.md5((paramsStr + _apiKey).toLocaleUpperCase());\r\n const logInfo = {\r\n params: paramsStr,\r\n md5: str\r\n }\r\n this.logger.debug(logInfo)\r\n return str;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private assemblyParameter(data?: Record<string, any>, username?: string): Record<string, any> {\r\n const params = data ?? {};\r\n params['timestamp'] = Date.now() + '';\r\n params['echostr'] = randomString(10);\r\n params['version'] = this.version;\r\n params['deviceId'] = this.deviceId;\r\n params['webid'] = this.websiteId;\r\n params['apiKey'] = this.apiKey;\r\n if (username && username.length > 0) {\r\n params['username'] = username;\r\n }\r\n return params;\r\n }\r\n\r\n private async assemblyHeader({ urlParams, token }: Readonly<{ urlParams: string, token?: Readonly<HttpToken> }>) {\r\n const h: Record<string, string> = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Device-Id': this.deviceId,\r\n 'Lang': this.lang,\r\n 'User-Type': token?.utype.toString() ?? this.userType.toString(),\r\n 'User-From': this.userFrom,\r\n 'Api-Key': this.apiKey\r\n }\r\n if (this.websiteId && this.websiteId.length > 0) {\r\n h['Web-Id'] = this.websiteId\r\n }\r\n if (this.websiteNo && this.websiteNo.length > 0) {\r\n h['Web-No'] = this.websiteNo\r\n }\r\n if (token) {\r\n if (token.token && token.token.length > 0 && token.username && token.username.length > 0) {\r\n h['Authorization'] = token.token;\r\n h['Username'] = token.username;\r\n }\r\n if (token.xcsrf) {\r\n h[token.xcsrf.csrfHeader] = token.xcsrf.csrfToken;\r\n }\r\n }\r\n const data = urlParamToJson(urlParams);\r\n const sign = await this.sign(data);\r\n h['Sign'] = sign\r\n return h;\r\n }\r\n\r\n private async helloIboot(): Promise<string> {\r\n const helloUrl = process.env.HELLO_URL ?? '';\r\n if (helloUrl.length === 0) {\r\n return this.apiKey;\r\n }\r\n const api = this.getApiUrl(helloUrl);\r\n const h = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Api-Key': this.apiKey\r\n }\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: h,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result.data;\r\n }\r\n throw new Error('hello iBoot error!')\r\n }\r\n\r\n private getApiUrl(url: string): string {\r\n return `${this.baseUrl}/${url}`;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async get<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n const api = `${this.getApiUrl(url)}?${urlParams.toString()}`\r\n const logInfo = {\r\n \"method\": \"GET\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: headers,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n async csrf(): Promise<string | undefined> {\r\n const res = await this.get<CSRFToken>({\r\n url: 'guest/csrf'\r\n });\r\n if (res.success) {\r\n const data = res.data;\r\n if (data) {\r\n return data[\"csrfToken\"].toString();\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async post<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n const api = this.getApiUrl(url);\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async stream({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<Response> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params); //new URLSearchParams(params);\r\n\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n headers['Connection'] = 'keep-alive';\r\n headers['X-Accel-Buffering'] = 'no'; //防止 Nginx 缓存\r\n headers['Cache-Control'] = 'no-cache';\r\n const api = this.getApiUrl(url)\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers,\r\n\r\n }\r\n this.logger.info(logInfo);\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP error! status: ${res.status}`);\r\n }\r\n if (!res.body) {\r\n throw new Error('No response body');\r\n }\r\n return new Response(res.body, {\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive'\r\n }\r\n });\r\n } catch (e) {\r\n throw e;\r\n }\r\n }\r\n\r\n getUserInfo(cookies: IbootCookieStore): User | null {\r\n const userjson = cookies.get(COOKIE_NAMES.user)?.value;\r\n if (userjson && userjson.length > 0) {\r\n return JSON.parse(userjson);\r\n }\r\n return null;\r\n }\r\n\r\n getToken(cookies: IbootCookieStore): HttpToken {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n getTokenByCookies = (cookies: IbootReadonlyCookies): HttpToken => {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n setToken(data: User & { token: string, extFields: Record<string, any> }, response: { cookies: IbootWritableCookie }) {\r\n const { id, name, username, nickname, sex, headImg, token, lastLoginTime, tokenExpired, deviceId, userType, mustChangePwd } = data;\r\n const loginUser: User = {\r\n id: id,\r\n name: name,\r\n username: username,\r\n nickname: nickname,\r\n sex: sex,\r\n headImg: headImg,\r\n lastLoginTime: lastLoginTime,\r\n tokenExpired: tokenExpired,\r\n deviceId: deviceId,\r\n userType: userType,\r\n status: 0,\r\n accountType: 0,\r\n enabled: false,\r\n userFrom: 1,\r\n needToReview: false,\r\n socketOnline: false,\r\n createTime: \"\",\r\n mustChangePwd: mustChangePwd\r\n };\r\n response.cookies.set(COOKIE_NAMES.token, token, {\r\n httpOnly: true,\r\n secure: !this._isDebug, // 在生产环境中启用Secure\r\n sameSite: 'strict', // 防止 CSRF 攻击\r\n path: '/', // Cookie 的路径\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, JSON.stringify(loginUser));\r\n return response;\r\n }\r\n\r\n cleanToken(response: { cookies: IbootWritableCookie }) {\r\n response.cookies.set(COOKIE_NAMES.token, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.delete(COOKIE_NAMES.token);\r\n response.cookies.delete(COOKIE_NAMES.user)\r\n return response;\r\n }\r\n}"],"names":["ACCOUNT_TYPE_MAP","USER_TYPE_MAP","USER_FORM_MAP","USER_SEX_MAP","isArray","obj","randomString","len","l","$chars","maxPos","pwd","i","urlParamToJson","urlQueryParams","exclude","result","item","arr","urlEncode","value","DEFAULT_LOCALE","DEVICE_ID_KEY","CURRENT_WEBSITE_KEY","_GET_ERROR","_POST_ERROR","HEADER_NAMES","COOKIE_NAMES","getDefaultRequestHeader","devideId","json","curWebsite","header","setDefaultRequestHeader","deviceId","website","get","url","opts","params","headers","heads","field","response","iGet","res","post","data","body","proxyHeaders","iPost","iPostSuccess","getHttpClientOpts","request","lang","websiteId","websiteNo","getHttpClientOptsByCookie","cookie","HttpClient","userType","pino","key","CryptoJS","p","o","v","arr_item","item_field","item_field_value","item1","index","f","s","oValue","_apiKey","a","b","paramsStr","str","md5","logInfo","username","urlParams","token","h","sign","helloUrl","api","e","buffer","boundary","cookies","userjson","utype","user","id","name","nickname","sex","headImg","lastLoginTime","tokenExpired","mustChangePwd","loginUser"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(i,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("js-md5"),require("crypto-js"),require("pino")):typeof define=="function"&&define.amd?define(["exports","js-md5","crypto-js","pino"],r):(i=typeof globalThis<"u"?globalThis:i||self,r(i["iboot-http-client"]={}))})(this,(function(i){"use strict";const r={GENERAL:0,PHONE:1,EMAIL:2},S={TYPE_MGT:0,TYPE_C:1,TYPE_B:2},w={FROM_WEB:1,FROM_PC:2,FROM_WX_MINI_PRO:3,FROM_WX_PLU:4,FROM_WX_E:5,FROM_APP:6,FROM_DEVICE:7},R={unknown:0,male:1,female:2},C="zh-CN",d="_device_id_key",I="_current_website_key",l="Get request error!",f="Post request error!",E={"Device-Id":"Device-Id",Lang:"Lang","Website-Id":"Website-Id","Website-No":"Website-No"},_={IBOOT_DEVICE_ID:"IBOOT_DEVICE_ID",IBOOT_LOCALE:"IBOOT_LOCALE",IBOOT_WEBSITE_ID:"IBOOT_WEBSITE_ID",IBOOT_WEBSITE_NO:"IBOOT_WEBSITE_NO"},u=()=>{const s=localStorage.getItem(d)??"",e=localStorage.getItem(I),t=e!=null?JSON.parse(e):null,n={};return s.length>0&&(n["Device-Id"]=s),t&&(n.Lang=t.language,t.websiteId&&(n["Website-Id"]=t.websiteId),t.websiteNo&&(n["Website-No"]=t.websiteNo)),n},P=(s,e)=>{localStorage.setItem(d,s),e&&localStorage.setItem(I,JSON.stringify(e))},g=async(s,e)=>{if(e?.data){const o=new URLSearchParams(e.data);s.indexOf("?")!=-1?s+=`&${o}`:s+=`?${o}`}const t=u(),n=e?.heads;if(n)for(const o in n){const a=n[o];a&&(t[o]=a)}const c=await fetch(s,{method:"GET",headers:t,cache:e?.useCache?"force-cache":"default"});return c.ok?await c.json():{code:c.status,success:!1,msg:c.statusText}},b=async(s,e)=>{const t=await g(s,e);if(t.success)return t.data;if(e?.showError){e.showError(t.msg??l);return}throw Error(t.msg??l)},O=async(s,e)=>{const t=e?.data??{},n=e?.heads;let c;const o=new Headers(u());if(t instanceof FormData?c=t:(c=JSON.stringify(t),o.set("Content-Type","application/json")),n)for(let T in n){const h=n[T];h&&o.set(T,h)}const a=await fetch(s,{method:"POST",headers:o,body:c});return a.ok?await a.json():{code:a.status,success:!1,msg:a.statusText}},N=async(s,e)=>{const t=await O(s,e);if(t.success)return t.data;if(e?.showError){e.showError(t.msg??f);return}throw Error(t.msg??f)},D=async(s,e)=>{const t=await O(s,e);return t.success?(e?.showSuccess&&e.showSuccess(t.msg??"SUCCESS"),!0):(e?.showError&&e.showError(t.msg??f),!1)},m=s=>{const e=s.headers.get(E["Device-Id"]),t=s.headers.get(E.Lang),n=s.headers.get(E["Website-Id"]),c=s.headers.get(E["Website-No"]),o={};return e&&e.length>0&&(o.deviceId=e),t&&t.length>0&&(o.lang=t),n&&n.length>0&&(o.websiteId=n),c&&c.length>0&&(o.websiteNo=c),o},B=s=>{const e={},t=s.get(_.IBOOT_DEVICE_ID)?.value,n=s.get(_.IBOOT_LOCALE)?.value,c=s.get(_.IBOOT_WEBSITE_ID)?.value,o=s.get(_.IBOOT_WEBSITE_NO)?.value;return t&&t.length>0&&(e.deviceId=t),n&&n.length>0&&(e.lang=n),c&&c.length>0&&(e.websiteId=c),o&&o.length>0&&(e.websiteNo=o),e};i.ACCOUNT_TYPE_MAP=r,i.CURRENT_WEBSITE_KEY=I,i.DEFAULT_LOCALE=C,i.DEVICE_ID_KEY=d,i.USER_FORM_MAP=w,i.USER_SEX_MAP=R,i.USER_TYPE_MAP=S,i.get=g,i.getHttpClientOpts=m,i.getHttpClientOptsByCookie=B,i.iGet=b,i.iPost=N,i.iPostSuccess=D,i.post=O,i.setDefaultRequestHeader=P,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(l,p){typeof exports=="object"&&typeof module<"u"?p(exports,require("js-md5"),require("crypto-js"),require("pino")):typeof define=="function"&&define.amd?define(["exports","js-md5","crypto-js","pino"],p):(l=typeof globalThis<"u"?globalThis:l||self,p(l["iboot-http-client"]={},l.md5,l.CryptoJS,l.pino))})(this,(function(l,p,m,N){"use strict";const U={GENERAL:0,PHONE:1,EMAIL:2},O={TYPE_MGT:0,TYPE_C:1,TYPE_B:2},D={FROM_WEB:1,FROM_PC:2,FROM_WX_MINI_PRO:3,FROM_WX_PLU:4,FROM_WX_E:5,FROM_APP:6,FROM_DEVICE:7},k={unknown:0,male:1,female:2},S=o=>Array.isArray(o)||typeof o=="object"&&Object.prototype.toString.call(o)==="[object Array]",v=o=>{const t=o,e="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",r=e.length;let s="";for(let n=0;n<t;n++)s+=e.charAt(Math.floor(Math.random()*r));return s},B=(o,t)=>{const e={};return o.split("&").forEach(s=>{const n=s.split("=");n[1]&&(e[n[0]]=n[1])}),e},y=o=>o==null||o==""||o.length==0?"":encodeURIComponent(o).replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/\'/g,"%27").replace(/\!/g,"%21").replace(/\~/g,"%7E"),P="zh-CN",I="_device_id_key",b="_current_website_key",C="Get request error!",T="Post request error!",E={"Device-Id":"Device-Id",Lang:"Lang","Website-Id":"Website-Id","Website-No":"Website-No"},f={IBOOT_DEVICE_ID:"IBOOT_DEVICE_ID",IBOOT_LOCALE:"IBOOT_LOCALE",IBOOT_WEBSITE_ID:"IBOOT_WEBSITE_ID",IBOOT_WEBSITE_NO:"IBOOT_WEBSITE_NO",token:"token",user:"user"},A=()=>{const o=localStorage.getItem(I)??"",t=localStorage.getItem(b),e=t!=null?JSON.parse(t):null,r={};return o.length>0&&(r["Device-Id"]=o),e&&(r.Lang=e.language,e.websiteId&&(r["Website-Id"]=e.websiteId),e.websiteNo&&(r["Website-No"]=e.websiteNo)),r},L=(o,t)=>{localStorage.setItem(I,o),t&&localStorage.setItem(b,JSON.stringify(t))},R=async(o,t)=>{if(t?.data){const n=new URLSearchParams(t.data);o.indexOf("?")!=-1?o+=`&${n}`:o+=`?${n}`}const e=A(),r=t?.heads;if(r)for(const n in r){const a=r[n];a&&(e[n]=a)}const s=await fetch(o,{method:"GET",headers:e,cache:t?.useCache?"force-cache":"default"});return s.ok?await s.json():{code:s.status,success:!1,msg:s.statusText}},M=async(o,t)=>{const e=await R(o,t);if(e.success)return e.data;if(t?.showError){t.showError(e.msg??C);return}throw Error(e.msg??C)},w=async(o,t)=>{const e=t?.data??{},r=t?.heads;let s;const n=new Headers(A());if(e instanceof FormData?s=e:(s=JSON.stringify(e),n.set("Content-Type","application/json")),r)for(let u in r){const i=r[u];i&&n.set(u,i)}const a=await fetch(o,{method:"POST",headers:n,body:s});return a.ok?await a.json():{code:a.status,success:!1,msg:a.statusText}},j=async(o,t)=>{const e=await w(o,t);if(e.success)return e.data;if(t?.showError){t.showError(e.msg??T);return}throw Error(e.msg??T)},W=async(o,t)=>{const e=await w(o,t);return e.success?(t?.showSuccess&&t.showSuccess(e.msg??"SUCCESS"),!0):(t?.showError&&t.showError(e.msg??T),!1)},$=o=>{const t=o.headers.get(E["Device-Id"]),e=o.headers.get(E.Lang),r=o.headers.get(E["Website-Id"]),s=o.headers.get(E["Website-No"]),n={};return t&&t.length>0&&(n.deviceId=t),e&&e.length>0&&(n.lang=e),r&&r.length>0&&(n.websiteId=r),s&&s.length>0&&(n.websiteNo=s),n},H=o=>{const t={},e=o.get(f.IBOOT_DEVICE_ID)?.value,r=o.get(f.IBOOT_LOCALE)?.value,s=o.get(f.IBOOT_WEBSITE_ID)?.value,n=o.get(f.IBOOT_WEBSITE_NO)?.value;return e&&e.length>0&&(t.deviceId=e),r&&r.length>0&&(t.lang=r),s&&s.length>0&&(t.websiteId=s),n&&n.length>0&&(t.websiteNo=n),t};class K{baseUrl;apiKey;userType;userFrom;deviceId;version="1";lang;websiteId;websiteNo;_isDebug;logger;constructor({deviceId:t,lang:e,websiteId:r,websiteNo:s,userType:n}){this.baseUrl=process.env.BASE_URL??"",this.apiKey=process.env.API_KEY??"",this.userType=n??O.TYPE_MGT,this.userFrom=process.env.USER_FROM||"1",this.deviceId=t??v(10),this.lang=e??P,this.websiteId=r,this.websiteNo=s,this._isDebug=process.env.NODE_ENV!="production",this.logger=N({name:"iboot",level:this._isDebug?"debug":"info",nestedKey:"payload"})}isDebug(){return this._isDebug}encrypt(t){const e=m.enc.Utf8.parse(this.apiKey);return m.AES.encrypt(t,e).toString()}decrypt(t){const e=m.enc.Utf8.parse(this.apiKey);return m.AES.decrypt(t,e,{mode:m.mode.ECB}).toString(m.enc.Utf8)}getDeviceId(){return this.deviceId}convertUrlParameter(t){const e=[];for(const r in t){let s=t[r];if(s&&typeof s=="string")s=s.trim();else if(s&&typeof s=="object"){if(S(s)){if(s.length===0)continue;for(let n=0;n<s.length;n++){const a=s[n];for(const u in a){const i=a[u]??void 0;if(i){if(typeof i=="object")S(i)&&i.forEach((c,d)=>{if(c)for(const g in c){const h=c[g];if(h&&h.toString().length>0){const _=`[${n.toString()}].${u+`[${d.toString()}].${g}`}=${y(h)}`;e.push(r+_)}}});else if(i.toString().length>0){const c=`[${n.toString()}].${u}=${y(i.toString())}`;e.push(r+c)}}}}}else for(const n in s){const a=s[n];if(a!=null&&a!=""&&a.length!=0){const u=`.${n}=${y(a)}`;e.push(r+u)}}continue}else s&&typeof s=="function"&&(s=null);s!=null&&s!=""&&s.length!=0&&e.push(r+"="+y(s))}return e&&e.join("&")}async sign(t){const e="&key="+await this.helloIboot(),r=[];for(const i in t)r.push(i);r.sort((i,c)=>i.toLowerCase().localeCompare(c.toLowerCase()));const s=[];r.forEach(i=>{let c=t[i];typeof c=="object"&&(c=JSON.stringify(c)),s.push(i+"="+c)});const n=s.join("&"),a=p.md5((n+e).toLocaleUpperCase()),u={params:n,md5:a};return this.logger.debug(u),a}assemblyParameter(t,e){const r=t??{};return r.timestamp=Date.now()+"",r.echostr=v(10),r.version=this.version,r.deviceId=this.deviceId,r.webid=this.websiteId,r.apiKey=this.apiKey,e&&e.length>0&&(r.username=e),r}async assemblyHeader({urlParams:t,token:e}){const r={"Content-Type":"application/x-www-form-urlencoded","Res-Type":"json","Device-Id":this.deviceId,Lang:this.lang,"User-Type":e?.utype.toString()??this.userType.toString(),"User-From":this.userFrom,"Api-Key":this.apiKey};this.websiteId&&this.websiteId.length>0&&(r["Web-Id"]=this.websiteId),this.websiteNo&&this.websiteNo.length>0&&(r["Web-No"]=this.websiteNo),e&&(e.token&&e.token.length>0&&e.username&&e.username.length>0&&(r.Authorization=e.token,r.Username=e.username),e.xcsrf&&(r[e.xcsrf.csrfHeader]=e.xcsrf.csrfToken));const s=B(t),n=await this.sign(s);return r.Sign=n,r}async helloIboot(){const t=process.env.HELLO_URL??"";if(t.length===0)return this.apiKey;const e=this.getApiUrl(t),r={"Content-Type":"application/x-www-form-urlencoded","Res-Type":"json","Api-Key":this.apiKey},s=await fetch(e,{method:"GET",headers:r,credentials:"include",cache:"force-cache"});if(s.ok)return(await s.json()).data;throw new Error("hello iBoot error!")}getApiUrl(t){return`${this.baseUrl}/${t}`}async get({url:t,data:e,token:r}){const s=this.assemblyParameter(e),n=this.convertUrlParameter(s),a=await this.assemblyHeader({urlParams:n,token:r}),u=`${this.getApiUrl(t)}?${n.toString()}`,i={method:"GET",url:u,headers:a};this.logger.info(i);try{const c=await fetch(u,{method:"GET",headers:a,credentials:"include",cache:"force-cache"});return c.ok?await c.json():{code:c.status,success:!1,msg:c.statusText}}catch(c){return{code:500,success:!1,msg:c?.toString()??"Server exception!"}}}async csrf(){const t=await this.get({url:"guest/csrf"});if(t.success){const e=t.data;if(e)return e.csrfToken.toString()}}async post({url:t,data:e,token:r}){e=e?{...e}:{};const s=e.buffer??void 0,n=e.boundary??void 0;s&&delete e.buffer,n&&delete e.boundary;const a=this.assemblyParameter(e),u=this.convertUrlParameter(a),i=await this.assemblyHeader({urlParams:u,token:r});s&&n&&(i["Content-Type"]=`multipart/form-data; boundary=${n}`);const c=this.getApiUrl(t),d={method:"POST",url:c,headers:i};this.logger.info(d);try{const g=s?`${c}?${u}`:c,h=await fetch(g,{method:"POST",headers:i,body:s||u.toString(),credentials:"include"});return h.ok?await h.json():{code:h.status,success:!1,msg:h.statusText}}catch(g){return{code:500,success:!1,msg:g?.toString()??"Server exception!"}}}async stream({url:t,data:e,token:r}){e=e?{...e}:{};const s=e.buffer??void 0,n=e.boundary??void 0;s&&delete e.buffer,n&&delete e.boundary;const a=this.assemblyParameter(e),u=this.convertUrlParameter(a),i=await this.assemblyHeader({urlParams:u,token:r});s&&n&&(i["Content-Type"]=`multipart/form-data; boundary=${n}`),i.Connection="keep-alive",i["X-Accel-Buffering"]="no",i["Cache-Control"]="no-cache";const c=this.getApiUrl(t);try{const d=s?`${c}?${u}`:c,g={method:"POST",url:c,headers:i};this.logger.info(g);const h=await fetch(d,{method:"POST",headers:i,body:s||u.toString(),credentials:"include"});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);if(!h.body)throw new Error("No response body");return new Response(h.body,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}catch(d){throw d}}getUserInfo(t){const e=t.get(f.user)?.value;return e&&e.length>0?JSON.parse(e):null}getToken(t){const e=t.get("user")?.value;let r="",s=this.userType;if(e&&e.length>0){const n=JSON.parse(e);r=n.username,s=n.userType.toString()}return{username:r,utype:s,token:t.get(f.token)?.value??""}}getTokenByCookies=t=>{const e=t.get("user")?.value;let r="",s=this.userType;if(e&&e.length>0){const n=JSON.parse(e);r=n.username,s=n.userType.toString()}return{username:r,utype:s,token:t.get(f.token)?.value??""}};setToken(t,e){const{id:r,name:s,username:n,nickname:a,sex:u,headImg:i,token:c,lastLoginTime:d,tokenExpired:g,deviceId:h,userType:_,mustChangePwd:F}=t,Y={id:r,name:s,username:n,nickname:a,sex:u,headImg:i,lastLoginTime:d,tokenExpired:g,deviceId:h,userType:_,status:0,accountType:0,enabled:!1,userFrom:1,needToReview:!1,socketOnline:!1,createTime:"",mustChangePwd:F};return e.cookies.set(f.token,c,{httpOnly:!0,secure:!this._isDebug,sameSite:"strict",path:"/"}),e.cookies.set(f.user,JSON.stringify(Y)),e}cleanToken(t){return t.cookies.set(f.token,"",{maxAge:-1,httpOnly:!0,path:"/"}),t.cookies.set(f.user,"",{maxAge:-1,httpOnly:!0,path:"/"}),t.cookies.delete(f.token),t.cookies.delete(f.user),t}}l.ACCOUNT_TYPE_MAP=U,l.CURRENT_WEBSITE_KEY=b,l.DEFAULT_LOCALE=P,l.DEVICE_ID_KEY=I,l.HttpClient=K,l.USER_FORM_MAP=D,l.USER_SEX_MAP=k,l.USER_TYPE_MAP=O,l.get=R,l.getHttpClientOpts=$,l.getHttpClientOptsByCookie=H,l.iGet=M,l.iPost=j,l.iPostSuccess=W,l.post=w,l.setDefaultRequestHeader=L,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
|
|
2
2
|
//# sourceMappingURL=iboot-http-client.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iboot-http-client.umd.js","sources":["../src/types/user.ts","../src/http-client.ts"],"sourcesContent":["export const ACCOUNT_TYPE_MAP = {\r\n GENERAL : 0,\r\n PHONE : 1,\r\n EMAIL : 2\r\n}\r\n\r\nexport const USER_TYPE_MAP = {\r\n TYPE_MGT : 0,\r\n TYPE_C : 1,\r\n TYPE_B : 2\r\n}\r\n\r\nexport const USER_FORM_MAP = {\r\n FROM_WEB : 1,\r\n FROM_PC : 2,\r\n FROM_WX_MINI_PRO : 3,\r\n FROM_WX_PLU : 4,\r\n FROM_WX_E : 5,\r\n FROM_APP : 6,\r\n FROM_DEVICE : 7\r\n}\r\n\r\nexport const USER_SEX_MAP = {\r\n unknown:0,\r\n male:1,\r\n female:2,\r\n}\r\n\r\nexport type ACCOUNT_TYPE = typeof ACCOUNT_TYPE_MAP[keyof typeof ACCOUNT_TYPE_MAP];\r\nexport type USER_TYPE = typeof USER_TYPE_MAP[keyof typeof USER_TYPE_MAP];\r\nexport type USER_FORM = typeof USER_FORM_MAP[keyof typeof USER_FORM_MAP];\r\nexport type USER_SEX = typeof USER_SEX_MAP[keyof typeof USER_SEX_MAP];\r\n\r\n// User interface\r\nexport interface User {\r\n id: string;\r\n name: string;\r\n username: string;\r\n nickname: string;\r\n sex: USER_SEX;\r\n headImg: string;\r\n lastLoginTime: string;\r\n tokenExpired: string;\r\n deviceId: string;\r\n userType: USER_TYPE;\r\n status: number;\r\n accountType: number;\r\n enabled: boolean;\r\n userFrom: USER_FORM;\r\n needToReview: boolean;\r\n socketOnline: boolean;\r\n createTime: string;\r\n mustChangePwd: boolean;\r\n}","import md5 from \"js-md5\";\r\nimport CryptoJS from 'crypto-js';\r\nimport { isArray, randomString, urlEncode, urlParamToJson } from \"./utils\";\r\nimport pino from \"pino\";\r\nimport { \r\n ClientGetParams, \r\n ClientPostParams, \r\n CookieNames, \r\n CSRFToken, \r\n CurWebsite, \r\n HttpClientOpts, \r\n HttpHeaderNames, \r\n HttpHeaders, \r\n HttpToken, \r\n IbootCookieStore, \r\n IbootReadonlyCookies, \r\n IbootWritableCookie, \r\n ResultModel \r\n} from \"./types/http\";\r\nimport { User, USER_TYPE, USER_TYPE_MAP } from \"./types/user\";\r\n\r\nexport const DEFAULT_LOCALE = 'zh-CN';\r\nexport const DEVICE_ID_KEY = \"_device_id_key\";\r\nexport const CURRENT_WEBSITE_KEY = \"_current_website_key\"\r\n\r\nconst _GET_ERROR = \"Get request error!\"\r\nconst _POST_ERROR = \"Post request error!\";\r\n\r\nconst HEADER_NAMES: Record<HttpHeaderNames, HttpHeaderNames> = {\r\n \"Device-Id\": \"Device-Id\",\r\n \"Lang\": \"Lang\",\r\n \"Website-Id\": \"Website-Id\",\r\n \"Website-No\": \"Website-No\",\r\n}\r\n\r\nconst COOKIE_NAMES: Record<CookieNames, CookieNames> = {\r\n \"IBOOT_DEVICE_ID\": \"IBOOT_DEVICE_ID\",\r\n \"IBOOT_LOCALE\": \"IBOOT_LOCALE\",\r\n \"IBOOT_WEBSITE_ID\": \"IBOOT_WEBSITE_ID\",\r\n \"IBOOT_WEBSITE_NO\": \"IBOOT_WEBSITE_NO\",\r\n \"token\": \"token\",\r\n \"user\": \"user\"\r\n}\r\n\r\nconst getDefaultRequestHeader = (): HttpHeaders => {\r\n const devideId = localStorage.getItem(DEVICE_ID_KEY) ?? ''\r\n const json = localStorage.getItem(CURRENT_WEBSITE_KEY);\r\n const curWebsite: CurWebsite | null = json != null ? JSON.parse(json) : null;\r\n const header: HttpHeaders = {}\r\n if (devideId.length > 0) {\r\n header['Device-Id'] = devideId\r\n }\r\n if (curWebsite) {\r\n header['Lang'] = curWebsite.language;\r\n if (curWebsite.websiteId) {\r\n header['Website-Id'] = curWebsite.websiteId;\r\n }\r\n if (curWebsite.websiteNo) {\r\n header['Website-No'] = curWebsite.websiteNo\r\n }\r\n }\r\n return header;\r\n};\r\n\r\nexport const setDefaultRequestHeader = (deviceId: string, website?: CurWebsite): void => {\r\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\r\n if (website) {\r\n localStorage.setItem(CURRENT_WEBSITE_KEY, JSON.stringify(website));\r\n }\r\n}\r\n\r\nexport const get = async <T>(url: string, opts?: ClientGetParams): Promise<ResultModel<T>> => {\r\n if (opts?.data) {\r\n const params = new URLSearchParams(opts.data);\r\n if (url.indexOf(\"?\") != -1) {\r\n url += `&${params}`\r\n } else {\r\n url += `?${params}`\r\n }\r\n }\r\n const headers: Record<string, string> = getDefaultRequestHeader();\r\n const heads = opts?.heads;\r\n if (heads) {\r\n for (const field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n headers[field] = value;\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: headers,\r\n cache: opts?.useCache ? 'force-cache' : 'default'\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText\r\n }\r\n}\r\n\r\nexport const iGet = async <T>(url: string, opts?: ClientGetParams): Promise<T | undefined> => {\r\n const res = await get<T>(url, opts);\r\n if (res.success) {\r\n return res.data as T;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _GET_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _GET_ERROR)\r\n}\r\n\r\nexport const post = async <T>(url: string, opts?: ClientPostParams): Promise<ResultModel<T>> => {\r\n const data = opts?.data ?? {};\r\n const heads = opts?.heads;\r\n let body: string | FormData;\r\n const proxyHeaders = new Headers(getDefaultRequestHeader());\r\n if (!(data instanceof FormData)) {\r\n body = JSON.stringify(data);\r\n proxyHeaders.set('Content-Type', 'application/json');\r\n } else {\r\n body = data;\r\n }\r\n if (heads) {\r\n for (let field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n proxyHeaders.set(field, value);\r\n }\r\n }\r\n }\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: proxyHeaders,\r\n body: body,\r\n });\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText,\r\n }\r\n}\r\n\r\nexport const iPost = async <T>(url: string, opts?: ClientPostParams): Promise<T | undefined> => {\r\n const res = await post<T>(url, opts);\r\n if (res.success) {\r\n return res.data;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _POST_ERROR)\r\n}\r\n\r\nexport const iPostSuccess = async (url: string, opts?: ClientPostParams): Promise<boolean> => {\r\n const res = await post(url, opts);\r\n if (res.success) {\r\n if (opts?.showSuccess) {\r\n opts.showSuccess(res.msg ?? 'SUCCESS')\r\n }\r\n return true;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport const getHttpClientOpts = (request: Request): HttpClientOpts => {\r\n const deviceId = request.headers.get(HEADER_NAMES[\"Device-Id\"]);\r\n const lang = request.headers.get(HEADER_NAMES.Lang);\r\n const websiteId = request.headers.get(HEADER_NAMES[\"Website-Id\"]);\r\n const websiteNo = request.headers.get(HEADER_NAMES[\"Website-No\"]);\r\n const result: HttpClientOpts = {}\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport const getHttpClientOptsByCookie = (cookie: IbootReadonlyCookies): HttpClientOpts => {\r\n const result: HttpClientOpts = {}\r\n const deviceId = cookie.get(COOKIE_NAMES.IBOOT_DEVICE_ID)?.value;\r\n const lang = cookie.get(COOKIE_NAMES.IBOOT_LOCALE)?.value;\r\n const websiteId = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_ID)?.value;\r\n const websiteNo = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_NO)?.value;\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport default class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly apiKey: string;\r\n private readonly userType: USER_TYPE;\r\n private readonly userFrom: string;\r\n private readonly deviceId: string;\r\n private readonly version: string = '1';\r\n private readonly lang: string;\r\n private readonly websiteId?: string;\r\n private readonly websiteNo?: string;\r\n private readonly _isDebug: boolean;\r\n private readonly logger: pino.Logger;\r\n constructor({ deviceId, lang, websiteId, websiteNo, userType }: Readonly<HttpClientOpts>) {\r\n this.baseUrl = process.env.BASE_URL ?? '';\r\n this.apiKey = process.env.API_KEY ?? '';\r\n this.userType = userType ?? USER_TYPE_MAP.TYPE_MGT;\r\n this.userFrom = process.env.USER_FROM || '1';\r\n this.deviceId = deviceId ?? randomString(10);\r\n this.lang = lang ?? DEFAULT_LOCALE;\r\n this.websiteId = websiteId\r\n this.websiteNo = websiteNo\r\n this._isDebug = process.env.NODE_ENV != 'production';\r\n this.logger = pino({\r\n name: 'iboot',\r\n level: this._isDebug ? 'debug' : 'info',\r\n nestedKey: 'payload'\r\n })\r\n }\r\n\r\n isDebug() {\r\n return this._isDebug;\r\n }\r\n\r\n encrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.encrypt(data, key).toString();\r\n }\r\n\r\n decrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.decrypt(data, key, {\r\n mode: CryptoJS.mode.ECB,\r\n }).toString(CryptoJS.enc.Utf8);\r\n }\r\n\r\n getDeviceId() {\r\n return this.deviceId;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private convertUrlParameter(data: Record<string, any>): string {\r\n const p: string[] = [];\r\n for (const o in data) {\r\n let v = data[o];\r\n if (v && typeof v === \"string\") {\r\n v = v.trim();\r\n } else if (v && typeof v === \"object\") {\r\n if (isArray(v)) {\r\n if (v.length === 0) {\r\n continue;\r\n }\r\n for (let i = 0; i < v.length; i++) {\r\n const arr_item = v[i];\r\n for (const item_field in arr_item) {\r\n const item_field_value = arr_item[item_field] ?? undefined;\r\n if (item_field_value) {\r\n if (typeof item_field_value === \"object\") {\r\n if (isArray(item_field_value)) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n item_field_value.forEach((item1: any, index: number) => {\r\n if (item1) {\r\n for (const f in item1) {\r\n const v = item1[f];\r\n if (v && v.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field + `[${index.toString()}].${f}`}=${urlEncode(v)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } else if (item_field_value.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field}=${urlEncode(item_field_value.toString())}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n for (const obj in v) {\r\n const oValue = v[obj];\r\n if (oValue != null && oValue != \"\" && oValue.length != 0) {\r\n const s = `.${obj}=${urlEncode(oValue)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n continue;\r\n } else if (v && typeof v === \"function\") {\r\n v = null;\r\n }\r\n\r\n if (v != null && v != \"\" && v.length != 0) {\r\n p.push(o + \"=\" + urlEncode(v));\r\n }\r\n }\r\n return (p && p.join(\"&\"));\r\n }\r\n\r\n private async sign(data: Record<string, object | string>): Promise<string> {\r\n //由后台分配\r\n const _apiKey = \"&key=\" + (await this.helloIboot());\r\n const arr: string[] = [];\r\n for (const o in data) {\r\n arr.push(o);\r\n }\r\n arr.sort((a: string, b: string) => {\r\n return a.toLowerCase().localeCompare(b.toLowerCase());\r\n });\r\n const res: string[] = [];\r\n arr.forEach((v: string) => {\r\n let value: object | string = data[v];\r\n if (typeof value === \"object\") {\r\n value = JSON.stringify(value);\r\n }\r\n res.push(v + \"=\" + value);\r\n });\r\n const paramsStr: string = res.join(\"&\");\r\n const str = md5.md5((paramsStr + _apiKey).toLocaleUpperCase());\r\n const logInfo = {\r\n params: paramsStr,\r\n md5: str\r\n }\r\n this.logger.debug(logInfo)\r\n return str;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private assemblyParameter(data?: Record<string, any>, username?: string): Record<string, any> {\r\n const params = data ?? {};\r\n params['timestamp'] = Date.now() + '';\r\n params['echostr'] = randomString(10);\r\n params['version'] = this.version;\r\n params['deviceId'] = this.deviceId;\r\n params['webid'] = this.websiteId;\r\n params['apiKey'] = this.apiKey;\r\n if (username && username.length > 0) {\r\n params['username'] = username;\r\n }\r\n return params;\r\n }\r\n\r\n private async assemblyHeader({ urlParams, token }: Readonly<{ urlParams: string, token?: Readonly<HttpToken> }>) {\r\n const h: Record<string, string> = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Device-Id': this.deviceId,\r\n 'Lang': this.lang,\r\n 'User-Type': token?.utype.toString() ?? this.userType.toString(),\r\n 'User-From': this.userFrom,\r\n 'Api-Key': this.apiKey\r\n }\r\n if (this.websiteId && this.websiteId.length > 0) {\r\n h['Web-Id'] = this.websiteId\r\n }\r\n if (this.websiteNo && this.websiteNo.length > 0) {\r\n h['Web-No'] = this.websiteNo\r\n }\r\n if (token) {\r\n if (token.token && token.token.length > 0 && token.username && token.username.length > 0) {\r\n h['Authorization'] = token.token;\r\n h['Username'] = token.username;\r\n }\r\n if (token.xcsrf) {\r\n h[token.xcsrf.csrfHeader] = token.xcsrf.csrfToken;\r\n }\r\n }\r\n const data = urlParamToJson(urlParams);\r\n const sign = await this.sign(data);\r\n h['Sign'] = sign\r\n return h;\r\n }\r\n\r\n private async helloIboot(): Promise<string> {\r\n const helloUrl = process.env.HELLO_URL ?? '';\r\n if (helloUrl.length === 0) {\r\n return this.apiKey;\r\n }\r\n const api = this.getApiUrl(helloUrl);\r\n const h = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Api-Key': this.apiKey\r\n }\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: h,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result.data;\r\n }\r\n throw new Error('hello iBoot error!')\r\n }\r\n\r\n private getApiUrl(url: string): string {\r\n return `${this.baseUrl}/${url}`;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async get<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n const api = `${this.getApiUrl(url)}?${urlParams.toString()}`\r\n const logInfo = {\r\n \"method\": \"GET\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: headers,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n async csrf(): Promise<string | undefined> {\r\n const res = await this.get<CSRFToken>({\r\n url: 'guest/csrf'\r\n });\r\n if (res.success) {\r\n const data = res.data;\r\n if (data) {\r\n return data[\"csrfToken\"].toString();\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async post<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n const api = this.getApiUrl(url);\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async stream({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<Response> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params); //new URLSearchParams(params);\r\n\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n headers['Connection'] = 'keep-alive';\r\n headers['X-Accel-Buffering'] = 'no'; //防止 Nginx 缓存\r\n headers['Cache-Control'] = 'no-cache';\r\n const api = this.getApiUrl(url)\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers,\r\n\r\n }\r\n this.logger.info(logInfo);\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP error! status: ${res.status}`);\r\n }\r\n if (!res.body) {\r\n throw new Error('No response body');\r\n }\r\n return new Response(res.body, {\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive'\r\n }\r\n });\r\n } catch (e) {\r\n throw e;\r\n }\r\n }\r\n\r\n getUserInfo(cookies: IbootCookieStore): User | null {\r\n const userjson = cookies.get(COOKIE_NAMES.user)?.value;\r\n if (userjson && userjson.length > 0) {\r\n return JSON.parse(userjson);\r\n }\r\n return null;\r\n }\r\n\r\n getToken(cookies: IbootCookieStore): HttpToken {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n getTokenByCookies = (cookies: IbootReadonlyCookies): HttpToken => {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n setToken(data: User & { token: string, extFields: Record<string, any> }, response: { cookies: IbootWritableCookie }) {\r\n const { id, name, username, nickname, sex, headImg, token, lastLoginTime, tokenExpired, deviceId, userType, mustChangePwd } = data;\r\n const loginUser: User = {\r\n id: id,\r\n name: name,\r\n username: username,\r\n nickname: nickname,\r\n sex: sex,\r\n headImg: headImg,\r\n lastLoginTime: lastLoginTime,\r\n tokenExpired: tokenExpired,\r\n deviceId: deviceId,\r\n userType: userType,\r\n status: 0,\r\n accountType: 0,\r\n enabled: false,\r\n userFrom: 1,\r\n needToReview: false,\r\n socketOnline: false,\r\n createTime: \"\",\r\n mustChangePwd: mustChangePwd\r\n };\r\n response.cookies.set(COOKIE_NAMES.token, token, {\r\n httpOnly: true,\r\n secure: !this._isDebug, // 在生产环境中启用Secure\r\n sameSite: 'strict', // 防止 CSRF 攻击\r\n path: '/', // Cookie 的路径\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, JSON.stringify(loginUser));\r\n return response;\r\n }\r\n\r\n cleanToken(response: { cookies: IbootWritableCookie }) {\r\n response.cookies.set(COOKIE_NAMES.token, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.delete(COOKIE_NAMES.token);\r\n response.cookies.delete(COOKIE_NAMES.user)\r\n return response;\r\n }\r\n}"],"names":["ACCOUNT_TYPE_MAP","USER_TYPE_MAP","USER_FORM_MAP","USER_SEX_MAP","DEFAULT_LOCALE","DEVICE_ID_KEY","CURRENT_WEBSITE_KEY","_GET_ERROR","_POST_ERROR","HEADER_NAMES","COOKIE_NAMES","getDefaultRequestHeader","devideId","json","curWebsite","header","setDefaultRequestHeader","deviceId","website","get","url","opts","params","headers","heads","field","value","response","iGet","res","post","data","body","proxyHeaders","iPost","iPostSuccess","getHttpClientOpts","request","lang","websiteId","websiteNo","result","getHttpClientOptsByCookie","cookie"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"iboot-http-client.umd.js","sources":["../src/types/user.ts","../src/utils.ts","../src/http-client.ts"],"sourcesContent":["export const ACCOUNT_TYPE_MAP = {\r\n GENERAL : 0,\r\n PHONE : 1,\r\n EMAIL : 2\r\n}\r\n\r\nexport const USER_TYPE_MAP = {\r\n TYPE_MGT : 0,\r\n TYPE_C : 1,\r\n TYPE_B : 2\r\n}\r\n\r\nexport const USER_FORM_MAP = {\r\n FROM_WEB : 1,\r\n FROM_PC : 2,\r\n FROM_WX_MINI_PRO : 3,\r\n FROM_WX_PLU : 4,\r\n FROM_WX_E : 5,\r\n FROM_APP : 6,\r\n FROM_DEVICE : 7\r\n}\r\n\r\nexport const USER_SEX_MAP = {\r\n unknown:0,\r\n male:1,\r\n female:2,\r\n}\r\n\r\nexport type ACCOUNT_TYPE = typeof ACCOUNT_TYPE_MAP[keyof typeof ACCOUNT_TYPE_MAP];\r\nexport type USER_TYPE = typeof USER_TYPE_MAP[keyof typeof USER_TYPE_MAP];\r\nexport type USER_FORM = typeof USER_FORM_MAP[keyof typeof USER_FORM_MAP];\r\nexport type USER_SEX = typeof USER_SEX_MAP[keyof typeof USER_SEX_MAP];\r\n\r\n// User interface\r\nexport interface User {\r\n id: string;\r\n name: string;\r\n username: string;\r\n nickname: string;\r\n sex: USER_SEX;\r\n headImg: string;\r\n lastLoginTime: string;\r\n tokenExpired: string;\r\n deviceId: string;\r\n userType: USER_TYPE;\r\n status: number;\r\n accountType: number;\r\n enabled: boolean;\r\n userFrom: USER_FORM;\r\n needToReview: boolean;\r\n socketOnline: boolean;\r\n createTime: string;\r\n mustChangePwd: boolean;\r\n}","export const isArray = (obj: unknown) => {\r\n return (\r\n Array.isArray(obj) ||\r\n (typeof obj === \"object\" &&\r\n Object.prototype.toString.call(obj) === \"[object Array]\")\r\n );\r\n};\r\n\r\n/**\r\n * 生成指定长度的随机串\r\n * @param {Object} len\r\n */\r\nexport const randomString = (len: number) => {\r\n const l = len || 32;\r\n const $chars = \"ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678\";\r\n const maxPos = $chars.length;\r\n let pwd = \"\";\r\n for (let i = 0; i < l; i++) {\r\n pwd += $chars.charAt(Math.floor(Math.random() * maxPos));\r\n }\r\n return pwd;\r\n};\r\n\r\nexport const urlParamToJson = (urlQueryParams: string, exclude?: string[]): Record<string, string> => {\r\n const result: Record<string, string> = {};\r\n const strs = urlQueryParams.split(\"&\");\r\n strs.forEach((item) => {\r\n const arr = item.split(\"=\");\r\n if (arr[1]) {\r\n if (!exclude || exclude.indexOf(arr[0]) == -1) {\r\n result[arr[0]] = arr[1];\r\n }\r\n }\r\n });\r\n return result;\r\n};\r\n\r\nexport const urlEncode = (value: string | null | undefined): string => {\r\n if (value == null || value == \"\" || value.length == 0) {\r\n return \"\";\r\n }\r\n return (\r\n encodeURIComponent(value)\r\n // .replace(/%20/g, '+')\r\n // .replace(/%2B/g, '\\\\+')\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\'/g, \"%27\")\r\n .replace(/\\!/g, \"%21\")\r\n .replace(/\\~/g, \"%7E\")\r\n );\r\n};\r\n","import md5 from \"js-md5\";\r\nimport CryptoJS from 'crypto-js';\r\nimport { isArray, randomString, urlEncode, urlParamToJson } from \"./utils\";\r\nimport pino from \"pino\";\r\nimport { \r\n ClientGetParams, \r\n ClientPostParams, \r\n CookieNames, \r\n CSRFToken, \r\n CurWebsite, \r\n HttpClientOpts, \r\n HttpHeaderNames, \r\n HttpHeaders, \r\n HttpToken, \r\n IbootCookieStore, \r\n IbootReadonlyCookies, \r\n IbootWritableCookie, \r\n ResultModel \r\n} from \"./types/http\";\r\nimport { User, USER_TYPE, USER_TYPE_MAP } from \"./types/user\";\r\n\r\nexport const DEFAULT_LOCALE = 'zh-CN';\r\nexport const DEVICE_ID_KEY = \"_device_id_key\";\r\nexport const CURRENT_WEBSITE_KEY = \"_current_website_key\"\r\n\r\nconst _GET_ERROR = \"Get request error!\"\r\nconst _POST_ERROR = \"Post request error!\";\r\n\r\nconst HEADER_NAMES: Record<HttpHeaderNames, HttpHeaderNames> = {\r\n \"Device-Id\": \"Device-Id\",\r\n \"Lang\": \"Lang\",\r\n \"Website-Id\": \"Website-Id\",\r\n \"Website-No\": \"Website-No\",\r\n}\r\n\r\nconst COOKIE_NAMES: Record<CookieNames, CookieNames> = {\r\n \"IBOOT_DEVICE_ID\": \"IBOOT_DEVICE_ID\",\r\n \"IBOOT_LOCALE\": \"IBOOT_LOCALE\",\r\n \"IBOOT_WEBSITE_ID\": \"IBOOT_WEBSITE_ID\",\r\n \"IBOOT_WEBSITE_NO\": \"IBOOT_WEBSITE_NO\",\r\n \"token\": \"token\",\r\n \"user\": \"user\"\r\n}\r\n\r\nconst getDefaultRequestHeader = (): HttpHeaders => {\r\n const devideId = localStorage.getItem(DEVICE_ID_KEY) ?? ''\r\n const json = localStorage.getItem(CURRENT_WEBSITE_KEY);\r\n const curWebsite: CurWebsite | null = json != null ? JSON.parse(json) : null;\r\n const header: HttpHeaders = {}\r\n if (devideId.length > 0) {\r\n header['Device-Id'] = devideId\r\n }\r\n if (curWebsite) {\r\n header['Lang'] = curWebsite.language;\r\n if (curWebsite.websiteId) {\r\n header['Website-Id'] = curWebsite.websiteId;\r\n }\r\n if (curWebsite.websiteNo) {\r\n header['Website-No'] = curWebsite.websiteNo\r\n }\r\n }\r\n return header;\r\n};\r\n\r\nexport const setDefaultRequestHeader = (deviceId: string, website?: CurWebsite): void => {\r\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\r\n if (website) {\r\n localStorage.setItem(CURRENT_WEBSITE_KEY, JSON.stringify(website));\r\n }\r\n}\r\n\r\nexport const get = async <T>(url: string, opts?: ClientGetParams): Promise<ResultModel<T>> => {\r\n if (opts?.data) {\r\n const params = new URLSearchParams(opts.data);\r\n if (url.indexOf(\"?\") != -1) {\r\n url += `&${params}`\r\n } else {\r\n url += `?${params}`\r\n }\r\n }\r\n const headers: Record<string, string> = getDefaultRequestHeader();\r\n const heads = opts?.heads;\r\n if (heads) {\r\n for (const field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n headers[field] = value;\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: headers,\r\n cache: opts?.useCache ? 'force-cache' : 'default'\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText\r\n }\r\n}\r\n\r\nexport const iGet = async <T>(url: string, opts?: ClientGetParams): Promise<T | undefined> => {\r\n const res = await get<T>(url, opts);\r\n if (res.success) {\r\n return res.data as T;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _GET_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _GET_ERROR)\r\n}\r\n\r\nexport const post = async <T>(url: string, opts?: ClientPostParams): Promise<ResultModel<T>> => {\r\n const data = opts?.data ?? {};\r\n const heads = opts?.heads;\r\n let body: string | FormData;\r\n const proxyHeaders = new Headers(getDefaultRequestHeader());\r\n if (!(data instanceof FormData)) {\r\n body = JSON.stringify(data);\r\n proxyHeaders.set('Content-Type', 'application/json');\r\n } else {\r\n body = data;\r\n }\r\n if (heads) {\r\n for (let field in heads) {\r\n const value = heads[field];\r\n if (value) {\r\n proxyHeaders.set(field, value);\r\n }\r\n }\r\n }\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: proxyHeaders,\r\n body: body,\r\n });\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n return {\r\n code: response.status,\r\n success: false,\r\n msg: response.statusText,\r\n }\r\n}\r\n\r\nexport const iPost = async <T>(url: string, opts?: ClientPostParams): Promise<T | undefined> => {\r\n const res = await post<T>(url, opts);\r\n if (res.success) {\r\n return res.data;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n return;\r\n }\r\n throw Error(res.msg ?? _POST_ERROR)\r\n}\r\n\r\nexport const iPostSuccess = async (url: string, opts?: ClientPostParams): Promise<boolean> => {\r\n const res = await post(url, opts);\r\n if (res.success) {\r\n if (opts?.showSuccess) {\r\n opts.showSuccess(res.msg ?? 'SUCCESS')\r\n }\r\n return true;\r\n }\r\n if (opts?.showError) {\r\n opts.showError(res.msg ?? _POST_ERROR);\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport const getHttpClientOpts = (request: Request): HttpClientOpts => {\r\n const deviceId = request.headers.get(HEADER_NAMES[\"Device-Id\"]);\r\n const lang = request.headers.get(HEADER_NAMES.Lang);\r\n const websiteId = request.headers.get(HEADER_NAMES[\"Website-Id\"]);\r\n const websiteNo = request.headers.get(HEADER_NAMES[\"Website-No\"]);\r\n const result: HttpClientOpts = {}\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport const getHttpClientOptsByCookie = (cookie: IbootReadonlyCookies): HttpClientOpts => {\r\n const result: HttpClientOpts = {}\r\n const deviceId = cookie.get(COOKIE_NAMES.IBOOT_DEVICE_ID)?.value;\r\n const lang = cookie.get(COOKIE_NAMES.IBOOT_LOCALE)?.value;\r\n const websiteId = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_ID)?.value;\r\n const websiteNo = cookie.get(COOKIE_NAMES.IBOOT_WEBSITE_NO)?.value;\r\n if (deviceId && deviceId.length > 0) {\r\n result.deviceId = deviceId;\r\n }\r\n if (lang && lang.length > 0) {\r\n result.lang = lang\r\n }\r\n if (websiteId && websiteId.length > 0) {\r\n result.websiteId = websiteId\r\n }\r\n if (websiteNo && websiteNo.length > 0) {\r\n result.websiteNo = websiteNo\r\n }\r\n return result;\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly apiKey: string;\r\n private readonly userType: USER_TYPE;\r\n private readonly userFrom: string;\r\n private readonly deviceId: string;\r\n private readonly version: string = '1';\r\n private readonly lang: string;\r\n private readonly websiteId?: string;\r\n private readonly websiteNo?: string;\r\n private readonly _isDebug: boolean;\r\n private readonly logger: pino.Logger;\r\n constructor({ deviceId, lang, websiteId, websiteNo, userType }: Readonly<HttpClientOpts>) {\r\n this.baseUrl = process.env.BASE_URL ?? '';\r\n this.apiKey = process.env.API_KEY ?? '';\r\n this.userType = userType ?? USER_TYPE_MAP.TYPE_MGT;\r\n this.userFrom = process.env.USER_FROM || '1';\r\n this.deviceId = deviceId ?? randomString(10);\r\n this.lang = lang ?? DEFAULT_LOCALE;\r\n this.websiteId = websiteId\r\n this.websiteNo = websiteNo\r\n this._isDebug = process.env.NODE_ENV != 'production';\r\n this.logger = pino({\r\n name: 'iboot',\r\n level: this._isDebug ? 'debug' : 'info',\r\n nestedKey: 'payload'\r\n })\r\n }\r\n\r\n isDebug() {\r\n return this._isDebug;\r\n }\r\n\r\n encrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.encrypt(data, key).toString();\r\n }\r\n\r\n decrypt(data: string) {\r\n const key = CryptoJS.enc.Utf8.parse(this.apiKey);\r\n return CryptoJS.AES.decrypt(data, key, {\r\n mode: CryptoJS.mode.ECB,\r\n }).toString(CryptoJS.enc.Utf8);\r\n }\r\n\r\n getDeviceId() {\r\n return this.deviceId;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private convertUrlParameter(data: Record<string, any>): string {\r\n const p: string[] = [];\r\n for (const o in data) {\r\n let v = data[o];\r\n if (v && typeof v === \"string\") {\r\n v = v.trim();\r\n } else if (v && typeof v === \"object\") {\r\n if (isArray(v)) {\r\n if (v.length === 0) {\r\n continue;\r\n }\r\n for (let i = 0; i < v.length; i++) {\r\n const arr_item = v[i];\r\n for (const item_field in arr_item) {\r\n const item_field_value = arr_item[item_field] ?? undefined;\r\n if (item_field_value) {\r\n if (typeof item_field_value === \"object\") {\r\n if (isArray(item_field_value)) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n item_field_value.forEach((item1: any, index: number) => {\r\n if (item1) {\r\n for (const f in item1) {\r\n const v = item1[f];\r\n if (v && v.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field + `[${index.toString()}].${f}`}=${urlEncode(v)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } else if (item_field_value.toString().length > 0) {\r\n const s = `[${i.toString()}].${item_field}=${urlEncode(item_field_value.toString())}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n for (const obj in v) {\r\n const oValue = v[obj];\r\n if (oValue != null && oValue != \"\" && oValue.length != 0) {\r\n const s = `.${obj}=${urlEncode(oValue)}`;\r\n p.push(o + s);\r\n }\r\n }\r\n }\r\n continue;\r\n } else if (v && typeof v === \"function\") {\r\n v = null;\r\n }\r\n\r\n if (v != null && v != \"\" && v.length != 0) {\r\n p.push(o + \"=\" + urlEncode(v));\r\n }\r\n }\r\n return (p && p.join(\"&\"));\r\n }\r\n\r\n private async sign(data: Record<string, object | string>): Promise<string> {\r\n //由后台分配\r\n const _apiKey = \"&key=\" + (await this.helloIboot());\r\n const arr: string[] = [];\r\n for (const o in data) {\r\n arr.push(o);\r\n }\r\n arr.sort((a: string, b: string) => {\r\n return a.toLowerCase().localeCompare(b.toLowerCase());\r\n });\r\n const res: string[] = [];\r\n arr.forEach((v: string) => {\r\n let value: object | string = data[v];\r\n if (typeof value === \"object\") {\r\n value = JSON.stringify(value);\r\n }\r\n res.push(v + \"=\" + value);\r\n });\r\n const paramsStr: string = res.join(\"&\");\r\n const str = md5.md5((paramsStr + _apiKey).toLocaleUpperCase());\r\n const logInfo = {\r\n params: paramsStr,\r\n md5: str\r\n }\r\n this.logger.debug(logInfo)\r\n return str;\r\n }\r\n\r\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private assemblyParameter(data?: Record<string, any>, username?: string): Record<string, any> {\r\n const params = data ?? {};\r\n params['timestamp'] = Date.now() + '';\r\n params['echostr'] = randomString(10);\r\n params['version'] = this.version;\r\n params['deviceId'] = this.deviceId;\r\n params['webid'] = this.websiteId;\r\n params['apiKey'] = this.apiKey;\r\n if (username && username.length > 0) {\r\n params['username'] = username;\r\n }\r\n return params;\r\n }\r\n\r\n private async assemblyHeader({ urlParams, token }: Readonly<{ urlParams: string, token?: Readonly<HttpToken> }>) {\r\n const h: Record<string, string> = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Device-Id': this.deviceId,\r\n 'Lang': this.lang,\r\n 'User-Type': token?.utype.toString() ?? this.userType.toString(),\r\n 'User-From': this.userFrom,\r\n 'Api-Key': this.apiKey\r\n }\r\n if (this.websiteId && this.websiteId.length > 0) {\r\n h['Web-Id'] = this.websiteId\r\n }\r\n if (this.websiteNo && this.websiteNo.length > 0) {\r\n h['Web-No'] = this.websiteNo\r\n }\r\n if (token) {\r\n if (token.token && token.token.length > 0 && token.username && token.username.length > 0) {\r\n h['Authorization'] = token.token;\r\n h['Username'] = token.username;\r\n }\r\n if (token.xcsrf) {\r\n h[token.xcsrf.csrfHeader] = token.xcsrf.csrfToken;\r\n }\r\n }\r\n const data = urlParamToJson(urlParams);\r\n const sign = await this.sign(data);\r\n h['Sign'] = sign\r\n return h;\r\n }\r\n\r\n private async helloIboot(): Promise<string> {\r\n const helloUrl = process.env.HELLO_URL ?? '';\r\n if (helloUrl.length === 0) {\r\n return this.apiKey;\r\n }\r\n const api = this.getApiUrl(helloUrl);\r\n const h = {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n 'Res-Type': 'json',\r\n 'Api-Key': this.apiKey\r\n }\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: h,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result.data;\r\n }\r\n throw new Error('hello iBoot error!')\r\n }\r\n\r\n private getApiUrl(url: string): string {\r\n return `${this.baseUrl}/${url}`;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async get<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n const api = `${this.getApiUrl(url)}?${urlParams.toString()}`\r\n const logInfo = {\r\n \"method\": \"GET\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const res = await fetch(api, {\r\n method: 'GET',\r\n headers: headers,\r\n credentials: 'include',\r\n cache: 'force-cache'\r\n });\r\n\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n async csrf(): Promise<string | undefined> {\r\n const res = await this.get<CSRFToken>({\r\n url: 'guest/csrf'\r\n });\r\n if (res.success) {\r\n const data = res.data;\r\n if (data) {\r\n return data[\"csrfToken\"].toString();\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async post<T>({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<ResultModel<T>> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params);\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n const api = this.getApiUrl(url);\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers\r\n }\r\n this.logger.info(logInfo);\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n if (res.ok) {\r\n const result = await res.json();\r\n return result;\r\n }\r\n return {\r\n code: res.status,\r\n success: false,\r\n msg: res.statusText\r\n }\r\n } catch (e) {\r\n return {\r\n code: 500,\r\n success: false,\r\n msg: e?.toString() ?? 'Server exception!'\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n async stream({ url, data, token }: Readonly<{ url: string, data?: Record<string, any>, token?: Readonly<HttpToken> }>): Promise<Response> {\r\n data = data ? { ...data } : {}\r\n const buffer = data.buffer ?? undefined;\r\n const boundary = data.boundary ?? undefined;\r\n if (buffer) {\r\n delete data.buffer;\r\n }\r\n if (boundary) {\r\n delete data.boundary;\r\n }\r\n const params = this.assemblyParameter(data);\r\n const urlParams = this.convertUrlParameter(params); //new URLSearchParams(params);\r\n\r\n const headers = await this.assemblyHeader({ \"urlParams\": urlParams, \"token\": token });\r\n if (buffer && boundary) {\r\n headers['Content-Type'] = `multipart/form-data; boundary=${boundary}`;\r\n }\r\n headers['Connection'] = 'keep-alive';\r\n headers['X-Accel-Buffering'] = 'no'; //防止 Nginx 缓存\r\n headers['Cache-Control'] = 'no-cache';\r\n const api = this.getApiUrl(url)\r\n try {\r\n const url = buffer ? `${api}?${urlParams}` : api;\r\n const logInfo = {\r\n \"method\": \"POST\",\r\n \"url\": api,\r\n \"headers\": headers,\r\n\r\n }\r\n this.logger.info(logInfo);\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers: headers,\r\n body: buffer ? buffer : urlParams.toString(),\r\n credentials: 'include'\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP error! status: ${res.status}`);\r\n }\r\n if (!res.body) {\r\n throw new Error('No response body');\r\n }\r\n return new Response(res.body, {\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive'\r\n }\r\n });\r\n } catch (e) {\r\n throw e;\r\n }\r\n }\r\n\r\n getUserInfo(cookies: IbootCookieStore): User | null {\r\n const userjson = cookies.get(COOKIE_NAMES.user)?.value;\r\n if (userjson && userjson.length > 0) {\r\n return JSON.parse(userjson);\r\n }\r\n return null;\r\n }\r\n\r\n getToken(cookies: IbootCookieStore): HttpToken {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n getTokenByCookies = (cookies: IbootReadonlyCookies): HttpToken => {\r\n const userjson = cookies.get('user')?.value;\r\n let username = '';\r\n let utype = this.userType;\r\n if (userjson && userjson.length > 0) {\r\n const user = JSON.parse(userjson);\r\n username = user.username;\r\n utype = user.userType.toString();\r\n }\r\n return {\r\n username: username,\r\n utype: utype,\r\n token: cookies.get(COOKIE_NAMES.token)?.value ?? ''\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n setToken(data: User & { token: string, extFields: Record<string, any> }, response: { cookies: IbootWritableCookie }) {\r\n const { id, name, username, nickname, sex, headImg, token, lastLoginTime, tokenExpired, deviceId, userType, mustChangePwd } = data;\r\n const loginUser: User = {\r\n id: id,\r\n name: name,\r\n username: username,\r\n nickname: nickname,\r\n sex: sex,\r\n headImg: headImg,\r\n lastLoginTime: lastLoginTime,\r\n tokenExpired: tokenExpired,\r\n deviceId: deviceId,\r\n userType: userType,\r\n status: 0,\r\n accountType: 0,\r\n enabled: false,\r\n userFrom: 1,\r\n needToReview: false,\r\n socketOnline: false,\r\n createTime: \"\",\r\n mustChangePwd: mustChangePwd\r\n };\r\n response.cookies.set(COOKIE_NAMES.token, token, {\r\n httpOnly: true,\r\n secure: !this._isDebug, // 在生产环境中启用Secure\r\n sameSite: 'strict', // 防止 CSRF 攻击\r\n path: '/', // Cookie 的路径\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, JSON.stringify(loginUser));\r\n return response;\r\n }\r\n\r\n cleanToken(response: { cookies: IbootWritableCookie }) {\r\n response.cookies.set(COOKIE_NAMES.token, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.set(COOKIE_NAMES.user, '', {\r\n maxAge: -1, //设置为 -1表示立即过期\r\n httpOnly: true,\r\n path: '/',\r\n });\r\n response.cookies.delete(COOKIE_NAMES.token);\r\n response.cookies.delete(COOKIE_NAMES.user)\r\n return response;\r\n }\r\n}"],"names":["ACCOUNT_TYPE_MAP","USER_TYPE_MAP","USER_FORM_MAP","USER_SEX_MAP","isArray","obj","randomString","len","l","$chars","maxPos","pwd","i","urlParamToJson","urlQueryParams","exclude","result","item","arr","urlEncode","value","DEFAULT_LOCALE","DEVICE_ID_KEY","CURRENT_WEBSITE_KEY","_GET_ERROR","_POST_ERROR","HEADER_NAMES","COOKIE_NAMES","getDefaultRequestHeader","devideId","json","curWebsite","header","setDefaultRequestHeader","deviceId","website","get","url","opts","params","headers","heads","field","response","iGet","res","post","data","body","proxyHeaders","iPost","iPostSuccess","getHttpClientOpts","request","lang","websiteId","websiteNo","getHttpClientOptsByCookie","cookie","HttpClient","userType","pino","key","CryptoJS","p","o","v","arr_item","item_field","item_field_value","item1","index","f","s","oValue","_apiKey","a","b","paramsStr","str","md5","logInfo","username","urlParams","token","h","sign","helloUrl","api","e","buffer","boundary","cookies","userjson","utype","user","id","name","nickname","sex","headImg","lastLoginTime","tokenExpired","mustChangePwd","loginUser"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export declare const iPost: <T>(url: string, opts?: ClientPostParams) => Promise
|
|
|
11
11
|
export declare const iPostSuccess: (url: string, opts?: ClientPostParams) => Promise<boolean>;
|
|
12
12
|
export declare const getHttpClientOpts: (request: Request) => HttpClientOpts;
|
|
13
13
|
export declare const getHttpClientOptsByCookie: (cookie: IbootReadonlyCookies) => HttpClientOpts;
|
|
14
|
-
export
|
|
14
|
+
export declare class HttpClient {
|
|
15
15
|
private readonly baseUrl;
|
|
16
16
|
private readonly apiKey;
|
|
17
17
|
private readonly userType;
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iboot-http-client",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
5
|
-
"description": "iBoot
|
|
4
|
+
"version": "1.0.3",
|
|
5
|
+
"description": "iBoot.xin 相关应用的客户端Http封装",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/iboot-http-client.cjs.js",
|
|
8
8
|
"module": "./dist/iboot-http-client.es.js",
|
|
9
9
|
"browser": "./dist/iboot-http-client.umd.js",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
+
"types": "./dist/types/index.d.ts",
|
|
12
13
|
"import": "./dist/iboot-http-client.es.js",
|
|
13
14
|
"require": "./dist/iboot-http-client.cjs.js",
|
|
14
15
|
"default": "./dist/iboot-http-client.es.js"
|