npm package: @mohanmaali/react-auth-manager
Description: Modern, secure, backend-agnostic React authentication library
Author: Mohan maali - India
Latest version: 1.0.4

# @mohanmaali/react-auth-manager

[![npm version](https://img.shields.io/npm/v/@mohanmaali/react-auth-manager.svg)](https://www.npmjs.com/package/@mohanmaali/react-auth-manager)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)

Simple authentication library for React applications.

## Features

- Works with any backend API
- Automatic token refresh
- Multiple storage options (cookie, localStorage, memory)
- Easy to use hooks
- Axios support

## Installation

**npm:**
```bash
npm install @mohanmaali/react-auth-manager
```

**yarn:**
```bash
yarn add @mohanmaali/react-auth-manager
```

**pnpm:**
```bash
pnpm add @mohanmaali/react-auth-manager
```

## Quick Start

### Step 1: Configure Authentication

Create a file to configure your authentication:

```javascript
// authConfig.js
export const authConfig = {
  login: async ({ email, password }) => {
    const response = await fetch("https://api.example.com/login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, password }),
    });
    return response.json(); // Returns: { accessToken, refreshToken }
  },

  getUser: async (accessToken) => {
    const response = await fetch("https://api.example.com/me", {
      headers: { Authorization: `Bearer ${accessToken}` },
    });
    return response.json(); // Returns user data
  },

  refresh: async () => {
    const response = await fetch("https://api.example.com/refresh", {
      method: "POST",
    });
    return response.json(); // Returns new tokens
  },

  logout: async () => {
    await fetch("https://api.example.com/logout", {
      method: "POST",
    });
  },

  tokenStorage: "cookie", // Options: "cookie", "localStorage", "memory"
};
```

### Step 2: Setup Provider

Wrap your application with AuthProvider:

```javascript
// App.js
import { AuthProvider } from "@mohanmaali/react-auth-manager";
import { authConfig } from "./authConfig";

function App() {
  return (
    <AuthProvider config={authConfig}>
      <YourApp />
    </AuthProvider>
  );
}

export default App;
```

### Step 3: Use in Components

```javascript
import { useAuth } from "@mohanmaali/react-auth-manager";

function LoginPage() {
  const { login, isLoading } = useAuth();

  const handleLogin = async () => {
    await login({
      email: "user@example.com",
      password: "password123",
    });
  };

  return (
    <button onClick={handleLogin} disabled={isLoading}>
      {isLoading ? "Loading..." : "Login"}
    </button>
  );
}
```

## Usage Examples

### Login Form

```javascript
import { useState } from "react";
import { useAuth } from "@mohanmaali/react-auth-manager";

function LoginForm() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const { login, isLoading, error } = useAuth();

  const handleSubmit = async (e) => {
    e.preventDefault();
    await login({ email, password });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
      />
      <button type="submit" disabled={isLoading}>
        {isLoading ? "Logging in..." : "Login"}
      </button>
      {error && <p>{error.message}</p>}
    </form>
  );
}
```

### Display User Info

```javascript
import { useAuth } from "@mohanmaali/react-auth-manager";

function UserProfile() {
  const { isAuthenticated, user, logout, isLoading } = useAuth();

  if (isLoading) return <p>Loading...</p>;

  if (!isAuthenticated) return <p>Please log in</p>;

  return (
    <div>
      <h1>Welcome, {user.name}!</h1>
      <p>Email: {user.email}</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}
```

### Protected Routes

```javascript
import { useRequireAuth } from "@mohanmaali/react-auth-manager";

function AdminPage() {
  useRequireAuth(() => {
    window.location.href = "/login";
  });

  return <div>Admin Dashboard</div>;
}
```

### Navigation Menu

```javascript
import { useAuth } from "@mohanmaali/react-auth-manager";

function Navigation() {
  const { isAuthenticated, user, logout } = useAuth();

  return (
    <nav>
      <a href="/">Home</a>
      {isAuthenticated ? (
        <>
          <span>Hello, {user.name}</span>
          <button onClick={logout}>Logout</button>
        </>
      ) : (
        <a href="/login">Login</a>
      )}
    </nav>
  );
}
```

## Axios Integration

Setup automatic token injection for Axios:

```javascript
import axios from "axios";
import { setupAxiosInterceptors } from "@mohanmaali/react-auth-manager";

const api = axios.create({
  baseURL: "https://api.example.com",
});

setupAxiosInterceptors({
  axiosInstance: api,
  tokenStorage: "cookie",
  refresh: async () => {
    const response = await fetch("https://api.example.com/refresh", {
      method: "POST",
    });
    return response.json();
  },
});

export default api;
```

Now all requests will include the authentication token automatically:

```javascript
// Tokens are added automatically
api.get("/user/profile");
api.post("/user/update", { name: "John" });
```

## API Reference

### useAuth Hook

```javascript
const {
  isAuthenticated,  // Boolean: user is logged in
  isLoading,        // Boolean: authentication in progress
  user,             // Object: user information
  error,            // Object: any error occurred
  login,            // Function: login user
  logout,           // Function: logout user
  refreshToken,     // Function: manually refresh token
} = useAuth();
```

### useRequireAuth Hook

```javascript
useRequireAuth((callback) => {
  // Runs if user is not authenticated
});
```

Example:
```javascript
useRequireAuth(() => {
  navigate("/login");
});
```

## Token Storage Options

| Storage | Description |
|---------|-------------|
| `cookie` | Recommended. Most secure, protected from XSS attacks |
| `localStorage` | Persists across browser sessions, less secure |
| `memory` | Highest security but lost on page refresh |

## Configuration

Your `authConfig` object should have:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `login` | Function | Yes | Handles user login |
| `getUser` | Function | Yes | Fetches user information |
| `refresh` | Function | Yes | Refreshes authentication token |
| `logout` | Function | Yes | Handles user logout |
| `tokenStorage` | String | Yes | Where to store tokens: "cookie", "localStorage", or "memory" |

## Troubleshooting

**Tokens not saved after refresh?**
- Use `tokenStorage: "cookie"` or `"localStorage"` instead of `"memory"`

**User logged out unexpectedly?**
- Check your `refresh` function is working correctly

**CORS errors?**
- Add `credentials: "include"` in your fetch requests when using cookies

## License

MIT License

## Links

- [GitHub Repository](https://github.com/mohanmaali/react-auth-manager)
- [Report Issues](https://github.com/mohanmaali/react-auth-manager/issues)
- [npm Package](https://www.npmjs.com/package/@mohanmaali/react-auth-manager)

---

Made by [Mohan Maali](https://github.com/mohanmaali)