@eventuras/fides-auth-store 0.2.2 → 0.3.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/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { createStore } from "@xstate/store";
2
2
  import { configureLogger, createLogger } from "@eventuras/fides-auth/logger";
3
3
  import { SESSION_EVENT } from "@eventuras/fides-auth/session-events";
4
4
  import { Logger } from "@eventuras/logger";
5
- //#region src/store.ts
5
+ // src/store.ts
6
6
  /**
7
7
  * Default configuration values
8
8
  */
@@ -117,7 +117,7 @@ function createAuthStore(options) {
117
117
  * Login success
118
118
  */
119
119
  loginSuccess: (_context, event) => {
120
- logger.info({ user: event.user.email }, "Login successful");
120
+ logger.info({ user: event.user.email ?? event.user.name }, "Login successful");
121
121
  return {
122
122
  user: event.user,
123
123
  isAdmin: event.user.roles?.includes(config.adminRole) ?? false,
@@ -214,8 +214,7 @@ async function checkAuth(store, checkAuthStatus) {
214
214
  }
215
215
  }
216
216
  }
217
- //#endregion
218
- //#region src/session-monitor.ts
217
+ // src/session-monitor.ts
219
218
  var DEFAULT_CONFIG = {
220
219
  interval: 3e4,
221
220
  loggerNamespace: "fides:session-monitor"
@@ -318,8 +317,7 @@ function startSessionMonitor(store, checkAuthStatus, config = {}) {
318
317
  }
319
318
  };
320
319
  }
321
- //#endregion
322
- //#region src/configure-logger.ts
320
+ // src/configure-logger.ts
323
321
  /**
324
322
  * Configures fides-auth to use @eventuras/logger for all internal logging.
325
323
  *
@@ -338,7 +336,6 @@ function configureAuthLogger() {
338
336
  return Logger.create(options);
339
337
  } });
340
338
  }
341
- //#endregion
342
339
  export { checkAuth, configureAuthLogger, createAuthStore, initializeAuth, startSessionMonitor };
343
340
 
344
341
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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 { createLogger } from '@eventuras/fides-auth/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 = createLogger({\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 = createLogger({\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 = createLogger({\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 { createLogger } from '@eventuras/fides-auth/logger';\nimport { SESSION_EVENT, type SessionClientEvent } from '@eventuras/fides-auth/session-events';\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 /**\n * Called for every session lifecycle event the monitor observes, using the\n * same vocabulary as the server-side events.\n *\n * The logger writes to the browser console, which production never sees.\n * Forward these to your own endpoint, Sentry or an OTLP collector to get the\n * client half of a session's story into the same place as the server half.\n * The library ships no transport of its own.\n */\n onEvent?: (event: SessionClientEvent) => 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 // The pluggable factory, not @eventuras/logger directly — otherwise\n // configureAuthLogger() has no effect here and this one module logs to a\n // different place than the rest of the package.\n const logger = createLogger({\n namespace: finalConfig.loggerNamespace,\n context: { component: 'SessionMonitor' },\n });\n\n // A consumer's beacon must never be able to stop the monitor.\n const emit = (event: SessionClientEvent): void => {\n try {\n finalConfig.onEvent?.(event);\n } catch (error) {\n logger.warn({ error: String(error) }, 'onEvent callback threw');\n }\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 emit({ event: SESSION_EVENT.REJECTED, source: 'session-monitor' });\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 emit({\n event: SESSION_EVENT.REJECTED,\n source: 'session-monitor',\n reason: 'refresh_failed',\n });\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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"}
1
+ {"version":3,"file":"index.js","names":["DEFAULT_CONFIG"],"sources":["../src/store.ts","../src/session-monitor.ts","../src/configure-logger.ts"],"sourcesContent":["import { createStore } from '@xstate/store';\nimport { createLogger } from '@eventuras/fides-auth/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 = createLogger({\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 ?? event.user.name }, '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 = createLogger({\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 = createLogger({\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 { createLogger } from '@eventuras/fides-auth/logger';\nimport { SESSION_EVENT, type SessionClientEvent } from '@eventuras/fides-auth/session-events';\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 /**\n * Called for every session lifecycle event the monitor observes, using the\n * same vocabulary as the server-side events.\n *\n * The logger writes to the browser console, which production never sees.\n * Forward these to your own endpoint, Sentry or an OTLP collector to get the\n * client half of a session's story into the same place as the server half.\n * The library ships no transport of its own.\n */\n onEvent?: (event: SessionClientEvent) => 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 // The pluggable factory, not @eventuras/logger directly — otherwise\n // configureAuthLogger() has no effect here and this one module logs to a\n // different place than the rest of the package.\n const logger = createLogger({\n namespace: finalConfig.loggerNamespace,\n context: { component: 'SessionMonitor' },\n });\n\n // A consumer's beacon must never be able to stop the monitor.\n const emit = (event: SessionClientEvent): void => {\n try {\n finalConfig.onEvent?.(event);\n } catch (error) {\n logger.warn({ error: String(error) }, 'onEvent callback threw');\n }\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 emit({ event: SESSION_EVENT.REJECTED, source: 'session-monitor' });\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 emit({\n event: SESSION_EVENT.REJECTED,\n source: 'session-monitor',\n reason: 'refresh_failed',\n });\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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"}
@@ -1,6 +1,6 @@
1
- import { SessionClientEvent } from '@eventuras/fides-auth/session-events';
2
- import { createAuthStore } from './store';
3
- import { AuthStatus } from './types';
1
+ import { type SessionClientEvent } from '@eventuras/fides-auth/session-events';
2
+ import type { createAuthStore } from './store';
3
+ import type { AuthStatus } from './types';
4
4
  /**
5
5
  * Configuration for session monitoring
6
6
  */
package/dist/store.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { SessionUser, AuthStatus } from './types';
1
+ import type { SessionUser, AuthStatus } from './types';
2
2
  /**
3
3
  * Authentication store context
4
4
  */
@@ -51,7 +51,7 @@ export type AuthStoreConfig = {
51
51
  * });
