# `Rivet.Ident.Factor.Lib`
[🔗](https://github.com/srevenant/rivet-ident/blob/main/lib/ident/factor/lib.ex#L1)

# `auth_result`

```elixir
@type auth_result() :: {:ok | :error, Rivet.Auth.Domain.t()}
```

# `ecto_p_result`

```elixir
@type ecto_p_result() :: {:ok | :error, Ecto.Changeset.t()}
```

# `log_msg`

```elixir
@type log_msg() :: str()
```

# `model_p_result`

```elixir
@type model_p_result() :: {:ok, Rivet.Ident.Factor.t()}
```

# `str`

```elixir
@type str() :: String.t()
```

# `usr_msg`

```elixir
@type usr_msg() :: str()
```

# `all_not_expired!`

# `all_not_expired!`

# `clean_password_history`

# `drop_expired`

# `get`

# `get_user`

# `preloaded_with`

Preload factors for a related model, with criteria, and only unexpired factors

    Ident.Factor.Lib.preloaded_with(model, type)

# `set_factor`

```elixir
@spec set_factor(user :: Rivet.Ident.User.t(), fedid :: Rivet.Ident.Factor.FedId.t()) ::
  {:ok, Rivet.Ident.Factor.t()} | {:error, Ecto.Changeset.t()}
```

# `set_password`

set a password

Future change:

change Ident.Factors so there is an archive state, some types when being cleaned
are archived instead of deleted (such as passwords).

Then Auth.Signin.Local.load_password_factor should filter on !archived

# `strong_password`

```
iex> strong_password("<KO)(IJM,ko09ijm")
:ok
iex> strong_password("boo")
{:error, "Password is not long enough (greater than 8)"}
iex> strong_password("<ko)(ijm,ko09ijm")
{:error, "Password needs both upper and lower case characters"}
iex> strong_password("KOIJMko09ijm")
{:error, "Password needs special characters (not alphanumeric)"}
iex> strong_password("<KO)(IJM,koijm")
{:error, "Password needs numbers"}
iex> strong_password("<)(,)(*&^%$#@><")
{:error, "Password needs letters"}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
