{"version":3,"file":"AuthProvider.mjs","sources":["../../../src/lib/auth/AuthProvider.tsx"],"sourcesContent":["import {\n  useContext,\n  useState,\n  useEffect,\n  useCallback,\n  useMemo,\n  type ReactNode,\n  type JSX,\n} from 'react';\nimport { AuthContext } from '@/lib/contexts';\nimport { authService } from './authService';\nimport { hasPermission as checkPermission } from '@/config/authConfig';\nimport type {\n  User,\n  Role,\n  Permission,\n  LoginCredentials,\n  RegisterCredentials,\n  AuthContextValue,\n} from './types';\n\ninterface AuthProviderProps {\n  children: ReactNode;\n}\n\n/**\n * Provides auth state, token refresh, session sync.\n */\nexport function AuthProvider({ children }: AuthProviderProps): JSX.Element {\n  const [user, setUser] = useState<User | null>(null);\n  const [isLoading, setIsLoading] = useState(true);\n  const [error, setError] = useState<string | null>(null);\n\n  const isAuthenticated = user !== null;\n\n  /**\n   * Initialize auth state on mount.\n   *\n   * SECURITY: First initializes the AuthService to load encrypted tokens\n   * from SecureStorage into memory cache, then checks authentication status.\n   */\n  useEffect(() => {\n    const initAuth = async (): Promise<void> => {\n      try {\n        // Initialize secure token storage first\n        await authService.initialize();\n\n        if (authService.isAuthenticated()) {\n          const currentUser = await authService.getCurrentUser();\n          setUser(currentUser);\n        }\n      } catch (err) {\n        console.error('Failed to initialize auth:', err);\n        setUser(null);\n      } finally {\n        setIsLoading(false);\n      }\n    };\n\n    void initAuth();\n  }, []);\n\n  /**\n   * Set up automatic token refresh interval.\n   *\n   * SECURITY: Automatically refreshes tokens every 4 minutes while authenticated\n   * to maintain session validity without user interaction.\n   *\n   * Dependencies:\n   * - `isAuthenticated`: Effect should re-run when auth status changes\n   * - `authService` and `setUser` are stable references (singleton/useState setter)\n   */\n  useEffect(() => {\n    if (!isAuthenticated) return;\n\n    const refreshInterval = setInterval(\n      () => {\n        void (async (): Promise<void> => {\n          try {\n            await authService.refreshTokens();\n          } catch {\n            // If refresh fails, log out the user\n            setUser(null);\n          }\n        })();\n      },\n      4 * 60 * 1000\n    ); // Refresh every 4 minutes\n\n    return () => clearInterval(refreshInterval);\n  }, [isAuthenticated]);\n\n  const login = useCallback(async (credentials: LoginCredentials) => {\n    setIsLoading(true);\n    setError(null);\n\n    try {\n      const { user: loggedInUser } = await authService.login(credentials);\n      setUser(loggedInUser);\n    } catch (err) {\n      const message = err instanceof Error ? err.message : 'Login failed';\n      setError(message);\n      throw err;\n    } finally {\n      setIsLoading(false);\n    }\n  }, []);\n\n  const logout = useCallback(async () => {\n    setIsLoading(true);\n\n    try {\n      await authService.logout();\n    } finally {\n      setUser(null);\n      setError(null);\n      setIsLoading(false);\n    }\n  }, []);\n\n  const register = useCallback(async (credentials: RegisterCredentials) => {\n    setIsLoading(true);\n    setError(null);\n\n    try {\n      const { user: newUser } = await authService.register(credentials);\n      setUser(newUser);\n    } catch (err) {\n      const message = err instanceof Error ? err.message : 'Registration failed';\n      setError(message);\n      throw err;\n    } finally {\n      setIsLoading(false);\n    }\n  }, []);\n\n  const refreshSession = useCallback(async () => {\n    try {\n      await authService.refreshTokens();\n      const currentUser = await authService.getCurrentUser();\n      setUser(currentUser);\n    } catch (err) {\n      setUser(null);\n      throw err;\n    }\n  }, []);\n\n  const hasRole = useCallback(\n    (role: Role): boolean => {\n      if (!user) return false;\n      return user.roles.includes(role);\n    },\n    [user]\n  );\n\n  const hasAnyRole = useCallback(\n    (roles: Role[]): boolean => {\n      if (!user) return false;\n      return roles.some((role) => user.roles.includes(role));\n    },\n    [user]\n  );\n\n  const hasPermissionFn = useCallback(\n    (permission: Permission): boolean => {\n      if (!user) return false;\n      // Check direct permissions\n      if (user.permissions.includes(permission)) return true;\n      // Check role-based permissions\n      return user.roles.some((role) => checkPermission(role, permission));\n    },\n    [user]\n  );\n\n  const hasAnyPermission = useCallback(\n    (permissions: Permission[]): boolean => {\n      return permissions.some((p) => hasPermissionFn(p));\n    },\n    [hasPermissionFn]\n  );\n\n  // Alias for context compatibility\n  const refreshToken = refreshSession;\n\n  const value: AuthContextValue = useMemo(\n    () => ({\n      user,\n      isAuthenticated,\n      isLoading,\n      error,\n      login,\n      logout,\n      register,\n      refreshToken,\n      refreshSession,\n      hasRole,\n      hasAnyRole,\n      hasPermission: hasPermissionFn,\n      hasAnyPermission,\n    }),\n    [\n      user,\n      isAuthenticated,\n      isLoading,\n      error,\n      login,\n      logout,\n      register,\n      refreshToken,\n      refreshSession,\n      hasRole,\n      hasAnyRole,\n      hasPermissionFn,\n      hasAnyPermission,\n    ]\n  );\n\n  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n/**\n * Hook to access auth context.\n */\n// @refresh reset\n// eslint-disable-next-line react-refresh/only-export-components\nexport function useAuthContext(): AuthContextValue {\n  const context = useContext(AuthContext);\n  if (!context) {\n    throw new Error('useAuthContext must be used within an AuthProvider');\n  }\n  return context;\n}\n"],"names":["AuthProvider","children","user","setUser","useState","isLoading","setIsLoading","error","setError","isAuthenticated","useEffect","authService","currentUser","err","refreshInterval","login","useCallback","credentials","loggedInUser","message","logout","register","newUser","refreshSession","hasRole","role","hasAnyRole","roles","hasPermissionFn","permission","checkPermission","hasAnyPermission","permissions","p","refreshToken","value","useMemo","jsx","AuthContext","useAuthContext","context","useContext"],"mappings":";;;;;AA4BO,SAASA,EAAa,EAAE,UAAAC,KAA4C;AACzE,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAsB,IAAI,GAC5C,CAACC,GAAWC,CAAY,IAAIF,EAAS,EAAI,GACzC,CAACG,GAAOC,CAAQ,IAAIJ,EAAwB,IAAI,GAEhDK,IAAkBP,MAAS;AAQjC,EAAAQ,EAAU,MAAM;AAkBd,KAjBiB,YAA2B;AAC1C,UAAI;AAIF,YAFA,MAAMC,EAAY,WAAA,GAEdA,EAAY,mBAAmB;AACjC,gBAAMC,IAAc,MAAMD,EAAY,eAAA;AACtC,UAAAR,EAAQS,CAAW;AAAA,QACrB;AAAA,MACF,SAASC,GAAK;AACZ,gBAAQ,MAAM,8BAA8BA,CAAG,GAC/CV,EAAQ,IAAI;AAAA,MACd,UAAA;AACE,QAAAG,EAAa,EAAK;AAAA,MACpB;AAAA,IACF,GAEK;AAAA,EACP,GAAG,CAAA,CAAE,GAYLI,EAAU,MAAM;AACd,QAAI,CAACD,EAAiB;AAEtB,UAAMK,IAAkB;AAAA,MACtB,MAAM;AACJ,SAAM,YAA2B;AAC/B,cAAI;AACF,kBAAMH,EAAY,cAAA;AAAA,UACpB,QAAQ;AAEN,YAAAR,EAAQ,IAAI;AAAA,UACd;AAAA,QACF,GAAA;AAAA,MACF;AAAA,MACA,MAAS;AAAA,IAAA;AAGX,WAAO,MAAM,cAAcW,CAAe;AAAA,EAC5C,GAAG,CAACL,CAAe,CAAC;AAEpB,QAAMM,IAAQC,EAAY,OAAOC,MAAkC;AACjE,IAAAX,EAAa,EAAI,GACjBE,EAAS,IAAI;AAEb,QAAI;AACF,YAAM,EAAE,MAAMU,EAAA,IAAiB,MAAMP,EAAY,MAAMM,CAAW;AAClE,MAAAd,EAAQe,CAAY;AAAA,IACtB,SAASL,GAAK;AACZ,YAAMM,IAAUN,aAAe,QAAQA,EAAI,UAAU;AACrD,YAAAL,EAASW,CAAO,GACVN;AAAA,IACR,UAAA;AACE,MAAAP,EAAa,EAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAA,CAAE,GAECc,IAASJ,EAAY,YAAY;AACrC,IAAAV,EAAa,EAAI;AAEjB,QAAI;AACF,YAAMK,EAAY,OAAA;AAAA,IACpB,UAAA;AACE,MAAAR,EAAQ,IAAI,GACZK,EAAS,IAAI,GACbF,EAAa,EAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAA,CAAE,GAECe,IAAWL,EAAY,OAAOC,MAAqC;AACvE,IAAAX,EAAa,EAAI,GACjBE,EAAS,IAAI;AAEb,QAAI;AACF,YAAM,EAAE,MAAMc,EAAA,IAAY,MAAMX,EAAY,SAASM,CAAW;AAChE,MAAAd,EAAQmB,CAAO;AAAA,IACjB,SAAST,GAAK;AACZ,YAAMM,IAAUN,aAAe,QAAQA,EAAI,UAAU;AACrD,YAAAL,EAASW,CAAO,GACVN;AAAA,IACR,UAAA;AACE,MAAAP,EAAa,EAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAA,CAAE,GAECiB,IAAiBP,EAAY,YAAY;AAC7C,QAAI;AACF,YAAML,EAAY,cAAA;AAClB,YAAMC,IAAc,MAAMD,EAAY,eAAA;AACtC,MAAAR,EAAQS,CAAW;AAAA,IACrB,SAASC,GAAK;AACZ,YAAAV,EAAQ,IAAI,GACNU;AAAA,IACR;AAAA,EACF,GAAG,CAAA,CAAE,GAECW,IAAUR;AAAA,IACd,CAACS,MACMvB,IACEA,EAAK,MAAM,SAASuB,CAAI,IADb;AAAA,IAGpB,CAACvB,CAAI;AAAA,EAAA,GAGDwB,IAAaV;AAAA,IACjB,CAACW,MACMzB,IACEyB,EAAM,KAAK,CAACF,MAASvB,EAAK,MAAM,SAASuB,CAAI,CAAC,IADnC;AAAA,IAGpB,CAACvB,CAAI;AAAA,EAAA,GAGD0B,IAAkBZ;AAAA,IACtB,CAACa,MACM3B,IAEDA,EAAK,YAAY,SAAS2B,CAAU,IAAU,KAE3C3B,EAAK,MAAM,KAAK,CAACuB,MAASK,EAAgBL,GAAMI,CAAU,CAAC,IAJhD;AAAA,IAMpB,CAAC3B,CAAI;AAAA,EAAA,GAGD6B,IAAmBf;AAAA,IACvB,CAACgB,MACQA,EAAY,KAAK,CAACC,MAAML,EAAgBK,CAAC,CAAC;AAAA,IAEnD,CAACL,CAAe;AAAA,EAAA,GAIZM,IAAeX,GAEfY,IAA0BC;AAAA,IAC9B,OAAO;AAAA,MACL,MAAAlC;AAAA,MACA,iBAAAO;AAAA,MACA,WAAAJ;AAAA,MACA,OAAAE;AAAA,MACA,OAAAQ;AAAA,MACA,QAAAK;AAAA,MACA,UAAAC;AAAA,MACA,cAAAa;AAAA,MACA,gBAAAX;AAAA,MACA,SAAAC;AAAA,MACA,YAAAE;AAAA,MACA,eAAeE;AAAA,MACf,kBAAAG;AAAA,IAAA;AAAA,IAEF;AAAA,MACE7B;AAAA,MACAO;AAAA,MACAJ;AAAA,MACAE;AAAA,MACAQ;AAAA,MACAK;AAAA,MACAC;AAAA,MACAa;AAAA,MACAX;AAAA,MACAC;AAAA,MACAE;AAAA,MACAE;AAAA,MACAG;AAAA,IAAA;AAAA,EACF;AAGF,SAAO,gBAAAM,EAACC,EAAY,UAAZ,EAAqB,OAAAH,GAAe,UAAAlC,EAAA,CAAS;AACvD;AAOO,SAASsC,IAAmC;AACjD,QAAMC,IAAUC,EAAWH,CAAW;AACtC,MAAI,CAACE;AACH,UAAM,IAAI,MAAM,oDAAoD;AAEtE,SAAOA;AACT;"}