52
52
  * ```
53
53
  */
54
- export declare function createAuthStore(options: AuthStoreConfig): import('@xstate/store').Store<AuthStoreContext, {
54
+ export declare function createAuthStore(options: AuthStoreConfig): import("@xstate/store").Store<AuthStoreContext, {
55
55
  initialize: unknown;
56
56
  authSuccess: {
57
57
  user: SessionUser;
package/dist/types.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  export type SessionUser = {
10
10
  name: string;
11
- email: string;
11
+ email?: string;
12
12
  roles: string[];
13
13
  };
14
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventuras/fides-auth-store",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Framework-agnostic authentication state store (XState Store) for @eventuras/fides-auth",
5
5
  "keywords": [
6
6
  "authentication",
@@ -38,23 +38,23 @@
38
38
  "README.md"
39
39
  ],
40
40
  "dependencies": {
41
- "@eventuras/logger": "^0.8.1",
42
- "@xstate/store": "^4.2.2",
43
- "@eventuras/fides-auth": "0.14.0"
41
+ "@eventuras/logger": "^0.9.2",
42
+ "@xstate/store": "^4.3.0",
43
+ "@eventuras/fides-auth": "0.15.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@types/node": "^22.20.1",
47
- "typescript": "^6.0.2",
48
- "vite": "^8.2.1",
46
+ "@types/node": "^22.20.5",
47
+ "typescript": "^7.0.2",
48
+ "vite": "^8.3.5",
49
49
  "vitest": "^4.1.10",
50
- "@eventuras/vite-config": "0.2.2",
50
+ "@eventuras/vite-config": "0.3.0",
51
51
  "@eventuras/typescript-config": "1.0.0"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=18"
55
55
  },
56
56
  "scripts": {
57
- "build": "vite build",
57
+ "build": "vite build && tsc --emitDeclarationOnly",
58
58
  "typecheck": "tsc --noEmit",
59
59
  "dev": "vite build --watch",
60
60
  "test": "vitest run",