Authorization¶
[!abstract] Summary All data is scoped to groups. Users have roles that control access to features. Registration requires email confirmation and admin approval.
Multi-Tenancy Model¶
Every user belongs to exactly one group. All data entities are scoped to groups (see Entity Relationship Diagram for the full schema). Users in the same group can see each other's markers, transactions, and budget accounts. Notes can be private (user-only) or public (group-visible).
Roles¶
| Role | Description |
|---|---|
User | Default role, standard access to group data |
Admin | Full access + user management + Hangfire dashboard |
Admin Assignment¶
Admins are configured via Security__AdminUserNames environment variable (comma-separated usernames). On application startup:
- Users in the list who aren't admins are promoted to Admin
- Users not in the list who are admins are demoted to User
Admins cannot be assigned via UI.
Admin Capabilities¶
- Approve, decline, or deactivate users
- Access all admin endpoints (
/api/users/*) - Access Hangfire dashboard (
/hangfire) - All standard User capabilities
Feature Modules¶
Groups can have specific modules enabled/disabled:
| Module | Features |
|---|---|
Map | Markers, photos, map view |
Budget | Transactions, categories, budget accounts, recurring transactions |
Notes | Checklists, items, sharing |
Module access is checked via hasModule() in frontend and enforced in backend.
Registration Flow¶
New users go through a two-step verification:
stateDiagram-v2
[*] --> EmailUnconfirmed: Register
EmailUnconfirmed --> Pending: Confirm email
Pending --> Confirmed: Admin approves
Pending --> Declined: Admin declines
Confirmed --> Deactivated: Admin deactivates
Deactivated --> Confirmed: Admin reactivates Email Status¶
| Status | Description |
|---|---|
Unconfirmed | Initial state after registration |
Confirmed | Email verified via confirmation link |
ChangePending | User requested email change, awaiting confirmation |
Users can resend confirmation emails (with cooldown). Unconfirmed registrations:
- Receive warning email before expiry
- Are automatically declined after expiry period
Registration Status¶
| Status | Description |
|---|---|
Pending | Email confirmed, awaiting admin approval |
Confirmed | Admin approved, full access granted |
Declined | Admin declined (with reason) |
Deactivated | Admin deactivated existing user |
Admin Status Changes¶
| Transition | Requirements |
|---|---|
| Pending → Confirmed | Email must be confirmed, GroupId must be provided |
| Pending → Declined | Decline reason required |
| Confirmed → Deactivated | Cannot deactivate admin users |
| Deactivated → Confirmed | Can optionally re-enable recurring transactions |
Admins cannot change their own status.
Decline Reasons¶
| Reason | Description |
|---|---|
UnknownPerson | Don't know this person |
DuplicateAccount | Already has an account |
SpamBot | Detected as spam/bot |
EmailNotConfirmed | Auto-set when registration expires |
Other | Custom reason (requires text) |
Route Guards (Frontend)¶
Two route guards in components/routing/:
| Component | Purpose |
|---|---|
ProtectedRoute | Requires authentication; redirects to login if not logged in |
GuestRoute | Redirects to home if already logged in (for login, register, etc.) |
ProtectedRoute optional props:
| Prop | Purpose |
|---|---|
requiredModule | Require specific module access (e.g., MODULE_TYPES.MAP) |
requiredRole | Require specific role (e.g., ROLES.ADMIN) |
<Route path={ROUTES.LOGIN} element={<GuestRoute><Login /></GuestRoute>} />
<Route path={ROUTES.HOME} element={<ProtectedRoute><Hub /></ProtectedRoute>} />
<Route path={ROUTES.MAP} element={<ProtectedRoute requiredModule={MODULE_TYPES.MAP}><Map /></ProtectedRoute>} />
<Route path={ROUTES.ADMIN} element={<ProtectedRoute requiredRole={ROLES.ADMIN}><Admin /></ProtectedRoute>} />
Registration status-specific routes:
/registration-pending— Shown to pending users/registration-declined— Shown to declined users/account-deactivated— Shown to deactivated users
Related¶
- Authentication — Login and tokens
- Security — Security architecture
- Authorization Pattern — Module authorization
- Background Jobs — Registration expiry job
- Data Model — Entity relationships