@jasperoosthoek/zustand-auth-registry 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,14 +4,14 @@ Authentication state management library using Zustand and Axios with a type-safe
4
4
 
5
5
  ## Features
6
6
 
7
- - **Authentication State Management** - User, token, and authentication status with reactive updates
7
+ - **Authentication State Management** - Data, token, and authentication status with reactive updates
8
8
  - **Registry Pattern** - Type-safe multiple auth stores per application
9
9
  - **Axios Integration** - Automatic authentication header management
10
10
  - **Token Lifecycle** - Automatic expiration detection and refresh workflows
11
11
  - **Cookie Authentication** - httpOnly cookie support with CSRF protection
12
12
  - **Typed Errors** - `AuthError` class with error codes for better error handling
13
13
  - **Persistence** - Flexible storage options (localStorage, sessionStorage, custom)
14
- - **Type-Safe** - Full TypeScript support with generics for user models
14
+ - **Type-Safe** - Full TypeScript support with generics for your auth data
15
15
 
16
16
  ## Installation
17
17
 
@@ -25,7 +25,7 @@ npm install @jasperoosthoek/zustand-auth-registry zustand axios react
25
25
  import axios from 'axios';
26
26
  import { createAuthRegistry, useAuth } from '@jasperoosthoek/zustand-auth-registry';
27
27
 
