UNPKG

rentdynamics

Version:

Package to help facilitate communicating with the Rent Dynamics API

1 lines 5.79 kB
var RentDynamics;(()=>{"use strict";var e,t={d:(e,s)=>{for(var r in s)t.o(s,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:s[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},s={};t.r(s),t.d(s,{BASE_URL:()=>e,Client:()=>r,ClientHelpers:()=>n,ClientOptions:()=>o,ProofOfPossession:()=>i,decodePayload:()=>h,encodeSegment:()=>c});class r{constructor(e){this.helpers=new n(e)}async get(e){const t=this.helpers.baseUrl+e,s=await this.helpers.getHeaders(e,void 0,this.authToken);return fetch(t.replace(/\|/g,"%7C"),{method:"GET",headers:Object.assign(Object.assign({},s),{"Content-Type":"application/json"})})}async put(e,t){const s=this.helpers.baseUrl+e,r=await this.helpers.getHeaders(e,t,this.authToken);return fetch(s,{method:"PUT",headers:Object.assign(Object.assign({},r),{"Content-Type":"application/json"}),body:JSON.stringify(t)})}async post(e,t){const s=this.helpers.baseUrl+e,r=await this.helpers.getHeaders(e,t,this.authToken);return fetch(s,{method:"POST",headers:Object.assign(Object.assign({},r),{"Content-Type":"application/json"}),body:JSON.stringify(t)})}async delete(e){const t=this.helpers.baseUrl+e,s=await this.helpers.getHeaders(e,void 0,this.authToken);return fetch(t,{method:"DELETE",headers:Object.assign(Object.assign({},s),{"Content-Type":"application/json"})})}async login(e,t){const s=await this.helpers.encryptPassword(t),r=await this.post("/auth/login",{username:e,password:s});if(!r.ok)return r;const{token:o}=await r.json();return this.authToken=o,r}async logout(){const e=await this.post("/auth/logout",{authToken:this.authToken});return e.ok?(this.authToken=void 0,e):e}}!function(e){e.DEV_RD="https://api.rentdynamics.dev",e.PROD_RD="https://api.rentdynamics.com",e.DEV_RP="https://api.rentplus.dev",e.PROD_RP="https://api.rentplus.com"}(e||(e={}));class o{constructor(){this.baseUrl=e.DEV_RD,this.getEncoder=async()=>new TextEncoder,this.getCryptographer=async()=>crypto.subtle}}class n{constructor(e){this.options=e}get baseUrl(){return this.options.baseUrl}getTimestamp(){return Date.now()}async getHeaders(e,t,s){const r={};if(this.options.apiKey&&this.options.apiSecretKey){t&&Object.keys(t).length||(t=void 0),void 0!==t&&(t=JSON.stringify(this.formatPayload(t)));const o=this.getTimestamp(),n=await this.getNonce(o,e,t);return s&&(r.Authorization="TOKEN "+s),r["x-rd-api-key"]=this.options.apiKey,r["x-rd-api-nonce"]=n,r["x-rd-timestamp"]=o.toString(),r}return r}formatPayload(e){let t={};return null==e?t=null:e!==Object(e)?t=e:Array.isArray(e)?(t=[],e.forEach(((s,r)=>{t[r]=this.formatPayload(e[r])}))):Object.keys(e).sort().forEach((s=>{"object"==typeof e[s]?t[s]=this.formatPayload(e[s]):"string"==typeof e[s]?t[s]=e[s].replace(/ /g,""):t[s]=e[s]})),t}async getNonce(e,t,s){if(!this.options.apiSecretKey)return Promise.resolve("");const r=encodeURI(t).replace(/%7[Cc]/g,"|").replace(/%20/g," "),o=void 0!==s?e+r+s:e+r,n=await this.options.getCryptographer(),i=await this.options.getEncoder(),c=i.encode(this.options.apiSecretKey),h=i.encode(o),p={name:"HMAC",hash:"SHA-1"},y=await n.importKey("raw",c,p,!1,["sign"]),d=await n.sign(p.name,y,h);return a(d)}async encryptPassword(e){const t=await this.options.getCryptographer(),s=(await this.options.getEncoder()).encode(e),r=await t.digest("SHA-1",s);return a(r)}}const a=e=>Array.from(new Uint8Array(e)).map((e=>e.toString(16).padStart(2,"0"))).join("");class i{constructor(e){this._encoder=new TextEncoder,this._keyStoreName="keys",this._keyKey=1,this._dbName="rdb",this._dbVersion=2,this._algorithm={name:"RSA-PSS",modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:"SHA-256",saltLength:32},this.indexedDB=e}async generateProof(){const e=await this._getOrCreateKey(),t=this._getHeader(),s=this._getPayload(),r=this._encoder.encode(`${t}.${s}`),o=await crypto.subtle.sign(this._algorithm,e.privateKey,r);return`${t}.${s}.${c(String.fromCharCode(...new Uint8Array(o)))}`}async getPublicKey(){const e=await this._getOrCreateKey(),t=await crypto.subtle.exportKey("jwk",e.publicKey);return c(JSON.stringify(t))}evictKeyPair(){return new Promise(((e,t)=>{const s=this.indexedDB.open(this._dbName,this._dbVersion);s.onsuccess=()=>{const r=s.result.transaction(this._keyStoreName,"readwrite").objectStore(this._keyStoreName).delete(this._keyKey);r.onsuccess=e,r.onerror=t},s.onupgradeneeded=this._upgradeDb(s),s.onerror=t}))}_getHeader(){return c(JSON.stringify({typ:"dpop+jwt",alg:"PS256"}))}_getPayload(){const e=Math.floor((new Date).getTime()/1e3);return c(JSON.stringify({iat:e}))}_getOrCreateKey(){return new Promise(((e,t)=>{const s=this.indexedDB.open(this._dbName,this._dbVersion);s.onsuccess=this._onDatabaseOpened(e,t,s),s.onupgradeneeded=this._upgradeDb(s),s.onerror=t}))}_onDatabaseOpened(e,t,s){return()=>{const r=s.result.transaction(this._keyStoreName,"readwrite");r.onerror=t;const o=r.objectStore(this._keyStoreName).get(this._keyKey);o.onerror=t,o.onsuccess=this._onKeyLookup(e,t,s,o)}}_onKeyLookup(e,t,s,r){return async()=>{if(r.result)return e(r.result);const o=await this._createKey(),n=s.result.transaction(this._keyStoreName,"readwrite");n.onerror=t,n.objectStore(this._keyStoreName).put(o,this._keyKey).onsuccess=()=>e(o)}}_upgradeDb(e){return()=>{e.result.objectStoreNames.contains(this._keyStoreName)||e.result.createObjectStore(this._keyStoreName)}}_createKey(){return crypto.subtle.generateKey(this._algorithm,!1,["sign","verify"])}}const c=e=>btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,""),h=e=>{const[,t]=e.split("."),s=t.length%4==0?"":"=".repeat(4-t.length%4);return JSON.parse(atob(`${t.replace(/-/g,"+").replace(/_/g,"/")}${s}`))};RentDynamics=s})();