@jasperoosthoek/zustand-auth-registry 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -293
- package/dist/authConfig.d.ts +25 -20
- package/dist/authStore.d.ts +3 -3
- package/dist/errors.d.ts +39 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/useAuth.d.ts +3 -2
- package/package.json +2 -1
- package/src/authConfig.ts +119 -112
- package/src/authStore.ts +46 -57
- package/src/createAuthRegistry.ts +1 -1
- package/src/errors.ts +104 -0
- package/src/index.ts +2 -1
- package/src/useAuth.ts +181 -101
- package/dist/setupTests.d.ts +0 -1
- package/src/__tests__/authConfig.test.ts +0 -463
- package/src/__tests__/authStore.test.ts +0 -608
- package/src/__tests__/createAuthRegistry.test.ts +0 -202
- package/src/__tests__/testHelpers.ts +0 -92
- package/src/__tests__/testUtils.ts +0 -142
- package/src/__tests__/useAuth.test.ts +0 -975
- package/src/setupTests.ts +0 -46
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r(require("zustand"),require("react"),require("axios")):"function"==typeof define&&define.amd?define(["zustand","react","axios"],r):"object"==typeof exports?exports["@jasperoosthoek/zustand-auth-registry"]=r(require("zustand"),require("react"),require("axios")):e["@jasperoosthoek/zustand-auth-registry"]=r(e.zustand,e.react,e.axios)}(this,(e,r,t)=>(()=>{"use strict";var n={155:e=>{e.exports=r},287:r=>{r.exports=e},742:e=>{e.exports=t}},o={};function s(e){var r=o[e];if(void 0!==r)return r.exports;var t=o[e]={exports:{}};return n[e](t,t.exports,s),t.exports}s.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return s.d(r,{a:r}),r},s.d=(e,r)=>{for(var t in r)s.o(r,t)&&!s.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},s.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};s.r(a),s.d(a,{createAuthRegistry:()=>f,createAuthStore:()=>l,useAuth:()=>y,validateAuthConfig:()=>u});var i=function(){return i=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++)for(var o in r=arguments[t])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e},i.apply(this,arguments)},u=function(e){var r,t;if(!e.axios)throw new Error("AuthConfig: axios instance is required");var n=e.tokenUrl||e.loginUrl;if(!n)throw new Error("AuthConfig: tokenUrl or loginUrl is required");var o=e.revokeUrl,s=e.userInfoUrl||e.getUserUrl,a=function(e){return function(r){if(e.extractTokens)return e.extractTokens(r);if(r.access_token)return{accessToken:e.extractAccessToken?e.extractAccessToken(r):r.access_token,refreshToken:e.extractRefreshToken?e.extractRefreshToken(r):r.refresh_token,expiresAt:e.extractExpiresIn?e.extractExpiresIn(r)?Date.now()+1e3*e.extractExpiresIn(r):void 0:r.expires_in?Date.now()+1e3*r.expires_in:void 0,tokenType:e.extractTokenType?e.extractTokenType(r):r.token_type||"Bearer",scope:e.extractScope?e.extractScope(r):r.scope?r.scope.split(" "):void 0};if(e.extractToken||r.auth_token||r.token)return{accessToken:e.extractToken?e.extractToken(r):r.auth_token||r.token,tokenType:"Bearer"};throw new Error("No valid token found in response. Provide extractTokens, extractToken, or ensure response contains access_token/auth_token field.")}}(e),u={enabled:!0,storage:"undefined"!=typeof window&&window.localStorage?window.localStorage:{},tokenKey:"token",refreshTokenKey:"refresh_token",userKey:"user",expiryKey:"expires_at"};return{axios:e.axios,tokenUrl:n,revokeUrl:o,userInfoUrl:s,loginUrl:e.loginUrl,logoutUrl:e.logoutUrl,getUserUrl:e.getUserUrl,extractTokens:a,extractToken:e.extractToken,formatAuthHeader:e.formatAuthHeader||function(e,r){return void 0===r&&(r="Bearer"),"".concat(r," ").concat(e)},autoRefresh:null===(r=e.autoRefresh)||void 0===r||r,refreshThreshold:null!==(t=e.refreshThreshold)&&void 0!==t?t:3e5,persistence:i(i({},u),e.persistence),onError:e.onError,onLogin:e.onLogin,onLogout:e.onLogout,onTokenRefresh:e.onTokenRefresh}},c=s(287),l=function(e){var r=e.persistence,t=function(){if(!r.enabled)return null;try{var e=r.storage.getItem(r.tokenKey);if(!e)return null;var t=r.storage.getItem(r.refreshTokenKey),n=r.storage.getItem(r.expiryKey),o=n?parseInt(n,10):void 0;return{accessToken:e,refreshToken:t||void 0,expiresAt:o&&!isNaN(o)?o:void 0,tokenType:"Bearer"}}catch(e){return null}}(),n=function(){if(!r.enabled)return null;try{var e=r.storage.getItem(r.userKey);return e?JSON.parse(e):null}catch(e){return null}}(),o=!!(null==t?void 0:t.accessToken),s=(0,c.create)(function(s,a){return{tokens:t,user:n,isAuthenticated:o,setTokens:function(t){a().user;var n,o=!!t.accessToken;if(s({tokens:t,isAuthenticated:o,token:t.accessToken}),r.enabled)try{r.storage.setItem(r.tokenKey,t.accessToken),t.refreshToken?r.storage.setItem(r.refreshTokenKey,t.refreshToken):r.storage.removeItem(r.refreshTokenKey),t.expiresAt?r.storage.setItem(r.expiryKey,t.expiresAt.toString()):r.storage.removeItem(r.expiryKey)}catch(r){null===(n=e.onError)||void 0===n||n.call(e,r)}},setUser:function(t){var n,o=a().tokens,i=!!(null==o?void 0:o.accessToken);if(s({user:t,isAuthenticated:i}),r.enabled)try{r.storage.setItem(r.userKey,JSON.stringify(t))}catch(r){null===(n=e.onError)||void 0===n||n.call(e,r)}},unsetUser:function(){var t;if(s({user:null,tokens:null,isAuthenticated:!1,token:""}),r.enabled)try{r.storage.removeItem(r.tokenKey),r.storage.removeItem(r.refreshTokenKey),r.storage.removeItem(r.userKey),r.storage.removeItem(r.expiryKey)}catch(r){null===(t=e.onError)||void 0===t||t.call(e,r)}},isTokenExpired:function(){var e=a().tokens;return!!(null==e?void 0:e.expiresAt)&&Date.now()>=e.expiresAt},token:(null==t?void 0:t.accessToken)||"",setToken:function(t){var n,o=a().tokens,i=(a().user,{accessToken:t,refreshToken:null==o?void 0:o.refreshToken,expiresAt:null==o?void 0:o.expiresAt,tokenType:(null==o?void 0:o.tokenType)||"Bearer",scope:null==o?void 0:o.scope});if(s({tokens:i,token:t,isAuthenticated:!!t}),r.enabled)try{r.storage.setItem(r.tokenKey,t)}catch(r){null===(n=e.onError)||void 0===n||n.call(e,r)}}}});return Object.assign(s,{config:e})};function f(){var e={};return function(r,t){var n=String(r);if(!e[n]){var o=u(t);e[n]=l(o)}return e[n]}}var k=s(155),d=s(742),h=s.n(d),p=function(e,r,t,n){return new(t||(t=Promise))(function(o,s){function a(e){try{u(n.next(e))}catch(e){s(e)}}function i(e){try{u(n.throw(e))}catch(e){s(e)}}function u(e){var r;e.done?o(e.value):(r=e.value,r instanceof t?r:new t(function(e){e(r)})).then(a,i)}u((n=n.apply(e,r||[])).next())})},v=function(e,r){var t,n,o,s,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(u){return function(i){if(t)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(a=0)),a;)try{if(t=1,n&&(o=2&i[0]?n.return:i[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,i[1])).done)return o;switch(n=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,n=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=r.call(e,a)}catch(e){i=[6,e],n=0}finally{t=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}};function y(e){var r=this,t=e(),n=t.setTokens,o=t.setUser,s=t.unsetUser,a=t.tokens,i=t.user,u=t.isTokenExpired,c=e.config,l=e(),f=(l.setToken,l.token,(0,k.useCallback)(function(){return p(r,void 0,void 0,function(){var e,r,t,o,i;return v(this,function(u){switch(u.label){case 0:if(!(null==a?void 0:a.refreshToken))return[2,!1];u.label=1;case 1:return u.trys.push([1,3,,4]),[4,c.axios.post(c.tokenUrl,{grant_type:"refresh_token",refresh_token:a.refreshToken})];case 2:return e=u.sent(),r=c.extractTokens(e.data),n(r),d(r.accessToken,r.tokenType),null===(o=c.onTokenRefresh)||void 0===o||o.call(c,r),[2,!0];case 3:return t=u.sent(),s(),d(),null===(i=c.onError)||void 0===i||i.call(c,t),[2,!1];case 4:return[2]}})})},[null==a?void 0:a.refreshToken,c,n,s]));(0,k.useEffect)(function(){var e,r;if(null==a?void 0:a.accessToken){if(d(a.accessToken,a.tokenType),u())return void(a.refreshToken&&c.autoRefresh?f():s());if(a.expiresAt&&a.refreshToken&&c.autoRefresh){var t=a.expiresAt-Date.now(),n=Math.max(t-c.refreshThreshold,0),o=setTimeout(function(){f()},n);return function(){return clearTimeout(o)}}try{i||!c.userInfoUrl&&!c.getUserUrl||y()}catch(t){h().isAxiosError(t)&&403===(null===(e=t.response)||void 0===e?void 0:e.status)&&(s(),d()),null===(r=c.onError)||void 0===r||r.call(c,t)}}},[a,i,c.autoRefresh,c.refreshThreshold,c.userInfoUrl,c.getUserUrl,u,f,s]);var d=function(e,r){void 0!==e&&e?c.axios.defaults.headers.common.Authorization=c.formatAuthHeader(e,r):delete c.axios.defaults.headers.common.Authorization},y=function(){return p(r,void 0,void 0,function(){var e,r,t,n;return v(this,function(a){switch(a.label){case 0:if(!(e=c.userInfoUrl||c.getUserUrl))return[2];a.label=1;case 1:return a.trys.push([1,3,,4]),[4,c.axios.get(e)];case 2:return r=a.sent(),o(r.data),[3,4];case 3:return t=a.sent(),s(),d(),null===(n=c.onError)||void 0===n||n.call(c,t),[3,4];case 4:return[2]}})})};return{login:function(e,t){return p(r,void 0,void 0,function(){var r,o,a,u,l;return v(this,function(f){switch(f.label){case 0:return f.trys.push([0,4,,5]),[4,c.axios.post(c.tokenUrl,e)];case 1:return r=f.sent(),o=c.extractTokens(r.data),n(o),d(o.accessToken,o.tokenType),c.userInfoUrl||c.getUserUrl?[4,y()]:[3,3];case 2:f.sent(),f.label=3;case 3:return i&&(null===(u=c.onLogin)||void 0===u||u.call(c,i)),null==t||t(),[3,5];case 4:return a=f.sent(),s(),d(),null===(l=c.onError)||void 0===l||l.call(c,a),[3,5];case 5:return[2]}})})},getCurrentUser:y,logout:function(){return p(r,void 0,void 0,function(){var e,r,t,n;return v(this,function(o){switch(o.label){case 0:return o.trys.push([0,5,6,7]),(e=c.revokeUrl||c.logoutUrl)?c.revokeUrl&&(null==a?void 0:a.refreshToken)?[4,c.axios.post(e,{token:a.refreshToken,token_type_hint:"refresh_token"})]:[3,2]:[3,4];case 1:return o.sent(),[3,4];case 2:return[4,c.axios.post(e)];case 3:o.sent(),o.label=4;case 4:return[3,7];case 5:return r=o.sent(),null===(t=c.onError)||void 0===t||t.call(c,r),[3,7];case 6:return s(),d(),null===(n=c.onLogout)||void 0===n||n.call(c),[7];case 7:return[2]}})})},refreshTokens:f}}return a})());
|
|
1
|
+
!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r(require("zustand"),require("react")):"function"==typeof define&&define.amd?define(["zustand","react"],r):"object"==typeof exports?exports["@jasperoosthoek/zustand-auth-registry"]=r(require("zustand"),require("react")):e["@jasperoosthoek/zustand-auth-registry"]=r(e.zustand,e.react)}(this,(e,r)=>(()=>{"use strict";var t={155:e=>{e.exports=r},287:r=>{r.exports=e}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,o),i.exports}o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};o.r(i),o.d(i,{AuthError:()=>b,AuthErrorCode:()=>T,createAuthError:()=>A,createAuthRegistry:()=>c,createAuthStore:()=>l,useAuth:()=>p,validateAuthConfig:()=>s});var s=function(e){var r,t,n,o,i,s,a,l,c,d,f,v,h,p,k,y,g,T,E,b,A;if(!e.axios)throw new Error("AuthConfig: axios instance is required");if(!e.loginUrl)throw new Error("AuthConfig: loginUrl is required");var N,x=(null===(r=e.cookieAuth)||void 0===r?void 0:r.enabled)?{enabled:!0,csrf:{enabled:null!==(n=null===(t=e.cookieAuth.csrf)||void 0===t?void 0:t.enabled)&&void 0!==n&&n,headerName:(null===(o=e.cookieAuth.csrf)||void 0===o?void 0:o.headerName)||"X-CSRFToken",cookieName:(null===(i=e.cookieAuth.csrf)||void 0===i?void 0:i.cookieName)||"csrftoken"}}:void 0,m={enabled:null!==(a=null===(s=e.persistence)||void 0===s?void 0:s.enabled)&&void 0!==a&&a,storage:null!==(c=null===(l=e.persistence)||void 0===l?void 0:l.storage)&&void 0!==c?c:"undefined"!=typeof window&&window.localStorage?window.localStorage:{},tokenKey:null!==(f=null===(d=e.persistence)||void 0===d?void 0:d.tokenKey)&&void 0!==f?f:"token",refreshTokenKey:null!==(h=null===(v=e.persistence)||void 0===v?void 0:v.refreshTokenKey)&&void 0!==h?h:"refresh_token",userKey:null!==(k=null===(p=e.persistence)||void 0===p?void 0:p.userKey)&&void 0!==k?k:"user",expiryKey:null!==(g=null===(y=e.persistence)||void 0===y?void 0:y.expiryKey)&&void 0!==g?g:"expires_at"};return{axios:e.axios,loginUrl:e.loginUrl,logoutUrl:e.logoutUrl,refreshUrl:e.refreshUrl,getUserUrl:e.getUserUrl,authCheckUrl:e.authCheckUrl,extractTokens:null!==(T=e.extractTokens)&&void 0!==T?T:u,extractUser:(N=e.extractUser,"string"==typeof N?function(e){var r;return null!==(r=e[N])&&void 0!==r?r:null}:N),formatAuthHeader:null!==(E=e.formatAuthHeader)&&void 0!==E?E:function(e,r){return void 0===r&&(r="Bearer"),"".concat(r," ").concat(e)},autoRefresh:null===(b=e.autoRefresh)||void 0===b||b,refreshThreshold:null!==(A=e.refreshThreshold)&&void 0!==A?A:3e5,cookieAuth:x,persistence:m,onError:e.onError,onLogin:e.onLogin,onLogout:e.onLogout}};function u(e){if(e.access_token)return{accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:e.expires_in?Date.now()+1e3*e.expires_in:void 0,tokenType:e.token_type||"Bearer"};var r=e.token||e.auth_token;if(r)return{accessToken:r,tokenType:"Bearer"};throw new Error("No token found in response. Provide extractTokens or ensure response contains access_token/token field.")}var a=o(287),l=function(e){var r=e.persistence,t=e.cookieAuth,n=function(){if(null==t?void 0:t.enabled)return null;if(!r.enabled)return null;try{var e=r.storage.getItem(r.tokenKey);if(!e)return null;var n=r.storage.getItem(r.refreshTokenKey),o=r.storage.getItem(r.expiryKey),i=o?parseInt(o,10):void 0;return{accessToken:e,refreshToken:n||void 0,expiresAt:i&&!isNaN(i)?i:void 0,tokenType:"Bearer"}}catch(e){return null}}(),o=function(){if(!r.enabled)return null;try{var e=r.storage.getItem(r.userKey);return e?JSON.parse(e):null}catch(e){return null}}(),i=(null==t?void 0:t.enabled)?null:!!(null==n?void 0:n.accessToken),s=(0,a.create)(function(s,u){return{tokens:n,user:o,isAuthenticated:i,setTokens:function(n){var o;if(s({tokens:n,isAuthenticated:!0}),!(null==t?void 0:t.enabled)&&r.enabled)try{r.storage.setItem(r.tokenKey,n.accessToken),n.refreshToken?r.storage.setItem(r.refreshTokenKey,n.refreshToken):r.storage.removeItem(r.refreshTokenKey),n.expiresAt?r.storage.setItem(r.expiryKey,n.expiresAt.toString()):r.storage.removeItem(r.expiryKey)}catch(r){null===(o=e.onError)||void 0===o||o.call(e,r)}},setBearerToken:function(e){u().setTokens({accessToken:e,tokenType:"Bearer"})},setAuthenticated:function(e){s({isAuthenticated:e})},setUser:function(t){var n;if(s({user:t}),r.enabled)try{r.storage.setItem(r.userKey,JSON.stringify(t))}catch(r){null===(n=e.onError)||void 0===n||n.call(e,r)}},unsetUser:function(){var t;if(s({user:null,tokens:null,isAuthenticated:!1}),r.enabled)try{r.storage.removeItem(r.tokenKey),r.storage.removeItem(r.refreshTokenKey),r.storage.removeItem(r.userKey),r.storage.removeItem(r.expiryKey)}catch(r){null===(t=e.onError)||void 0===t||t.call(e,r)}},isTokenExpired:function(){var e=u().tokens;return!!(null==e?void 0:e.expiresAt)&&Date.now()>=e.expiresAt}}});return Object.assign(s,{config:e})};function c(){var e={};return function(r,t){var n=String(r);if(!e[n]){var o=s(t);e[n]=l(o)}return e[n]}}var d=o(155),f=function(e,r,t,n){return new(t||(t=Promise))(function(o,i){function s(e){try{a(n.next(e))}catch(e){i(e)}}function u(e){try{a(n.throw(e))}catch(e){i(e)}}function a(e){var r;e.done?o(e.value):(r=e.value,r instanceof t?r:new t(function(e){e(r)})).then(s,u)}a((n=n.apply(e,r||[])).next())})},v=function(e,r){var t,n,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(u){return function(a){return function(u){if(t)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(s=0)),s;)try{if(t=1,n&&(o=2&u[0]?n.return:u[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,u[1])).done)return o;switch(n=0,o&&(u=[2&u[0],o.value]),u[0]){case 0:case 1:o=u;break;case 4:return s.label++,{value:u[1],done:!1};case 5:s.label++,n=u[1],u=[0];continue;case 7:u=s.ops.pop(),s.trys.pop();continue;default:if(!((o=(o=s.trys).length>0&&o[o.length-1])||6!==u[0]&&2!==u[0])){s=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){s.label=u[1];break}if(6===u[0]&&s.label<o[1]){s.label=o[1],o=u;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(u);break}o[2]&&s.ops.pop(),s.trys.pop();continue}u=r.call(e,s)}catch(e){u=[6,e],n=0}finally{t=o=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,a])}}},h=new WeakMap;function p(e){var r=this,t=e(),n=t.setTokens,o=t.setAuthenticated,i=t.setUser,s=t.unsetUser,u=t.tokens,a=t.user,l=t.isAuthenticated,c=t.isTokenExpired,p=e.config,g=(0,d.useCallback)(function(e,r){var t;if(null===(t=p.cookieAuth)||void 0===t?void 0:t.enabled){if(p.cookieAuth.csrf.enabled){var n=k(p.cookieAuth.csrf.cookieName);n&&(p.axios.defaults.headers.common[p.cookieAuth.csrf.headerName]=n)}}else e?p.axios.defaults.headers.common.Authorization=p.formatAuthHeader(e,r):delete p.axios.defaults.headers.common.Authorization},[p]),T=(0,d.useCallback)(function(){return f(r,void 0,void 0,function(){var e,r,t,o,i,a;return v(this,function(l){switch(l.label){case 0:if(!p.refreshUrl)return[2,!1];l.label=1;case 1:return l.trys.push([1,5,,6]),(null===(i=p.cookieAuth)||void 0===i?void 0:i.enabled)?(e=y(p),[4,p.axios.post(p.refreshUrl,{},{headers:e})]):[3,3];case 2:return l.sent(),[2,!0];case 3:return(null==u?void 0:u.refreshToken)?[4,p.axios.post(p.refreshUrl,{refresh_token:u.refreshToken})]:[2,!1];case 4:return r=l.sent(),t=p.extractTokens(r.data),n(t),g(t.accessToken,t.tokenType),[2,!0];case 5:return o=l.sent(),s(),g(),null===(a=p.onError)||void 0===a||a.call(p,o),[2,!1];case 6:return[2]}})})},[u,p,n,s,g]),E=(0,d.useCallback)(function(){return f(r,void 0,void 0,function(){var r,t,n,s,u,a=this;return v(this,function(l){return r=p.authCheckUrl,(null===(u=p.cookieAuth)||void 0===u?void 0:u.enabled)&&r?(t=h.get(e))?[2,t]:(n=function(){return f(a,void 0,void 0,function(){var t,n,s,u,a,l;return v(this,function(c){switch(c.label){case 0:return c.trys.push([0,6,7,8]),t=y(p),[4,p.axios.get(r,{headers:t})];case 1:return(n=c.sent()).data.authenticated?(o(!0),(s=null===(a=p.extractUser)||void 0===a?void 0:a.call(p,n.data))?(i(s),[3,4]):[3,2]):[3,5];case 2:return p.getUserUrl?[4,b()]:[3,4];case 3:c.sent(),c.label=4;case 4:return[2,!0];case 5:return o(!1),[2,!1];case 6:return u=c.sent(),o(!1),null===(l=p.onError)||void 0===l||l.call(p,u),[2,!1];case 7:return h.delete(e),[7];case 8:return[2]}})})},s=n(),h.set(e,s),[2,s]):[2,!1]})})},[e,p,o,i]),b=(0,d.useCallback)(function(){return f(r,void 0,void 0,function(){var e,r,t;return v(this,function(n){switch(n.label){case 0:if(!p.getUserUrl)return[2];n.label=1;case 1:return n.trys.push([1,3,,4]),[4,p.axios.get(p.getUserUrl)];case 2:return e=n.sent(),i(e.data),[3,4];case 3:throw r=n.sent(),s(),g(),null===(t=p.onError)||void 0===t||t.call(p,r),r;case 4:return[2]}})})},[p,i,s,g]);return(0,d.useEffect)(function(){var e;if(null===(e=p.cookieAuth)||void 0===e?void 0:e.enabled)null===l&&E();else if(null==u?void 0:u.accessToken){if(g(u.accessToken,u.tokenType),c())return void(u.refreshToken&&p.autoRefresh?T():s());if(u.expiresAt&&u.refreshToken&&p.autoRefresh){var r=u.expiresAt-Date.now(),t=Math.max(r-p.refreshThreshold,0),n=setTimeout(T,t);return function(){return clearTimeout(n)}}!a&&p.getUserUrl&&b().catch(function(){})}},[u,a,l,p,c,T,E,b,g,s]),{login:function(t,u){return f(r,void 0,void 0,function(){var r,a,l,c,d,f,h,k,T,E,A,N;return v(this,function(v){switch(v.label){case 0:return v.trys.push([0,5,,6]),r=(null===(h=p.cookieAuth)||void 0===h?void 0:h.enabled)?y(p):{},[4,p.axios.post(p.loginUrl,t,{headers:r})];case 1:return a=v.sent(),(null===(k=p.cookieAuth)||void 0===k?void 0:k.enabled)?o(!0):(l=p.extractTokens(a.data),n(l),g(l.accessToken,l.tokenType)),(c=null===(T=p.extractUser)||void 0===T?void 0:T.call(p,a.data))?(i(c),null===(E=p.onLogin)||void 0===E||E.call(p,c),[3,4]):[3,2];case 2:return p.getUserUrl?[4,b()]:[3,4];case 3:v.sent(),(d=e.getState().user)&&(null===(A=p.onLogin)||void 0===A||A.call(p,d)),v.label=4;case 4:return null==u||u(),[3,6];case 5:throw f=v.sent(),s(),g(),null===(N=p.onError)||void 0===N||N.call(p,f),f;case 6:return[2]}})})},logout:function(){return f(r,void 0,void 0,function(){var e,r,t,n,o;return v(this,function(i){switch(i.label){case 0:return i.trys.push([0,3,4,5]),p.logoutUrl?(e=(null===(t=p.cookieAuth)||void 0===t?void 0:t.enabled)?y(p):{},[4,p.axios.post(p.logoutUrl,{},{headers:e})]):[3,2];case 1:i.sent(),i.label=2;case 2:return[3,5];case 3:return r=i.sent(),null===(n=p.onError)||void 0===n||n.call(p,r),[3,5];case 4:return s(),g(),null===(o=p.onLogout)||void 0===o||o.call(p),[7];case 5:return[2]}})})},refresh:T,checkAuth:E,getCurrentUser:b}}function k(e){if("undefined"==typeof document)return null;var r=document.cookie.match(new RegExp("(^| )".concat(e,"=([^;]+)")));return r?r[2]:null}function y(e){var r,t,n={};if(null===(t=null===(r=e.cookieAuth)||void 0===r?void 0:r.csrf)||void 0===t?void 0:t.enabled){var o=k(e.cookieAuth.csrf.cookieName);o&&(n[e.cookieAuth.csrf.headerName]=o)}return n}var g,T,E=(g=function(e,r){return g=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,r){e.__proto__=r}||function(e,r){for(var t in r)Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=r[t])},g(e,r)},function(e,r){if("function"!=typeof r&&null!==r)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");function t(){this.constructor=e}g(e,r),e.prototype=null===r?Object.create(r):(t.prototype=r.prototype,new t)});!function(e){e.INVALID_CREDENTIALS="INVALID_CREDENTIALS",e.TOKEN_EXPIRED="TOKEN_EXPIRED",e.TOKEN_INVALID="TOKEN_INVALID",e.REFRESH_FAILED="REFRESH_FAILED",e.NETWORK_ERROR="NETWORK_ERROR",e.USER_NOT_FOUND="USER_NOT_FOUND",e.UNAUTHORIZED="UNAUTHORIZED",e.CSRF_TOKEN_MISSING="CSRF_TOKEN_MISSING",e.FORBIDDEN="FORBIDDEN",e.UNKNOWN="UNKNOWN"}(T||(T={}));var b=function(e){function r(t,n,o){var i=e.call(this,o||t)||this;return i.code=t,i.originalError=n,i.name="AuthError",Error.captureStackTrace&&Error.captureStackTrace(i,r),i}return E(r,e),r.prototype.toJSON=function(){return{code:this.code,message:this.message,name:this.name}},r.isAuthError=function(e){return e instanceof r},r}(Error);function A(e){var r,t,n,o,i,s;if(b.isAuthError(e))return e;if(e.response){var u=e.response.status,a=e.response.data;switch(u){case 401:return(null===(r=null==a?void 0:a.detail)||void 0===r?void 0:r.toLowerCase().includes("expired"))||(null===(t=null==a?void 0:a.message)||void 0===t?void 0:t.toLowerCase().includes("expired"))?new b(T.TOKEN_EXPIRED,e,"Token has expired"):(null===(n=null==a?void 0:a.detail)||void 0===n?void 0:n.toLowerCase().includes("invalid"))||(null===(o=null==a?void 0:a.detail)||void 0===o?void 0:o.toLowerCase().includes("credentials"))?new b(T.INVALID_CREDENTIALS,e,"Invalid credentials"):new b(T.UNAUTHORIZED,e,"Unauthorized");case 403:return(null===(i=null==a?void 0:a.detail)||void 0===i?void 0:i.toLowerCase().includes("csrf"))?new b(T.CSRF_TOKEN_MISSING,e,"CSRF token missing or invalid"):new b(T.FORBIDDEN,e,"Access forbidden");case 404:return(null===(s=null==a?void 0:a.detail)||void 0===s?void 0:s.toLowerCase().includes("user"))?new b(T.USER_NOT_FOUND,e,"User not found"):new b(T.UNKNOWN,e,"Resource not found");default:return new b(T.UNKNOWN,e,"HTTP ".concat(u," error"))}}return e.request?new b(T.NETWORK_ERROR,e,"Network error - no response received"):new b(T.UNKNOWN,e,e.message||"Unknown error")}return i})());
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://@jasperoosthoek/zustand-auth-registry/webpack/universalModuleDefinition","webpack://@jasperoosthoek/zustand-auth-registry/external umd \"react\"","webpack://@jasperoosthoek/zustand-auth-registry/external umd \"zustand\"","webpack://@jasperoosthoek/zustand-auth-registry/external umd \"axios\"","webpack://@jasperoosthoek/zustand-auth-registry/webpack/bootstrap","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/compat get default export","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/define property getters","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/hasOwnProperty shorthand","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/make namespace object","webpack://@jasperoosthoek/zustand-auth-registry/./src/authConfig.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/authStore.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/createAuthRegistry.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/useAuth.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"zustand\"), require(\"react\"), require(\"axios\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"zustand\", \"react\", \"axios\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"@jasperoosthoek/zustand-auth-registry\"] = factory(require(\"zustand\"), require(\"react\"), require(\"axios\"));\n\telse\n\t\troot[\"@jasperoosthoek/zustand-auth-registry\"] = factory(root[\"zustand\"], root[\"react\"], root[\"axios\"]);\n})(this, (__WEBPACK_EXTERNAL_MODULE__287__, __WEBPACK_EXTERNAL_MODULE__155__, __WEBPACK_EXTERNAL_MODULE__742__) => {\nreturn ","module.exports = __WEBPACK_EXTERNAL_MODULE__155__;","module.exports = __WEBPACK_EXTERNAL_MODULE__287__;","module.exports = __WEBPACK_EXTERNAL_MODULE__742__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { AxiosInstance } from 'axios';\n\n// OAuth 2.0 token data structure\nexport type TokenData = {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n tokenType: string;\n scope?: string[];\n};\n\n// Backward compatibility: extract single token vs OAuth token data\nexport type TokenExtractor = (data: any) => string | TokenData;\n\nexport type AuthConfig<U> = {\n axios: AxiosInstance;\n \n // OAuth 2.0 compliant endpoints (new defaults)\n tokenUrl?: string;\n revokeUrl?: string;\n userInfoUrl?: string;\n \n // Backward compatibility: Django-style endpoints\n loginUrl?: string;\n logoutUrl?: string;\n getUserUrl?: string;\n \n // OAuth 2.0 compliant token extraction\n extractTokens?: (data: any) => TokenData;\n extractAccessToken?: (data: any) => string;\n extractRefreshToken?: (data: any) => string | undefined;\n extractExpiresIn?: (data: any) => number | undefined;\n extractTokenType?: (data: any) => string;\n extractScope?: (data: any) => string[] | undefined;\n \n // Backward compatibility: single token extraction\n extractToken?: (data: any) => string;\n \n formatAuthHeader?: (token: string, tokenType?: string) => string;\n \n // OAuth 2.0 features\n autoRefresh?: boolean;\n refreshThreshold?: number; // ms before expiry to refresh\n \n persistence?: {\n enabled?: boolean;\n storage?: Storage;\n tokenKey?: string;\n refreshTokenKey?: string;\n userKey?: string;\n expiryKey?: string;\n };\n \n onError?: (error: any) => void;\n onLogin?: (user: U) => void;\n onLogout?: () => void;\n onTokenRefresh?: (tokens: TokenData) => void;\n};\n\nexport type ValidatedAuthConfig<U> = {\n axios: AxiosInstance;\n \n // Resolved endpoints (OAuth preferred, Django fallback)\n tokenUrl: string;\n revokeUrl?: string;\n userInfoUrl?: string;\n \n // Backward compatibility endpoints\n loginUrl?: string;\n logoutUrl?: string;\n getUserUrl?: string;\n \n // Token extraction functions\n extractTokens: (data: any) => TokenData;\n extractToken?: (data: any) => string;\n \n formatAuthHeader: (token: string, tokenType?: string) => string;\n \n // OAuth features\n autoRefresh: boolean;\n refreshThreshold: number;\n \n persistence: {\n enabled: boolean;\n storage: Storage;\n tokenKey: string;\n refreshTokenKey: string;\n userKey: string;\n expiryKey: string;\n };\n \n onError?: (error: any) => void;\n onLogin?: (user: U) => void;\n onLogout?: () => void;\n onTokenRefresh?: (tokens: TokenData) => void;\n};\n\nexport const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfig<U> => {\n if (!config.axios) {\n throw new Error('AuthConfig: axios instance is required');\n }\n\n // Determine token endpoint (OAuth preferred, Django fallback)\n const tokenUrl = config.tokenUrl || config.loginUrl;\n if (!tokenUrl) {\n throw new Error('AuthConfig: tokenUrl or loginUrl is required');\n }\n\n // Keep revokeUrl and logoutUrl distinct for proper OAuth/legacy behavior\n const revokeUrl = config.revokeUrl;\n\n // Determine user info endpoint\n const userInfoUrl = config.userInfoUrl || config.getUserUrl;\n\n // Create OAuth-compliant token extraction function\n const extractTokens = createTokenExtractor(config);\n\n const defaultPersistence = {\n enabled: true,\n storage: typeof window !== 'undefined' && window.localStorage ? window.localStorage : ({} as Storage),\n tokenKey: 'token',\n refreshTokenKey: 'refresh_token',\n userKey: 'user',\n expiryKey: 'expires_at',\n };\n\n return {\n axios: config.axios,\n tokenUrl,\n revokeUrl,\n userInfoUrl,\n // Backward compatibility\n loginUrl: config.loginUrl,\n logoutUrl: config.logoutUrl,\n getUserUrl: config.getUserUrl,\n extractTokens,\n extractToken: config.extractToken,\n formatAuthHeader: config.formatAuthHeader || ((token: string, tokenType: string = 'Bearer') => `${tokenType} ${token}`),\n autoRefresh: config.autoRefresh ?? true,\n refreshThreshold: config.refreshThreshold ?? 300000, // 5 minutes\n persistence: {\n ...defaultPersistence,\n ...config.persistence,\n },\n onError: config.onError,\n onLogin: config.onLogin,\n onLogout: config.onLogout,\n onTokenRefresh: config.onTokenRefresh,\n };\n};\n\n// Helper function to create OAuth-compliant token extractor with backward compatibility\nfunction createTokenExtractor<U>(config: AuthConfig<U>): (data: any) => TokenData {\n return (data: any): TokenData => {\n // If custom extractTokens function provided, use it\n if (config.extractTokens) {\n return config.extractTokens(data);\n }\n\n // OAuth 2.0 compliant extraction (preferred)\n if (data.access_token) {\n return {\n accessToken: config.extractAccessToken ? config.extractAccessToken(data) : data.access_token,\n refreshToken: config.extractRefreshToken ? config.extractRefreshToken(data) : data.refresh_token,\n expiresAt: config.extractExpiresIn \n ? (config.extractExpiresIn(data) ? Date.now() + (config.extractExpiresIn(data)! * 1000) : undefined)\n : (data.expires_in ? Date.now() + (data.expires_in * 1000) : undefined),\n tokenType: config.extractTokenType ? config.extractTokenType(data) : (data.token_type || 'Bearer'),\n scope: config.extractScope ? config.extractScope(data) : (data.scope ? data.scope.split(' ') : undefined),\n };\n }\n\n // Single token fallback (backward compatibility)\n if (config.extractToken || data.auth_token || data.token) {\n const token = config.extractToken ? config.extractToken(data) : (data.auth_token || data.token);\n return {\n accessToken: token,\n tokenType: 'Bearer', // Standard default\n };\n }\n\n throw new Error('No valid token found in response. Provide extractTokens, extractToken, or ensure response contains access_token/auth_token field.');\n };\n}","import { create, StoreApi, UseBoundStore } from 'zustand';\nimport { ValidatedAuthConfig, TokenData } from './authConfig';\n\nexport type AuthState<U> = {\n isAuthenticated: boolean;\n user: U | null;\n tokens: TokenData | null;\n \n // OAuth 2.0 methods\n setTokens: (tokens: TokenData) => void;\n setUser: (user: U) => void;\n unsetUser: () => void;\n isTokenExpired: () => boolean;\n \n // Backward compatibility\n token: string;\n setToken: (token: string) => void;\n};\n\nexport type AuthStore<U> = UseBoundStore<StoreApi<AuthState<U>>> & {\n config: ValidatedAuthConfig<U>;\n};\n\nexport const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U> => {\n const { persistence } = config;\n \n const getStoredTokens = (): TokenData | null => {\n if (!persistence.enabled) return null;\n try {\n const accessToken = persistence.storage.getItem(persistence.tokenKey);\n if (!accessToken) return null;\n \n const refreshToken = persistence.storage.getItem(persistence.refreshTokenKey);\n const expiryString = persistence.storage.getItem(persistence.expiryKey);\n const expiresAt = expiryString ? parseInt(expiryString, 10) : undefined;\n \n return {\n accessToken,\n refreshToken: refreshToken || undefined,\n expiresAt: expiresAt && !isNaN(expiresAt) ? expiresAt : undefined,\n tokenType: 'Bearer', // Default, will be updated on setTokens\n };\n } catch {\n return null;\n }\n };\n\n const getStoredUser = (): U | null => {\n if (!persistence.enabled) return null;\n try {\n const userString = persistence.storage.getItem(persistence.userKey);\n return userString ? (JSON.parse(userString) as U) : null;\n } catch {\n return null;\n }\n };\n\n const initialTokens = getStoredTokens();\n const initialUser = getStoredUser();\n const initialIsAuthenticated = !!initialTokens?.accessToken;\n\n const store = create<AuthState<U>>((set, get) => ({\n tokens: initialTokens,\n user: initialUser,\n isAuthenticated: initialIsAuthenticated,\n\n // OAuth 2.0 methods\n setTokens: (tokens: TokenData) => {\n const user = get().user;\n const isAuthenticated = !!tokens.accessToken;\n \n set({ tokens, isAuthenticated, token: tokens.accessToken });\n \n if (persistence.enabled) {\n try {\n persistence.storage.setItem(persistence.tokenKey, tokens.accessToken);\n \n if (tokens.refreshToken) {\n persistence.storage.setItem(persistence.refreshTokenKey, tokens.refreshToken);\n } else {\n persistence.storage.removeItem(persistence.refreshTokenKey);\n }\n \n if (tokens.expiresAt) {\n persistence.storage.setItem(persistence.expiryKey, tokens.expiresAt.toString());\n } else {\n persistence.storage.removeItem(persistence.expiryKey);\n }\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n setUser: (user: U) => {\n const tokens = get().tokens;\n const isAuthenticated = !!tokens?.accessToken;\n \n set({ user, isAuthenticated });\n \n if (persistence.enabled) {\n try {\n persistence.storage.setItem(persistence.userKey, JSON.stringify(user));\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n unsetUser: () => {\n set({ user: null, tokens: null, isAuthenticated: false, token: '' });\n \n if (persistence.enabled) {\n try {\n persistence.storage.removeItem(persistence.tokenKey);\n persistence.storage.removeItem(persistence.refreshTokenKey);\n persistence.storage.removeItem(persistence.userKey);\n persistence.storage.removeItem(persistence.expiryKey);\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n isTokenExpired: () => {\n const tokens = get().tokens;\n if (!tokens?.expiresAt) return false; // No expiry info means no expiration\n return Date.now() >= tokens.expiresAt;\n },\n\n // Backward compatibility - computed property\n token: initialTokens?.accessToken || '',\n\n setToken: (token: string) => {\n const currentTokens = get().tokens;\n const user = get().user;\n const newTokens: TokenData = {\n accessToken: token,\n refreshToken: currentTokens?.refreshToken,\n expiresAt: currentTokens?.expiresAt,\n tokenType: currentTokens?.tokenType || 'Bearer', // Standard default\n scope: currentTokens?.scope,\n };\n \n const isAuthenticated = !!token;\n set({ tokens: newTokens, token, isAuthenticated });\n \n // Handle persistence\n if (persistence.enabled) {\n try {\n persistence.storage.setItem(persistence.tokenKey, token);\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n }));\n\n return Object.assign(store, { config });\n};\n","import { AuthConfig, validateAuthConfig } from './authConfig';\nimport { createAuthStore, AuthStore } from './authStore';\n\nexport function createAuthRegistry<AuthModels extends Record<string, any>>() {\n const registry: Record<string, AuthStore<any>> = {};\n\n function getAuthStore<K extends keyof AuthModels>(\n key: K,\n config: AuthConfig<AuthModels[K]>\n ): AuthStore<AuthModels[K]> {\n const stringKey = String(key);\n \n if (!registry[stringKey]) {\n const validatedConfig = validateAuthConfig(config);\n registry[stringKey] = createAuthStore(validatedConfig);\n }\n \n return registry[stringKey];\n }\n\n return getAuthStore;\n}","import { useEffect, useCallback } from 'react';\nimport axios from 'axios';\nimport { AuthStore } from './authStore';\nimport { TokenData } from './authConfig';\n\nexport function useAuth<U>(store: AuthStore<U>) {\n const { setTokens, setUser, unsetUser, tokens, user, isTokenExpired } = store();\n const config = store.config;\n\n // Backward compatibility\n const { setToken, token } = store();\n\n // OAuth 2.0 refresh token functionality\n const refreshTokens = useCallback(async (): Promise<boolean> => {\n if (!tokens?.refreshToken) {\n return false;\n }\n\n try {\n const response = await config.axios.post(config.tokenUrl, {\n grant_type: 'refresh_token',\n refresh_token: tokens.refreshToken,\n });\n\n const newTokens = config.extractTokens(response.data);\n setTokens(newTokens);\n setAxiosAuth(newTokens.accessToken, newTokens.tokenType);\n \n config.onTokenRefresh?.(newTokens);\n return true;\n } catch (error) {\n // Refresh failed, clear tokens\n unsetUser();\n setAxiosAuth();\n config.onError?.(error);\n return false;\n }\n }, [tokens?.refreshToken, config, setTokens, unsetUser]);\n\n // Auto-refresh and authentication setup\n useEffect(() => {\n // Handle current tokens\n if (tokens?.accessToken) {\n // Set axios headers immediately\n setAxiosAuth(tokens.accessToken, tokens.tokenType);\n\n // Check if token is expired or about to expire\n if (isTokenExpired()) {\n // Token is already expired, try to refresh\n if (tokens.refreshToken && config.autoRefresh) {\n refreshTokens();\n } else {\n unsetUser();\n }\n return;\n }\n\n // Set up auto-refresh timer if we have expiry info\n if (tokens.expiresAt && tokens.refreshToken && config.autoRefresh) {\n const timeUntilExpiry = tokens.expiresAt - Date.now();\n const refreshTime = Math.max(timeUntilExpiry - config.refreshThreshold, 0);\n\n const timer = setTimeout(() => {\n refreshTokens();\n }, refreshTime);\n\n return () => clearTimeout(timer);\n }\n\n // Try to get user info if missing\n try {\n if (!user && (config.userInfoUrl || config.getUserUrl)) {\n getCurrentUser();\n }\n } catch (error) {\n if (axios.isAxiosError(error) && error.response?.status === 403) {\n unsetUser();\n setAxiosAuth();\n }\n config.onError?.(error);\n }\n }\n }, [tokens, user, config.autoRefresh, config.refreshThreshold, config.userInfoUrl, config.getUserUrl, isTokenExpired, refreshTokens, unsetUser]);\n\n const setAxiosAuth = (token?: string, tokenType?: string) => {\n if (typeof token !== 'undefined' && token) {\n config.axios.defaults.headers.common['Authorization'] = config.formatAuthHeader(token, tokenType);\n } else {\n delete config.axios.defaults.headers.common['Authorization'];\n }\n };\n\n const login = async (\n credentials: Record<string, string>,\n callback?: () => void\n ) => {\n try {\n const res = await config.axios.post(config.tokenUrl, credentials);\n const tokens = config.extractTokens(res.data);\n setTokens(tokens);\n setAxiosAuth(tokens.accessToken, tokens.tokenType);\n \n if (config.userInfoUrl || config.getUserUrl) {\n await getCurrentUser();\n }\n \n if (user) {\n config.onLogin?.(user);\n }\n callback?.();\n } catch (err) {\n unsetUser();\n setAxiosAuth();\n config.onError?.(err);\n }\n };\n\n const getCurrentUser = async () => {\n const userUrl = config.userInfoUrl || config.getUserUrl;\n if (!userUrl) return;\n try {\n const res = await config.axios.get<U>(userUrl);\n setUser(res.data);\n } catch (err) {\n unsetUser();\n setAxiosAuth();\n config.onError?.(err);\n }\n };\n\n const logout = async () => {\n try {\n // If we have a revoke/logout URL, call it\n const logoutUrl = config.revokeUrl || config.logoutUrl;\n if (logoutUrl) {\n if (config.revokeUrl && tokens?.refreshToken) {\n // OAuth revoke\n await config.axios.post(logoutUrl, {\n token: tokens.refreshToken,\n token_type_hint: 'refresh_token'\n });\n } else {\n // Simple logout\n await config.axios.post(logoutUrl);\n }\n }\n } catch (err) {\n config.onError?.(err);\n } finally {\n unsetUser();\n setAxiosAuth();\n config.onLogout?.();\n }\n };\n\n return { login, getCurrentUser, logout, refreshTokens };\n}"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE__287__","__WEBPACK_EXTERNAL_MODULE__155__","__WEBPACK_EXTERNAL_MODULE__742__","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","validateAuthConfig","config","axios","Error","tokenUrl","loginUrl","revokeUrl","userInfoUrl","getUserUrl","extractTokens","data","access_token","accessToken","extractAccessToken","refreshToken","extractRefreshToken","refresh_token","expiresAt","extractExpiresIn","Date","now","expires_in","tokenType","extractTokenType","token_type","scope","extractScope","split","extractToken","auth_token","token","createTokenExtractor","defaultPersistence","enabled","storage","window","localStorage","tokenKey","refreshTokenKey","userKey","expiryKey","logoutUrl","formatAuthHeader","autoRefresh","refreshThreshold","persistence","onError","onLogin","onLogout","onTokenRefresh","createAuthStore","initialTokens","getItem","expiryString","parseInt","isNaN","getStoredTokens","initialUser","userString","JSON","parse","getStoredUser","initialIsAuthenticated","store","create","set","tokens","user","isAuthenticated","setTokens","setItem","removeItem","toString","error","setUser","stringify","unsetUser","isTokenExpired","setToken","currentTokens","newTokens","assign","createAuthRegistry","registry","stringKey","String","validatedConfig","useAuth","refreshTokens","useCallback","post","grant_type","response","setAxiosAuth","useEffect","timeUntilExpiry","refreshTime","Math","max","setTimeout","clearTimeout","getCurrentUser","status","defaults","headers","common","userUrl","res","login","credentials","callback","logout","token_type_hint"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://@jasperoosthoek/zustand-auth-registry/webpack/universalModuleDefinition","webpack://@jasperoosthoek/zustand-auth-registry/external umd \"react\"","webpack://@jasperoosthoek/zustand-auth-registry/external umd \"zustand\"","webpack://@jasperoosthoek/zustand-auth-registry/webpack/bootstrap","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/define property getters","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/hasOwnProperty shorthand","webpack://@jasperoosthoek/zustand-auth-registry/webpack/runtime/make namespace object","webpack://@jasperoosthoek/zustand-auth-registry/./src/authConfig.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/authStore.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/createAuthRegistry.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/useAuth.ts","webpack://@jasperoosthoek/zustand-auth-registry/./src/errors.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"zustand\"), require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"zustand\", \"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"@jasperoosthoek/zustand-auth-registry\"] = factory(require(\"zustand\"), require(\"react\"));\n\telse\n\t\troot[\"@jasperoosthoek/zustand-auth-registry\"] = factory(root[\"zustand\"], root[\"react\"]);\n})(this, (__WEBPACK_EXTERNAL_MODULE__287__, __WEBPACK_EXTERNAL_MODULE__155__) => {\nreturn ","module.exports = __WEBPACK_EXTERNAL_MODULE__155__;","module.exports = __WEBPACK_EXTERNAL_MODULE__287__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { AxiosInstance } from 'axios';\n\n// Token data structure\nexport type TokenData = {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n tokenType: string;\n};\n\nexport type AuthConfig<U> = {\n axios: AxiosInstance;\n\n // Endpoints\n loginUrl: string;\n logoutUrl?: string;\n refreshUrl?: string;\n getUserUrl?: string;\n authCheckUrl?: string; // For cookie auth verification\n\n // Token extraction from login response\n extractTokens?: (data: any) => TokenData;\n\n // User extraction from responses (login, checkAuth)\n // Can be a function or a string key (e.g., \"user\" extracts data.user)\n extractUser?: ((data: any) => U | null) | string;\n\n // Auth header format (default: \"Bearer {token}\")\n formatAuthHeader?: (token: string, tokenType?: string) => string;\n\n // Auto-refresh settings\n autoRefresh?: boolean;\n refreshThreshold?: number; // ms before expiry to refresh (default: 5 min)\n\n // Cookie-based authentication (alternative to localStorage)\n cookieAuth?: {\n enabled: boolean;\n csrf?: {\n enabled: boolean;\n headerName?: string; // Default: 'X-CSRFToken'\n cookieName?: string; // Default: 'csrftoken'\n };\n };\n\n // Token persistence (localStorage)\n persistence?: {\n enabled: boolean;\n storage?: Storage;\n tokenKey?: string;\n refreshTokenKey?: string;\n userKey?: string;\n expiryKey?: string;\n };\n\n // Callbacks\n onError?: (error: any) => void;\n onLogin?: (user: U) => void;\n onLogout?: () => void;\n};\n\nexport type ValidatedAuthConfig<U> = {\n axios: AxiosInstance;\n\n // Endpoints\n loginUrl: string;\n logoutUrl?: string;\n refreshUrl?: string;\n getUserUrl?: string;\n authCheckUrl?: string;\n\n // Extraction functions\n extractTokens: (data: any) => TokenData;\n extractUser?: (data: any) => U | null;\n\n // Auth header format\n formatAuthHeader: (token: string, tokenType?: string) => string;\n\n // Auto-refresh\n autoRefresh: boolean;\n refreshThreshold: number;\n\n // Cookie auth\n cookieAuth?: {\n enabled: boolean;\n csrf: {\n enabled: boolean;\n headerName: string;\n cookieName: string;\n };\n };\n\n // Persistence\n persistence: {\n enabled: boolean;\n storage: Storage;\n tokenKey: string;\n refreshTokenKey: string;\n userKey: string;\n expiryKey: string;\n };\n\n // Callbacks\n onError?: (error: any) => void;\n onLogin?: (user: U) => void;\n onLogout?: () => void;\n};\n\nexport const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfig<U> => {\n if (!config.axios) {\n throw new Error('AuthConfig: axios instance is required');\n }\n\n if (!config.loginUrl) {\n throw new Error('AuthConfig: loginUrl is required');\n }\n\n // Cookie auth config\n const cookieAuth = config.cookieAuth?.enabled ? {\n enabled: true,\n csrf: {\n enabled: config.cookieAuth.csrf?.enabled ?? false,\n headerName: config.cookieAuth.csrf?.headerName || 'X-CSRFToken',\n cookieName: config.cookieAuth.csrf?.cookieName || 'csrftoken',\n },\n } : undefined;\n\n // Persistence config (disabled by default)\n const persistence = {\n enabled: config.persistence?.enabled ?? false,\n storage: config.persistence?.storage ??\n (typeof window !== 'undefined' && window.localStorage ? window.localStorage : {} as Storage),\n tokenKey: config.persistence?.tokenKey ?? 'token',\n refreshTokenKey: config.persistence?.refreshTokenKey ?? 'refresh_token',\n userKey: config.persistence?.userKey ?? 'user',\n expiryKey: config.persistence?.expiryKey ?? 'expires_at',\n };\n\n return {\n axios: config.axios,\n loginUrl: config.loginUrl,\n logoutUrl: config.logoutUrl,\n refreshUrl: config.refreshUrl,\n getUserUrl: config.getUserUrl,\n authCheckUrl: config.authCheckUrl,\n extractTokens: config.extractTokens ?? defaultExtractTokens,\n extractUser: normalizeExtractUser(config.extractUser),\n formatAuthHeader: config.formatAuthHeader ??\n ((token: string, tokenType: string = 'Bearer') => `${tokenType} ${token}`),\n autoRefresh: config.autoRefresh ?? true,\n refreshThreshold: config.refreshThreshold ?? 300000, // 5 minutes\n cookieAuth,\n persistence,\n onError: config.onError,\n onLogin: config.onLogin,\n onLogout: config.onLogout,\n };\n};\n\n// Default token extraction - handles common response formats\nfunction defaultExtractTokens(data: any): TokenData {\n // OAuth 2.0 format: { access_token, refresh_token, expires_in, token_type }\n if (data.access_token) {\n return {\n accessToken: data.access_token,\n refreshToken: data.refresh_token,\n expiresAt: data.expires_in ? Date.now() + (data.expires_in * 1000) : undefined,\n tokenType: data.token_type || 'Bearer',\n };\n }\n\n // Simple format: { token } or { auth_token }\n const token = data.token || data.auth_token;\n if (token) {\n return {\n accessToken: token,\n tokenType: 'Bearer',\n };\n }\n\n throw new Error('No token found in response. Provide extractTokens or ensure response contains access_token/token field.');\n}\n\n// Normalize extractUser: string becomes key accessor, function passed through\nfunction normalizeExtractUser<U>(\n extractUser?: ((data: any) => U | null) | string\n): ((data: any) => U | null) | undefined {\n if (typeof extractUser === 'string') {\n return (data: any) => data[extractUser] ?? null;\n }\n return extractUser;\n}\n","import { create, StoreApi, UseBoundStore } from 'zustand';\nimport { ValidatedAuthConfig, TokenData } from './authConfig';\n\nexport type AuthState<U> = {\n isAuthenticated: boolean | null; // null = not checked yet (cookie mode)\n user: U | null;\n tokens: TokenData | null; // null in cookie mode or when logged out\n\n // Methods\n setTokens: (tokens: TokenData) => void;\n setBearerToken: (token: string) => void; // Convenience for simple Bearer token auth\n setAuthenticated: (authenticated: boolean) => void; // For cookie mode\n setUser: (user: U) => void;\n unsetUser: () => void;\n isTokenExpired: () => boolean;\n};\n\nexport type AuthStore<U> = UseBoundStore<StoreApi<AuthState<U>>> & {\n config: ValidatedAuthConfig<U>;\n};\n\nexport const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U> => {\n const { persistence, cookieAuth } = config;\n\n const getStoredTokens = (): TokenData | null => {\n // Cookie mode: No client-side tokens\n if (cookieAuth?.enabled) {\n return null;\n }\n\n // Token mode: Read from storage\n if (!persistence.enabled) return null;\n try {\n const accessToken = persistence.storage.getItem(persistence.tokenKey);\n if (!accessToken) return null;\n\n const refreshToken = persistence.storage.getItem(persistence.refreshTokenKey);\n const expiryString = persistence.storage.getItem(persistence.expiryKey);\n const expiresAt = expiryString ? parseInt(expiryString, 10) : undefined;\n\n return {\n accessToken,\n refreshToken: refreshToken || undefined,\n expiresAt: expiresAt && !isNaN(expiresAt) ? expiresAt : undefined,\n tokenType: 'Bearer',\n };\n } catch {\n return null;\n }\n };\n\n const getStoredUser = (): U | null => {\n if (!persistence.enabled) return null;\n try {\n const userString = persistence.storage.getItem(persistence.userKey);\n return userString ? (JSON.parse(userString) as U) : null;\n } catch {\n return null;\n }\n };\n\n const initialTokens = getStoredTokens();\n const initialUser = getStoredUser();\n\n // Cookie mode: null (unknown until checkAuth)\n // Token mode: true/false based on token presence\n const initialIsAuthenticated = cookieAuth?.enabled\n ? null\n : !!initialTokens?.accessToken;\n\n const store = create<AuthState<U>>((set, get) => ({\n tokens: initialTokens,\n user: initialUser,\n isAuthenticated: initialIsAuthenticated,\n\n setTokens: (tokens: TokenData) => {\n set({ tokens, isAuthenticated: true });\n\n // Cookie mode: No localStorage persistence for tokens\n if (cookieAuth?.enabled) {\n return;\n }\n\n // Token mode: Persist to storage\n if (persistence.enabled) {\n try {\n persistence.storage.setItem(persistence.tokenKey, tokens.accessToken);\n\n if (tokens.refreshToken) {\n persistence.storage.setItem(persistence.refreshTokenKey, tokens.refreshToken);\n } else {\n persistence.storage.removeItem(persistence.refreshTokenKey);\n }\n\n if (tokens.expiresAt) {\n persistence.storage.setItem(persistence.expiryKey, tokens.expiresAt.toString());\n } else {\n persistence.storage.removeItem(persistence.expiryKey);\n }\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n setBearerToken: (token: string) => {\n get().setTokens({ accessToken: token, tokenType: 'Bearer' });\n },\n\n setAuthenticated: (authenticated: boolean) => {\n set({ isAuthenticated: authenticated });\n },\n\n setUser: (user: U) => {\n set({ user });\n\n if (persistence.enabled) {\n try {\n persistence.storage.setItem(persistence.userKey, JSON.stringify(user));\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n unsetUser: () => {\n set({ user: null, tokens: null, isAuthenticated: false });\n\n if (persistence.enabled) {\n try {\n persistence.storage.removeItem(persistence.tokenKey);\n persistence.storage.removeItem(persistence.refreshTokenKey);\n persistence.storage.removeItem(persistence.userKey);\n persistence.storage.removeItem(persistence.expiryKey);\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n isTokenExpired: () => {\n const tokens = get().tokens;\n if (!tokens?.expiresAt) return false;\n return Date.now() >= tokens.expiresAt;\n },\n }));\n\n return Object.assign(store, { config });\n};\n","import { AuthConfig, validateAuthConfig } from './authConfig';\nimport { createAuthStore, AuthStore } from './authStore';\n\nexport function createAuthRegistry<AuthModels extends Record<string, any>>() {\n const registry: Record<string, AuthStore<any>> = {};\n\n function getAuthStore<K extends keyof AuthModels>(\n key: K,\n config: AuthConfig<AuthModels[K]>\n ): AuthStore<AuthModels[K]> {\n const stringKey = String(key);\n \n if (!registry[stringKey]) {\n const validatedConfig = validateAuthConfig(config);\n registry[stringKey] = createAuthStore(validatedConfig);\n }\n \n return registry[stringKey];\n }\n\n return getAuthStore;\n}\n","import { useEffect, useCallback } from 'react';\nimport { AuthStore } from './authStore';\n\n// Promise deduplication: prevents multiple concurrent checkAuth calls per store\nconst pendingCheckAuth = new WeakMap<AuthStore<any>, Promise<boolean>>();\n\nexport function useAuth<U>(store: AuthStore<U>) {\n const { setTokens, setAuthenticated, setUser, unsetUser, tokens, user, isAuthenticated, isTokenExpired } = store();\n const config = store.config;\n\n // Set axios Authorization header (token mode only)\n const setAxiosAuth = useCallback((token?: string, tokenType?: string) => {\n if (config.cookieAuth?.enabled) {\n // Cookie mode: CSRF header if enabled, no Authorization header\n if (config.cookieAuth.csrf.enabled) {\n const csrfToken = getCookie(config.cookieAuth.csrf.cookieName);\n if (csrfToken) {\n config.axios.defaults.headers.common[config.cookieAuth.csrf.headerName] = csrfToken;\n }\n }\n return;\n }\n\n // Token mode: Set Authorization header\n if (token) {\n config.axios.defaults.headers.common['Authorization'] = config.formatAuthHeader(token, tokenType);\n } else {\n delete config.axios.defaults.headers.common['Authorization'];\n }\n }, [config]);\n\n // Refresh tokens\n const refresh = useCallback(async (): Promise<boolean> => {\n if (!config.refreshUrl) return false;\n\n try {\n // Cookie mode: Just call refresh endpoint, server handles cookie\n if (config.cookieAuth?.enabled) {\n const headers = getCsrfHeaders(config);\n await config.axios.post(config.refreshUrl, {}, { headers });\n return true;\n }\n\n // Token mode: Send refresh token, get new tokens\n if (!tokens?.refreshToken) return false;\n\n const response = await config.axios.post(config.refreshUrl, {\n refresh_token: tokens.refreshToken,\n });\n\n const newTokens = config.extractTokens(response.data);\n setTokens(newTokens);\n setAxiosAuth(newTokens.accessToken, newTokens.tokenType);\n return true;\n } catch (error) {\n unsetUser();\n setAxiosAuth();\n config.onError?.(error);\n return false;\n }\n }, [tokens, config, setTokens, unsetUser, setAxiosAuth]);\n\n // Check authentication (cookie mode) - with promise deduplication\n const checkAuth = useCallback(async (): Promise<boolean> => {\n const authCheckUrl = config.authCheckUrl;\n if (!config.cookieAuth?.enabled || !authCheckUrl) {\n return false;\n }\n\n // Return existing promise if check is already in progress\n const pending = pendingCheckAuth.get(store);\n if (pending) {\n return pending;\n }\n\n const doCheck = async (): Promise<boolean> => {\n try {\n const headers = getCsrfHeaders(config);\n const response = await config.axios.get(authCheckUrl, { headers });\n\n if (response.data.authenticated) {\n setAuthenticated(true);\n\n const extractedUser = config.extractUser?.(response.data);\n if (extractedUser) {\n setUser(extractedUser);\n } else if (config.getUserUrl) {\n await getCurrentUser();\n }\n\n return true;\n }\n\n setAuthenticated(false);\n return false;\n } catch (error) {\n setAuthenticated(false);\n config.onError?.(error);\n return false;\n } finally {\n pendingCheckAuth.delete(store);\n }\n };\n\n const promise = doCheck();\n pendingCheckAuth.set(store, promise);\n return promise;\n }, [store, config, setAuthenticated, setUser]);\n\n // Get current user\n const getCurrentUser = useCallback(async () => {\n if (!config.getUserUrl) return;\n\n try {\n const res = await config.axios.get<U>(config.getUserUrl);\n setUser(res.data);\n } catch (error) {\n unsetUser();\n setAxiosAuth();\n config.onError?.(error);\n throw error;\n }\n }, [config, setUser, unsetUser, setAxiosAuth]);\n\n // Login\n const login = async (credentials: Record<string, string>, callback?: () => void) => {\n try {\n const headers = config.cookieAuth?.enabled ? getCsrfHeaders(config) : {};\n const res = await config.axios.post(config.loginUrl, credentials, { headers });\n\n if (config.cookieAuth?.enabled) {\n // Cookie mode: Server sets httpOnly cookie, just mark as authenticated\n setAuthenticated(true);\n } else {\n // Token mode: Extract and store tokens\n const newTokens = config.extractTokens(res.data);\n setTokens(newTokens);\n setAxiosAuth(newTokens.accessToken, newTokens.tokenType);\n }\n\n // Extract user from response\n const extractedUser = config.extractUser?.(res.data);\n if (extractedUser) {\n setUser(extractedUser);\n config.onLogin?.(extractedUser);\n } else if (config.getUserUrl) {\n await getCurrentUser();\n const currentUser = store.getState().user;\n if (currentUser) config.onLogin?.(currentUser);\n }\n\n callback?.();\n } catch (error) {\n unsetUser();\n setAxiosAuth();\n config.onError?.(error);\n throw error;\n }\n };\n\n // Logout\n const logout = async () => {\n try {\n if (config.logoutUrl) {\n const headers = config.cookieAuth?.enabled ? getCsrfHeaders(config) : {};\n await config.axios.post(config.logoutUrl, {}, { headers });\n }\n } catch (error) {\n config.onError?.(error);\n } finally {\n unsetUser();\n setAxiosAuth();\n config.onLogout?.();\n }\n };\n\n // Auto-setup on mount\n useEffect(() => {\n // Cookie mode: Check authentication if not yet determined\n if (config.cookieAuth?.enabled) {\n if (isAuthenticated === null) {\n checkAuth();\n }\n return;\n }\n\n // Token mode: Setup headers and auto-refresh\n if (tokens?.accessToken) {\n setAxiosAuth(tokens.accessToken, tokens.tokenType);\n\n // Check if expired\n if (isTokenExpired()) {\n if (tokens.refreshToken && config.autoRefresh) {\n refresh();\n } else {\n unsetUser();\n }\n return;\n }\n\n // Setup auto-refresh timer\n if (tokens.expiresAt && tokens.refreshToken && config.autoRefresh) {\n const timeUntilExpiry = tokens.expiresAt - Date.now();\n const refreshTime = Math.max(timeUntilExpiry - config.refreshThreshold, 0);\n\n const timer = setTimeout(refresh, refreshTime);\n return () => clearTimeout(timer);\n }\n\n // Fetch user if missing\n if (!user && config.getUserUrl) {\n getCurrentUser().catch(() => {});\n }\n }\n }, [tokens, user, isAuthenticated, config, isTokenExpired, refresh, checkAuth, getCurrentUser, setAxiosAuth, unsetUser]);\n\n return { login, logout, refresh, checkAuth, getCurrentUser };\n}\n\n// Helper: Get cookie value\nfunction getCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));\n return match ? match[2] : null;\n}\n\n// Helper: Get CSRF headers if enabled\nfunction getCsrfHeaders(config: any): Record<string, string> {\n const headers: Record<string, string> = {};\n if (config.cookieAuth?.csrf?.enabled) {\n const csrfToken = getCookie(config.cookieAuth.csrf.cookieName);\n if (csrfToken) {\n headers[config.cookieAuth.csrf.headerName] = csrfToken;\n }\n }\n return headers;\n}\n","/**\n * Authentication error codes\n */\nexport enum AuthErrorCode {\n INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',\n TOKEN_EXPIRED = 'TOKEN_EXPIRED',\n TOKEN_INVALID = 'TOKEN_INVALID',\n REFRESH_FAILED = 'REFRESH_FAILED',\n NETWORK_ERROR = 'NETWORK_ERROR',\n USER_NOT_FOUND = 'USER_NOT_FOUND',\n UNAUTHORIZED = 'UNAUTHORIZED',\n CSRF_TOKEN_MISSING = 'CSRF_TOKEN_MISSING',\n FORBIDDEN = 'FORBIDDEN',\n UNKNOWN = 'UNKNOWN',\n}\n\n/**\n * Typed authentication error\n */\nexport class AuthError extends Error {\n constructor(\n public code: AuthErrorCode,\n public originalError?: any,\n message?: string\n ) {\n super(message || code);\n this.name = 'AuthError';\n\n // Maintain proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AuthError);\n }\n }\n\n /**\n * Convert error to JSON (excludes originalError in production)\n */\n toJSON() {\n return {\n code: this.code,\n message: this.message,\n name: this.name,\n };\n }\n\n /**\n * Check if error is an AuthError\n */\n static isAuthError(error: any): error is AuthError {\n return error instanceof AuthError;\n }\n}\n\n/**\n * Create typed AuthError from any error\n */\nexport function createAuthError(error: any): AuthError {\n if (AuthError.isAuthError(error)) {\n return error;\n }\n\n // Axios error\n if (error.response) {\n const status = error.response.status;\n const data = error.response.data;\n\n switch (status) {\n case 401:\n // Check if it's an expired token\n if (data?.detail?.toLowerCase().includes('expired') ||\n data?.message?.toLowerCase().includes('expired')) {\n return new AuthError(AuthErrorCode.TOKEN_EXPIRED, error, 'Token has expired');\n }\n if (data?.detail?.toLowerCase().includes('invalid') ||\n data?.detail?.toLowerCase().includes('credentials')) {\n return new AuthError(AuthErrorCode.INVALID_CREDENTIALS, error, 'Invalid credentials');\n }\n return new AuthError(AuthErrorCode.UNAUTHORIZED, error, 'Unauthorized');\n\n case 403:\n if (data?.detail?.toLowerCase().includes('csrf')) {\n return new AuthError(AuthErrorCode.CSRF_TOKEN_MISSING, error, 'CSRF token missing or invalid');\n }\n return new AuthError(AuthErrorCode.FORBIDDEN, error, 'Access forbidden');\n\n case 404:\n if (data?.detail?.toLowerCase().includes('user')) {\n return new AuthError(AuthErrorCode.USER_NOT_FOUND, error, 'User not found');\n }\n return new AuthError(AuthErrorCode.UNKNOWN, error, 'Resource not found');\n\n default:\n return new AuthError(AuthErrorCode.UNKNOWN, error, `HTTP ${status} error`);\n }\n }\n\n // Network error (no response received)\n if (error.request) {\n return new AuthError(AuthErrorCode.NETWORK_ERROR, error, 'Network error - no response received');\n }\n\n // Other errors\n return new AuthError(AuthErrorCode.UNKNOWN, error, error.message || 'Unknown error');\n}\n"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE__287__","__WEBPACK_EXTERNAL_MODULE__155__","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","validateAuthConfig","config","axios","Error","loginUrl","extractUser","cookieAuth","enabled","csrf","headerName","cookieName","persistence","storage","window","localStorage","tokenKey","refreshTokenKey","userKey","expiryKey","logoutUrl","refreshUrl","getUserUrl","authCheckUrl","extractTokens","defaultExtractTokens","data","formatAuthHeader","token","tokenType","autoRefresh","refreshThreshold","onError","onLogin","onLogout","access_token","accessToken","refreshToken","refresh_token","expiresAt","expires_in","Date","now","token_type","auth_token","createAuthStore","initialTokens","getItem","expiryString","parseInt","isNaN","getStoredTokens","initialUser","userString","JSON","parse","getStoredUser","initialIsAuthenticated","store","create","set","tokens","user","isAuthenticated","setTokens","setItem","removeItem","toString","error","setBearerToken","setAuthenticated","authenticated","setUser","stringify","unsetUser","isTokenExpired","assign","createAuthRegistry","registry","stringKey","String","validatedConfig","pendingCheckAuth","WeakMap","useAuth","setAxiosAuth","useCallback","csrfToken","getCookie","defaults","headers","common","refresh","getCsrfHeaders","post","response","newTokens","checkAuth","pending","doCheck","extractedUser","getCurrentUser","delete","promise","res","useEffect","timeUntilExpiry","refreshTime","Math","max","setTimeout","clearTimeout","catch","login","credentials","callback","currentUser","getState","logout","name","document","match","cookie","RegExp","AuthErrorCode","code","originalError","message","captureStackTrace","AuthError","toJSON","isAuthError","createAuthError","status","detail","toLowerCase","includes","TOKEN_EXPIRED","INVALID_CREDENTIALS","UNAUTHORIZED","CSRF_TOKEN_MISSING","FORBIDDEN","USER_NOT_FOUND","UNKNOWN","request","NETWORK_ERROR"],"sourceRoot":""}
|
package/dist/useAuth.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AuthStore } from './authStore';
|
|
2
2
|
export declare function useAuth<U>(store: AuthStore<U>): {
|
|
3
3
|
login: (credentials: Record<string, string>, callback?: () => void) => Promise<void>;
|
|
4
|
-
getCurrentUser: () => Promise<void>;
|
|
5
4
|
logout: () => Promise<void>;
|
|
6
|
-
|
|
5
|
+
refresh: () => Promise<boolean>;
|
|
6
|
+
checkAuth: () => Promise<boolean>;
|
|
7
|
+
getCurrentUser: () => Promise<void>;
|
|
7
8
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jasperoosthoek/zustand-auth-registry",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"author": "jasperoosthoek",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/jasperoosthoek/zustand-auth-registry",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@types/react": "^19.1.8",
|
|
31
31
|
"babel-jest": "^29.7.0",
|
|
32
32
|
"babel-loader": "^8.2.5",
|
|
33
|
+
"baseline-browser-mapping": "^2.9.17",
|
|
33
34
|
"jest": "^29.7.0",
|
|
34
35
|
"jest-environment-jsdom": "^29.7.0",
|
|
35
36
|
"ts-loader": "^9.4.2",
|
package/src/authConfig.ts
CHANGED
|
@@ -1,85 +1,95 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios';
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Token data structure
|
|
4
4
|
export type TokenData = {
|
|
5
5
|
accessToken: string;
|
|
6
6
|
refreshToken?: string;
|
|
7
7
|
expiresAt?: number;
|
|
8
8
|
tokenType: string;
|
|
9
|
-
scope?: string[];
|
|
10
9
|
};
|
|
11
10
|
|
|
12
|
-
// Backward compatibility: extract single token vs OAuth token data
|
|
13
|
-
export type TokenExtractor = (data: any) => string | TokenData;
|
|
14
|
-
|
|
15
11
|
export type AuthConfig<U> = {
|
|
16
12
|
axios: AxiosInstance;
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
revokeUrl?: string;
|
|
21
|
-
userInfoUrl?: string;
|
|
22
|
-
|
|
23
|
-
// Backward compatibility: Django-style endpoints
|
|
24
|
-
loginUrl?: string;
|
|
13
|
+
|
|
14
|
+
// Endpoints
|
|
15
|
+
loginUrl: string;
|
|
25
16
|
logoutUrl?: string;
|
|
17
|
+
refreshUrl?: string;
|
|
26
18
|
getUserUrl?: string;
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
authCheckUrl?: string; // For cookie auth verification
|
|
20
|
+
|
|
21
|
+
// Token extraction from login response
|
|
29
22
|
extractTokens?: (data: any) => TokenData;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Backward compatibility: single token extraction
|
|
37
|
-
extractToken?: (data: any) => string;
|
|
38
|
-
|
|
23
|
+
|
|
24
|
+
// User extraction from responses (login, checkAuth)
|
|
25
|
+
// Can be a function or a string key (e.g., "user" extracts data.user)
|
|
26
|
+
extractUser?: ((data: any) => U | null) | string;
|
|
27
|
+
|
|
28
|
+
// Auth header format (default: "Bearer {token}")
|
|
39
29
|
formatAuthHeader?: (token: string, tokenType?: string) => string;
|
|
40
|
-
|
|
41
|
-
//
|
|
30
|
+
|
|
31
|
+
// Auto-refresh settings
|
|
42
32
|
autoRefresh?: boolean;
|
|
43
|
-
refreshThreshold?: number; // ms before expiry to refresh
|
|
44
|
-
|
|
33
|
+
refreshThreshold?: number; // ms before expiry to refresh (default: 5 min)
|
|
34
|
+
|
|
35
|
+
// Cookie-based authentication (alternative to localStorage)
|
|
36
|
+
cookieAuth?: {
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
csrf?: {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
headerName?: string; // Default: 'X-CSRFToken'
|
|
41
|
+
cookieName?: string; // Default: 'csrftoken'
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Token persistence (localStorage)
|
|
45
46
|
persistence?: {
|
|
46
|
-
enabled
|
|
47
|
+
enabled: boolean;
|
|
47
48
|
storage?: Storage;
|
|
48
49
|
tokenKey?: string;
|
|
49
50
|
refreshTokenKey?: string;
|
|
50
51
|
userKey?: string;
|
|
51
52
|
expiryKey?: string;
|
|
52
53
|
};
|
|
53
|
-
|
|
54
|
+
|
|
55
|
+
// Callbacks
|
|
54
56
|
onError?: (error: any) => void;
|
|
55
57
|
onLogin?: (user: U) => void;
|
|
56
58
|
onLogout?: () => void;
|
|
57
|
-
onTokenRefresh?: (tokens: TokenData) => void;
|
|
58
59
|
};
|
|
59
60
|
|
|
60
61
|
export type ValidatedAuthConfig<U> = {
|
|
61
62
|
axios: AxiosInstance;
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
revokeUrl?: string;
|
|
66
|
-
userInfoUrl?: string;
|
|
67
|
-
|
|
68
|
-
// Backward compatibility endpoints
|
|
69
|
-
loginUrl?: string;
|
|
63
|
+
|
|
64
|
+
// Endpoints
|
|
65
|
+
loginUrl: string;
|
|
70
66
|
logoutUrl?: string;
|
|
67
|
+
refreshUrl?: string;
|
|
71
68
|
getUserUrl?: string;
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
authCheckUrl?: string;
|
|
70
|
+
|
|
71
|
+
// Extraction functions
|
|
74
72
|
extractTokens: (data: any) => TokenData;
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
extractUser?: (data: any) => U | null;
|
|
74
|
+
|
|
75
|
+
// Auth header format
|
|
77
76
|
formatAuthHeader: (token: string, tokenType?: string) => string;
|
|
78
|
-
|
|
79
|
-
//
|
|
77
|
+
|
|
78
|
+
// Auto-refresh
|
|
80
79
|
autoRefresh: boolean;
|
|
81
80
|
refreshThreshold: number;
|
|
82
|
-
|
|
81
|
+
|
|
82
|
+
// Cookie auth
|
|
83
|
+
cookieAuth?: {
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
csrf: {
|
|
86
|
+
enabled: boolean;
|
|
87
|
+
headerName: string;
|
|
88
|
+
cookieName: string;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Persistence
|
|
83
93
|
persistence: {
|
|
84
94
|
enabled: boolean;
|
|
85
95
|
storage: Storage;
|
|
@@ -88,11 +98,11 @@ export type ValidatedAuthConfig<U> = {
|
|
|
88
98
|
userKey: string;
|
|
89
99
|
expiryKey: string;
|
|
90
100
|
};
|
|
91
|
-
|
|
101
|
+
|
|
102
|
+
// Callbacks
|
|
92
103
|
onError?: (error: any) => void;
|
|
93
104
|
onLogin?: (user: U) => void;
|
|
94
105
|
onLogout?: () => void;
|
|
95
|
-
onTokenRefresh?: (tokens: TokenData) => void;
|
|
96
106
|
};
|
|
97
107
|
|
|
98
108
|
export const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfig<U> => {
|
|
@@ -100,85 +110,82 @@ export const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfi
|
|
|
100
110
|
throw new Error('AuthConfig: axios instance is required');
|
|
101
111
|
}
|
|
102
112
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (!tokenUrl) {
|
|
106
|
-
throw new Error('AuthConfig: tokenUrl or loginUrl is required');
|
|
113
|
+
if (!config.loginUrl) {
|
|
114
|
+
throw new Error('AuthConfig: loginUrl is required');
|
|
107
115
|
}
|
|
108
116
|
|
|
109
|
-
//
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
// Determine user info endpoint
|
|
113
|
-
const userInfoUrl = config.userInfoUrl || config.getUserUrl;
|
|
114
|
-
|
|
115
|
-
// Create OAuth-compliant token extraction function
|
|
116
|
-
const extractTokens = createTokenExtractor(config);
|
|
117
|
-
|
|
118
|
-
const defaultPersistence = {
|
|
117
|
+
// Cookie auth config
|
|
118
|
+
const cookieAuth = config.cookieAuth?.enabled ? {
|
|
119
119
|
enabled: true,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
csrf: {
|
|
121
|
+
enabled: config.cookieAuth.csrf?.enabled ?? false,
|
|
122
|
+
headerName: config.cookieAuth.csrf?.headerName || 'X-CSRFToken',
|
|
123
|
+
cookieName: config.cookieAuth.csrf?.cookieName || 'csrftoken',
|
|
124
|
+
},
|
|
125
|
+
} : undefined;
|
|
126
|
+
|
|
127
|
+
// Persistence config (disabled by default)
|
|
128
|
+
const persistence = {
|
|
129
|
+
enabled: config.persistence?.enabled ?? false,
|
|
130
|
+
storage: config.persistence?.storage ??
|
|
131
|
+
(typeof window !== 'undefined' && window.localStorage ? window.localStorage : {} as Storage),
|
|
132
|
+
tokenKey: config.persistence?.tokenKey ?? 'token',
|
|
133
|
+
refreshTokenKey: config.persistence?.refreshTokenKey ?? 'refresh_token',
|
|
134
|
+
userKey: config.persistence?.userKey ?? 'user',
|
|
135
|
+
expiryKey: config.persistence?.expiryKey ?? 'expires_at',
|
|
125
136
|
};
|
|
126
137
|
|
|
127
138
|
return {
|
|
128
139
|
axios: config.axios,
|
|
129
|
-
tokenUrl,
|
|
130
|
-
revokeUrl,
|
|
131
|
-
userInfoUrl,
|
|
132
|
-
// Backward compatibility
|
|
133
140
|
loginUrl: config.loginUrl,
|
|
134
141
|
logoutUrl: config.logoutUrl,
|
|
142
|
+
refreshUrl: config.refreshUrl,
|
|
135
143
|
getUserUrl: config.getUserUrl,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
authCheckUrl: config.authCheckUrl,
|
|
145
|
+
extractTokens: config.extractTokens ?? defaultExtractTokens,
|
|
146
|
+
extractUser: normalizeExtractUser(config.extractUser),
|
|
147
|
+
formatAuthHeader: config.formatAuthHeader ??
|
|
148
|
+
((token: string, tokenType: string = 'Bearer') => `${tokenType} ${token}`),
|
|
139
149
|
autoRefresh: config.autoRefresh ?? true,
|
|
140
150
|
refreshThreshold: config.refreshThreshold ?? 300000, // 5 minutes
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
...config.persistence,
|
|
144
|
-
},
|
|
151
|
+
cookieAuth,
|
|
152
|
+
persistence,
|
|
145
153
|
onError: config.onError,
|
|
146
154
|
onLogin: config.onLogin,
|
|
147
155
|
onLogout: config.onLogout,
|
|
148
|
-
onTokenRefresh: config.onTokenRefresh,
|
|
149
156
|
};
|
|
150
157
|
};
|
|
151
158
|
|
|
152
|
-
//
|
|
153
|
-
function
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
159
|
+
// Default token extraction - handles common response formats
|
|
160
|
+
function defaultExtractTokens(data: any): TokenData {
|
|
161
|
+
// OAuth 2.0 format: { access_token, refresh_token, expires_in, token_type }
|
|
162
|
+
if (data.access_token) {
|
|
163
|
+
return {
|
|
164
|
+
accessToken: data.access_token,
|
|
165
|
+
refreshToken: data.refresh_token,
|
|
166
|
+
expiresAt: data.expires_in ? Date.now() + (data.expires_in * 1000) : undefined,
|
|
167
|
+
tokenType: data.token_type || 'Bearer',
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Simple format: { token } or { auth_token }
|
|
172
|
+
const token = data.token || data.auth_token;
|
|
173
|
+
if (token) {
|
|
174
|
+
return {
|
|
175
|
+
accessToken: token,
|
|
176
|
+
tokenType: 'Bearer',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
throw new Error('No token found in response. Provide extractTokens or ensure response contains access_token/token field.');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Normalize extractUser: string becomes key accessor, function passed through
|
|
184
|
+
function normalizeExtractUser<U>(
|
|
185
|
+
extractUser?: ((data: any) => U | null) | string
|
|
186
|
+
): ((data: any) => U | null) | undefined {
|
|
187
|
+
if (typeof extractUser === 'string') {
|
|
188
|
+
return (data: any) => data[extractUser] ?? null;
|
|
189
|
+
}
|
|
190
|
+
return extractUser;
|
|
191
|
+
}
|