@ubuilder/auth
Version:
UBuilder Auth
2 lines (1 loc) • 4.45 kB
JavaScript
import{Rest as e}from"@ubuilder/rest";export{Rest}from"@ubuilder/rest";import{getCurrentInstance as t,inject as r,watch as s,version as i,reactive as n}from"vue";function o(e){return void 0===e||this.authorities.includes(e)}const a={token:"",authorities:[],expireAt:Number.MAX_SAFE_INTEGER,sessionExpireAt:Number.MAX_SAFE_INTEGER,details:{},isLoggedIn:!1,hasAuthority:o},h=new Error("@ubuilder/auth module not registered");function u(){return Promise.reject(h)}const c={initialized:()=>Promise.resolve(),login:u,logout:u,changePassword:u,currentUser:()=>a,rest:()=>new e,refreshToken:u},l={};function g(e=""){return null===t()?l[e]??c:r(`${e}auth`,c)}function p(e){return g(e).rest()}function d(e=""){return null===t()?g(e).currentUser():r(`${e}user`,a)}function f(e,t){s(d(t),(t=>{e(t)}))}function m(e){return{...e,isLoggedIn:""!==e.token,hasAuthority:o}}function P(e){return null===e?a:m(JSON.parse(e))}function R(e,t){e.isLoggedIn?localStorage.setItem(t,JSON.stringify(e)):localStorage.removeItem(t)}class y{authRest;apiRest;storageKey;onUserChanged;current;intializePromise;refreshPromise=null;constructor(t){this.current=n({...a}),this.authRest=new e({baseURL:t.baseURL});const r=[...t.restOptions?.interceptors??[]];r.unshift({onRequest:e=>this.apiOnRequest(e)}),this.apiRest=new e({baseURL:t.apiURL,...t.restOptions,interceptors:r}),this.onUserChanged=t.onUserChanged,this.storageKey=t.storageKey;const s=P(localStorage.getItem(this.storageKey));this.assignUser(s),s.isLoggedIn?this.intializePromise=this.refresh(s.token).catch((()=>{})).then((()=>Promise.resolve())):this.intializePromise=Promise.resolve()}initialized(){return this.intializePromise}assignUser(e,t=!1){Object.assign(this.current,e),t&&this.onUserChanged?.(e)}parseAuthResponse=e=>e.ok?e.json().then((e=>{const t=Date.now(),r=m({token:e.token,authorities:e.authorities,expireAt:t+1e3*e.expire,sessionExpireAt:t+1e3*(e.sessionExpire??e.expire),details:e.details});return this.assignUser(r,!0),R(r,this.storageKey),this.current})):(""!==this.current.token&&this.processLogout(),Promise.reject(new Error(`${e.status} ${e.statusText}`)));processLogout(){this.assignUser(a,!0),R(a,this.storageKey)}apiOnRequest(e){return this.initialized().then((()=>{const t=this.current;return t.isLoggedIn?e.then((e=>{const r=new Headers(e.headers);return(function(e){return e.expireAt<Date.now()}(t)?this.refresh(t.token):Promise.resolve(t)).then((t=>(r.set("Authorization",`Bearer ${t.token}`),{...e,credentials:"include",headers:r})))})):e}))}login(e,t,r){const s=JSON.stringify(void 0===t?e:{username:e,password:t,remember:!0===r});return this.authRest.fetch("/login",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:s}).then(this.parseAuthResponse)}authPost(e,t){return this.authRest.fetch(e,{method:"POST",credentials:"include",headers:{Authorization:`Bearer ${t}`}})}logout(){return this.authPost("/logout",this.current.token).then((()=>this.processLogout()))}refresh(e){const t=this.refreshPromise;return null!==t?t:(this.refreshPromise=this.authPost("/refresh",e).then(this.parseAuthResponse).catch((e=>(e instanceof TypeError||this.processLogout(),Promise.reject(e)))).finally((()=>{this.refreshPromise=null})),this.refreshPromise)}changePassword(e,t){return this.authRest.fetch("/change-password",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.current.token}`},body:JSON.stringify({oldPassword:e,newPassword:t})}).then((()=>this.processLogout()))}currentUser(){return this.current}rest(){return this.apiRest}refreshToken(){return this.refresh(this.current.token).then((()=>Promise.resolve()))}}const U={install(e,t){const r=t?.storageKey??"ubuilder:user",s=t?.authPrefix??"",n=new y({baseURL:t?.baseURL??"/api/auth",apiURL:t?.apiURL??"/",storageKey:r,restOptions:t?.restOptions,onUserChanged:t?.onUserChanged});l[s]=n;const o=`${s}auth`,h=`${s}rest`,u=`${s}user`,c=n.rest(),g=n.currentUser();i.startsWith("3")?(e.config.globalProperties[o]=n,e.config.globalProperties[h]=c,e.config.globalProperties[u]=g,e.provide(o,n),e.provide(h,c),e.provide(u,g)):(e.prototype.$auth=n,e.prototype.$rest=c,e.prototype.$user=g,e.mixin({provide:{[o]:n,[h]:c,[u]:g}})),window.addEventListener("storage",(e=>{e.storageArea===localStorage&&(null!==e.key?e.key===r&&n.assignUser(P(e.newValue),!0):n.assignUser(a,!0))}))}};export{d as currentUser,U as default,f as onUserChanged,g as useAuth,p as useRest};