plutonium 0.33.1 → 0.34.0
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.
- checksums.yaml +4 -4
- data/# Plutonium: The pre-alpha demo.md +4 -2
- data/.claude/skills/assets/SKILL.md +416 -0
- data/.claude/skills/connect-resource/SKILL.md +112 -0
- data/.claude/skills/controller/SKILL.md +302 -0
- data/.claude/skills/create-resource/SKILL.md +240 -0
- data/.claude/skills/definition/SKILL.md +218 -0
- data/.claude/skills/definition-actions/SKILL.md +386 -0
- data/.claude/skills/definition-fields/SKILL.md +474 -0
- data/.claude/skills/definition-query/SKILL.md +334 -0
- data/.claude/skills/forms/SKILL.md +439 -0
- data/.claude/skills/installation/SKILL.md +300 -0
- data/.claude/skills/interaction/SKILL.md +382 -0
- data/.claude/skills/model/SKILL.md +267 -0
- data/.claude/skills/model-features/SKILL.md +286 -0
- data/.claude/skills/nested-resources/SKILL.md +274 -0
- data/.claude/skills/package/SKILL.md +191 -0
- data/.claude/skills/policy/SKILL.md +352 -0
- data/.claude/skills/portal/SKILL.md +400 -0
- data/.claude/skills/resource/SKILL.md +281 -0
- data/.claude/skills/rodauth/SKILL.md +452 -0
- data/.claude/skills/views/SKILL.md +563 -0
- data/Appraisals +46 -4
- data/CHANGELOG.md +32 -1
- data/app/assets/plutonium.css +2 -2
- data/config/brakeman.ignore +239 -0
- data/config/initializers/action_policy.rb +1 -1
- data/docs/.vitepress/config.ts +132 -47
- data/docs/concepts/architecture.md +226 -0
- data/docs/concepts/auto-detection.md +254 -0
- data/docs/concepts/index.md +61 -0
- data/docs/concepts/packages-portals.md +304 -0
- data/docs/concepts/resources.md +224 -0
- data/docs/cookbook/blog.md +412 -0
- data/docs/cookbook/index.md +289 -0
- data/docs/cookbook/saas.md +481 -0
- data/docs/getting-started/index.md +56 -0
- data/docs/getting-started/installation.md +146 -0
- data/docs/getting-started/tutorial/01-setup.md +118 -0
- data/docs/getting-started/tutorial/02-first-resource.md +180 -0
- data/docs/getting-started/tutorial/03-authentication.md +246 -0
- data/docs/getting-started/tutorial/04-authorization.md +170 -0
- data/docs/getting-started/tutorial/05-custom-actions.md +202 -0
- data/docs/getting-started/tutorial/06-nested-resources.md +147 -0
- data/docs/getting-started/tutorial/07-customizing-ui.md +254 -0
- data/docs/getting-started/tutorial/index.md +64 -0
- data/docs/guides/adding-resources.md +420 -0
- data/docs/guides/authentication.md +551 -0
- data/docs/guides/authorization.md +468 -0
- data/docs/guides/creating-packages.md +380 -0
- data/docs/guides/custom-actions.md +523 -0
- data/docs/guides/index.md +45 -0
- data/docs/guides/multi-tenancy.md +302 -0
- data/docs/guides/nested-resources.md +411 -0
- data/docs/guides/search-filtering.md +266 -0
- data/docs/guides/theming.md +321 -0
- data/docs/index.md +67 -26
- data/docs/public/CLAUDE.md +64 -21
- data/docs/reference/assets/index.md +496 -0
- data/docs/reference/controller/index.md +363 -0
- data/docs/reference/definition/actions.md +400 -0
- data/docs/reference/definition/fields.md +350 -0
- data/docs/reference/definition/index.md +252 -0
- data/docs/reference/definition/query.md +342 -0
- data/docs/reference/generators/index.md +469 -0
- data/docs/reference/index.md +49 -0
- data/docs/reference/interaction/index.md +445 -0
- data/docs/reference/model/features.md +248 -0
- data/docs/reference/model/index.md +219 -0
- data/docs/reference/policy/index.md +385 -0
- data/docs/reference/portal/index.md +382 -0
- data/docs/reference/views/forms.md +396 -0
- data/docs/reference/views/index.md +479 -0
- data/gemfiles/rails_7.gemfile +9 -2
- data/gemfiles/rails_7.gemfile.lock +146 -111
- data/gemfiles/rails_8.0.gemfile +20 -0
- data/gemfiles/rails_8.0.gemfile.lock +417 -0
- data/gemfiles/rails_8.1.gemfile +20 -0
- data/gemfiles/rails_8.1.gemfile.lock +419 -0
- data/lib/generators/pu/gem/dotenv/templates/.env +2 -0
- data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +3 -1
- data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +13 -16
- data/lib/generators/pu/pkg/portal/USAGE +65 -0
- data/lib/generators/pu/pkg/portal/portal_generator.rb +22 -9
- data/lib/generators/pu/res/conn/USAGE +71 -0
- data/lib/generators/pu/res/model/USAGE +106 -110
- data/lib/generators/pu/res/model/templates/model.rb.tt +6 -2
- data/lib/generators/pu/res/scaffold/USAGE +85 -0
- data/lib/generators/pu/rodauth/install_generator.rb +2 -6
- data/lib/generators/pu/rodauth/templates/config/initializers/url_options.rb +17 -0
- data/lib/generators/pu/skills/sync/USAGE +14 -0
- data/lib/generators/pu/skills/sync/sync_generator.rb +66 -0
- data/lib/plutonium/action_policy/sti_policy_lookup.rb +1 -1
- data/lib/plutonium/core/controller.rb +2 -2
- data/lib/plutonium/interaction/base.rb +1 -0
- data/lib/plutonium/package/engine.rb +2 -2
- data/lib/plutonium/query/adhoc_block.rb +6 -2
- data/lib/plutonium/query/model_scope.rb +1 -1
- data/lib/plutonium/railtie.rb +4 -0
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +1 -1
- data/lib/plutonium/resource/query_object.rb +38 -8
- data/lib/plutonium/ui/table/components/scopes_bar.rb +39 -34
- data/lib/plutonium/version.rb +1 -1
- data/lib/tasks/release.rake +19 -4
- data/package.json +1 -1
- metadata +76 -39
- data/brakeman.ignore +0 -28
- data/docs/api-examples.md +0 -49
- data/docs/guide/claude-code-guide.md +0 -74
- data/docs/guide/deep-dive/authorization.md +0 -189
- data/docs/guide/deep-dive/multitenancy.md +0 -256
- data/docs/guide/deep-dive/resources.md +0 -390
- data/docs/guide/getting-started/01-installation.md +0 -165
- data/docs/guide/index.md +0 -28
- data/docs/guide/introduction/01-what-is-plutonium.md +0 -211
- data/docs/guide/introduction/02-core-concepts.md +0 -440
- data/docs/guide/tutorial/01-project-setup.md +0 -75
- data/docs/guide/tutorial/02-creating-a-feature-package.md +0 -45
- data/docs/guide/tutorial/03-defining-resources.md +0 -90
- data/docs/guide/tutorial/04-creating-a-portal.md +0 -101
- data/docs/guide/tutorial/05-customizing-the-ui.md +0 -128
- data/docs/guide/tutorial/06-adding-custom-actions.md +0 -101
- data/docs/guide/tutorial/07-implementing-authorization.md +0 -90
- data/docs/markdown-examples.md +0 -85
- data/docs/modules/action.md +0 -244
- data/docs/modules/authentication.md +0 -236
- data/docs/modules/configuration.md +0 -599
- data/docs/modules/controller.md +0 -443
- data/docs/modules/core.md +0 -316
- data/docs/modules/definition.md +0 -1308
- data/docs/modules/display.md +0 -759
- data/docs/modules/form.md +0 -495
- data/docs/modules/generator.md +0 -400
- data/docs/modules/index.md +0 -167
- data/docs/modules/interaction.md +0 -642
- data/docs/modules/package.md +0 -151
- data/docs/modules/policy.md +0 -176
- data/docs/modules/portal.md +0 -710
- data/docs/modules/query.md +0 -297
- data/docs/modules/resource_record.md +0 -618
- data/docs/modules/routing.md +0 -690
- data/docs/modules/table.md +0 -301
- data/docs/modules/ui.md +0 -631
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rodauth
|
|
3
|
+
description: Plutonium Rodauth integration - authentication setup, account types, and configuration
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plutonium Rodauth Authentication
|
|
7
|
+
|
|
8
|
+
Plutonium integrates with [Rodauth](http://rodauth.jeremyevans.net/) via [rodauth-rails](https://github.com/janko/rodauth-rails) for authentication. This provides a full-featured, secure authentication system.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
### Step 1: Install Rodauth Base
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
rails generate pu:rodauth:install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This installs:
|
|
19
|
+
- Required gems (`rodauth-rails`, `bcrypt`, `sequel-activerecord_connection`)
|
|
20
|
+
- `app/rodauth/rodauth_app.rb` - Main Roda app
|
|
21
|
+
- `app/rodauth/rodauth_plugin.rb` - Base plugin
|
|
22
|
+
- `app/controllers/rodauth_controller.rb` - Base controller
|
|
23
|
+
- `config/initializers/rodauth.rb` - Configuration
|
|
24
|
+
- `app/views/layouts/rodauth.html.erb` - Auth layout
|
|
25
|
+
- PostgreSQL extension migration (if using PostgreSQL)
|
|
26
|
+
|
|
27
|
+
### Step 2: Create Account Type
|
|
28
|
+
|
|
29
|
+
Choose the appropriate generator for your use case:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Basic user account
|
|
33
|
+
rails generate pu:rodauth:account user
|
|
34
|
+
|
|
35
|
+
# Admin with 2FA and security features
|
|
36
|
+
rails generate pu:rodauth:admin admin
|
|
37
|
+
|
|
38
|
+
# Customer with entity association
|
|
39
|
+
rails generate pu:rodauth:customer customer
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Account Generators
|
|
43
|
+
|
|
44
|
+
### Basic Account (`pu:rodauth:account`)
|
|
45
|
+
|
|
46
|
+
Creates a standard user account with configurable features:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
rails generate pu:rodauth:account user [options]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Options:**
|
|
53
|
+
|
|
54
|
+
| Option | Description |
|
|
55
|
+
|--------|-------------|
|
|
56
|
+
| `--defaults` | Enable default features (login, logout, remember, password reset) |
|
|
57
|
+
| `--kitchen_sink` | Enable ALL available features |
|
|
58
|
+
| `--primary` | Mark as primary account (no URL prefix) |
|
|
59
|
+
| `--no-mails` | Skip mailer setup |
|
|
60
|
+
| `--argon2` | Use Argon2 instead of bcrypt for password hashing |
|
|
61
|
+
| `--api_only` | Configure for JSON API only (no sessions) |
|
|
62
|
+
|
|
63
|
+
**Feature Options:**
|
|
64
|
+
|
|
65
|
+
| Option | Default | Description |
|
|
66
|
+
|--------|---------|-------------|
|
|
67
|
+
| `--login` | ✓ | Login functionality |
|
|
68
|
+
| `--logout` | ✓ | Logout functionality |
|
|
69
|
+
| `--remember` | ✓ | "Remember me" cookies |
|
|
70
|
+
| `--create_account` | ✓ | User registration |
|
|
71
|
+
| `--verify_account` | ✓ | Email verification |
|
|
72
|
+
| `--reset_password` | ✓ | Password reset via email |
|
|
73
|
+
| `--change_password` | ✓ | Change password |
|
|
74
|
+
| `--change_login` | ✓ | Change email |
|
|
75
|
+
| `--verify_login_change` | ✓ | Verify email change |
|
|
76
|
+
| `--otp` | | TOTP two-factor auth |
|
|
77
|
+
| `--webauthn` | | WebAuthn/passkeys |
|
|
78
|
+
| `--recovery_codes` | | Recovery codes for 2FA |
|
|
79
|
+
| `--lockout` | | Account lockout after failed attempts |
|
|
80
|
+
| `--active_sessions` | | Track active sessions |
|
|
81
|
+
| `--audit_logging` | | Audit authentication events |
|
|
82
|
+
| `--close_account` | | Allow account deletion |
|
|
83
|
+
| `--email_auth` | | Passwordless login via email |
|
|
84
|
+
| `--sms_codes` | | SMS-based 2FA |
|
|
85
|
+
| `--jwt` | | JWT token authentication |
|
|
86
|
+
| `--jwt_refresh` | | JWT refresh tokens |
|
|
87
|
+
|
|
88
|
+
### Admin Account (`pu:rodauth:admin`)
|
|
89
|
+
|
|
90
|
+
Creates a secure admin account with:
|
|
91
|
+
- Multi-phase login (email first, then password)
|
|
92
|
+
- TOTP two-factor authentication (required)
|
|
93
|
+
- Recovery codes
|
|
94
|
+
- Account lockout
|
|
95
|
+
- Active sessions tracking
|
|
96
|
+
- Audit logging
|
|
97
|
+
- No public signup (accounts created via rake task)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
rails generate pu:rodauth:admin admin
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Creates rake task:**
|
|
104
|
+
```bash
|
|
105
|
+
# Create admin account
|
|
106
|
+
rails rodauth_admin:create[admin@example.com,password123]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Customer Account (`pu:rodauth:customer`)
|
|
110
|
+
|
|
111
|
+
Creates a customer account with an associated entity (organization/company):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
rails generate pu:rodauth:customer customer
|
|
115
|
+
rails generate pu:rodauth:customer customer --entity=Organization
|
|
116
|
+
rails generate pu:rodauth:customer customer --no-allow_signup
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Options:**
|
|
120
|
+
|
|
121
|
+
| Option | Description |
|
|
122
|
+
|--------|-------------|
|
|
123
|
+
| `--entity=NAME` | Entity model name (default: "Entity") |
|
|
124
|
+
| `--no-allow_signup` | Disable public registration |
|
|
125
|
+
|
|
126
|
+
This creates:
|
|
127
|
+
- Customer account model
|
|
128
|
+
- Entity model (Organization, Company, etc.)
|
|
129
|
+
- Membership join model
|
|
130
|
+
- Has-many-through associations
|
|
131
|
+
|
|
132
|
+
## Connecting Auth to Controllers
|
|
133
|
+
|
|
134
|
+
### Include in Resource Controller
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
# app/controllers/resource_controller.rb
|
|
138
|
+
class ResourceController < PlutoniumController
|
|
139
|
+
include Plutonium::Resource::Controller
|
|
140
|
+
include Plutonium::Auth::Rodauth(:user) # Use :user account
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Multiple Account Types
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
# app/controllers/admin_controller.rb
|
|
148
|
+
class AdminController < PlutoniumController
|
|
149
|
+
include Plutonium::Resource::Controller
|
|
150
|
+
include Plutonium::Auth::Rodauth(:admin)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# app/controllers/customer_controller.rb
|
|
154
|
+
class CustomerController < PlutoniumController
|
|
155
|
+
include Plutonium::Resource::Controller
|
|
156
|
+
include Plutonium::Auth::Rodauth(:customer)
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### What It Provides
|
|
161
|
+
|
|
162
|
+
Including `Plutonium::Auth::Rodauth(:name)` adds:
|
|
163
|
+
|
|
164
|
+
| Method | Description |
|
|
165
|
+
|--------|-------------|
|
|
166
|
+
| `current_user` | The authenticated account |
|
|
167
|
+
| `logout_url` | URL to logout |
|
|
168
|
+
| `rodauth` | Access to Rodauth instance |
|
|
169
|
+
|
|
170
|
+
## Generated Files
|
|
171
|
+
|
|
172
|
+
### Account Structure
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
app/
|
|
176
|
+
├── controllers/
|
|
177
|
+
│ └── rodauth/
|
|
178
|
+
│ └── user_controller.rb # Account-specific controller
|
|
179
|
+
├── mailers/
|
|
180
|
+
│ └── rodauth/
|
|
181
|
+
│ └── user_mailer.rb # Account-specific mailer
|
|
182
|
+
├── models/
|
|
183
|
+
│ └── user.rb # Account model
|
|
184
|
+
├── rodauth/
|
|
185
|
+
│ ├── rodauth_app.rb # Main Roda app
|
|
186
|
+
│ ├── rodauth_plugin.rb # Base plugin
|
|
187
|
+
│ └── user_rodauth_plugin.rb # Account-specific config
|
|
188
|
+
├── policies/
|
|
189
|
+
│ └── user_policy.rb # Account policy
|
|
190
|
+
├── definitions/
|
|
191
|
+
│ └── user_definition.rb # Account definition
|
|
192
|
+
└── views/
|
|
193
|
+
├── layouts/
|
|
194
|
+
│ └── rodauth.html.erb # Auth layout
|
|
195
|
+
└── rodauth/
|
|
196
|
+
└── user_mailer/ # Email templates
|
|
197
|
+
├── reset_password.text.erb
|
|
198
|
+
├── verify_account.text.erb
|
|
199
|
+
└── ...
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Plugin Configuration
|
|
203
|
+
|
|
204
|
+
```ruby
|
|
205
|
+
# app/rodauth/user_rodauth_plugin.rb
|
|
206
|
+
class UserRodauthPlugin < RodauthPlugin
|
|
207
|
+
configure do
|
|
208
|
+
# Features enabled for this account
|
|
209
|
+
enable :login, :logout, :remember, :create_account, ...
|
|
210
|
+
|
|
211
|
+
# URL prefix (non-primary accounts)
|
|
212
|
+
prefix "/users"
|
|
213
|
+
|
|
214
|
+
# Password storage
|
|
215
|
+
account_password_hash_column :password_hash
|
|
216
|
+
|
|
217
|
+
# Controller for views
|
|
218
|
+
rails_controller { Rodauth::UserController }
|
|
219
|
+
|
|
220
|
+
# Model
|
|
221
|
+
rails_account_model { User }
|
|
222
|
+
|
|
223
|
+
# Redirects
|
|
224
|
+
login_redirect "/"
|
|
225
|
+
logout_redirect "/"
|
|
226
|
+
|
|
227
|
+
# Session configuration
|
|
228
|
+
session_key "_user_session"
|
|
229
|
+
remember_cookie_key "_user_remember"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Customization
|
|
235
|
+
|
|
236
|
+
### Custom Login Redirect
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
# app/rodauth/user_rodauth_plugin.rb
|
|
240
|
+
configure do
|
|
241
|
+
login_redirect { "/dashboard" }
|
|
242
|
+
|
|
243
|
+
# Or dynamically based on user
|
|
244
|
+
login_redirect do
|
|
245
|
+
if rails_account.admin?
|
|
246
|
+
"/admin"
|
|
247
|
+
else
|
|
248
|
+
"/dashboard"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Custom Validation
|
|
255
|
+
|
|
256
|
+
```ruby
|
|
257
|
+
configure do
|
|
258
|
+
# Add custom field validation
|
|
259
|
+
before_create_account do
|
|
260
|
+
throw_error_status(422, "name", "must be present") if param("name").empty?
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# After account creation
|
|
264
|
+
after_create_account do
|
|
265
|
+
Profile.create!(account_id: account_id, name: param("name"))
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Password Requirements
|
|
271
|
+
|
|
272
|
+
```ruby
|
|
273
|
+
configure do
|
|
274
|
+
# Minimum length
|
|
275
|
+
password_minimum_length 12
|
|
276
|
+
|
|
277
|
+
# Custom complexity
|
|
278
|
+
password_meets_requirements? do |password|
|
|
279
|
+
super(password) && password.match?(/\d/) && password.match?(/[^a-zA-Z\d]/)
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Multi-Phase Login
|
|
285
|
+
|
|
286
|
+
```ruby
|
|
287
|
+
configure do
|
|
288
|
+
# Ask for email first, then password
|
|
289
|
+
use_multi_phase_login? true
|
|
290
|
+
end
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Prevent Public Signup
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
configure do
|
|
297
|
+
before_create_account_route do
|
|
298
|
+
request.halt unless internal_request?
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Email Configuration
|
|
304
|
+
|
|
305
|
+
Emails are sent via Action Mailer. Configure delivery in your environment:
|
|
306
|
+
|
|
307
|
+
```ruby
|
|
308
|
+
# config/environments/production.rb
|
|
309
|
+
config.action_mailer.delivery_method = :smtp
|
|
310
|
+
config.action_mailer.smtp_settings = {
|
|
311
|
+
address: "smtp.example.com",
|
|
312
|
+
port: 587,
|
|
313
|
+
user_name: ENV["SMTP_USER"],
|
|
314
|
+
password: ENV["SMTP_PASSWORD"]
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Custom Email Templates
|
|
319
|
+
|
|
320
|
+
Override templates in `app/views/rodauth/user_mailer/`:
|
|
321
|
+
|
|
322
|
+
```erb
|
|
323
|
+
<%# app/views/rodauth/user_mailer/reset_password.text.erb %>
|
|
324
|
+
Hi <%= @account.email %>,
|
|
325
|
+
|
|
326
|
+
Someone requested a password reset for your account.
|
|
327
|
+
|
|
328
|
+
Reset your password: <%= @reset_password_url %>
|
|
329
|
+
|
|
330
|
+
If you didn't request this, ignore this email.
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Portal Integration
|
|
334
|
+
|
|
335
|
+
### Selecting Auth for Portal
|
|
336
|
+
|
|
337
|
+
When generating a portal, select the Rodauth account:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
rails generate pu:pkg:portal admin
|
|
341
|
+
# Select "Rodauth account" when prompted
|
|
342
|
+
# Choose "admin" account
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Manual Portal Auth Setup
|
|
346
|
+
|
|
347
|
+
```ruby
|
|
348
|
+
# packages/admin_portal/lib/engine.rb
|
|
349
|
+
module AdminPortal
|
|
350
|
+
class Engine < Rails::Engine
|
|
351
|
+
include Plutonium::Portal::Engine
|
|
352
|
+
|
|
353
|
+
# Require authentication
|
|
354
|
+
config.before_initialize do
|
|
355
|
+
config.to_prepare do
|
|
356
|
+
AdminPortal::ResourceController.class_eval do
|
|
357
|
+
include Plutonium::Auth::Rodauth(:admin)
|
|
358
|
+
|
|
359
|
+
before_action :require_authenticated
|
|
360
|
+
|
|
361
|
+
private
|
|
362
|
+
|
|
363
|
+
def require_authenticated
|
|
364
|
+
redirect_to rodauth.login_path unless current_user
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## API Authentication
|
|
374
|
+
|
|
375
|
+
For JSON API authentication:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
rails generate pu:rodauth:account api_user --api_only --jwt --jwt_refresh
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
This enables:
|
|
382
|
+
- JWT token authentication
|
|
383
|
+
- Refresh tokens
|
|
384
|
+
- No session/cookie handling
|
|
385
|
+
|
|
386
|
+
### Using JWT
|
|
387
|
+
|
|
388
|
+
```ruby
|
|
389
|
+
# Login
|
|
390
|
+
POST /api_users/login
|
|
391
|
+
Content-Type: application/json
|
|
392
|
+
|
|
393
|
+
{"login": "user@example.com", "password": "secret"}
|
|
394
|
+
|
|
395
|
+
# Response includes JWT
|
|
396
|
+
{"access_token": "...", "refresh_token": "..."}
|
|
397
|
+
|
|
398
|
+
# Authenticated requests
|
|
399
|
+
GET /api/posts
|
|
400
|
+
Authorization: Bearer <access_token>
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## Internal Requests
|
|
404
|
+
|
|
405
|
+
Create accounts programmatically:
|
|
406
|
+
|
|
407
|
+
```ruby
|
|
408
|
+
# Using internal request
|
|
409
|
+
Rodauth::Rails.app(:user).rodauth(:user).create_account(
|
|
410
|
+
login: "user@example.com",
|
|
411
|
+
password: "secure_password"
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
# Or via model (if allowed)
|
|
415
|
+
User.create!(
|
|
416
|
+
email: "user@example.com",
|
|
417
|
+
password_hash: BCrypt::Password.create("secure_password"),
|
|
418
|
+
status: 2 # verified
|
|
419
|
+
)
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Feature Reference
|
|
423
|
+
|
|
424
|
+
| Feature | Description |
|
|
425
|
+
|---------|-------------|
|
|
426
|
+
| `login` | Basic login/logout |
|
|
427
|
+
| `create_account` | User registration |
|
|
428
|
+
| `verify_account` | Email verification |
|
|
429
|
+
| `reset_password` | Password reset via email |
|
|
430
|
+
| `change_password` | Change password when logged in |
|
|
431
|
+
| `change_login` | Change email address |
|
|
432
|
+
| `verify_login_change` | Verify email change |
|
|
433
|
+
| `remember` | "Remember me" functionality |
|
|
434
|
+
| `otp` | TOTP two-factor authentication |
|
|
435
|
+
| `sms_codes` | SMS-based 2FA |
|
|
436
|
+
| `recovery_codes` | Backup codes for 2FA |
|
|
437
|
+
| `webauthn` | WebAuthn/passkey authentication |
|
|
438
|
+
| `lockout` | Lock account after failed attempts |
|
|
439
|
+
| `active_sessions` | Track/manage active sessions |
|
|
440
|
+
| `audit_logging` | Log authentication events |
|
|
441
|
+
| `email_auth` | Passwordless email login |
|
|
442
|
+
| `jwt` | JWT token authentication |
|
|
443
|
+
| `jwt_refresh` | JWT refresh tokens |
|
|
444
|
+
| `close_account` | Allow account deletion |
|
|
445
|
+
| `password_expiration` | Force password changes |
|
|
446
|
+
| `disallow_password_reuse` | Prevent password reuse |
|
|
447
|
+
|
|
448
|
+
## Related Skills
|
|
449
|
+
|
|
450
|
+
- `installation` - Initial Plutonium setup
|
|
451
|
+
- `portal` - Portal configuration
|
|
452
|
+
- `policy` - Authorization after authentication
|