regstack 0.2.2__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {regstack-0.2.2 → regstack-0.2.4}/CHANGELOG.md +29 -0
- {regstack-0.2.2 → regstack-0.2.4}/PKG-INFO +1 -1
- regstack-0.2.4/docs/api.md +278 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/architecture.md +0 -1
- {regstack-0.2.2 → regstack-0.2.4}/docs/changelog.md +61 -0
- {regstack-0.2.2 → regstack-0.2.4}/pyproject.toml +1 -1
- regstack-0.2.4/src/regstack/app.py +322 -0
- regstack-0.2.4/src/regstack/auth/clock.py +73 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/auth/dependencies.py +47 -5
- regstack-0.2.4/src/regstack/auth/jwt.py +256 -0
- regstack-0.2.4/src/regstack/auth/lockout.py +119 -0
- regstack-0.2.4/src/regstack/auth/password.py +65 -0
- regstack-0.2.4/src/regstack/backends/mongo/repositories/__init__.py +13 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/repositories/mfa_code_repo.py +0 -3
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/repositories/pending_repo.py +0 -3
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/repositories/user_repo.py +0 -3
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/protocols.py +31 -6
- regstack-0.2.4/src/regstack/email/base.py +71 -0
- regstack-0.2.4/src/regstack/hooks/events.py +98 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/models/_objectid.py +0 -8
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/models/login_attempt.py +2 -2
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/models/mfa_code.py +2 -2
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/models/pending_registration.py +2 -2
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/models/user.py +2 -2
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/__init__.py +21 -1
- regstack-0.2.4/src/regstack/sms/base.py +67 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/pages.py +49 -8
- regstack-0.2.4/src/regstack/version.py +1 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_mfa_code_repo.py +2 -1
- {regstack-0.2.2 → regstack-0.2.4}/uv.lock +1 -1
- regstack-0.2.2/docs/api.md +0 -184
- regstack-0.2.2/src/regstack/app.py +0 -166
- regstack-0.2.2/src/regstack/auth/clock.py +0 -29
- regstack-0.2.2/src/regstack/auth/jwt.py +0 -145
- regstack-0.2.2/src/regstack/auth/lockout.py +0 -59
- regstack-0.2.2/src/regstack/auth/password.py +0 -20
- regstack-0.2.2/src/regstack/backends/mongo/repositories/__init__.py +0 -27
- regstack-0.2.2/src/regstack/email/base.py +0 -23
- regstack-0.2.2/src/regstack/hooks/events.py +0 -59
- regstack-0.2.2/src/regstack/sms/base.py +0 -24
- regstack-0.2.2/src/regstack/version.py +0 -1
- {regstack-0.2.2 → regstack-0.2.4}/.github/workflows/publish.yml +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/.github/workflows/test.yml +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/.gitignore +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/.python-version +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/.readthedocs.yaml +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/CLAUDE.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/LICENSE +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/NOTICE +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/README.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/SECURITY.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/_static/.gitkeep +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/_templates/.gitkeep +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/cli.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/conf.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/configuration.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/embedding.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/index.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/quickstart.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/security.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/docs/theming.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/_common/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/_common/app.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/mongo/README.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/mongo/branding/theme.css +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/mongo/main.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/mongo/regstack.toml +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/postgres/README.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/postgres/main.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/postgres/regstack.toml +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/sqlite/README.md +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/sqlite/main.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/examples/sqlite/regstack.toml +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/regstack.toml.example +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/auth/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/auth/mfa.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/auth/tokens.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/base.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/factory.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/backend.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/client.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/indexes.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/repositories/blacklist_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/mongo/repositories/login_attempt_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/backend.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/migrations/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/migrations/env.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/migrations/script.py.mako +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/migrations/versions/0001_initial_schema.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/repositories/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/repositories/blacklist_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/repositories/login_attempt_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/repositories/mfa_code_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/repositories/pending_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/repositories/user_repo.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/schema.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/backends/sql/types.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/__main__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/_runtime.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/admin.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/doctor.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/init.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/cli/migrate.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/config/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/config/loader.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/config/schema.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/config/secrets.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/composer.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/console.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/factory.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/ses.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/smtp.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/email_change.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/email_change.subject.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/email_change.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/password_reset.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/password_reset.subject.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/password_reset.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/sms_login_mfa.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/sms_phone_setup.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/verification.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/verification.subject.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/email/templates/verification.txt +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/hooks/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/models/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/_schemas.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/account.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/admin.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/login.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/logout.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/password.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/phone.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/register.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/routers/verify.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/sms/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/sms/factory.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/sms/null.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/sms/sns.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/sms/twilio.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/static/css/core.css +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/static/css/theme.css +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/static/js/regstack.js +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/email_change_confirm.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/forgot.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/login.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/me.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/mfa_confirm.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/register.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/reset.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/auth/verify.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/src/regstack/ui/templates/base.html +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tasks.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/conftest.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_account_management.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_admin_router.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_happy_path.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_indexes.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_login_lockout.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_mfa.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_password_reset.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_sql_migrations.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_ui_router.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/integration/test_verification.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/__init__.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_base_install_imports.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_cli.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_config_loader.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_jwt.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_lockout.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_mail_composer.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_password.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_ses_backend.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_sms.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_smtp_backend.py +0 -0
- {regstack-0.2.2 → regstack-0.2.4}/tests/unit/test_ui_env.py +0 -0
|
@@ -5,6 +5,35 @@ authoritative copy lives at
|
|
|
5
5
|
[`docs/changelog.md`](docs/changelog.md) and is rendered into the
|
|
6
6
|
Sphinx docs.
|
|
7
7
|
|
|
8
|
+
## 0.2.4 — 2026-04-28
|
|
9
|
+
|
|
10
|
+
**Breaking** — back-compat shims removed:
|
|
11
|
+
|
|
12
|
+
- `RegStack.install_indexes()` (alias for `install_schema()`).
|
|
13
|
+
- `ObjectIdStr` alias for `IdStr` in `regstack.models._objectid`.
|
|
14
|
+
- Re-exports of `UserAlreadyExistsError`,
|
|
15
|
+
`PendingAlreadyExistsError`, `MfaVerifyOutcome`, and
|
|
16
|
+
`MfaVerifyResult` from `regstack.backends.mongo.repositories.*`.
|
|
17
|
+
Their canonical home is `regstack.backends.protocols`.
|
|
18
|
+
|
|
19
|
+
If you import any of these from the old paths, switch to:
|
|
20
|
+
- `RegStack.install_schema()`
|
|
21
|
+
- `from regstack.models._objectid import IdStr`
|
|
22
|
+
- `from regstack.backends.protocols import UserAlreadyExistsError`
|
|
23
|
+
(and friends).
|
|
24
|
+
|
|
25
|
+
The internal mongo `install_indexes(db, config)` function is unchanged.
|
|
26
|
+
|
|
27
|
+
## 0.2.3 — 2026-04-28
|
|
28
|
+
|
|
29
|
+
Docs-only release. Restructured the API reference around the current
|
|
30
|
+
package layout (post multi-backend refactor) and added Google-style
|
|
31
|
+
docstrings (Args / Returns / Raises) to the public surface — RegStack,
|
|
32
|
+
JwtCodec, PasswordHasher, LockoutService, AuthDependencies,
|
|
33
|
+
HookRegistry, EmailService, SmsService, the router builders, and the
|
|
34
|
+
Clock implementations. Dataclass field docs moved to PEP 258
|
|
35
|
+
attribute docstrings. Sphinx builds clean under `-W` again.
|
|
36
|
+
|
|
8
37
|
## 0.2.2 — 2026-04-28
|
|
9
38
|
|
|
10
39
|
Docs-only release. The README and Sphinx docs landing page now lead
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: regstack
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Embeddable user registration, login, and account management for FastAPI apps. SQLite / Postgres / MongoDB.
|
|
5
5
|
Project-URL: Homepage, https://github.com/jdrumgoole/regstack
|
|
6
6
|
Project-URL: Repository, https://github.com/jdrumgoole/regstack
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
Auto-generated from docstrings. The most useful entry point is
|
|
4
|
+
[`regstack.RegStack`](#regstack.app.RegStack); everything else hangs
|
|
5
|
+
off it.
|
|
6
|
+
|
|
7
|
+
This page is organized by what you'd reach for, not by package
|
|
8
|
+
hierarchy. Each section starts with a one-paragraph orientation,
|
|
9
|
+
then the ``autoclass`` / ``autofunction`` directives pull the
|
|
10
|
+
docstrings, signatures, and parameter docs straight off the package
|
|
11
|
+
source.
|
|
12
|
+
|
|
13
|
+
## Top-level
|
|
14
|
+
|
|
15
|
+
The handful of things you import from `regstack` directly:
|
|
16
|
+
|
|
17
|
+
- [`RegStack`](#regstack.app.RegStack) — the embeddable façade.
|
|
18
|
+
- [`RegStackConfig`](#regstack.config.schema.RegStackConfig) — top-level config.
|
|
19
|
+
- [`EmailConfig`](#regstack.config.schema.EmailConfig) — email-backend sub-config.
|
|
20
|
+
- [`SmsConfig`](#regstack.config.schema.SmsConfig) — SMS-backend sub-config.
|
|
21
|
+
|
|
22
|
+
Most embeddings need only `RegStack` and `RegStackConfig`.
|
|
23
|
+
|
|
24
|
+
## Façade
|
|
25
|
+
|
|
26
|
+
`RegStack` is the embeddable façade. One per FastAPI application;
|
|
27
|
+
hosts mount its `router` and (optionally) `ui_router`. All collaborators
|
|
28
|
+
— password hasher, JWT codec, repos, hooks bus, email and SMS
|
|
29
|
+
services — hang off the instance.
|
|
30
|
+
|
|
31
|
+
```{eval-rst}
|
|
32
|
+
.. autoclass:: regstack.app.RegStack
|
|
33
|
+
:members:
|
|
34
|
+
:show-inheritance:
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
`RegStackConfig` is a `pydantic-settings` model loaded from
|
|
40
|
+
environment variables (`REGSTACK_*`), an optional
|
|
41
|
+
`regstack.secrets.env`, an optional `regstack.toml`, and programmatic
|
|
42
|
+
kwargs — in that priority order. See the
|
|
43
|
+
[Configuration guide](configuration.md) for every field with its
|
|
44
|
+
default.
|
|
45
|
+
|
|
46
|
+
```{eval-rst}
|
|
47
|
+
.. autoclass:: regstack.config.schema.RegStackConfig
|
|
48
|
+
:members:
|
|
49
|
+
:show-inheritance:
|
|
50
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
51
|
+
|
|
52
|
+
.. autoclass:: regstack.config.schema.EmailConfig
|
|
53
|
+
:members:
|
|
54
|
+
:show-inheritance:
|
|
55
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
56
|
+
|
|
57
|
+
.. autoclass:: regstack.config.schema.SmsConfig
|
|
58
|
+
:members:
|
|
59
|
+
:show-inheritance:
|
|
60
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
61
|
+
|
|
62
|
+
.. autofunction:: regstack.config.loader.load_config
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Auth primitives
|
|
66
|
+
|
|
67
|
+
The pieces that make authentication work: password hashing (Argon2id),
|
|
68
|
+
JWT issuance and validation with per-purpose derived keys, login
|
|
69
|
+
lockout, and the FastAPI dependency factory. Hosts rarely instantiate
|
|
70
|
+
these directly — they're built and wired by the `RegStack` constructor
|
|
71
|
+
— but the docstrings on the public methods explain the contract.
|
|
72
|
+
|
|
73
|
+
```{eval-rst}
|
|
74
|
+
.. autoclass:: regstack.auth.password.PasswordHasher
|
|
75
|
+
:members:
|
|
76
|
+
|
|
77
|
+
.. autoclass:: regstack.auth.jwt.JwtCodec
|
|
78
|
+
:members:
|
|
79
|
+
|
|
80
|
+
.. autoclass:: regstack.auth.jwt.TokenPayload
|
|
81
|
+
:members:
|
|
82
|
+
|
|
83
|
+
.. autoexception:: regstack.auth.jwt.TokenError
|
|
84
|
+
|
|
85
|
+
.. autofunction:: regstack.auth.jwt.is_payload_bulk_revoked
|
|
86
|
+
|
|
87
|
+
.. autoclass:: regstack.auth.lockout.LockoutService
|
|
88
|
+
:members:
|
|
89
|
+
|
|
90
|
+
.. autoclass:: regstack.auth.lockout.LockoutDecision
|
|
91
|
+
:members:
|
|
92
|
+
|
|
93
|
+
.. autoclass:: regstack.auth.dependencies.AuthDependencies
|
|
94
|
+
:members:
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Time
|
|
98
|
+
|
|
99
|
+
Every time-sensitive operation reads `now()` through a `Clock`. Tests
|
|
100
|
+
inject `FrozenClock` to make assertions deterministic.
|
|
101
|
+
|
|
102
|
+
```{eval-rst}
|
|
103
|
+
.. autoclass:: regstack.auth.clock.Clock
|
|
104
|
+
:members:
|
|
105
|
+
|
|
106
|
+
.. autoclass:: regstack.auth.clock.SystemClock
|
|
107
|
+
:members:
|
|
108
|
+
|
|
109
|
+
.. autoclass:: regstack.auth.clock.FrozenClock
|
|
110
|
+
:members:
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Backends
|
|
114
|
+
|
|
115
|
+
regstack ships three storage backends behind one set of `Protocol`
|
|
116
|
+
classes: SQLite (default, no infrastructure), PostgreSQL, and MongoDB.
|
|
117
|
+
The active backend is auto-built from `config.database_url`'s URL
|
|
118
|
+
scheme via `build_backend`. Hosts that need to share a connection pool
|
|
119
|
+
with their own application can pass an explicit `Backend` to the
|
|
120
|
+
`RegStack` constructor.
|
|
121
|
+
|
|
122
|
+
```{eval-rst}
|
|
123
|
+
.. autoclass:: regstack.backends.base.Backend
|
|
124
|
+
:members:
|
|
125
|
+
:show-inheritance:
|
|
126
|
+
|
|
127
|
+
.. autoclass:: regstack.backends.base.BackendKind
|
|
128
|
+
:members:
|
|
129
|
+
|
|
130
|
+
.. autofunction:: regstack.backends.factory.build_backend
|
|
131
|
+
|
|
132
|
+
.. autoclass:: regstack.backends.mongo.MongoBackend
|
|
133
|
+
:members:
|
|
134
|
+
:show-inheritance:
|
|
135
|
+
|
|
136
|
+
.. autoclass:: regstack.backends.sql.SqlBackend
|
|
137
|
+
:members:
|
|
138
|
+
:show-inheritance:
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Repository protocols
|
|
142
|
+
|
|
143
|
+
The five repository protocols are the contract every backend
|
|
144
|
+
implements. Routers and services depend only on these — switching
|
|
145
|
+
backends is a wiring change, not a code change.
|
|
146
|
+
|
|
147
|
+
```{eval-rst}
|
|
148
|
+
.. autoclass:: regstack.backends.protocols.UserRepoProtocol
|
|
149
|
+
:members:
|
|
150
|
+
|
|
151
|
+
.. autoclass:: regstack.backends.protocols.PendingRepoProtocol
|
|
152
|
+
:members:
|
|
153
|
+
|
|
154
|
+
.. autoclass:: regstack.backends.protocols.BlacklistRepoProtocol
|
|
155
|
+
:members:
|
|
156
|
+
|
|
157
|
+
.. autoclass:: regstack.backends.protocols.LoginAttemptRepoProtocol
|
|
158
|
+
:members:
|
|
159
|
+
|
|
160
|
+
.. autoclass:: regstack.backends.protocols.MfaCodeRepoProtocol
|
|
161
|
+
:members:
|
|
162
|
+
|
|
163
|
+
.. autoclass:: regstack.backends.protocols.MfaVerifyOutcome
|
|
164
|
+
:members:
|
|
165
|
+
|
|
166
|
+
.. autoclass:: regstack.backends.protocols.MfaVerifyResult
|
|
167
|
+
:members:
|
|
168
|
+
|
|
169
|
+
.. autoexception:: regstack.backends.protocols.UserAlreadyExistsError
|
|
170
|
+
|
|
171
|
+
.. autoexception:: regstack.backends.protocols.PendingAlreadyExistsError
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Models
|
|
175
|
+
|
|
176
|
+
The persisted data shapes. `BaseUser` is the canonical user document;
|
|
177
|
+
`UserCreate` validates registration input; `UserPublic` is what the
|
|
178
|
+
API returns (omits the password hash). The other models drive
|
|
179
|
+
verification, lockout, and SMS MFA.
|
|
180
|
+
|
|
181
|
+
```{eval-rst}
|
|
182
|
+
.. autoclass:: regstack.models.user.BaseUser
|
|
183
|
+
:members:
|
|
184
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
185
|
+
|
|
186
|
+
.. autoclass:: regstack.models.user.UserCreate
|
|
187
|
+
:members:
|
|
188
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
189
|
+
|
|
190
|
+
.. autoclass:: regstack.models.user.UserPublic
|
|
191
|
+
:members:
|
|
192
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
193
|
+
|
|
194
|
+
.. autoclass:: regstack.models.pending_registration.PendingRegistration
|
|
195
|
+
:members:
|
|
196
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
197
|
+
|
|
198
|
+
.. autoclass:: regstack.models.login_attempt.LoginAttempt
|
|
199
|
+
:members:
|
|
200
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
201
|
+
|
|
202
|
+
.. autoclass:: regstack.models.mfa_code.MfaCode
|
|
203
|
+
:members:
|
|
204
|
+
:exclude-members: model_config, model_fields, model_computed_fields
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Email + SMS
|
|
208
|
+
|
|
209
|
+
Pluggable transports for the verification / reset / change-email
|
|
210
|
+
emails and the SMS MFA codes. Implement `EmailService` or `SmsService`
|
|
211
|
+
to plug in a provider that isn't bundled (Postmark, SendGrid,
|
|
212
|
+
MessageBird, …) and pass the instance to `regstack.set_email_backend`
|
|
213
|
+
/ `set_sms_backend`.
|
|
214
|
+
|
|
215
|
+
### Email
|
|
216
|
+
|
|
217
|
+
```{eval-rst}
|
|
218
|
+
.. autoclass:: regstack.email.base.EmailMessage
|
|
219
|
+
:members:
|
|
220
|
+
|
|
221
|
+
.. autoclass:: regstack.email.base.EmailService
|
|
222
|
+
:members:
|
|
223
|
+
|
|
224
|
+
.. autoclass:: regstack.email.console.ConsoleEmailService
|
|
225
|
+
:members:
|
|
226
|
+
|
|
227
|
+
.. autoclass:: regstack.email.composer.MailComposer
|
|
228
|
+
:members:
|
|
229
|
+
|
|
230
|
+
.. autofunction:: regstack.email.factory.build_email_service
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### SMS
|
|
234
|
+
|
|
235
|
+
```{eval-rst}
|
|
236
|
+
.. autoclass:: regstack.sms.base.SmsMessage
|
|
237
|
+
:members:
|
|
238
|
+
|
|
239
|
+
.. autoclass:: regstack.sms.base.SmsService
|
|
240
|
+
:members:
|
|
241
|
+
|
|
242
|
+
.. autofunction:: regstack.sms.base.is_valid_e164
|
|
243
|
+
|
|
244
|
+
.. autoclass:: regstack.sms.null.NullSmsService
|
|
245
|
+
:members:
|
|
246
|
+
|
|
247
|
+
.. autofunction:: regstack.sms.factory.build_sms_service
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Hooks
|
|
251
|
+
|
|
252
|
+
The event bus regstack uses to fire side-effect notifications
|
|
253
|
+
(`user_registered`, `password_changed`, etc.) without coupling auth
|
|
254
|
+
code to host concerns like CRMs or analytics. See the
|
|
255
|
+
[Embedding guide](embedding.md#subscribing-to-events) for examples.
|
|
256
|
+
|
|
257
|
+
```{eval-rst}
|
|
258
|
+
.. autoclass:: regstack.hooks.events.HookRegistry
|
|
259
|
+
:members:
|
|
260
|
+
|
|
261
|
+
.. autodata:: regstack.hooks.events.KNOWN_EVENTS
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Routers
|
|
265
|
+
|
|
266
|
+
Hosts normally access these via the `regstack.router` and
|
|
267
|
+
`regstack.ui_router` properties; the builder functions are public for
|
|
268
|
+
hosts that want to compose differently.
|
|
269
|
+
|
|
270
|
+
```{eval-rst}
|
|
271
|
+
.. autofunction:: regstack.routers.build_router
|
|
272
|
+
|
|
273
|
+
.. autofunction:: regstack.ui.pages.build_ui_router
|
|
274
|
+
|
|
275
|
+
.. autofunction:: regstack.ui.pages.build_ui_environment
|
|
276
|
+
|
|
277
|
+
.. autofunction:: regstack.ui.pages.default_static_dir
|
|
278
|
+
```
|
|
@@ -72,7 +72,6 @@ The façade exposes:
|
|
|
72
72
|
- `backend` — the active `regstack.backends.base.Backend`.
|
|
73
73
|
- `install_schema()` — install indexes (Mongo) or run
|
|
74
74
|
[Alembic](https://alembic.sqlalchemy.org/) migrations (SQL).
|
|
75
|
-
`install_indexes()` is kept as a back-compat alias.
|
|
76
75
|
- `aclose()` — tear down the backend's connection pool.
|
|
77
76
|
- `bootstrap_admin(email, password)`,
|
|
78
77
|
`add_template_dir(path)`, `set_email_backend(...)`,
|
|
@@ -3,6 +3,67 @@
|
|
|
3
3
|
All notable changes to this project are documented here. Versions follow
|
|
4
4
|
[Semantic Versioning](https://semver.org/) once `1.0.0` ships.
|
|
5
5
|
|
|
6
|
+
## 0.2.4 — 2026-04-28
|
|
7
|
+
|
|
8
|
+
**Breaking** — every back-compat shim left over from the
|
|
9
|
+
multi-backend refactor has been removed.
|
|
10
|
+
|
|
11
|
+
### Removed
|
|
12
|
+
|
|
13
|
+
- `RegStack.install_indexes()` — the 0.1.x alias for
|
|
14
|
+
`install_schema()`. Call `install_schema()`.
|
|
15
|
+
- `ObjectIdStr` alias for `IdStr` in `regstack.models._objectid`.
|
|
16
|
+
Import `IdStr` directly.
|
|
17
|
+
- `__all__`-based re-exports of `UserAlreadyExistsError`,
|
|
18
|
+
`PendingAlreadyExistsError`, `MfaVerifyOutcome`, and
|
|
19
|
+
`MfaVerifyResult` from `regstack.backends.mongo.repositories.*` and
|
|
20
|
+
the package `__init__`. Their canonical home is
|
|
21
|
+
`regstack.backends.protocols`; that's where every consumer in the
|
|
22
|
+
package itself already imports them.
|
|
23
|
+
|
|
24
|
+
### Migration
|
|
25
|
+
|
|
26
|
+
| Old | New |
|
|
27
|
+
|----------------------------------------------------------------------------------|----------------------------------------------------------------|
|
|
28
|
+
| `await regstack.install_indexes()` | `await regstack.install_schema()` |
|
|
29
|
+
| `from regstack.models._objectid import ObjectIdStr` | `from regstack.models._objectid import IdStr` |
|
|
30
|
+
| `from regstack.backends.mongo.repositories.user_repo import UserAlreadyExistsError` | `from regstack.backends.protocols import UserAlreadyExistsError` |
|
|
31
|
+
| `from regstack.backends.mongo.repositories.pending_repo import PendingAlreadyExistsError` | `from regstack.backends.protocols import PendingAlreadyExistsError` |
|
|
32
|
+
| `from regstack.backends.mongo.repositories.mfa_code_repo import MfaVerifyOutcome, MfaVerifyResult` | `from regstack.backends.protocols import MfaVerifyOutcome, MfaVerifyResult` |
|
|
33
|
+
|
|
34
|
+
The internal Mongo helper
|
|
35
|
+
`regstack.backends.mongo.indexes.install_indexes(db, config)` is
|
|
36
|
+
unchanged — that's the function `MongoBackend.install_schema` calls
|
|
37
|
+
to actually create the indexes.
|
|
38
|
+
|
|
39
|
+
## 0.2.3 — 2026-04-28
|
|
40
|
+
|
|
41
|
+
**Docs-only release.** API reference rewritten around the current
|
|
42
|
+
package layout, public surface gained proper Google-style docstrings.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- ``docs/api.md`` restructured around the post-multi-backend package
|
|
47
|
+
layout (``regstack.backends.{base,protocols,factory,mongo,sql}`` and
|
|
48
|
+
friends). Each section now opens with a one-paragraph orientation
|
|
49
|
+
before the autodoc directives. The pre-refactor
|
|
50
|
+
``regstack.db.repositories.*`` references that rendered empty are
|
|
51
|
+
gone.
|
|
52
|
+
- Added Google-style docstrings (purpose summary + Args / Returns /
|
|
53
|
+
Raises) to the most-touched public methods on ``RegStack``,
|
|
54
|
+
``JwtCodec``, ``PasswordHasher``, ``LockoutService``,
|
|
55
|
+
``AuthDependencies``, ``HookRegistry``, ``EmailService``,
|
|
56
|
+
``SmsService``, ``build_router``, ``build_ui_router``,
|
|
57
|
+
``build_ui_environment``, ``default_static_dir``, ``Clock`` /
|
|
58
|
+
``SystemClock`` / ``FrozenClock``.
|
|
59
|
+
- Dataclass field documentation moved to PEP 258 attribute docstrings
|
|
60
|
+
on ``TokenPayload``, ``LockoutDecision``, ``EmailMessage``,
|
|
61
|
+
``SmsMessage``, ``MfaVerifyResult`` — autodoc now renders each field
|
|
62
|
+
with its description without the "duplicate object description"
|
|
63
|
+
warnings the napoleon ``Attributes:`` block was triggering.
|
|
64
|
+
- ``MfaVerifyOutcome`` enum docstring reformatted as a bullet list
|
|
65
|
+
(the napoleon ``Members:`` block isn't a recognised section).
|
|
66
|
+
|
|
6
67
|
## 0.2.2 — 2026-04-28
|
|
7
68
|
|
|
8
69
|
**Docs-only release.**
|