neocrates 0.1.45

A comprehensive Rust library for various utilities and helpers
Documentation
# Auth Module

The `auth` module provides Redis-backed helpers for issuing, rotating, storing, and deleting token pairs, plus a small fingerprint-binding API for associating devices or client fingerprints with users.

See also: [root README](../../README.md)

---

## Feature and runtime requirements

Enable with:

```toml
neocrates = { version = "0.1", default-features = false, features = ["web", "auth", "redis"] }
```

Important note:

- The current implementation is **Redis-backed in practice**.
- It also returns `AppError`/`AppResult`, so use it together with `web`.
- Treat `auth` as a **`web + auth + redis`** feature set, even though the Cargo feature table does not encode that coupling perfectly yet.

---

## Main types

- `AuthHelper` — static helper API
- `middlewares::models::AuthModel` — user/session identity payload
- `middlewares::models::AuthTokenResult` — access/refresh token pair and TTL data

Redis key families used by the module:

- `{prefix}:auth:uid:{uid}` → current `AuthTokenResult`
- `{prefix}:auth:token:{access_token}` → serialized `AuthModel`
- `{prefix}:auth:refresh_token:{refresh_token}` → serialized `AuthModel`
- `{prefix}:auth:fp:uid:{fingerprint}` → user ID
- `{prefix}:auth:uid:fp:{uid}` → fingerprint

---

## Quick start

```rust
use std::sync::Arc;

use neocrates::auth::auth_helper::AuthHelper;
use neocrates::middlewares::models::AuthModel;
use neocrates::rediscache::RedisPool;

async fn login() -> neocrates::anyhow::Result<()> {
    let redis = Arc::new(RedisPool::from_env().await?);

    let auth_model = AuthModel {
        uid: 42,
        mobile: "13800138000".into(),
        nickname: "neo".into(),
        username: "neo".into(),
        tid: 1,
        tname: "tenant".into(),
        ouid: 10,
        ouname: "org".into(),
        rids: vec![1],
        pmsids: vec![100, 101],
    };

    let tokens = AuthHelper::generate_auth_token(&redis, "app:", 300, 86_400, auth_model).await?;
    println!("{:?}", tokens.access_token);
    Ok(())
}
```

---

## Step-by-step tutorial

## 1. Issue tokens during login

```rust
let tokens = AuthHelper::generate_auth_token(
    &redis_pool,
    "app:",
    300,        // access-token TTL in seconds
    86_400,     // refresh-token TTL in seconds
    auth_model,
)
.await?;
```

This helper:

1. deletes any existing token pair for the user
2. generates a new access token and refresh token
3. stores the `AuthModel` and `AuthTokenResult` into Redis

## 2. Refresh a token pair

```rust
let rotated = AuthHelper::refresh_auth(
    &redis_pool,
    "app:",
    300,
    86_400,
    &old_access_token,
    &refresh_token,
)
.await?;
```

This verifies the old pair against Redis and rotates to a new pair.

## 3. Bind a fingerprint to a user

```rust
AuthHelper::bind_fingerprint(&redis_pool, "app:", 42, "browser-fingerprint").await?;
let uid = AuthHelper::get_uid_by_fingerprint(&redis_pool, "app:", "browser-fingerprint").await?;
println!("{uid:?}");
```

## 4. Logout and revoke tokens

```rust
AuthHelper::delete_token(&redis_pool, "app:", 42).await?;
```

---

## Key points and gotchas

- `generate_auth_token()` invalidates the previous session for the same user before issuing a new one.
- Prefix handling is entirely caller-driven; use a stable namespace such as `"app:"` or `"tenant-a:"`.
- `bind_fingerprint()` rejects empty fingerprint strings.
- The module manages token state, but it does **not** perform HTTP request parsing or middleware injection; that belongs to `middlewares`.

---

## Roadmap

Useful next improvements:

1. Support multiple active sessions per user.
2. Add a first-class config type for TTLs and prefixes.
3. Add cookie/session helpers for web apps.
4. Improve compile-time feature wiring so `auth` explicitly pulls in the backend it depends on.