@eventuras/fides-auth-store 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Losol AS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # @eventuras/fides-auth-store
2
+
3
+ Framework-agnostic authentication **state** for [`@eventuras/fides-auth`](../fides-auth),
4
+ built on [XState Store](https://stately.ai/docs/xstate-store).
5
+
6
+ It holds who is logged in, admin status, and error state, plus the logic to keep
7
+ that state in sync — with no dependency on any UI framework or server runtime.
8
+ The application supplies a `checkAuthStatus` callback; the store never reads
9
+ cookies or talks to a server itself, so it can be driven from Next.js, React
10
+ Router, or plain JavaScript alike.
11
+
12
+ React bindings (hooks) are layered on top of this package separately.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pnpm add @eventuras/fides-auth-store
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```ts
23
+ import {
24
+ configureAuthLogger,
25
+ createAuthStore,
26
+ initializeAuth,
27
+ startSessionMonitor,
28
+ } from '@eventuras/fides-auth-store';
29
+
30
+ // Wire fides-auth's internal logging to @eventuras/logger (once, at startup).
31
+ configureAuthLogger();
32
+
33
+ export const authStore = createAuthStore({
34
+ checkAuthStatus: getAuthStatus, // () => Promise<AuthStatus>
35
+ config: { adminRole: 'Admin', loggerNamespace: 'myapp:auth' },
36
+ });
37
+
38
+ // Populate the store from the current auth status.
39
+ await initializeAuth(authStore, getAuthStatus);
40
+
41
+ // Poll for session changes; returns a cleanup function.
42
+ const stop = startSessionMonitor(authStore, getAuthStatus, {
43
+ interval: 30_000,
44
+ onSessionExpired: () => console.warn('Session expired'),
45
+ });
46
+ ```
47
+
48
+ ## API
49
+
50
+ - `createAuthStore(options)` — create the store.
51
+ - `initializeAuth(store, checkAuthStatus)` — set initial state from a status check.
52
+ - `checkAuth(store, checkAuthStatus)` — re-check and update state.
53
+ - `startSessionMonitor(store, checkAuthStatus, config)` — poll on an interval; returns a cleanup function.
54
+ - `configureAuthLogger()` — route `@eventuras/fides-auth` logging through `@eventuras/logger`.
55
+ - Types: `AuthStoreContext`, `AuthStoreConfig`, `SessionMonitorConfig`, `SessionUser`, `AuthStatus`.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Configures fides-auth to use @eventuras/logger for all internal logging.
3
+ *
4
+ * Call this once at application startup, before creating the auth store.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { configureAuthLogger, createAuthStore } from '@eventuras/fides-auth-store';
9
+ *
10
+ * configureAuthLogger();
11
+ * const authStore = createAuthStore({ checkAuthStatus });
12
+ * ```
13
+ */
14
+ export declare function configureAuthLogger(): void;
15
+ //# sourceMappingURL=configure-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure-logger.d.ts","sourceRoot":"","sources":["../src/configure-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Framework-agnostic authentication state store.
3
+ *
4
+ * Built on XState Store, this package holds authentication *state* (who is logged
5
+ * in, admin status, errors) and the logic to keep it in sync — with no dependency
6
+ * on any UI framework or server runtime. The app supplies a `checkAuthStatus`
7
+ * callback; the store does not read cookies or talk to a server itself, so it can
8
+ * be driven from Next.js, React Router, or plain JavaScript alike.
9
+ *
10
+ * React bindings (hooks) live in a separate package layered on top of this one.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import {
15
+ * configureAuthLogger,
16
+ * createAuthStore,
17
+ * initializeAuth,
18
+ * startSessionMonitor,
19
+ * } from '@eventuras/fides-auth-store';
20
+ *
21
+ * configureAuthLogger();
22
+ *
23
+ * export const authStore = createAuthStore({
24
+ * checkAuthStatus: getAuthStatus,
25
+ * config: { adminRole: 'Admin', loggerNamespace: 'myapp:auth' },
26
+ * });
27
+ *
28
+ * await initializeAuth(authStore, getAuthStatus);
29
+ *
30
+ * const stop = startSessionMonitor(authStore, getAuthStatus, {
31
+ * interval: 30_000,
32
+ * onSessionExpired: () => console.warn('Session expired'),
33
+ * });
34
+ * ```
35
+ */
36
+ export { createAuthStore, initializeAuth, checkAuth, type AuthStoreContext, type AuthStoreConfig, } from './store';
37
+ export { startSessionMonitor, type SessionMonitorConfig, } from './session-monitor';
38
+ export { configureAuthLogger } from './configure-logger';
39
+ export type { SessionUser, AuthStatus } from './types';
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EACL,eAAe,EACf,cAAc,EACd,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,mBAAmB,EACnB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,327 @@
1
+ import { createStore } from "@xstate/store";
2
+ import { Logger } from "@eventuras/logger";
3
+ import { configureLogger } from "@eventuras/fides-auth/logger";
4
+ //#region src/store.ts
5
+ /**
6
+ * Default configuration values
7
+ */
8
+ var DEFAULT_CONFIG$1 = {
9
+ adminRole: "Admin",
10
+ loggerNamespace: "fides:auth-store"
11
+ };
12
+ /**
13
+ * Creates an authentication store with XState Store
14
+ *
15
+ * @param options - Configuration for the auth store
16
+ * @returns Configured XState store
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const authStore = createAuthStore({
21
+ * checkAuthStatus: async () => getAuthStatus(),
22
+ * config: {
23
+ * adminRole: 'Admin',
24
+ * loggerNamespace: 'myapp:auth',
25
+ * }
26
+ * });
27
+ * ```
28
+ */
29
+ function createAuthStore(options) {
30
+ const config = {
31
+ ...DEFAULT_CONFIG$1,
32
+ ...options.config
33
+ };
34
+ const logger = Logger.create({
35
+ namespace: config.loggerNamespace,
36
+ context: { component: "AuthStore" }
37
+ });
38
+ return createStore({
39
+ context: {
40
+ user: null,
41
+ isAdmin: false,
42
+ isAuthenticated: false,
43
+ error: null,
44
+ lastChecked: null,
45
+ isInitializing: true
46
+ },
47
+ on: {
48
+ /**
49
+ * Initialize authentication - check current status
50
+ */
51
+ initialize: () => ({
52
+ user: null,
53
+ isAdmin: false,
54
+ isAuthenticated: false,
55
+ error: null,
56
+ lastChecked: null,
57
+ isInitializing: true
58
+ }),
59
+ /**
60
+ * Authentication check succeeded
61
+ */
62
+ authSuccess: (_context, event) => {
63
+ logger.info({ user: event.user.roles }, "User authenticated");
64
+ return {
65
+ user: event.user,
66
+ isAdmin: event.user.roles?.includes(config.adminRole) ?? false,
67
+ isAuthenticated: true,
68
+ error: null,
69
+ lastChecked: /* @__PURE__ */ new Date(),
70
+ isInitializing: false
71
+ };
72
+ },
73
+ /**
74
+ * Authentication check failed - not authenticated
75
+ */
76
+ authFailed: (_context, event = {}) => {
77
+ logger.info("User not authenticated");
78
+ return {
79
+ user: null,
80
+ isAdmin: false,
81
+ isAuthenticated: false,
82
+ error: event.error || null,
83
+ lastChecked: /* @__PURE__ */ new Date(),
84
+ isInitializing: false
85
+ };
86
+ },
87
+ /**
88
+ * Session expired
89
+ */
90
+ sessionExpired: () => {
91
+ logger.warn("Session expired");
92
+ return {
93
+ user: null,
94
+ isAdmin: false,
95
+ isAuthenticated: false,
96
+ error: "Session expired",
97
+ lastChecked: /* @__PURE__ */ new Date(),
98
+ isInitializing: false
99
+ };
100
+ },
101
+ /**
102
+ * User logged out
103
+ */
104
+ logout: () => {
105
+ logger.info("User logged out");
106
+ return {
107
+ user: null,
108
+ isAdmin: false,
109
+ isAuthenticated: false,
110
+ error: null,
111
+ lastChecked: /* @__PURE__ */ new Date(),
112
+ isInitializing: false
113
+ };
114
+ },
115
+ /**
116
+ * Login success
117
+ */
118
+ loginSuccess: (_context, event) => {
119
+ logger.info({ user: event.user.email }, "Login successful");
120
+ return {
121
+ user: event.user,
122
+ isAdmin: event.user.roles?.includes(config.adminRole) ?? false,
123
+ isAuthenticated: true,
124
+ error: null,
125
+ lastChecked: /* @__PURE__ */ new Date(),
126
+ isInitializing: false
127
+ };
128
+ },
129
+ /**
130
+ * Update last checked timestamp
131
+ */
132
+ updateLastChecked: (context) => ({
133
+ ...context,
134
+ lastChecked: /* @__PURE__ */ new Date()
135
+ }),
136
+ /**
137
+ * Set error
138
+ */
139
+ setError: (context, event) => ({
140
+ ...context,
141
+ error: event.error
142
+ }),
143
+ /**
144
+ * Clear error
145
+ */
146
+ clearError: (context) => ({
147
+ ...context,
148
+ error: null
149
+ })
150
+ }
151
+ });
152
+ }
153
+ /**
154
+ * Helper function to initialize auth by checking status
155
+ */
156
+ async function initializeAuth(store, checkAuthStatus) {
157
+ const logger = Logger.create({
158
+ namespace: "fides:auth-store",
159
+ context: { component: "initializeAuth" }
160
+ });
161
+ logger.debug("Initializing authentication");
162
+ store.send({ type: "initialize" });
163
+ try {
164
+ const result = await checkAuthStatus();
165
+ logger.debug({ authenticated: result.authenticated }, "Auth status checked");
166
+ if (result.authenticated && result.user) store.send({
167
+ type: "authSuccess",
168
+ user: result.user
169
+ });
170
+ else store.send({ type: "authFailed" });
171
+ } catch (error) {
172
+ logger.debug({ error }, "Auth check returned no session");
173
+ store.send({ type: "authFailed" });
174
+ }
175
+ }
176
+ /**
177
+ * Helper function to check auth status and update store
178
+ */
179
+ async function checkAuth(store, checkAuthStatus) {
180
+ const logger = Logger.create({
181
+ namespace: "fides:auth-store",
182
+ context: { component: "checkAuth" }
183
+ });
184
+ logger.debug("Checking authentication status");
185
+ try {
186
+ const result = await checkAuthStatus();
187
+ logger.debug({ authenticated: result.authenticated }, "Auth status checked");
188
+ if (result.authenticated && result.user) store.send({
189
+ type: "authSuccess",
190
+ user: result.user
191
+ });
192
+ else store.send({ type: "authFailed" });
193
+ store.send({ type: "updateLastChecked" });
194
+ } catch (error) {
195
+ const err = error;
196
+ if (err?.code === "OAUTH_RESPONSE_BODY_ERROR" && err?.error === "invalid_grant") {
197
+ logger.info("Session ended - refresh token expired or invalid");
198
+ store.send({ type: "sessionExpired" });
199
+ } else {
200
+ const errorDetails = { message: error instanceof Error ? error.message : "Unknown error" };
201
+ if (error && typeof error === "object") {
202
+ const oauthError = error;
203
+ if (oauthError.code) errorDetails.code = oauthError.code;
204
+ if (oauthError.error) errorDetails.error = oauthError.error;
205
+ if (oauthError.error_description) errorDetails.error_description = oauthError.error_description;
206
+ if (oauthError.status) errorDetails.status = oauthError.status;
207
+ }
208
+ logger.error(errorDetails, "Auth check error");
209
+ store.send({
210
+ type: "authFailed",
211
+ error: error instanceof Error ? error.message : "Unknown error"
212
+ });
213
+ }
214
+ }
215
+ }
216
+ //#endregion
217
+ //#region src/session-monitor.ts
218
+ var DEFAULT_CONFIG = {
219
+ interval: 3e4,
220
+ loggerNamespace: "fides:session-monitor"
221
+ };
222
+ /**
223
+ * Creates a session monitor that polls auth status at regular intervals
224
+ *
225
+ * This is designed to be used with React's useEffect for cleanup.
226
+ *
227
+ * @param store - The auth store to update
228
+ * @param checkAuthStatus - Function to check authentication status
229
+ * @param config - Optional configuration
230
+ * @returns Cleanup function to stop monitoring
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * useEffect(() => {
235
+ * const cleanup = startSessionMonitor(authStore, checkAuthStatus, {
236
+ * interval: 30_000,
237
+ * onSessionExpired: () => {
238
+ * toast.warn('Your session has expired');
239
+ * }
240
+ * });
241
+ *
242
+ * return cleanup;
243
+ * }, []);
244
+ * ```
245
+ */
246
+ function startSessionMonitor(store, checkAuthStatus, config = {}) {
247
+ const finalConfig = {
248
+ ...DEFAULT_CONFIG,
249
+ ...config
250
+ };
251
+ const logger = Logger.create({
252
+ namespace: finalConfig.loggerNamespace,
253
+ context: { component: "SessionMonitor" }
254
+ });
255
+ logger.debug({ interval: finalConfig.interval }, "Starting session monitor");
256
+ let isActive = true;
257
+ let timeoutId = null;
258
+ const poll = async () => {
259
+ if (!isActive) return;
260
+ try {
261
+ const result = await checkAuthStatus();
262
+ logger.debug({ authenticated: result.authenticated }, "Session monitor check");
263
+ if (!result.authenticated) {
264
+ logger.info("Session monitor detected unauthenticated state - session ended");
265
+ store.send({ type: "sessionExpired" });
266
+ if (finalConfig.onSessionExpired) finalConfig.onSessionExpired();
267
+ return;
268
+ }
269
+ if (result.user) store.send({
270
+ type: "authSuccess",
271
+ user: result.user
272
+ });
273
+ } catch (error) {
274
+ const err = error;
275
+ if (err?.code === "OAUTH_RESPONSE_BODY_ERROR" && err?.error === "invalid_grant") {
276
+ logger.info("Session monitor detected expired refresh token - user session ended");
277
+ store.send({ type: "sessionExpired" });
278
+ if (finalConfig.onSessionExpired) finalConfig.onSessionExpired();
279
+ return;
280
+ }
281
+ const errorDetails = { message: error instanceof Error ? error.message : "Unknown error" };
282
+ if (error && typeof error === "object") {
283
+ const oauthError = error;
284
+ if (oauthError.code) errorDetails.code = oauthError.code;
285
+ if (oauthError.error) errorDetails.error = oauthError.error;
286
+ if (oauthError.error_description) errorDetails.error_description = oauthError.error_description;
287
+ if (oauthError.status) errorDetails.status = oauthError.status;
288
+ }
289
+ logger.error(errorDetails, "Session monitor error");
290
+ if (finalConfig.onError && error instanceof Error) finalConfig.onError(error);
291
+ }
292
+ if (isActive) timeoutId = setTimeout(poll, finalConfig.interval);
293
+ };
294
+ timeoutId = setTimeout(poll, finalConfig.interval);
295
+ return () => {
296
+ logger.debug("Stopping session monitor");
297
+ isActive = false;
298
+ if (timeoutId) {
299
+ clearTimeout(timeoutId);
300
+ timeoutId = null;
301
+ }
302
+ };
303
+ }
304
+ //#endregion
305
+ //#region src/configure-logger.ts
306
+ /**
307
+ * Configures fides-auth to use @eventuras/logger for all internal logging.
308
+ *
309
+ * Call this once at application startup, before creating the auth store.
310
+ *
311
+ * @example
312
+ * ```typescript
313
+ * import { configureAuthLogger, createAuthStore } from '@eventuras/fides-auth-store';
314
+ *
315
+ * configureAuthLogger();
316
+ * const authStore = createAuthStore({ checkAuthStatus });
317
+ * ```
318
+ */
319
+ function configureAuthLogger() {
320
+ configureLogger({ create(options) {
321
+ return Logger.create(options);
322
+ } });
323
+ }
324
+ //#endregion
325
+ export { checkAuth, configureAuthLogger, createAuthStore, initializeAuth, startSessionMonitor };
326
+
327
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/store.ts","../src/session-monitor.ts","../src/configure-logger.ts"],"sourcesContent":["import { createStore } from '@xstate/store';\nimport { Logger } from '@eventuras/logger';\nimport type { SessionUser, AuthStatus } from './types';\n\n/**\n * Authentication store context\n */\nexport type AuthStoreContext = {\n user: SessionUser | null;\n isAdmin: boolean;\n isAuthenticated: boolean;\n error: string | null;\n lastChecked: Date | null;\n isInitializing: boolean;\n};\n\n/**\n * Configuration for the auth store\n */\nexport type AuthStoreConfig = {\n /**\n * Function to check current authentication status\n */\n checkAuthStatus: () => Promise<AuthStatus>;\n\n /**\n * Optional configuration\n */\n config?: {\n /**\n * Role name that indicates admin access\n * @default 'Admin'\n */\n adminRole?: string;\n\n /**\n * Namespace for logger\n * @default 'fides-auth-next:store'\n */\n loggerNamespace?: string;\n };\n};\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG = {\n adminRole: 'Admin',\n loggerNamespace: 'fides:auth-store',\n};\n\n/**\n * Creates an authentication store with XState Store\n *\n * @param options - Configuration for the auth store\n * @returns Configured XState store\n *\n * @example\n * ```typescript\n * const authStore = createAuthStore({\n * checkAuthStatus: async () => getAuthStatus(),\n * config: {\n * adminRole: 'Admin',\n * loggerNamespace: 'myapp:auth',\n * }\n * });\n * ```\n */\nexport function createAuthStore(options: AuthStoreConfig) {\n const config = { ...DEFAULT_CONFIG, ...options.config };\n const logger = Logger.create({\n namespace: config.loggerNamespace,\n context: { component: 'AuthStore' },\n });\n\n /**\n * Initial context values\n */\n const initialContext: AuthStoreContext = {\n user: null,\n isAdmin: false,\n isAuthenticated: false,\n error: null,\n lastChecked: null,\n isInitializing: true,\n };\n\n /**\n * Create the store with events\n */\n const store = createStore(\n {\n context: initialContext,\n on: {\n /**\n * Initialize authentication - check current status\n */\n initialize: () => ({\n user: null,\n isAdmin: false,\n isAuthenticated: false,\n error: null,\n lastChecked: null,\n isInitializing: true,\n }),\n\n /**\n * Authentication check succeeded\n */\n authSuccess: (_context: AuthStoreContext, event: { user: SessionUser; }) => {\n logger.info({ user: event.user.roles }, 'User authenticated');\n return {\n user: event.user,\n isAdmin: event.user.roles?.includes(config.adminRole) ?? false,\n isAuthenticated: true,\n error: null,\n lastChecked: new Date(),\n isInitializing: false,\n };\n },\n\n /**\n * Authentication check failed - not authenticated\n */\n authFailed: (_context: AuthStoreContext, event: { error?: string; } = {}) => {\n logger.info('User not authenticated');\n return {\n user: null,\n isAdmin: false,\n isAuthenticated: false,\n error: event.error || null,\n lastChecked: new Date(),\n isInitializing: false,\n };\n },\n\n /**\n * Session expired\n */\n sessionExpired: () => {\n logger.warn('Session expired');\n return {\n user: null,\n isAdmin: false,\n isAuthenticated: false,\n error: 'Session expired',\n lastChecked: new Date(),\n isInitializing: false,\n };\n },\n\n /**\n * User logged out\n */\n logout: () => {\n logger.info('User logged out');\n return {\n user: null,\n isAdmin: false,\n isAuthenticated: false,\n error: null,\n lastChecked: new Date(),\n isInitializing: false,\n };\n },\n\n /**\n * Login success\n */\n loginSuccess: (_context: AuthStoreContext, event: { user: SessionUser; }) => {\n logger.info({ user: event.user.email }, 'Login successful');\n return {\n user: event.user,\n isAdmin: event.user.roles?.includes(config.adminRole) ?? false,\n isAuthenticated: true,\n error: null,\n lastChecked: new Date(),\n isInitializing: false,\n };\n },\n\n /**\n * Update last checked timestamp\n */\n updateLastChecked: (context: AuthStoreContext) => ({\n ...context,\n lastChecked: new Date(),\n }),\n\n /**\n * Set error\n */\n setError: (context: AuthStoreContext, event: { error: string; }) => ({\n ...context,\n error: event.error,\n }),\n\n /**\n * Clear error\n */\n clearError: (context: AuthStoreContext) => ({\n ...context,\n error: null,\n }),\n },\n }\n );\n\n return store;\n}\n\n/**\n * Helper function to initialize auth by checking status\n */\nexport async function initializeAuth(\n store: ReturnType<typeof createAuthStore>,\n checkAuthStatus: () => Promise<AuthStatus>\n) {\n const logger = Logger.create({\n namespace: 'fides:auth-store',\n context: { component: 'initializeAuth' },\n });\n\n logger.debug('Initializing authentication');\n store.send({ type: 'initialize' });\n\n try {\n const result = await checkAuthStatus();\n logger.debug({ authenticated: result.authenticated }, 'Auth status checked');\n\n if (result.authenticated && result.user) {\n store.send({ type: 'authSuccess', user: result.user });\n } else {\n store.send({ type: 'authFailed' });\n }\n } catch (error) {\n logger.debug({ error }, 'Auth check returned no session');\n store.send({ type: 'authFailed' });\n }\n}\n\n/**\n * Helper function to check auth status and update store\n */\nexport async function checkAuth(\n store: ReturnType<typeof createAuthStore>,\n checkAuthStatus: () => Promise<AuthStatus>\n) {\n const logger = Logger.create({\n namespace: 'fides:auth-store',\n context: { component: 'checkAuth' },\n });\n\n logger.debug('Checking authentication status');\n\n try {\n const result = await checkAuthStatus();\n logger.debug({ authenticated: result.authenticated }, 'Auth status checked');\n\n if (result.authenticated && result.user) {\n store.send({ type: 'authSuccess', user: result.user });\n } else {\n store.send({ type: 'authFailed' });\n }\n\n store.send({ type: 'updateLastChecked' });\n } catch (error) {\n // Check if this is an expected invalid_grant error (expired refresh token)\n const err = error as { code?: string; error?: string; error_description?: string; };\n const isInvalidGrant =\n err?.code === 'OAUTH_RESPONSE_BODY_ERROR' && err?.error === 'invalid_grant';\n\n if (isInvalidGrant) {\n // This is expected during logout or session expiry - log at info level\n logger.info('Session ended - refresh token expired or invalid');\n store.send({ type: 'sessionExpired' });\n } else {\n // Unexpected error during auth check - log with details\n const errorDetails: Record<string, unknown> = {\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n\n // Extract OAuth error details if present\n if (error && typeof error === 'object') {\n const oauthError = error as any;\n if (oauthError.code) errorDetails.code = oauthError.code;\n if (oauthError.error) errorDetails.error = oauthError.error;\n if (oauthError.error_description)\n errorDetails.error_description = oauthError.error_description;\n if (oauthError.status) errorDetails.status = oauthError.status;\n }\n\n logger.error(errorDetails, 'Auth check error');\n store.send({\n type: 'authFailed',\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n}\n","import { Logger } from '@eventuras/logger';\nimport type { createAuthStore } from './store';\nimport type { AuthStatus } from './types';\n\n/**\n * Configuration for session monitoring\n */\nexport type SessionMonitorConfig = {\n /**\n * Interval in milliseconds for session monitoring polling\n * @default 30000 (30 seconds)\n */\n interval?: number;\n\n /**\n * Namespace for logger\n * @default 'fides:session-monitor'\n */\n loggerNamespace?: string;\n\n /**\n * Callback when session expires\n */\n onSessionExpired?: () => void;\n\n /**\n * Callback when session check fails\n */\n onError?: (error: Error) => void;\n};\n\nconst DEFAULT_CONFIG = {\n interval: 30_000, // 30 seconds\n loggerNamespace: 'fides:session-monitor',\n};\n\n/**\n * Creates a session monitor that polls auth status at regular intervals\n *\n * This is designed to be used with React's useEffect for cleanup.\n *\n * @param store - The auth store to update\n * @param checkAuthStatus - Function to check authentication status\n * @param config - Optional configuration\n * @returns Cleanup function to stop monitoring\n *\n * @example\n * ```typescript\n * useEffect(() => {\n * const cleanup = startSessionMonitor(authStore, checkAuthStatus, {\n * interval: 30_000,\n * onSessionExpired: () => {\n * toast.warn('Your session has expired');\n * }\n * });\n *\n * return cleanup;\n * }, []);\n * ```\n */\nexport function startSessionMonitor(\n store: ReturnType<typeof createAuthStore>,\n checkAuthStatus: () => Promise<AuthStatus>,\n config: SessionMonitorConfig = {}\n): () => void {\n const finalConfig = { ...DEFAULT_CONFIG, ...config };\n const logger = Logger.create({\n namespace: finalConfig.loggerNamespace,\n context: { component: 'SessionMonitor' },\n });\n\n logger.debug({ interval: finalConfig.interval }, 'Starting session monitor');\n\n let isActive = true;\n // Portable timer handle: `number` in the browser, `NodeJS.Timeout` under Node —\n // this package is framework-agnostic and runs in both.\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const poll = async (): Promise<void> => {\n if (!isActive) return;\n\n try {\n const result = await checkAuthStatus();\n logger.debug({ authenticated: result.authenticated }, 'Session monitor check');\n\n if (!result.authenticated) {\n // User is no longer authenticated - session ended\n logger.info('Session monitor detected unauthenticated state - session ended');\n store.send({ type: 'sessionExpired' });\n\n if (finalConfig.onSessionExpired) {\n finalConfig.onSessionExpired();\n }\n\n // Stop monitoring after session expires\n return;\n }\n\n if (result.user) {\n store.send({ type: 'authSuccess', user: result.user });\n }\n } catch (error) {\n // Check if this is an expected invalid_grant error (expired refresh token)\n const err = error as { code?: string; error?: string; error_description?: string; };\n const isInvalidGrant =\n err?.code === 'OAUTH_RESPONSE_BODY_ERROR' && err?.error === 'invalid_grant';\n\n if (isInvalidGrant) {\n // This is expected during logout or session expiry - log at info level\n logger.info('Session monitor detected expired refresh token - user session ended');\n store.send({ type: 'sessionExpired' });\n\n if (finalConfig.onSessionExpired) {\n finalConfig.onSessionExpired();\n }\n\n // Stop monitoring after session expires\n return;\n }\n\n // Unexpected error during auth check - log with details\n const errorDetails: Record<string, unknown> = {\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n\n // Extract OAuth error details if present\n if (error && typeof error === 'object') {\n const oauthError = error as any;\n if (oauthError.code) errorDetails.code = oauthError.code;\n if (oauthError.error) errorDetails.error = oauthError.error;\n if (oauthError.error_description)\n errorDetails.error_description = oauthError.error_description;\n if (oauthError.status) errorDetails.status = oauthError.status;\n }\n\n logger.error(errorDetails, 'Session monitor error');\n\n if (finalConfig.onError && error instanceof Error) {\n finalConfig.onError(error);\n }\n }\n\n // Schedule next poll if still active\n if (isActive) {\n timeoutId = setTimeout(poll, finalConfig.interval);\n }\n };\n\n // Start first poll\n timeoutId = setTimeout(poll, finalConfig.interval);\n\n // Return cleanup function\n return () => {\n logger.debug('Stopping session monitor');\n isActive = false;\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n}\n","/**\n * Configures fides-auth to use @eventuras/logger for all internal logging.\n *\n * Call this once at application startup, before creating the auth store.\n *\n * @example\n * ```typescript\n * import { configureAuthLogger, createAuthStore } from '@eventuras/fides-auth-store';\n *\n * configureAuthLogger();\n * const authStore = createAuthStore({ checkAuthStatus });\n * ```\n */\n\nimport { configureLogger } from '@eventuras/fides-auth/logger';\nimport { Logger } from '@eventuras/logger';\n\nexport function configureAuthLogger(): void {\n configureLogger({\n create(options) {\n return Logger.create(options);\n },\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { createAuthStore } from './store';
2
+ import { AuthStatus } from './types';
3
+ /**
4
+ * Configuration for session monitoring
5
+ */
6
+ export type SessionMonitorConfig = {
7
+ /**
8
+ * Interval in milliseconds for session monitoring polling
9
+ * @default 30000 (30 seconds)
10
+ */
11
+ interval?: number;
12
+ /**
13
+ * Namespace for logger
14
+ * @default 'fides:session-monitor'
15
+ */
16
+ loggerNamespace?: string;
17
+ /**
18
+ * Callback when session expires
19
+ */
20
+ onSessionExpired?: () => void;
21
+ /**
22
+ * Callback when session check fails
23
+ */
24
+ onError?: (error: Error) => void;
25
+ };
26
+ /**
27
+ * Creates a session monitor that polls auth status at regular intervals
28
+ *
29
+ * This is designed to be used with React's useEffect for cleanup.
30
+ *
31
+ * @param store - The auth store to update
32
+ * @param checkAuthStatus - Function to check authentication status
33
+ * @param config - Optional configuration
34
+ * @returns Cleanup function to stop monitoring
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * useEffect(() => {
39
+ * const cleanup = startSessionMonitor(authStore, checkAuthStatus, {
40
+ * interval: 30_000,
41
+ * onSessionExpired: () => {
42
+ * toast.warn('Your session has expired');
43
+ * }
44
+ * });
45
+ *
46
+ * return cleanup;
47
+ * }, []);
48
+ * ```
49
+ */
50
+ export declare function startSessionMonitor(store: ReturnType<typeof createAuthStore>, checkAuthStatus: () => Promise<AuthStatus>, config?: SessionMonitorConfig): () => void;
51
+ //# sourceMappingURL=session-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-monitor.d.ts","sourceRoot":"","sources":["../src/session-monitor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC,CAAC;AAOF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EACzC,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,EAC1C,MAAM,GAAE,oBAAyB,GAChC,MAAM,IAAI,CAgGZ"}
@@ -0,0 +1,81 @@
1
+ import { SessionUser, AuthStatus } from './types';
2
+ /**
3
+ * Authentication store context
4
+ */
5
+ export type AuthStoreContext = {
6
+ user: SessionUser | null;
7
+ isAdmin: boolean;
8
+ isAuthenticated: boolean;
9
+ error: string | null;
10
+ lastChecked: Date | null;
11
+ isInitializing: boolean;
12
+ };
13
+ /**
14
+ * Configuration for the auth store
15
+ */
16
+ export type AuthStoreConfig = {
17
+ /**
18
+ * Function to check current authentication status
19
+ */
20
+ checkAuthStatus: () => Promise<AuthStatus>;
21
+ /**
22
+ * Optional configuration
23
+ */
24
+ config?: {
25
+ /**
26
+ * Role name that indicates admin access
27
+ * @default 'Admin'
28
+ */
29
+ adminRole?: string;
30
+ /**
31
+ * Namespace for logger
32
+ * @default 'fides-auth-next:store'
33
+ */
34
+ loggerNamespace?: string;
35
+ };
36
+ };
37
+ /**
38
+ * Creates an authentication store with XState Store
39
+ *
40
+ * @param options - Configuration for the auth store
41
+ * @returns Configured XState store
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const authStore = createAuthStore({
46
+ * checkAuthStatus: async () => getAuthStatus(),
47
+ * config: {
48
+ * adminRole: 'Admin',
49
+ * loggerNamespace: 'myapp:auth',
50
+ * }
51
+ * });
52
+ * ```
53
+ */
54
+ export declare function createAuthStore(options: AuthStoreConfig): import('@xstate/store').Store<AuthStoreContext, {
55
+ initialize: unknown;
56
+ authSuccess: {
57
+ user: SessionUser;
58
+ };
59
+ authFailed: {
60
+ error?: string;
61
+ } | undefined;
62
+ sessionExpired: unknown;
63
+ logout: unknown;
64
+ loginSuccess: {
65
+ user: SessionUser;
66
+ };
67
+ updateLastChecked: unknown;
68
+ setError: {
69
+ error: string;
70
+ };
71
+ clearError: unknown;
72
+ }, never>;
73
+ /**
74
+ * Helper function to initialize auth by checking status
75
+ */
76
+ export declare function initializeAuth(store: ReturnType<typeof createAuthStore>, checkAuthStatus: () => Promise<AuthStatus>): Promise<void>;
77
+ /**
78
+ * Helper function to check auth status and update store
79
+ */
80
+ export declare function checkAuth(store: ReturnType<typeof createAuthStore>, checkAuthStatus: () => Promise<AuthStatus>): Promise<void>;
81
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEvD;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;;WAGG;QACH,SAAS,CAAC,EAAE,MAAM,CAAC;QAEnB;;;WAGG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC;AAUF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe;;;cAyCS,WAAW;;;gBAeV,MAAM;;;;;cA6CN,WAAW;;;;eAuBf,MAAM;;;UAiBnE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EACzC,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,iBAuB3C;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EACzC,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,iBAqD3C"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@eventuras/fides-auth-store",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic authentication state store (XState Store) for @eventuras/fides-auth",
5
+ "keywords": [
6
+ "authentication",
7
+ "oauth",
8
+ "oidc",
9
+ "session",
10
+ "state-management",
11
+ "xstate",
12
+ "store"
13
+ ],
14
+ "homepage": "https://github.com/losol/fides-auth/tree/main/packages/fides-auth-store#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/losol/fides-auth/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/losol/fides-auth.git",
21
+ "directory": "packages/fides-auth-store"
22
+ },
23
+ "license": "MIT",
24
+ "author": "losol <losol@users.noreply.github.com>",
25
+ "sideEffects": false,
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ }
32
+ },
33
+ "main": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "files": [
36
+ "dist",
37
+ "LICENSE",
38
+ "README.md"
39
+ ],
40
+ "dependencies": {
41
+ "@eventuras/logger": "^0.8.1",
42
+ "@xstate/store": "^4.0.0",
43
+ "@eventuras/fides-auth": "0.9.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^22.20.0",
47
+ "vite": "^8.0.8",
48
+ "vitest": "^4.1.4",
49
+ "@eventuras/typescript-config": "1.0.0",
50
+ "@eventuras/vite-config": "0.2.2"
51
+ },
52
+ "engines": {
53
+ "node": ">=18"
54
+ },
55
+ "scripts": {
56
+ "build": "vite build",
57
+ "dev": "vite build --watch",
58
+ "test": "vitest run",
59
+ "test:watch": "vitest"
60
+ }
61
+ }