caspian-utils 0.0.11 → 0.0.12

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.
package/dist/docs/auth.md CHANGED
@@ -3,7 +3,7 @@ title: Authentication
3
3
  description: Manage session-backed authentication in Caspian with `casp.auth`, `AuthSettings`, the global `auth` object, centralized `auth_config.py`, page decorators, RPC protection, role-based routes, and optional Google or GitHub OAuth providers.
4
4
  related:
5
5
  title: Related docs
6
- description: Use the fetch-data guide when sign-in happens through RPC, then use the state guide for transient auth-adjacent request state, validation to guard credentials, and routing or project structure to place auth files correctly.
6
+ description: Use the fetch-data guide when sign-in or signout happens through RPC, then use the state guide for transient auth-adjacent request state, validation to guard credentials, and routing or project structure to place auth files correctly.
7
7
  links:
8
8
  - /docs/fetch-data
9
9
  - /docs/state
@@ -50,6 +50,7 @@ from casp.auth import (
50
50
 
51
51
  - Define app-wide auth behavior in `build_auth_settings()` and apply it once at startup with `configure_auth(...)`.
52
52
  - Use `auth.sign_in(...)` and `auth.sign_out(...)` instead of setting or clearing session keys directly.
53
+ - Prefer `pp.rpc(...)` plus `@rpc(require_auth=True)` for signout buttons or menus rendered in pages or components. Use a dedicated signout route only when you need a plain HTML form POST or a no-JavaScript fallback.
53
54
  - Use `@require_auth`, `@require_role`, and `@guest_only` for page access rules.
54
55
  - Use `@rpc(require_auth=True, allowed_roles=[...])` for browser-triggered actions that need protection.
55
56
  - Use `StateManager` only for transient auth-adjacent request state; keep the authenticated session itself owned by `casp.auth`.
@@ -112,12 +113,52 @@ Important behavior from the current implementation:
112
113
  - `default_token_validity` is parsed by the installed auth runtime with the format `^\d+(s|m|h|d)$`. Use values such as `30m`, `1h`, or `7d`.
113
114
  - `token_auto_refresh` only changes behavior when the request lifecycle calls `auth.refresh_session()`. In the installed `auth.py`, the flag alone does not refresh expiry by itself.
114
115
  - The framework `AuthSettings` dataclass defaults `is_all_routes_private=True`, but the project example above explicitly changes that to `False`.
116
+ - In generated app-owned config like this workspace, `src/lib/auth/auth_config.py` starts with `is_all_routes_private=False`, so routes are public by default until the app chooses stricter route protection.
115
117
  - `public_routes`, `auth_routes`, `private_routes`, and `role_based_routes` are exact path matches in the installed `Auth` methods.
116
118
  - `private_routes` matters only when `is_all_routes_private=False`.
117
119
  - `role_based_routes` currently expects `PATH -> [ROLES]`, not role names keyed to paths the other way around.
118
120
  - `role_identifier` defaults to `role`, and the current `auth.sign_in(...)` flow also normalizes `userRole` into `role` when possible.
119
121
  - `api_auth_prefix` defaults to `/api/auth` and should stay centralized here rather than being hard-coded across routes.
120
122
 
123
+ ## Choosing Public vs Private Route Mode
124
+
125
+ Make this decision at app setup time in `src/lib/auth/auth_config.py`.
126
+
127
+ - In the default app-owned starter pattern used in this workspace, routes start public because `is_all_routes_private=False` in `src/lib/auth/auth_config.py`.
128
+ - If the application has only a few public pages and most routes require auth, set `is_all_routes_private=True` and list the exceptions in `public_routes`.
129
+ - If the application has many public pages and only a few protected areas, keep `is_all_routes_private=False` and list only the protected routes in `private_routes`.
130
+ - In the current runtime, `auth_routes=["/signin", "/signup"]` stays public by default, and most apps do not need to change it unless the user explicitly asks for different auth routes.
131
+ - In all-private mode, the default `public_routes=["/"]` keeps the home page public unless you change that list.
132
+ - `token_auto_refresh=True` does not make routes private. It only enables sliding-session refresh when the request lifecycle calls `auth.refresh_session()`.
133
+ - You do not need to modify Caspian core files for this decision. Keep the policy in `src/lib/auth/auth_config.py`.
134
+ - If you customize `src/lib/auth/auth_config.py`, add it to `excludeFiles` in `caspian.config.json` so update commands do not overwrite your local auth policy.
135
+
136
+ Example all-private setup with a few public exceptions:
137
+
138
+ ```python
139
+ return AuthSettings(
140
+ default_token_validity="1h",
141
+ token_auto_refresh=False,
142
+ is_all_routes_private=True,
143
+ public_routes=["/", "/pricing", "/about"],
144
+ auth_routes=["/signin", "/signup"],
145
+ private_routes=[],
146
+ )
147
+ ```
148
+
149
+ Example mixed app with many public routes and only a few protected areas:
150
+
151
+ ```python
152
+ return AuthSettings(
153
+ default_token_validity="1h",
154
+ token_auto_refresh=False,
155
+ is_all_routes_private=False,
156
+ public_routes=["/"],
157
+ auth_routes=["/signin", "/signup"],
158
+ private_routes=["/dashboard", "/settings", "/billing"],
159
+ )
160
+ ```
161
+
121
162
  ## Environment Variables
122
163
 
123
164
  The installed auth code reads several values from `.env` when explicit values are not passed.
@@ -414,16 +455,58 @@ src/
414
455
  signup/
415
456
  index.py
416
457
  index.html
417
- signout/
418
- index.py
458
+ signout/
459
+ index.py
419
460
  dashboard/
420
461
  index.py
421
462
  index.html
422
463
  ```
423
464
 
424
- Use `guest_only()` on signin and signup routes, use `auth.sign_in(...)` inside the owning RPC action after validation and credential checks, and protect private destinations with `require_auth()` or central route policy.
465
+ Use `guest_only()` on signin and signup routes, use `auth.sign_in(...)` inside the owning RPC action after validation and credential checks, prefer RPC for signout UI actions, and protect private destinations with `require_auth()` or central route policy.
466
+
467
+ Preferred signout pattern: auth-protected RPC from a page or component.
468
+
469
+ Use this when the logout trigger lives in a page, layout, header, dropdown, or reusable component. The HTML can live at page level or component level.
470
+
471
+ ```html
472
+ <div>
473
+ <button onclick="signout()">
474
+ Sign out
475
+ </button>
476
+
477
+ <script>
478
+ async function signout() {
479
+ await pp.rpc("signout");
480
+ }
481
+ </script>
482
+ </div>
483
+ ```
484
+
485
+ ```python
486
+ from casp.auth import auth
487
+ from casp.rpc import rpc
488
+
489
+
490
+ @rpc(require_auth=True)
491
+ def signout():
492
+ return auth.sign_out()
493
+ ```
494
+
495
+ Fallback signout pattern: dedicated route.
496
+
497
+ Use this when you need a plain HTML form POST, a no-JavaScript fallback, or a full-route signout endpoint.
498
+
499
+ HTML:
500
+
501
+ ```html
502
+ <form action="/signout" method="post">
503
+ <button type="submit">
504
+ <span>Log Out</span>
505
+ </button>
506
+ </form>
507
+ ```
425
508
 
426
- Simple signout route example:
509
+ Route: `src/app/(auth)/signout/index.py`
427
510
 
428
511
  ```python
429
512
  from casp.auth import auth, require_auth
@@ -659,11 +742,17 @@ Validate and authenticate close to the input boundary.
659
742
  Common placement patterns are:
660
743
 
661
744
  - put centralized policy in `src/lib/auth/auth_config.py`
745
+ - decide public-vs-private route mode at app start in `src/lib/auth/auth_config.py` instead of scattering route privacy logic across route files
746
+ - use `is_all_routes_private=True` only when most routes should require auth; otherwise keep `is_all_routes_private=False` and maintain `private_routes`
747
+ - keep public exceptions in `public_routes`, and leave `auth_routes=["/signin", "/signup"]` alone unless the app explicitly needs different auth endpoints
662
748
  - call `configure_auth(build_auth_settings())` during startup
663
- - keep sign-in, signup, signout, and reset-password handlers in the owning route backend under `src/app/**/index.py`
749
+ - keep sign-in, signup, and reset-password handlers in the owning route backend under `src/app/**/index.py`
750
+ - prefer signout through `pp.rpc("signout")` with `@rpc(require_auth=True)` when the trigger lives in page or component UI
751
+ - use a dedicated signout route only for no-JavaScript, form-post, or full-navigation edge cases
664
752
  - use `@rpc()` for browser-triggered auth actions and page decorators for full-route protection
665
753
  - use `Validate` and `Rule` from `casp.validate` before password checks, user lookup, persistence, or external provider flows
666
754
  - keep reusable auth helpers in `src/lib/auth/`
755
+ - protect customized auth policy files from updater overwrite with `excludeFiles` in `caspian.config.json`
667
756
 
668
757
  For browser-triggered auth forms, pair this page with `fetch-data.md`. For credential and form validation, pair it with `validation.md`.
669
758
 
@@ -673,15 +762,22 @@ If an AI agent is deciding how to handle auth in Caspian, apply these rules firs
673
762
 
674
763
  - Treat `casp.auth` as the default authentication layer.
675
764
  - Centralize route visibility, redirects, and RBAC policy in `src/lib/auth/auth_config.py`.
765
+ - Decide route mode early in `src/lib/auth/auth_config.py`: use `is_all_routes_private=True` when most routes should require auth, otherwise keep `is_all_routes_private=False` and list protected routes in `private_routes`.
766
+ - In app-owned starter config like this workspace, treat `is_all_routes_private=False` as the default starting point, which means routes begin public until the app opts into stricter protection.
767
+ - Treat `public_routes` as the public exception list for all-private apps. In the current defaults, `/` stays public and `auth_routes=["/signin", "/signup"]` stays public too.
676
768
  - Apply settings at startup in `main.py` with `configure_auth(build_auth_settings())`.
677
769
  - Register provider instances in `main.py` with `Auth.set_providers(...)` when Google or GitHub OAuth is enabled.
678
770
  - Use `auth.sign_in(...)` and `auth.sign_out(...)` for session lifecycle changes.
771
+ - Prefer `pp.rpc("signout")` plus `@rpc(require_auth=True)` for logout buttons or menus in pages and components.
772
+ - Use a dedicated `/signout` route only for plain HTML form POST, no-JavaScript fallback, or other full-navigation edge cases.
773
+ - Do not treat `token_auto_refresh` as a route-privacy switch. In the current app it only affects sliding-session refresh if `auth.refresh_session()` is called.
679
774
  - Use `@require_auth`, `@require_role`, and `@guest_only` for page-level access rules.
680
775
  - Use `@rpc(require_auth=True, allowed_roles=[...])` for protected browser-triggered actions.
681
776
  - Keep `SessionMiddleware` outermost so auth, CSRF, and RPC handlers can read `request.session`.
682
777
  - Use [state.md](./state.md) only for transient auth-adjacent request state, not as the auth session store.
683
778
  - Align `SESSION_LIFETIME_HOURS` with `default_token_validity` unless you intentionally want different cookie and auth-payload expiry windows.
684
779
  - Prefer exact route strings in `public_routes`, `auth_routes`, `private_routes`, and `role_based_routes`.
780
+ - Protect customized `src/lib/auth/auth_config.py` from updater overwrite by adding it to `excludeFiles` in `caspian.config.json`.
685
781
  - Keep auth secrets and OAuth provider credentials in `.env`.
686
782
  - Set `AUTH_COOKIE_NAME` explicitly so the session middleware cookie name and auth settings stay aligned.
687
783
  - Use `.venv/Lib/site-packages/casp/auth.py` only when the task is about framework auth internals or debugging installed behavior.
@@ -643,6 +643,10 @@ This is useful for protecting:
643
643
  - entry-point files
644
644
  - other locally modified framework-managed files
645
645
 
646
+ Auth example:
647
+
648
+ - add `./src/lib/auth/auth_config.py` to `excludeFiles` when you customize route privacy policy, public-route exceptions, redirects, or other app-specific auth settings there
649
+
646
650
  If you exclude a file, the updater preserves it, but you are responsible for merging future framework changes into that file manually.
647
651
 
648
652
  ## 10. Operational Notes
@@ -40,7 +40,7 @@ The packaged Caspian docs distributed by the current toolchain also live here:
40
40
  - `commands.md` - Main Caspian CLI workflows for project creation, generation, updates, and config-aware maintenance
41
41
  - `mcp.md` - Workspace FastMCP server layout, nested config path, local launch flow, and MCP-specific AI routing rules
42
42
  - `database.md` - Prisma schema, migration, seed, and client-generation workflow for the current workspace, plus Python-side helper caveats
43
- - `auth.md` - Session-backed authentication with `casp.auth`, centralized `auth_config.py`, decorators, RBAC, and OAuth provider helpers
43
+ - `auth.md` - Session-backed authentication with `casp.auth`, centralized `auth_config.py`, public-vs-private route mode guidance, RPC-first signout guidance, RBAC, and OAuth provider helpers
44
44
  - `components.md` - Create reusable Python components, template-backed UI, JSX-style imports, and the single-parent root rule for component HTML files
45
45
  - `pulsepoint.md` - Default reactive frontend runtime contract for component scripts, state, effects, directives, and client-side behaviors
46
46
  - `fetch-data.md` - Initial server-side data loading and browser-triggered RPC flows with `pp.rpc()`, streaming, uploads, and auth-aware actions
@@ -88,7 +88,7 @@ Once the project is scaffolded:
88
88
 
89
89
  - Read `database.md` when the app includes Prisma ORM support or needs database changes.
90
90
  - Read `mcp.md` when the app includes MCP support or needs FastMCP server, config, or launch-flow changes.
91
- - Read `auth.md` before wiring session config, sign-in or signout routes, route guards, or OAuth providers.
91
+ - Read `auth.md` before choosing public-vs-private route mode, wiring session config, sign-in or signout flows, route guards, or OAuth providers.
92
92
  - Read `pulsepoint.md` before generating interactive frontend behavior.
93
93
  - Read `fetch-data.md` before adding browser-triggered reads, writes, uploads, or streams.
94
94
  - Read `validation.md` before handling forms, auth input, or RPC payloads.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "caspian-utils",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "Caspian tooling",
5
5
  "main": "index.js",
6
6
  "scripts": {