28
- // 1. Define your user type
28
+ // 1. Define your data type
29
29
  type User = {
30
30
  id: number;
31
31
  email: string;
@@ -45,21 +45,21 @@ export const authStore = getAuthStore('main', {
45
45
  axios: api,
46
46
  loginUrl: '/auth/login',
47
47
  logoutUrl: '/auth/logout',
48
- getUserUrl: '/users/me',
49
- extractUser: 'user', // Extract user from response.data.user
48
+ dataUrl: '/users/me',
49
+ extractData: 'user', // Extract data from response.data.user
50
50
  });
51
51
 
52
52
  // 5. Use in components
53
53
  function LoginForm() {
54
54
  const { login } = useAuth(authStore);
55
- const { user, isAuthenticated } = authStore((s) => s);
55
+ const { data, isAuthenticated } = authStore((s) => s);
56
56
 
57
57
  const handleLogin = async () => {
58
58
  await login({ username: 'user@example.com', password: 'password' });
59
59
  };
60
60
 
61
61
  if (isAuthenticated) {
62
- return <div>Welcome {user?.name}!</div>;
62
+ return <div>Welcome {data?.name}!</div>;
63
63
  }
64
64
 
65
65
  return <button onClick={handleLogin}>Login</button>;
@@ -119,24 +119,24 @@ const authStore = getAuthStore('main', {
119
119
 
120
120
  ## API Reference
121
121
 
122
- ### `AuthConfig<U>`
122
+ ### `AuthConfig<D>`
123
123
 
124
124
  ```typescript
125
- type AuthConfig<U> = {
125
+ type AuthConfig<D> = {
126
126
  axios: AxiosInstance;
127
127
 
128
128
  // Endpoints
129
129
  loginUrl: string;
130
130
  logoutUrl?: string;
131
131
  refreshUrl?: string;
132
- getUserUrl?: string;
132
+ dataUrl?: string;
133
133
  authCheckUrl?: string; // For cookie auth
134
134
 
135
135
  // Token extraction from login response
136
136
  extractTokens?: (data: any) => TokenData;
137
137
 
138
- // User extraction (function or string key)
139
- extractUser?: ((data: any) => U | null) | string;
138
+ // Data extraction (function or string key)
139
+ extractData?: ((data: any) => D | null) | string;
140
140
 
141
141
  // Auth header format (default: "Bearer {token}")
142
142
  formatAuthHeader?: (token: string, tokenType?: string) => string;
@@ -161,13 +161,13 @@ type AuthConfig<U> = {
161
161
  storage?: Storage; // Default: localStorage
162
162
  tokenKey?: string;
163
163
  refreshTokenKey?: string;
164
- userKey?: string;
164
+ dataKey?: string;
165
165
  expiryKey?: string;
166
166
  };
167
167
 
168
168
  // Callbacks
169
169
  onError?: (error: any) => void;
170
- onLogin?: (user: U) => void;
170
+ onLogin?: (data: D) => void;
171
171
  onLogout?: () => void;
172
172
  };
173
173
  ```
@@ -186,31 +186,31 @@ type TokenData = {
186
186
  ### `useAuth(store)`
187
187
 
188
188
  ```typescript
189
- const { login, logout, getCurrentUser, refreshTokens, checkAuth } = useAuth(authStore);
189
+ const { login, logout, fetchData, refresh, checkAuth } = useAuth(authStore);
190
190
  ```
191
191
 
192
192
  - `login(credentials, callback?)` - Login with credentials
193
- - `logout()` - Logout and clear tokens
194
- - `getCurrentUser()` - Fetch current user
195
- - `refreshTokens()` - Refresh access token
193
+ - `logout()` - Logout and clear state
194
+ - `fetchData()` - Fetch data from `dataUrl`
195
+ - `refresh()` - Refresh access token
196
196
  - `checkAuth()` - Check cookie authentication status
197
197
 
198
198
  ### Auth Store State
199
199
 
200
200
  ```typescript
201
- const { user, tokens, isAuthenticated, setBearerToken, setTokens } = authStore((s) => s);
201
+ const { data, tokens, isAuthenticated, setBearerToken, setTokens } = authStore((s) => s);
202
202
  ```
203
203
 
204
204
  **State:**
205
- - `user: U | null` - Current user
205
+ - `data: D | null` - Stored auth data
206
206
  - `tokens: TokenData | null` - Token data (access token, refresh token, etc.)
207
- - `isAuthenticated: boolean` - Authentication status
207
+ - `isAuthenticated: boolean | null` - Authentication status (`null` = not yet checked, cookie mode only)
208
208
 
209
209
  **Methods:**
210
210
  - `setBearerToken(token)` - Convenience method for simple Bearer token auth
211
211
  - `setTokens(tokenData)` - Set full token data (access, refresh, expiry)
212
- - `setUser(user)` - Set user
213
- - `unsetUser()` - Clear user and tokens
212
+ - `setData(data)` - Set auth data
213
+ - `reset()` - Clear data, tokens, and authentication state
214
214
 
215
215
  ## Related Projects
216
216
 
@@ -5,15 +5,15 @@ export type TokenData = {
5
5
  expiresAt?: number;
6
6
  tokenType: string;
7
7
  };
8
- export type AuthConfig<U> = {
8
+ export type AuthConfig<D> = {
9
9
  axios: AxiosInstance;
10
10
  loginUrl: string;
11
11
  logoutUrl?: string;
12
12
  refreshUrl?: string;
13
- getUserUrl?: string;
13
+ dataUrl?: string;
14
14
  authCheckUrl?: string;
15
15
  extractTokens?: (data: any) => TokenData;
16
- extractUser?: ((data: any) => U | null) | string;
16
+ extractData?: ((data: any) => D | null) | string;
17
17
  formatAuthHeader?: (token: string, tokenType?: string) => string;
18
18
  autoRefresh?: boolean;
19
19
  refreshThreshold?: number;
@@ -31,22 +31,22 @@ export type AuthConfig<U> = {
31
31
  storage?: Storage;
32
32
  tokenKey?: string;
33
33
  refreshTokenKey?: string;
34
- userKey?: string;
34
+ dataKey?: string;
35
35
  expiryKey?: string;
36
36
  };
37
37
  onError?: (error: any) => void;
38
- onLogin?: (user: U) => void;
38
+ onLogin?: (data: D) => void;
39
39
  onLogout?: () => void;
40
40
  };
41
- export type ValidatedAuthConfig<U> = {
41
+ export type ValidatedAuthConfig<D> = {
42
42
  axios: AxiosInstance;
43
43
  loginUrl: string;
44
44
  logoutUrl?: string;
45
45
  refreshUrl?: string;
46
- getUserUrl?: string;
46
+ dataUrl?: string;
47
47
  authCheckUrl?: string;
48
48
  extractTokens: (data: any) => TokenData;
49
- extractUser?: (data: any) => U | null;
49
+ extractData?: (data: any) => D | null;
50
50
  formatAuthHeader: (token: string, tokenType?: string) => string;
51
51
  autoRefresh: boolean;
52
52
  refreshThreshold: number;
@@ -63,11 +63,11 @@ export type ValidatedAuthConfig<U> = {
63
63
  storage: Storage;
64
64
  tokenKey: string;
65
65
  refreshTokenKey: string;
66
- userKey: string;
66
+ dataKey: string;
67
67
  expiryKey: string;
68
68
  };
69
69
  onError?: (error: any) => void;
70
- onLogin?: (user: U) => void;
70
+ onLogin?: (data: D) => void;
71
71
  onLogout?: () => void;
72
72
  };
73
- export declare const validateAuthConfig: <U>(config: AuthConfig<U>) => ValidatedAuthConfig<U>;
73
+ export declare const validateAuthConfig: <D>(config: AuthConfig<D>) => ValidatedAuthConfig<D>;
@@ -1,17 +1,17 @@
1
1
  import { StoreApi, UseBoundStore } from 'zustand';
2
2
  import { ValidatedAuthConfig, TokenData } from './authConfig';
3
- export type AuthState<U> = {
3
+ export type AuthState<D> = {
4
4
  isAuthenticated: boolean | null;
5
- user: U | null;
5
+ data: D | null;
6
6
  tokens: TokenData | null;
7
7
  setTokens: (tokens: TokenData) => void;
8
8
  setBearerToken: (token: string) => void;
9
9
  setAuthenticated: (authenticated: boolean) => void;
10
- setUser: (user: U) => void;
11
- unsetUser: () => void;
10
+ setData: (data: D) => void;
11
+ reset: () => void;
12
12
  isTokenExpired: () => boolean;
13
13
  };
14
- export type AuthStore<U> = UseBoundStore<StoreApi<AuthState<U>>> & {
15
- config: ValidatedAuthConfig<U>;
14
+ export type AuthStore<D> = UseBoundStore<StoreApi<AuthState<D>>> & {
15
+ config: ValidatedAuthConfig<D>;
16
16
  };
17
- export declare const createAuthStore: <U>(config: ValidatedAuthConfig<U>) => AuthStore<U>;
17
+ export declare const createAuthStore: <D>(config: ValidatedAuthConfig<D>) => AuthStore<D>;
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")):"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:()=>d,createAuthStore:()=>c,useAuth:()=>k,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,x,N;if(!e.axios)throw new Error("AuthConfig: axios instance is required");if(!e.loginUrl)throw new Error("AuthConfig: loginUrl is required");var U,w,m=(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",getToken:null!==(s=null===(i=e.cookieAuth.csrf)||void 0===i?void 0:i.getToken)&&void 0!==s?s:(U=(null===(a=e.cookieAuth.csrf)||void 0===a?void 0:a.cookieName)||"csrftoken",function(){if("undefined"==typeof document)return null;var e=document.cookie.match(new RegExp("".concat(U,"=([^;]+)")));return e?e[1]:null})}}:void 0,I={enabled:null!==(c=null===(l=e.persistence)||void 0===l?void 0:l.enabled)&&void 0!==c&&c,storage:null!==(f=null===(d=e.persistence)||void 0===d?void 0:d.storage)&&void 0!==f?f:"undefined"!=typeof window&&window.localStorage?window.localStorage:{},tokenKey:null!==(h=null===(v=e.persistence)||void 0===v?void 0:v.tokenKey)&&void 0!==h?h:"token",refreshTokenKey:null!==(k=null===(p=e.persistence)||void 0===p?void 0:p.refreshTokenKey)&&void 0!==k?k:"refresh_token",userKey:null!==(g=null===(y=e.persistence)||void 0===y?void 0:y.userKey)&&void 0!==g?g:"user",expiryKey:null!==(E=null===(T=e.persistence)||void 0===T?void 0:T.expiryKey)&&void 0!==E?E:"expires_at"};return{axios:e.axios,loginUrl:e.loginUrl,logoutUrl:e.logoutUrl,refreshUrl:e.refreshUrl,getUserUrl:e.getUserUrl,authCheckUrl:e.authCheckUrl,extractTokens:null!==(b=e.extractTokens)&&void 0!==b?b:u,extractUser:(w=e.extractUser,"string"==typeof w?function(e){var r;return null!==(r=e[w])&&void 0!==r?r:null}:w),formatAuthHeader:null!==(A=e.formatAuthHeader)&&void 0!==A?A:function(e,r){return void 0===r&&(r="Bearer"),"".concat(r," ").concat(e)},autoRefresh:null===(x=e.autoRefresh)||void 0===x||x,refreshThreshold:null!==(N=e.refreshThreshold)&&void 0!==N?N:3e5,cookieAuth:m,persistence:I,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=["post","put","patch","delete"],c=function(e){var r=e.persistence,t=e.cookieAuth;!function(e){var r;if(!(null===(r=e.cookieAuth)||void 0===r?void 0:r.csrf.enabled))return null;var t=e.cookieAuth.csrf,n=t.headerName,o=t.getToken;e.axios.interceptors.request.use(function(e){var r,t=null===(r=e.method)||void 0===r?void 0:r.toLowerCase();if(t&&l.includes(t)){var i=o();i&&(e.headers[n]=i)}return e})}(e);var 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 d(){var e={};return function(r,t){var n=String(r);if(!e[n]){var o=s(t);e[n]=c(o)}return e[n]}}var f=o(155),v=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())})},h=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])}}},p=new WeakMap;function k(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,d=e.config,k=(0,f.useCallback)(function(e,r){var t;(null===(t=d.cookieAuth)||void 0===t?void 0:t.enabled)||(e?d.axios.defaults.headers.common.Authorization=d.formatAuthHeader(e,r):delete d.axios.defaults.headers.common.Authorization)},[d]),g=(0,f.useCallback)(function(){return v(r,void 0,void 0,function(){var e,r,t,o,i,a;return h(this,function(l){switch(l.label){case 0:if(!d.refreshUrl)return[2,!1];l.label=1;case 1:return l.trys.push([1,5,,6]),(null===(i=d.cookieAuth)||void 0===i?void 0:i.enabled)?(e=y(d),[4,d.axios.post(d.refreshUrl,{},{headers:e})]):[3,3];case 2:return l.sent(),[2,!0];case 3:return(null==u?void 0:u.refreshToken)?[4,d.axios.post(d.refreshUrl,{refresh_token:u.refreshToken})]:[2,!1];case 4:return r=l.sent(),t=d.extractTokens(r.data),n(t),k(t.accessToken,t.tokenType),[2,!0];case 5:return o=l.sent(),s(),k(),null===(a=d.onError)||void 0===a||a.call(d,o),[2,!1];case 6:return[2]}})})},[u,d,n,s,k]),T=(0,f.useCallback)(function(){return v(r,void 0,void 0,function(){var r,t,n,s,u,a=this;return h(this,function(l){return r=d.authCheckUrl,(null===(u=d.cookieAuth)||void 0===u?void 0:u.enabled)&&r?(t=p.get(e))?[2,t]:(n=function(){return v(a,void 0,void 0,function(){var t,n,s,u,a,l;return h(this,function(c){switch(c.label){case 0:return c.trys.push([0,6,7,8]),t=y(d),[4,d.axios.get(r,{headers:t})];case 1:return(n=c.sent()).data.authenticated?(o(!0),(s=null===(a=d.extractUser)||void 0===a?void 0:a.call(d,n.data))?(i(s),[3,4]):[3,2]):[3,5];case 2:return d.getUserUrl?[4,E()]:[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=d.onError)||void 0===l||l.call(d,u),[2,!1];case 7:return p.delete(e),[7];case 8:return[2]}})})},s=n(),p.set(e,s),[2,s]):[2,!1]})})},[e,d,o,i]),E=(0,f.useCallback)(function(){return v(r,void 0,void 0,function(){var e,r,t;return h(this,function(n){switch(n.label){case 0:if(!d.getUserUrl)return[2];n.label=1;case 1:return n.trys.push([1,3,,4]),[4,d.axios.get(d.getUserUrl)];case 2:return e=n.sent(),i(e.data),[3,4];case 3:throw r=n.sent(),s(),k(),null===(t=d.onError)||void 0===t||t.call(d,r),r;case 4:return[2]}})})},[d,i,s,k]);return(0,f.useEffect)(function(){var e;if(null===(e=d.cookieAuth)||void 0===e?void 0:e.enabled)null===l&&T();else if(null==u?void 0:u.accessToken){if(k(u.accessToken,u.tokenType),c())return void(u.refreshToken&&d.autoRefresh?g():s());if(u.expiresAt&&u.refreshToken&&d.autoRefresh){var r=u.expiresAt-Date.now(),t=Math.max(r-d.refreshThreshold,0),n=setTimeout(g,t);return function(){return clearTimeout(n)}}!a&&d.getUserUrl&&E().catch(function(){})}},[u,a,l,d,c,g,T,E,k,s]),{login:function(t,u){return v(r,void 0,void 0,function(){var r,a,l,c,f,v,p,g,T,b,A,x;return h(this,function(h){switch(h.label){case 0:return h.trys.push([0,5,,6]),r=(null===(p=d.cookieAuth)||void 0===p?void 0:p.enabled)?y(d):{},[4,d.axios.post(d.loginUrl,t,{headers:r})];case 1:return a=h.sent(),(null===(g=d.cookieAuth)||void 0===g?void 0:g.enabled)?o(!0):(l=d.extractTokens(a.data),n(l),k(l.accessToken,l.tokenType)),(c=null===(T=d.extractUser)||void 0===T?void 0:T.call(d,a.data))?(i(c),null===(b=d.onLogin)||void 0===b||b.call(d,c),[3,4]):[3,2];case 2:return d.getUserUrl?[4,E()]:[3,4];case 3:h.sent(),(f=e.getState().user)&&(null===(A=d.onLogin)||void 0===A||A.call(d,f)),h.label=4;case 4:return null==u||u(),[3,6];case 5:throw v=h.sent(),s(),k(),null===(x=d.onError)||void 0===x||x.call(d,v),v;case 6:return[2]}})})},logout:function(){return v(r,void 0,void 0,function(){var e,r,t,n,o;return h(this,function(i){switch(i.label){case 0:return i.trys.push([0,3,4,5]),d.logoutUrl?(e=(null===(t=d.cookieAuth)||void 0===t?void 0:t.enabled)?y(d):{},[4,d.axios.post(d.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=d.onError)||void 0===n||n.call(d,r),[3,5];case 4:return s(),k(),null===(o=d.onLogout)||void 0===o||o.call(d),[7];case 5:return[2]}})})},refresh:g,checkAuth:T,getCurrentUser:E}}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=e.cookieAuth.csrf.getToken();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})());
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 a=n[e]={exports:{}};return t[e](a,a.exports,o),a.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 a={};o.r(a),o.d(a,{AuthError:()=>b,AuthErrorCode:()=>g,createAuthError:()=>A,createAuthRegistry:()=>d,createAuthStore:()=>c,useAuth:()=>k,validateAuthConfig:()=>i});var i=function(e){var r,t,n,o,a,i,s,l,c,d,f,v,h,p,k,y,T,g,E,b,A,x,N;if(!e.axios)throw new Error("AuthConfig: axios instance is required");if(!e.loginUrl)throw new Error("AuthConfig: loginUrl is required");var w,m,I=(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",getToken:null!==(i=null===(a=e.cookieAuth.csrf)||void 0===a?void 0:a.getToken)&&void 0!==i?i:(w=(null===(s=e.cookieAuth.csrf)||void 0===s?void 0:s.cookieName)||"csrftoken",function(){if("undefined"==typeof document)return null;var e=document.cookie.match(new RegExp("".concat(w,"=([^;]+)")));return e?e[1]:null})}}:void 0,_={enabled:null!==(c=null===(l=e.persistence)||void 0===l?void 0:l.enabled)&&void 0!==c&&c,storage:null!==(f=null===(d=e.persistence)||void 0===d?void 0:d.storage)&&void 0!==f?f:"undefined"!=typeof window&&window.localStorage?window.localStorage:{},tokenKey:null!==(h=null===(v=e.persistence)||void 0===v?void 0:v.tokenKey)&&void 0!==h?h:"token",refreshTokenKey:null!==(k=null===(p=e.persistence)||void 0===p?void 0:p.refreshTokenKey)&&void 0!==k?k:"refresh_token",dataKey:null!==(T=null===(y=e.persistence)||void 0===y?void 0:y.dataKey)&&void 0!==T?T:"data",expiryKey:null!==(E=null===(g=e.persistence)||void 0===g?void 0:g.expiryKey)&&void 0!==E?E:"expires_at"};return{axios:e.axios,loginUrl:e.loginUrl,logoutUrl:e.logoutUrl,refreshUrl:e.refreshUrl,dataUrl:e.dataUrl,authCheckUrl:e.authCheckUrl,extractTokens:null!==(b=e.extractTokens)&&void 0!==b?b:u,extractData:(m=e.extractData,"string"==typeof m?function(e){var r;return null!==(r=e[m])&&void 0!==r?r:null}:m),formatAuthHeader:null!==(A=e.formatAuthHeader)&&void 0!==A?A:function(e,r){return void 0===r&&(r="Bearer"),"".concat(r," ").concat(e)},autoRefresh:null===(x=e.autoRefresh)||void 0===x||x,refreshThreshold:null!==(N=e.refreshThreshold)&&void 0!==N?N:3e5,cookieAuth:I,persistence:_,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 s=o(287),l=["post","put","patch","delete"],c=function(e){var r=e.persistence,t=e.cookieAuth;!function(e){var r;if(!(null===(r=e.cookieAuth)||void 0===r?void 0:r.csrf.enabled))return null;var t=e.cookieAuth.csrf,n=t.headerName,o=t.getToken;e.axios.interceptors.request.use(function(e){var r,t=null===(r=e.method)||void 0===r?void 0:r.toLowerCase();if(t&&l.includes(t)){var a=o();a&&(e.headers[n]=a)}return e})}(e);var 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),a=o?parseInt(o,10):void 0;return{accessToken:e,refreshToken:n||void 0,expiresAt:a&&!isNaN(a)?a:void 0,tokenType:"Bearer"}}catch(e){return null}}(),o=function(){if(!r.enabled)return null;try{var e=r.storage.getItem(r.dataKey);return e?JSON.parse(e):null}catch(e){return null}}(),a=(null==t?void 0:t.enabled)?null:!!(null==n?void 0:n.accessToken),i=(0,s.create)(function(i,u){return{tokens:n,data:o,isAuthenticated:a,setTokens:function(n){var o;if(i({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){i({isAuthenticated:e})},setData:function(t){var n;if(i({data:t}),r.enabled)try{r.storage.setItem(r.dataKey,JSON.stringify(t))}catch(r){null===(n=e.onError)||void 0===n||n.call(e,r)}},reset:function(){var t;if(i({data:null,tokens:null,isAuthenticated:!1}),r.enabled)try{r.storage.removeItem(r.tokenKey),r.storage.removeItem(r.refreshTokenKey),r.storage.removeItem(r.dataKey),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(i,{config:e})};function d(){var e={};return function(r,t){var n=String(r);if(!e[n]){var o=i(t);e[n]=c(o)}return e[n]}}var f=o(155),v=function(e,r,t,n){return new(t||(t=Promise))(function(o,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function u(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var r;e.done?o(e.value):(r=e.value,r instanceof t?r:new t(function(e){e(r)})).then(i,u)}s((n=n.apply(e,r||[])).next())})},h=function(e,r){var t,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(u){return function(s){return function(u){if(t)throw new TypeError("Generator is already executing.");for(;a&&(a=0,u[0]&&(i=0)),i;)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 i.label++,{value:u[1],done:!1};case 5:i.label++,n=u[1],u=[0];continue;case 7:u=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==u[0]&&2!==u[0])){i=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){i.label=u[1];break}if(6===u[0]&&i.label<o[1]){i.label=o[1],o=u;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(u);break}o[2]&&i.ops.pop(),i.trys.pop();continue}u=r.call(e,i)}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,s])}}},p=new WeakMap;function k(e){var r=this,t=e(),n=t.setTokens,o=t.setAuthenticated,a=t.setData,i=t.reset,u=t.tokens,s=t.data,l=t.isAuthenticated,c=t.isTokenExpired,d=e.config,k=(0,f.useCallback)(function(e,r){var t;(null===(t=d.cookieAuth)||void 0===t?void 0:t.enabled)||(e?d.axios.defaults.headers.common.Authorization=d.formatAuthHeader(e,r):delete d.axios.defaults.headers.common.Authorization)},[d]),T=(0,f.useCallback)(function(){return v(r,void 0,void 0,function(){var e,r,t,o,a,s;return h(this,function(l){switch(l.label){case 0:if(!d.refreshUrl)return[2,!1];l.label=1;case 1:return l.trys.push([1,5,,6]),(null===(a=d.cookieAuth)||void 0===a?void 0:a.enabled)?(e=y(d),[4,d.axios.post(d.refreshUrl,{},{headers:e})]):[3,3];case 2:return l.sent(),[2,!0];case 3:return(null==u?void 0:u.refreshToken)?[4,d.axios.post(d.refreshUrl,{refresh_token:u.refreshToken})]:[2,!1];case 4:return r=l.sent(),t=d.extractTokens(r.data),n(t),k(t.accessToken,t.tokenType),[2,!0];case 5:return o=l.sent(),i(),k(),null===(s=d.onError)||void 0===s||s.call(d,o),[2,!1];case 6:return[2]}})})},[u,d,n,i,k]),g=(0,f.useCallback)(function(){return v(r,void 0,void 0,function(){var r,t,n,u,s,l=this;return h(this,function(c){return r=d.authCheckUrl,(null===(s=d.cookieAuth)||void 0===s?void 0:s.enabled)&&r?(t=p.get(e))?[2,t]:(n=function(){return v(l,void 0,void 0,function(){var t,n,u,s,l,c;return h(this,function(f){switch(f.label){case 0:return f.trys.push([0,6,7,8]),t=y(d),[4,d.axios.get(r,{headers:t})];case 1:return(n=f.sent()).data.authenticated?(o(!0),(u=null===(l=d.extractData)||void 0===l?void 0:l.call(d,n.data))?(a(u),[3,4]):[3,2]):[3,5];case 2:return d.dataUrl?[4,E()]:[3,4];case 3:f.sent(),f.label=4;case 4:return[2,!0];case 5:return i(),[2,!1];case 6:return s=f.sent(),i(),null===(c=d.onError)||void 0===c||c.call(d,s),[2,!1];case 7:return p.delete(e),[7];case 8:return[2]}})})},u=n(),p.set(e,u),[2,u]):[2,!1]})})},[e,d,o,a]),E=(0,f.useCallback)(function(){return v(r,void 0,void 0,function(){var e,r,t;return h(this,function(n){switch(n.label){case 0:if(!d.dataUrl)return[2];n.label=1;case 1:return n.trys.push([1,3,,4]),[4,d.axios.get(d.dataUrl)];case 2:return e=n.sent(),a(e.data),[3,4];case 3:throw r=n.sent(),i(),k(),null===(t=d.onError)||void 0===t||t.call(d,r),r;case 4:return[2]}})})},[d,a,i,k]);return(0,f.useEffect)(function(){var e;if(null===(e=d.cookieAuth)||void 0===e?void 0:e.enabled)null===l&&g();else if(null==u?void 0:u.accessToken){if(k(u.accessToken,u.tokenType),c())return void(u.refreshToken&&d.autoRefresh?T():i());if(u.expiresAt&&u.refreshToken&&d.autoRefresh){var r=u.expiresAt-Date.now(),t=Math.max(r-d.refreshThreshold,0),n=setTimeout(T,t);return function(){return clearTimeout(n)}}!s&&d.dataUrl&&E().catch(function(){})}},[u,s,l,d,c,T,g,E,k,i]),{login:function(t,u){return v(r,void 0,void 0,function(){var r,s,l,c,f,v,p,T,g,b,A,x;return h(this,function(h){switch(h.label){case 0:return h.trys.push([0,5,,6]),r=(null===(p=d.cookieAuth)||void 0===p?void 0:p.enabled)?y(d):{},[4,d.axios.post(d.loginUrl,t,{headers:r})];case 1:return s=h.sent(),(null===(T=d.cookieAuth)||void 0===T?void 0:T.enabled)?o(!0):(l=d.extractTokens(s.data),n(l),k(l.accessToken,l.tokenType)),(c=null===(g=d.extractData)||void 0===g?void 0:g.call(d,s.data))?(a(c),null===(b=d.onLogin)||void 0===b||b.call(d,c),[3,4]):[3,2];case 2:return d.dataUrl?[4,E()]:[3,4];case 3:h.sent(),(f=e.getState().data)&&(null===(A=d.onLogin)||void 0===A||A.call(d,f)),h.label=4;case 4:return null==u||u(),[3,6];case 5:throw v=h.sent(),i(),k(),null===(x=d.onError)||void 0===x||x.call(d,v),v;case 6:return[2]}})})},logout:function(){return v(r,void 0,void 0,function(){var e,r,t,n,o;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,3,4,5]),d.logoutUrl?(e=(null===(t=d.cookieAuth)||void 0===t?void 0:t.enabled)?y(d):{},[4,d.axios.post(d.logoutUrl,{},{headers:e})]):[3,2];case 1:a.sent(),a.label=2;case 2:return[3,5];case 3:return r=a.sent(),null===(n=d.onError)||void 0===n||n.call(d,r),[3,5];case 4:return i(),k(),null===(o=d.onLogout)||void 0===o||o.call(d),[7];case 5:return[2]}})})},refresh:T,checkAuth:g,fetchData:E}}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=e.cookieAuth.csrf.getToken();o&&(n[e.cookieAuth.csrf.headerName]=o)}return n}var T,g,E=(T=function(e,r){return T=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])},T(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}T(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"}(g||(g={}));var b=function(e){function r(t,n,o){var a=e.call(this,o||t)||this;return a.code=t,a.originalError=n,a.name="AuthError",Error.captureStackTrace&&Error.captureStackTrace(a,r),a}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,a,i;if(b.isAuthError(e))return e;if(e.response){var u=e.response.status,s=e.response.data;switch(u){case 401:return(null===(r=null==s?void 0:s.detail)||void 0===r?void 0:r.toLowerCase().includes("expired"))||(null===(t=null==s?void 0:s.message)||void 0===t?void 0:t.toLowerCase().includes("expired"))?new b(g.TOKEN_EXPIRED,e,"Token has expired"):(null===(n=null==s?void 0:s.detail)||void 0===n?void 0:n.toLowerCase().includes("invalid"))||(null===(o=null==s?void 0:s.detail)||void 0===o?void 0:o.toLowerCase().includes("credentials"))?new b(g.INVALID_CREDENTIALS,e,"Invalid credentials"):new b(g.UNAUTHORIZED,e,"Unauthorized");case 403:return(null===(a=null==s?void 0:s.detail)||void 0===a?void 0:a.toLowerCase().includes("csrf"))?new b(g.CSRF_TOKEN_MISSING,e,"CSRF token missing or invalid"):new b(g.FORBIDDEN,e,"Access forbidden");case 404:return(null===(i=null==s?void 0:s.detail)||void 0===i?void 0:i.toLowerCase().includes("user"))?new b(g.USER_NOT_FOUND,e,"User not found"):new b(g.UNKNOWN,e,"Resource not found");default:return new b(g.UNKNOWN,e,"HTTP ".concat(u," error"))}}return e.request?new b(g.NETWORK_ERROR,e,"Network error - no response received"):new b(g.UNKNOWN,e,e.message||"Unknown error")}return a})());
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/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 // Option 1: Provide cookie name (web only, uses document.cookie)\n cookieName?: string; // Default: 'csrftoken'\n // Option 2: Provide custom token getter (platform-agnostic)\n getToken?: () => string | null;\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 getToken: () => string | null;\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 getToken: config.cookieAuth.csrf?.getToken ?? createCookieTokenGetter(\n config.cookieAuth.csrf?.cookieName || 'csrftoken'\n ),\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\n// Create a cookie-based CSRF token getter (web only)\nfunction createCookieTokenGetter(cookieName: string): () => string | null {\n return () => {\n if (typeof document === 'undefined') return null;\n const match = document.cookie.match(new RegExp(`${cookieName}=([^;]+)`));\n return match ? match[1] : null;\n };\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\n// Methods that modify state (require CSRF protection)\nconst CSRF_METHODS = ['post', 'put', 'patch', 'delete'];\n\nconst setupCsrfInterceptor = <U>(config: ValidatedAuthConfig<U>): number | null => {\n if (!config.cookieAuth?.csrf.enabled) {\n return null;\n }\n\n const { headerName, getToken } = config.cookieAuth.csrf;\n\n return config.axios.interceptors.request.use((requestConfig) => {\n const method = requestConfig.method?.toLowerCase();\n if (method && CSRF_METHODS.includes(method)) {\n const csrfToken = getToken();\n if (csrfToken) {\n requestConfig.headers[headerName] = csrfToken;\n }\n }\n return requestConfig;\n });\n};\n\nexport const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U> => {\n const { persistence, cookieAuth } = config;\n\n // Set up CSRF interceptor if enabled\n setupCsrfInterceptor(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 // Note: CSRF is handled by interceptor in authStore.ts\n const setAxiosAuth = useCallback((token?: string, tokenType?: string) => {\n if (config.cookieAuth?.enabled) {\n // Cookie mode: CSRF handled by interceptor, no Authorization header needed\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 CSRF headers if enabled (uses getToken from config)\nfunction getCsrfHeaders(config: any): Record<string, string> {\n const headers: Record<string, string> = {};\n if (config.cookieAuth?.csrf?.enabled) {\n const csrfToken = config.cookieAuth.csrf.getToken();\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","cookieName","extractUser","cookieAuth","enabled","csrf","headerName","getToken","document","match","cookie","RegExp","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","CSRF_METHODS","createAuthStore","interceptors","request","use","requestConfig","method","toLowerCase","includes","csrfToken","headers","setupCsrfInterceptor","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","defaults","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","AuthErrorCode","code","originalError","message","name","captureStackTrace","AuthError","toJSON","isAuthError","createAuthError","status","detail","TOKEN_EXPIRED","INVALID_CREDENTIALS","UNAUTHORIZED","CSRF_TOKEN_MISSING","FORBIDDEN","USER_NOT_FOUND","UNKNOWN","NETWORK_ERROR"],"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<D> = {\n axios: AxiosInstance;\n\n // Endpoints\n loginUrl: string;\n logoutUrl?: string;\n refreshUrl?: string;\n dataUrl?: string;\n authCheckUrl?: string; // For cookie auth verification\n\n // Token extraction from login response\n extractTokens?: (data: any) => TokenData;\n\n // Data extraction from responses (login, checkAuth)\n // Can be a function or a string key (e.g., \"user\" extracts data.user)\n extractData?: ((data: any) => D | 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 // Option 1: Provide cookie name (web only, uses document.cookie)\n cookieName?: string; // Default: 'csrftoken'\n // Option 2: Provide custom token getter (platform-agnostic)\n getToken?: () => string | null;\n };\n };\n\n // Token persistence (localStorage)\n persistence?: {\n enabled: boolean;\n storage?: Storage;\n tokenKey?: string;\n refreshTokenKey?: string;\n dataKey?: string;\n expiryKey?: string;\n };\n\n // Callbacks\n onError?: (error: any) => void;\n onLogin?: (data: D) => void;\n onLogout?: () => void;\n};\n\nexport type ValidatedAuthConfig<D> = {\n axios: AxiosInstance;\n\n // Endpoints\n loginUrl: string;\n logoutUrl?: string;\n refreshUrl?: string;\n dataUrl?: string;\n authCheckUrl?: string;\n\n // Extraction functions\n extractTokens: (data: any) => TokenData;\n extractData?: (data: any) => D | 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 getToken: () => string | null;\n };\n };\n\n // Persistence\n persistence: {\n enabled: boolean;\n storage: Storage;\n tokenKey: string;\n refreshTokenKey: string;\n dataKey: string;\n expiryKey: string;\n };\n\n // Callbacks\n onError?: (error: any) => void;\n onLogin?: (data: D) => void;\n onLogout?: () => void;\n};\n\nexport const validateAuthConfig = <D>(config: AuthConfig<D>): ValidatedAuthConfig<D> => {\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 getToken: config.cookieAuth.csrf?.getToken ?? createCookieTokenGetter(\n config.cookieAuth.csrf?.cookieName || 'csrftoken'\n ),\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 dataKey: config.persistence?.dataKey ?? 'data',\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 dataUrl: config.dataUrl,\n authCheckUrl: config.authCheckUrl,\n extractTokens: config.extractTokens ?? defaultExtractTokens,\n extractData: normalizeExtractData(config.extractData),\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 extractData: string becomes key accessor, function passed through\nfunction normalizeExtractData<D>(\n extractData?: ((data: any) => D | null) | string\n): ((data: any) => D | null) | undefined {\n if (typeof extractData === 'string') {\n return (data: any) => data[extractData] ?? null;\n }\n return extractData;\n}\n\n// Create a cookie-based CSRF token getter (web only)\nfunction createCookieTokenGetter(cookieName: string): () => string | null {\n return () => {\n if (typeof document === 'undefined') return null;\n const match = document.cookie.match(new RegExp(`${cookieName}=([^;]+)`));\n return match ? match[1] : null;\n };\n}\n","import { create, StoreApi, UseBoundStore } from 'zustand';\nimport { ValidatedAuthConfig, TokenData } from './authConfig';\n\nexport type AuthState<D> = {\n isAuthenticated: boolean | null; // null = not checked yet (cookie mode)\n data: D | 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 setData: (data: D) => void;\n reset: () => void;\n isTokenExpired: () => boolean;\n};\n\nexport type AuthStore<D> = UseBoundStore<StoreApi<AuthState<D>>> & {\n config: ValidatedAuthConfig<D>;\n};\n\n// Methods that modify state (require CSRF protection)\nconst CSRF_METHODS = ['post', 'put', 'patch', 'delete'];\n\nconst setupCsrfInterceptor = <D>(config: ValidatedAuthConfig<D>): number | null => {\n if (!config.cookieAuth?.csrf.enabled) {\n return null;\n }\n\n const { headerName, getToken } = config.cookieAuth.csrf;\n\n return config.axios.interceptors.request.use((requestConfig) => {\n const method = requestConfig.method?.toLowerCase();\n if (method && CSRF_METHODS.includes(method)) {\n const csrfToken = getToken();\n if (csrfToken) {\n requestConfig.headers[headerName] = csrfToken;\n }\n }\n return requestConfig;\n });\n};\n\nexport const createAuthStore = <D>(config: ValidatedAuthConfig<D>): AuthStore<D> => {\n const { persistence, cookieAuth } = config;\n\n // Set up CSRF interceptor if enabled\n setupCsrfInterceptor(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 getStoredData = (): D | null => {\n if (!persistence.enabled) return null;\n try {\n const dataString = persistence.storage.getItem(persistence.dataKey);\n return dataString ? (JSON.parse(dataString) as D) : null;\n } catch {\n return null;\n }\n };\n\n const initialTokens = getStoredTokens();\n const initialData = getStoredData();\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<D>>((set, get) => ({\n tokens: initialTokens,\n data: initialData,\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 setData: (data: D) => {\n set({ data });\n\n if (persistence.enabled) {\n try {\n persistence.storage.setItem(persistence.dataKey, JSON.stringify(data));\n } catch (error) {\n config.onError?.(error);\n }\n }\n },\n\n reset: () => {\n set({ data: 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.dataKey);\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<D>(store: AuthStore<D>) {\n const { setTokens, setAuthenticated, setData, reset, tokens, data, isAuthenticated, isTokenExpired } = store();\n const config = store.config;\n\n // Set axios Authorization header (token mode only)\n // Note: CSRF is handled by interceptor in authStore.ts\n const setAxiosAuth = useCallback((token?: string, tokenType?: string) => {\n if (config.cookieAuth?.enabled) {\n // Cookie mode: CSRF handled by interceptor, no Authorization header needed\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 reset();\n setAxiosAuth();\n config.onError?.(error);\n return false;\n }\n }, [tokens, config, setTokens, reset, 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 extractedData = config.extractData?.(response.data);\n if (extractedData) {\n setData(extractedData);\n } else if (config.dataUrl) {\n await fetchData();\n }\n\n return true;\n }\n\n reset();\n return false;\n } catch (error) {\n reset();\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, setData]);\n\n // Fetch data from dataUrl\n const fetchData = useCallback(async () => {\n if (!config.dataUrl) return;\n\n try {\n const res = await config.axios.get<D>(config.dataUrl);\n setData(res.data);\n } catch (error) {\n reset();\n setAxiosAuth();\n config.onError?.(error);\n throw error;\n }\n }, [config, setData, reset, 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 data from response\n const extractedData = config.extractData?.(res.data);\n if (extractedData) {\n setData(extractedData);\n config.onLogin?.(extractedData);\n } else if (config.dataUrl) {\n await fetchData();\n const currentData = store.getState().data;\n if (currentData) config.onLogin?.(currentData);\n }\n\n callback?.();\n } catch (error) {\n reset();\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 reset();\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 reset();\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 data if missing\n if (!data && config.dataUrl) {\n fetchData().catch(() => {});\n }\n }\n }, [tokens, data, isAuthenticated, config, isTokenExpired, refresh, checkAuth, fetchData, setAxiosAuth, reset]);\n\n return { login, logout, refresh, checkAuth, fetchData };\n}\n\n// Helper: Get CSRF headers if enabled (uses getToken from config)\nfunction getCsrfHeaders(config: any): Record<string, string> {\n const headers: Record<string, string> = {};\n if (config.cookieAuth?.csrf?.enabled) {\n const csrfToken = config.cookieAuth.csrf.getToken();\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","cookieName","extractData","cookieAuth","enabled","csrf","headerName","getToken","document","match","cookie","RegExp","persistence","storage","window","localStorage","tokenKey","refreshTokenKey","dataKey","expiryKey","logoutUrl","refreshUrl","dataUrl","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","CSRF_METHODS","createAuthStore","interceptors","request","use","requestConfig","method","toLowerCase","includes","csrfToken","headers","setupCsrfInterceptor","initialTokens","getItem","expiryString","parseInt","isNaN","getStoredTokens","initialData","dataString","JSON","parse","getStoredData","initialIsAuthenticated","store","create","set","tokens","isAuthenticated","setTokens","setItem","removeItem","toString","error","setBearerToken","setAuthenticated","authenticated","setData","stringify","reset","isTokenExpired","assign","createAuthRegistry","registry","stringKey","String","validatedConfig","pendingCheckAuth","WeakMap","useAuth","setAxiosAuth","useCallback","defaults","common","refresh","getCsrfHeaders","post","response","newTokens","checkAuth","pending","doCheck","extractedData","fetchData","delete","promise","res","useEffect","timeUntilExpiry","refreshTime","Math","max","setTimeout","clearTimeout","catch","login","credentials","callback","currentData","getState","logout","AuthErrorCode","code","originalError","message","name","captureStackTrace","AuthError","toJSON","isAuthError","createAuthError","status","detail","TOKEN_EXPIRED","INVALID_CREDENTIALS","UNAUTHORIZED","CSRF_TOKEN_MISSING","FORBIDDEN","USER_NOT_FOUND","UNKNOWN","NETWORK_ERROR"],"sourceRoot":""}
package/dist/useAuth.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { AuthStore } from './authStore';
2
- export declare function useAuth<U>(store: AuthStore<U>): {
2
+ export declare function useAuth<D>(store: AuthStore<D>): {
3
3
  login: (credentials: Record<string, string>, callback?: () => void) => Promise<void>;
4
4
  logout: () => Promise<void>;
5
5
  refresh: () => Promise<boolean>;
6
6
  checkAuth: () => Promise<boolean>;
7
- getCurrentUser: () => Promise<void>;
7
+ fetchData: () => Promise<void>;
8
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jasperoosthoek/zustand-auth-registry",
3
- "version": "0.0.3",
3
+ "version": "0.1.0",
4
4
  "author": "jasperoosthoek",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/jasperoosthoek/zustand-auth-registry",
package/src/authConfig.ts CHANGED
@@ -8,22 +8,22 @@ export type TokenData = {
8
8
  tokenType: string;
9
9
  };
10
10
 
11
- export type AuthConfig<U> = {
11
+ export type AuthConfig<D> = {
12
12
  axios: AxiosInstance;
13
13
 
14
14
  // Endpoints
15
15
  loginUrl: string;
16
16
  logoutUrl?: string;
17
17
  refreshUrl?: string;
18
- getUserUrl?: string;
18
+ dataUrl?: string;
19
19
  authCheckUrl?: string; // For cookie auth verification
20
20
 
21
21
  // Token extraction from login response
22
22
  extractTokens?: (data: any) => TokenData;
23
23
 
24
- // User extraction from responses (login, checkAuth)
24
+ // Data extraction from responses (login, checkAuth)
25
25
  // Can be a function or a string key (e.g., "user" extracts data.user)
26
- extractUser?: ((data: any) => U | null) | string;
26
+ extractData?: ((data: any) => D | null) | string;
27
27
 
28
28
  // Auth header format (default: "Bearer {token}")
29
29
  formatAuthHeader?: (token: string, tokenType?: string) => string;
@@ -51,29 +51,29 @@ export type AuthConfig<U> = {
51
51
  storage?: Storage;
52
52
  tokenKey?: string;
53
53
  refreshTokenKey?: string;
54
- userKey?: string;
54
+ dataKey?: string;
55
55
  expiryKey?: string;
56
56
  };
57
57
 
58
58
  // Callbacks
59
59
  onError?: (error: any) => void;
60
- onLogin?: (user: U) => void;
60
+ onLogin?: (data: D) => void;
61
61
  onLogout?: () => void;
62
62
  };
63
63
 
64
- export type ValidatedAuthConfig<U> = {
64
+ export type ValidatedAuthConfig<D> = {
65
65
  axios: AxiosInstance;
66
66
 
67
67
  // Endpoints
68
68
  loginUrl: string;
69
69
  logoutUrl?: string;
70
70
  refreshUrl?: string;
71
- getUserUrl?: string;
71
+ dataUrl?: string;
72
72
  authCheckUrl?: string;
73
73
 
74
74
  // Extraction functions
75
75
  extractTokens: (data: any) => TokenData;
76
- extractUser?: (data: any) => U | null;
76
+ extractData?: (data: any) => D | null;
77
77
 
78
78
  // Auth header format
79
79
  formatAuthHeader: (token: string, tokenType?: string) => string;
@@ -98,17 +98,17 @@ export type ValidatedAuthConfig<U> = {
98
98
  storage: Storage;
99
99
  tokenKey: string;
100
100
  refreshTokenKey: string;
101
- userKey: string;
101
+ dataKey: string;
102
102
  expiryKey: string;
103
103
  };
104
104
 
105
105
  // Callbacks
106
106
  onError?: (error: any) => void;
107
- onLogin?: (user: U) => void;
107
+ onLogin?: (data: D) => void;
108
108
  onLogout?: () => void;
109
109
  };
110
110
 
111
- export const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfig<U> => {
111
+ export const validateAuthConfig = <D>(config: AuthConfig<D>): ValidatedAuthConfig<D> => {
112
112
  if (!config.axios) {
113
113
  throw new Error('AuthConfig: axios instance is required');
114
114
  }
@@ -136,7 +136,7 @@ export const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfi
136
136
  (typeof window !== 'undefined' && window.localStorage ? window.localStorage : {} as Storage),
137
137
  tokenKey: config.persistence?.tokenKey ?? 'token',
138
138
  refreshTokenKey: config.persistence?.refreshTokenKey ?? 'refresh_token',
139
- userKey: config.persistence?.userKey ?? 'user',
139
+ dataKey: config.persistence?.dataKey ?? 'data',
140
140
  expiryKey: config.persistence?.expiryKey ?? 'expires_at',
141
141
  };
142
142
 
@@ -145,10 +145,10 @@ export const validateAuthConfig = <U>(config: AuthConfig<U>): ValidatedAuthConfi
145
145
  loginUrl: config.loginUrl,
146
146
  logoutUrl: config.logoutUrl,
147
147
  refreshUrl: config.refreshUrl,
148
- getUserUrl: config.getUserUrl,
148
+ dataUrl: config.dataUrl,
149
149
  authCheckUrl: config.authCheckUrl,
150
150
  extractTokens: config.extractTokens ?? defaultExtractTokens,
151
- extractUser: normalizeExtractUser(config.extractUser),
151
+ extractData: normalizeExtractData(config.extractData),
152
152
  formatAuthHeader: config.formatAuthHeader ??
153
153
  ((token: string, tokenType: string = 'Bearer') => `${tokenType} ${token}`),
154
154
  autoRefresh: config.autoRefresh ?? true,
@@ -185,14 +185,14 @@ function defaultExtractTokens(data: any): TokenData {
185
185
  throw new Error('No token found in response. Provide extractTokens or ensure response contains access_token/token field.');
186
186
  }
187
187
 
188
- // Normalize extractUser: string becomes key accessor, function passed through
189
- function normalizeExtractUser<U>(
190
- extractUser?: ((data: any) => U | null) | string
191
- ): ((data: any) => U | null) | undefined {
192
- if (typeof extractUser === 'string') {
193
- return (data: any) => data[extractUser] ?? null;
188
+ // Normalize extractData: string becomes key accessor, function passed through
189
+ function normalizeExtractData<D>(
190
+ extractData?: ((data: any) => D | null) | string
191
+ ): ((data: any) => D | null) | undefined {
192
+ if (typeof extractData === 'string') {
193
+ return (data: any) => data[extractData] ?? null;
194
194
  }
195
- return extractUser;
195
+ return extractData;
196
196
  }
197
197
 
198
198
  // Create a cookie-based CSRF token getter (web only)
package/src/authStore.ts CHANGED
@@ -1,28 +1,28 @@
1
1
  import { create, StoreApi, UseBoundStore } from 'zustand';
2
2
  import { ValidatedAuthConfig, TokenData } from './authConfig';
3
3
 
4
- export type AuthState<U> = {
4
+ export type AuthState<D> = {
5
5
  isAuthenticated: boolean | null; // null = not checked yet (cookie mode)
6
- user: U | null;
6
+ data: D | null;
7
7
  tokens: TokenData | null; // null in cookie mode or when logged out
8
8
 
9
9
  // Methods
10
10
  setTokens: (tokens: TokenData) => void;
11
11
  setBearerToken: (token: string) => void; // Convenience for simple Bearer token auth
12
12
  setAuthenticated: (authenticated: boolean) => void; // For cookie mode
13
- setUser: (user: U) => void;
14
- unsetUser: () => void;
13
+ setData: (data: D) => void;
14
+ reset: () => void;
15
15
  isTokenExpired: () => boolean;
16
16
  };
17
17
 
18
- export type AuthStore<U> = UseBoundStore<StoreApi<AuthState<U>>> & {
19
- config: ValidatedAuthConfig<U>;
18
+ export type AuthStore<D> = UseBoundStore<StoreApi<AuthState<D>>> & {
19
+ config: ValidatedAuthConfig<D>;
20
20
  };
21
21
 
22
22
  // Methods that modify state (require CSRF protection)
23
23
  const CSRF_METHODS = ['post', 'put', 'patch', 'delete'];
24
24
 
25
- const setupCsrfInterceptor = <U>(config: ValidatedAuthConfig<U>): number | null => {
25
+ const setupCsrfInterceptor = <D>(config: ValidatedAuthConfig<D>): number | null => {
26
26
  if (!config.cookieAuth?.csrf.enabled) {
27
27
  return null;
28
28
  }
@@ -41,7 +41,7 @@ const setupCsrfInterceptor = <U>(config: ValidatedAuthConfig<U>): number | null
41
41
  });
42
42
  };
43
43
 
44
- export const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U> => {
44
+ export const createAuthStore = <D>(config: ValidatedAuthConfig<D>): AuthStore<D> => {
45
45
  const { persistence, cookieAuth } = config;
46
46
 
47
47
  // Set up CSRF interceptor if enabled
@@ -74,18 +74,18 @@ export const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U>
74
74
  }
75
75
  };
76
76
 
77
- const getStoredUser = (): U | null => {
77
+ const getStoredData = (): D | null => {
78
78
  if (!persistence.enabled) return null;
79
79
  try {
80
- const userString = persistence.storage.getItem(persistence.userKey);
81
- return userString ? (JSON.parse(userString) as U) : null;
80
+ const dataString = persistence.storage.getItem(persistence.dataKey);
81
+ return dataString ? (JSON.parse(dataString) as D) : null;
82
82
  } catch {
83
83
  return null;
84
84
  }
85
85
  };
86
86
 
87
87
  const initialTokens = getStoredTokens();
88
- const initialUser = getStoredUser();
88
+ const initialData = getStoredData();
89
89
 
90
90
  // Cookie mode: null (unknown until checkAuth)
91
91
  // Token mode: true/false based on token presence
@@ -93,9 +93,9 @@ export const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U>
93
93
  ? null
94
94
  : !!initialTokens?.accessToken;
95
95
 
96
- const store = create<AuthState<U>>((set, get) => ({
96
+ const store = create<AuthState<D>>((set, get) => ({
97
97
  tokens: initialTokens,
98
- user: initialUser,
98
+ data: initialData,
99
99
  isAuthenticated: initialIsAuthenticated,
100
100
 
101
101
  setTokens: (tokens: TokenData) => {
@@ -136,26 +136,26 @@ export const createAuthStore = <U>(config: ValidatedAuthConfig<U>): AuthStore<U>
136
136
  set({ isAuthenticated: authenticated });
137
137
  },
138
138
 
139
- setUser: (user: U) => {
140
- set({ user });
139
+ setData: (data: D) => {
140
+ set({ data });
141
141
 
142
142
  if (persistence.enabled) {
143
143
  try {
144
- persistence.storage.setItem(persistence.userKey, JSON.stringify(user));
144
+ persistence.storage.setItem(persistence.dataKey, JSON.stringify(data));
145
145
  } catch (error) {
146
146
  config.onError?.(error);
147
147
  }
148
148
  }
149
149
  },
150
150
 
151
- unsetUser: () => {
152
- set({ user: null, tokens: null, isAuthenticated: false });
151
+ reset: () => {
152
+ set({ data: null, tokens: null, isAuthenticated: false });
153
153
 
154
154
  if (persistence.enabled) {
155
155
  try {
156
156
  persistence.storage.removeItem(persistence.tokenKey);
157
157
  persistence.storage.removeItem(persistence.refreshTokenKey);
158
- persistence.storage.removeItem(persistence.userKey);
158
+ persistence.storage.removeItem(persistence.dataKey);
159
159
  persistence.storage.removeItem(persistence.expiryKey);
160
160
  } catch (error) {
161
161
  config.onError?.(error);
package/src/useAuth.ts CHANGED
@@ -4,8 +4,8 @@ import { AuthStore } from './authStore';
4
4
  // Promise deduplication: prevents multiple concurrent checkAuth calls per store
5
5
  const pendingCheckAuth = new WeakMap<AuthStore<any>, Promise<boolean>>();
6
6
 
7
- export function useAuth<U>(store: AuthStore<U>) {
8
- const { setTokens, setAuthenticated, setUser, unsetUser, tokens, user, isAuthenticated, isTokenExpired } = store();
7
+ export function useAuth<D>(store: AuthStore<D>) {
8
+ const { setTokens, setAuthenticated, setData, reset, tokens, data, isAuthenticated, isTokenExpired } = store();
9
9
  const config = store.config;
10
10
 
11
11
  // Set axios Authorization header (token mode only)
@@ -48,12 +48,12 @@ export function useAuth<U>(store: AuthStore<U>) {
48
48
  setAxiosAuth(newTokens.accessToken, newTokens.tokenType);
49
49
  return true;
50
50
  } catch (error) {
51
- unsetUser();
51
+ reset();
52
52
  setAxiosAuth();
53
53
  config.onError?.(error);
54
54
  return false;
55
55
  }
56
- }, [tokens, config, setTokens, unsetUser, setAxiosAuth]);
56
+ }, [tokens, config, setTokens, reset, setAxiosAuth]);
57
57
 
58
58
  // Check authentication (cookie mode) - with promise deduplication
59
59
  const checkAuth = useCallback(async (): Promise<boolean> => {
@@ -76,20 +76,20 @@ export function useAuth<U>(store: AuthStore<U>) {
76
76
  if (response.data.authenticated) {
77
77
  setAuthenticated(true);
78
78
 
79
- const extractedUser = config.extractUser?.(response.data);
80
- if (extractedUser) {
81
- setUser(extractedUser);
82
- } else if (config.getUserUrl) {
83
- await getCurrentUser();
79
+ const extractedData = config.extractData?.(response.data);
80
+ if (extractedData) {
81
+ setData(extractedData);
82
+ } else if (config.dataUrl) {
83
+ await fetchData();
84
84
  }
85
85
 
86
86
  return true;
87
87
  }
88
88
 
89
- setAuthenticated(false);
89
+ reset();
90
90
  return false;
91
91
  } catch (error) {
92
- setAuthenticated(false);
92
+ reset();
93
93
  config.onError?.(error);
94
94
  return false;
95
95
  } finally {
@@ -100,22 +100,22 @@ export function useAuth<U>(store: AuthStore<U>) {
100
100
  const promise = doCheck();
101
101
  pendingCheckAuth.set(store, promise);
102
102
  return promise;
103
- }, [store, config, setAuthenticated, setUser]);
103
+ }, [store, config, setAuthenticated, setData]);
104
104
 
105
- // Get current user
106
- const getCurrentUser = useCallback(async () => {
107
- if (!config.getUserUrl) return;
105
+ // Fetch data from dataUrl
106
+ const fetchData = useCallback(async () => {
107
+ if (!config.dataUrl) return;
108
108
 
109
109
  try {
110
- const res = await config.axios.get<U>(config.getUserUrl);
111
- setUser(res.data);
110
+ const res = await config.axios.get<D>(config.dataUrl);
111
+ setData(res.data);
112
112
  } catch (error) {
113
- unsetUser();
113
+ reset();
114
114
  setAxiosAuth();
115
115
  config.onError?.(error);
116
116
  throw error;
117
117
  }
118
- }, [config, setUser, unsetUser, setAxiosAuth]);
118
+ }, [config, setData, reset, setAxiosAuth]);
119
119
 
120
120
  // Login
121
121
  const login = async (credentials: Record<string, string>, callback?: () => void) => {
@@ -133,20 +133,20 @@ export function useAuth<U>(store: AuthStore<U>) {
133
133
  setAxiosAuth(newTokens.accessToken, newTokens.tokenType);
134
134
  }
135
135
 
136
- // Extract user from response
137
- const extractedUser = config.extractUser?.(res.data);
138
- if (extractedUser) {
139
- setUser(extractedUser);
140
- config.onLogin?.(extractedUser);
141
- } else if (config.getUserUrl) {
142
- await getCurrentUser();
143
- const currentUser = store.getState().user;
144
- if (currentUser) config.onLogin?.(currentUser);
136
+ // Extract data from response
137
+ const extractedData = config.extractData?.(res.data);
138
+ if (extractedData) {
139
+ setData(extractedData);
140
+ config.onLogin?.(extractedData);
141
+ } else if (config.dataUrl) {
142
+ await fetchData();
143
+ const currentData = store.getState().data;
144
+ if (currentData) config.onLogin?.(currentData);
145
145
  }
146
146
 
147
147
  callback?.();
148
148
  } catch (error) {
149
- unsetUser();
149
+ reset();
150
150
  setAxiosAuth();
151
151
  config.onError?.(error);
152
152
  throw error;
@@ -163,7 +163,7 @@ export function useAuth<U>(store: AuthStore<U>) {
163
163
  } catch (error) {
164
164
  config.onError?.(error);
165
165
  } finally {
166
- unsetUser();
166
+ reset();
167
167
  setAxiosAuth();
168
168
  config.onLogout?.();
169
169
  }
@@ -188,7 +188,7 @@ export function useAuth<U>(store: AuthStore<U>) {
188
188
  if (tokens.refreshToken && config.autoRefresh) {
189
189
  refresh();
190
190
  } else {
191
- unsetUser();
191
+ reset();
192
192
  }
193
193
  return;
194
194
  }
@@ -202,14 +202,14 @@ export function useAuth<U>(store: AuthStore<U>) {
202
202
  return () => clearTimeout(timer);
203
203
  }
204
204
 
205
- // Fetch user if missing
206
- if (!user && config.getUserUrl) {
207
- getCurrentUser().catch(() => {});
205
+ // Fetch data if missing
206
+ if (!data && config.dataUrl) {
207
+ fetchData().catch(() => {});
208
208
  }
209
209
  }
210
- }, [tokens, user, isAuthenticated, config, isTokenExpired, refresh, checkAuth, getCurrentUser, setAxiosAuth, unsetUser]);
210
+ }, [tokens, data, isAuthenticated, config, isTokenExpired, refresh, checkAuth, fetchData, setAxiosAuth, reset]);
211
211
 
212
- return { login, logout, refresh, checkAuth, getCurrentUser };
212
+ return { login, logout, refresh, checkAuth, fetchData };
213
213
  }
214
214
 
215
215
  // Helper: Get CSRF headers if enabled (uses getToken from config)