Metadata-Version: 2.4
Name: nxauth
Version: 0.1.0
Summary: Authentication extension for Nexa.py
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: nexa
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"

# NxAuth

Authentication extension for [Nexa.py](https://github.com/faizanurrahim/Nexa.PY).

```text
Flask       → Flask-Login
Nexa.py     → NxAuth
```

## Installation

```bash
pip install nxauth
```

## Quick Start

```python
from nexa import Nexa
from nxauth import Auth

application = Nexa()
auth = Auth(application)

# Create a user
user = auth.create_user(username="admin", password="secret")

# Authenticate
user = auth.authenticate(username="admin", password="secret")

# Login
auth.login(user)
```

## Protected Routes

```python
@application.schema(route="/dashboard")
@auth.login_required
def dashboard(request):
    user = request._nxauth_user
    return f"Welcome {user.username}"
```

When unauthenticated, returns `401 Unauthorized`.

## API

### `Auth(application, **kwargs)`

Create an authentication manager for a Nexa application.

| Parameter | Default | Description |
|---|---|---|
| `database` | `:memory:` | SQLite database path |
| `session_lifetime` | `3600` | Session lifetime in seconds |
| `login_route` | `/login` | Redirect target for unauthenticated requests |

### `auth.create_user(username, password)`

Create a new user. Password is securely hashed with PBKDF2-SHA256.

### `auth.authenticate(username, password)`

Verify credentials. Returns `User` on success, `None` on failure.

### `auth.login(user)`

Create a session for the user.

### `auth.logout(request)`

Invalidate the current session.

### `auth.current_user(request)`

Get the authenticated user from the request, or `None`.

### `auth.is_authenticated(request)`

Check if the request is authenticated.

## Multiple Applications

```python
admin = Nexa()
public = Nexa()

admin_auth = Auth(admin)
public_auth = Auth(public)
```

Authentication state is completely isolated between applications.

## Security

- Passwords hashed with PBKDF2-SHA256 (260,000 iterations)
- Session IDs are cryptographically secure (`secrets.token_hex`)
- Constant-time password comparison prevents timing attacks
- No plaintext passwords stored anywhere
- No global authentication state

## License

MIT
