propel_authentication 0.1.3 → 0.2.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/CHANGELOG.md +128 -0
- data/README.md +254 -116
- data/lib/generators/{propel_auth → propel_authentication}/install_generator.rb +152 -170
- data/lib/generators/propel_authentication/templates/application_mailer.rb +6 -0
- data/lib/generators/propel_authentication/templates/auth/passwords_controller.rb.tt +132 -0
- data/lib/generators/propel_authentication/templates/auth/signup_controller.rb.tt +242 -0
- data/lib/generators/{propel_auth/templates → propel_authentication/templates/auth}/tokens_controller.rb.tt +39 -22
- data/lib/generators/{propel_auth → propel_authentication}/templates/auth_mailer.rb +3 -1
- data/lib/generators/{propel_auth → propel_authentication}/templates/authenticatable.rb +10 -4
- data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/confirmable.rb +3 -3
- data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/lockable.rb +10 -8
- data/lib/generators/{propel_auth/templates/concerns/propel_authentication.rb → propel_authentication/templates/concerns/propel_authentication_concern.rb} +33 -3
- data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/recoverable.rb +21 -11
- data/lib/generators/propel_authentication/templates/core/configuration_methods.rb +191 -0
- data/lib/generators/propel_authentication/templates/db/seeds.rb +75 -0
- data/lib/generators/propel_authentication/templates/doc/signup_flow.md +315 -0
- data/lib/generators/propel_authentication/templates/models/agency.rb.tt +13 -0
- data/lib/generators/propel_authentication/templates/models/agent.rb.tt +13 -0
- data/lib/generators/{propel_auth/templates/invitation.rb → propel_authentication/templates/models/invitation.rb.tt} +8 -2
- data/lib/generators/propel_authentication/templates/models/organization.rb.tt +12 -0
- data/lib/generators/{propel_auth/templates/user.rb → propel_authentication/templates/models/user.rb.tt} +5 -0
- data/lib/generators/propel_authentication/templates/propel_authentication.rb.tt +218 -0
- data/lib/generators/propel_authentication/templates/routes/auth_routes.rb.tt +55 -0
- data/lib/generators/{propel_auth → propel_authentication}/templates/services/auth_notification_service.rb +3 -3
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/confirmable_test.rb.tt +34 -10
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/lockable_test.rb.tt +12 -12
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/propel_authentication_test.rb.tt +2 -2
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/recoverable_test.rb.tt +11 -11
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/controllers/auth/lockable_integration_test.rb.tt +18 -15
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/controllers/auth/password_reset_integration_test.rb.tt +38 -40
- data/lib/generators/propel_authentication/templates/test/controllers/auth/signup_controller_test.rb.tt +201 -0
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/controllers/auth/tokens_controller_test.rb.tt +33 -25
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/mailers/auth_mailer_test.rb.tt +51 -36
- data/lib/generators/{propel_auth → propel_authentication}/templates/user_test.rb.tt +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/email_confirmation.html.erb +2 -2
- data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/email_confirmation.text.erb +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/test/generators/authentication/install_generator_test.rb +4 -4
- data/lib/generators/{propel_auth → propel_authentication}/test/generators/authentication/uninstall_generator_test.rb +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/test/integration/generator_integration_test.rb +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/test/integration/multi_version_generator_test.rb +13 -12
- data/lib/generators/{propel_auth → propel_authentication}/unpack_generator.rb +55 -38
- data/lib/propel_authentication.rb +3 -0
- metadata +101 -98
- data/lib/generators/propel_auth/core/configuration_methods.rb +0 -134
- data/lib/generators/propel_auth/pack_generator.rb +0 -277
- data/lib/generators/propel_auth/templates/agency.rb +0 -7
- data/lib/generators/propel_auth/templates/agent.rb +0 -7
- data/lib/generators/propel_auth/templates/auth/base_passwords_controller.rb.tt +0 -99
- data/lib/generators/propel_auth/templates/auth/base_tokens_controller.rb.tt +0 -90
- data/lib/generators/propel_auth/templates/auth/passwords_controller.rb.tt +0 -126
- data/lib/generators/propel_auth/templates/db/seeds.rb +0 -29
- data/lib/generators/propel_auth/templates/organization.rb +0 -7
- data/lib/generators/propel_auth/templates/propel_auth.rb.tt +0 -141
- data/lib/propel_auth.rb +0 -3
- /data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/rack_session_disable.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/config/environments/development_email.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_agencies.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_agents.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_invitations.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_organizations.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_users.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/mailers/previews/auth_mailer_preview.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/account_unlock.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/account_unlock.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/password_reset.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/password_reset.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/user_invitation.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/user_invitation.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/Dockerfile +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/Gemfile +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/README.md +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/Rakefile +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/assets/stylesheets/application.css +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/controllers/application_controller.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/helpers/application_helper.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/jobs/application_job.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/mailers/application_mailer.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/models/application_record.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/layouts/application.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/layouts/mailer.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/layouts/mailer.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/pwa/manifest.json.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/pwa/service-worker.js +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/brakeman +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/dev +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/docker-entrypoint +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/rails +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/rake +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/rubocop +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/setup +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/thrust +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/application.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/boot.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/cable.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/credentials.yml.enc +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/database.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environment.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environments/development.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environments/production.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environments/test.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/assets.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/content_security_policy.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/filter_parameter_logging.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/inflections.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/locales/en.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/master.key +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/puma.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/routes.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/storage.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config.ru +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/db/schema.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/generators/authentication/controllers/tokens_controller_test.rb +0 -0
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# PropelAuthentication
|
2
2
|
|
3
|
-
A comprehensive Rails generator that creates a complete JWT-based authentication system with
|
3
|
+
A comprehensive Rails generator that creates a complete JWT-based authentication system with multi-tenant organization structure, user management, password security, and email notifications.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
PropelAuthentication is designed as a **self-extracting generator gem** following the "no black box" policy. You install it temporarily, run the generators to extract all code into your application, then optionally remove the gem dependency.
|
8
8
|
|
9
|
-
### Step 1: Add to Gemfile
|
9
|
+
### Step 1: Add to Gemfile
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
# In your Gemfile
|
13
|
-
gem '
|
13
|
+
gem 'propel_authentication', '~> 0.2.0'
|
14
14
|
```
|
15
15
|
|
16
16
|
### Step 2: Bundle Install
|
@@ -19,27 +19,23 @@ gem 'propel_auth', path: 'propel_auth'
|
|
19
19
|
bundle install
|
20
20
|
```
|
21
21
|
|
22
|
-
### Step 3:
|
23
|
-
|
24
|
-
If you want to customize the generator templates:
|
22
|
+
### Step 3: Install PropelAuthentication
|
25
23
|
|
26
24
|
```bash
|
27
|
-
rails generate
|
25
|
+
rails generate propel_authentication:install
|
28
26
|
```
|
29
27
|
|
30
|
-
This
|
28
|
+
This installs the complete authentication system including models, controllers, services, mailers, and tests.
|
31
29
|
|
32
|
-
### Step 4:
|
30
|
+
### Step 4: Run Migrations
|
33
31
|
|
34
32
|
```bash
|
35
|
-
rails
|
33
|
+
rails db:migrate
|
36
34
|
```
|
37
35
|
|
38
|
-
This installs the complete authentication system including models, controllers, services, and mailers.
|
39
|
-
|
40
36
|
### Step 5: Remove Gem Dependency (Optional)
|
41
37
|
|
42
|
-
After installation, you can remove the gem from your Gemfile. All functionality remains in your application.
|
38
|
+
After installation, you can remove the gem from your Gemfile. All functionality remains in your application as extracted code.
|
43
39
|
|
44
40
|
## Usage
|
45
41
|
|
@@ -47,45 +43,77 @@ After installation, you can remove the gem from your Gemfile. All functionality
|
|
47
43
|
|
48
44
|
The generator creates a complete authentication system with:
|
49
45
|
|
50
|
-
- **User model** - Primary user accounts with authentication
|
46
|
+
- **User model** - Primary user accounts with JWT authentication
|
51
47
|
- **Organization model** - Multi-tenant organization structure
|
52
|
-
- **Agency model** - Intermediate organization management
|
53
|
-
- **Agent model** -
|
54
|
-
- **Invitation model** - User invitation system
|
55
|
-
- **Authentication controllers** - Login, logout, token management
|
56
|
-
- **
|
57
|
-
- **
|
58
|
-
- **Account locking** - Security protection against brute force
|
59
|
-
- **Auth mailer** - Email notifications for auth events
|
60
|
-
- **Auth service** - Centralized authentication logic
|
48
|
+
- **Agency model** - Intermediate organization management layer
|
49
|
+
- **Agent model** - Agent user accounts within agencies
|
50
|
+
- **Invitation model** - User invitation and onboarding system
|
51
|
+
- **Authentication controllers** - Login, logout, token management, password reset
|
52
|
+
- **Email system** - Password reset, account unlock, and invitation emails
|
53
|
+
- **Security features** - Account locking, password validation, JWT tokens
|
61
54
|
|
62
55
|
### Authentication Flow
|
63
56
|
|
64
|
-
```
|
57
|
+
```bash
|
65
58
|
# Login
|
66
|
-
POST /
|
59
|
+
POST /login
|
60
|
+
Content-Type: application/json
|
61
|
+
|
67
62
|
{
|
68
|
-
"
|
69
|
-
|
63
|
+
"user": {
|
64
|
+
"email_address": "user@example.com",
|
65
|
+
"password": "password"
|
66
|
+
}
|
70
67
|
}
|
71
68
|
|
72
69
|
# Response
|
73
70
|
{
|
74
|
-
"
|
75
|
-
|
76
|
-
"
|
77
|
-
"
|
71
|
+
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
|
72
|
+
"user": {
|
73
|
+
"id": 1,
|
74
|
+
"email_address": "user@example.com",
|
75
|
+
"first_name": "John",
|
76
|
+
"last_name": "Doe",
|
77
|
+
"organization": {
|
78
|
+
"id": 1,
|
79
|
+
"name": "Acme Corp"
|
80
|
+
}
|
78
81
|
}
|
79
82
|
}
|
80
83
|
|
81
84
|
# Access protected resources
|
82
85
|
GET /api/v1/protected_resource
|
83
86
|
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
|
87
|
+
|
88
|
+
# Get current user info
|
89
|
+
GET /me
|
90
|
+
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
|
91
|
+
|
92
|
+
# Logout (client-side token removal)
|
93
|
+
DELETE /logout
|
94
|
+
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
|
95
|
+
```
|
96
|
+
|
97
|
+
### Authentication Routes
|
98
|
+
|
99
|
+
The system generates these authentication routes:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
# JWT Authentication routes
|
103
|
+
post 'login', to: 'auth/tokens#create'
|
104
|
+
get 'me', to: 'auth/tokens#me'
|
105
|
+
delete 'logout', to: 'auth/tokens#destroy'
|
106
|
+
post 'unlock', to: 'auth/tokens#unlock'
|
107
|
+
|
108
|
+
# Password reset routes
|
109
|
+
post 'reset', to: 'auth/passwords#create'
|
110
|
+
get 'reset', to: 'auth/passwords#show'
|
111
|
+
patch 'reset', to: 'auth/passwords#update'
|
84
112
|
```
|
85
113
|
|
86
114
|
### Authentication Concerns
|
87
115
|
|
88
|
-
|
116
|
+
PropelAuthentication generates reusable concerns for models and controllers:
|
89
117
|
|
90
118
|
```ruby
|
91
119
|
# In your models
|
@@ -93,27 +121,32 @@ class User < ApplicationRecord
|
|
93
121
|
include Authenticatable # JWT token generation and validation
|
94
122
|
include Lockable # Account locking after failed attempts
|
95
123
|
include Recoverable # Password reset functionality
|
96
|
-
include Confirmable # Email confirmation
|
124
|
+
include Confirmable # Email confirmation (future feature)
|
97
125
|
|
98
126
|
# Your model customizations here
|
99
127
|
end
|
100
128
|
|
101
129
|
# In your controllers
|
102
130
|
class ApplicationController < ActionController::API
|
103
|
-
include
|
104
|
-
include RackSessionDisable # Disable Rails sessions for API
|
131
|
+
include PropelAuthenticationConcernConcern # Authentication helpers
|
132
|
+
include RackSessionDisable # Disable Rails sessions for API-only apps
|
133
|
+
|
134
|
+
# Use authenticate_user to protect endpoints
|
135
|
+
before_action :authenticate_user, except: [:public_endpoint]
|
105
136
|
end
|
106
137
|
```
|
107
138
|
|
108
139
|
### Password Reset Flow
|
109
140
|
|
110
|
-
```
|
141
|
+
```bash
|
111
142
|
# Request password reset
|
112
|
-
POST /
|
113
|
-
{
|
143
|
+
POST /reset
|
144
|
+
{
|
145
|
+
"email_address": "user@example.com"
|
146
|
+
}
|
114
147
|
|
115
|
-
# Reset password with token
|
116
|
-
PATCH /
|
148
|
+
# Reset password with token (from email)
|
149
|
+
PATCH /reset
|
117
150
|
{
|
118
151
|
"token": "reset_token_from_email",
|
119
152
|
"password": "new_password",
|
@@ -121,46 +154,50 @@ PATCH /auth/passwords
|
|
121
154
|
}
|
122
155
|
```
|
123
156
|
|
124
|
-
### Account Features
|
157
|
+
### Account Security Features
|
125
158
|
|
126
|
-
- **
|
127
|
-
- **Account
|
128
|
-
- **Password
|
129
|
-
- **
|
130
|
-
- **Multi-tenancy** - Organization-based
|
159
|
+
- **JWT Authentication** - Stateless, secure token-based authentication
|
160
|
+
- **Account Locking** - Automatic lockout after failed login attempts
|
161
|
+
- **Password Security** - BCrypt hashing with configurable requirements
|
162
|
+
- **Password Reset** - Secure token-based password reset via email
|
163
|
+
- **Multi-tenancy** - Organization-based user isolation
|
164
|
+
- **Email Notifications** - Automated emails for security events
|
131
165
|
|
132
166
|
## Features
|
133
167
|
|
134
168
|
### Complete Authentication System
|
135
169
|
- **JWT-based authentication** - Stateless, scalable token system
|
136
170
|
- **Multi-tenant architecture** - User/Organization/Agency/Agent model hierarchy
|
137
|
-
- **
|
138
|
-
- **Password security** - Reset, expiration, and strength requirements
|
171
|
+
- **Password security** - BCrypt hashing, reset functionality, strength requirements
|
139
172
|
- **Account protection** - Automatic locking and unlock mechanisms
|
140
|
-
- **
|
173
|
+
- **Email notifications** - Password reset, account unlock, user invitations
|
174
|
+
- **Invitation system** - Complete user invitation and onboarding workflow
|
141
175
|
|
142
176
|
### Production-Ready Security
|
143
177
|
- **BCrypt password hashing** - Industry standard password protection
|
144
|
-
- **JWT token validation** - Secure token-based authentication
|
145
|
-
- **
|
146
|
-
- **
|
147
|
-
- **
|
178
|
+
- **JWT token validation** - Secure token-based authentication with configurable expiration
|
179
|
+
- **Account lockout protection** - Configurable failed attempt limits and lockout duration
|
180
|
+
- **Rate limiting ready** - Designed for integration with rate limiting systems
|
181
|
+
- **Secure token generation** - Cryptographically secure tokens for password reset
|
182
|
+
- **Environment-specific configuration** - Different security settings per environment
|
148
183
|
|
149
184
|
### Rails Integration
|
150
185
|
- **Standard Rails patterns** - Follows Rails conventions throughout
|
151
186
|
- **ActiveRecord models** - Standard model associations and validations
|
152
|
-
- **ActionMailer integration** - Built-in email functionality
|
187
|
+
- **ActionMailer integration** - Built-in email functionality with templates
|
153
188
|
- **Controller concerns** - Reusable authentication logic
|
154
|
-
- **
|
189
|
+
- **Comprehensive testing** - Complete test suite included
|
190
|
+
- **Migration support** - Database schema with proper indexes
|
155
191
|
|
156
192
|
## Self-Extracting Architecture
|
157
193
|
|
158
|
-
|
194
|
+
PropelAuthentication follows a "no black box" self-extracting pattern:
|
159
195
|
|
160
|
-
- **
|
161
|
-
- **
|
162
|
-
- **
|
163
|
-
- **
|
196
|
+
- **Complete code extraction** - All functionality copied to your application
|
197
|
+
- **No runtime dependencies** - Remove the gem after installation
|
198
|
+
- **Full customization** - Modify any component after installation
|
199
|
+
- **Transparent implementation** - Readable, standard Rails code
|
200
|
+
- **Generator extraction** - Optionally extract generator templates for customization
|
164
201
|
|
165
202
|
After installation, you can:
|
166
203
|
- Remove the gem from your Gemfile
|
@@ -170,18 +207,23 @@ After installation, you can:
|
|
170
207
|
|
171
208
|
## Configuration
|
172
209
|
|
173
|
-
Configure
|
210
|
+
Configure PropelAuthentication in the generated `config/initializers/propel_authentication.rb`:
|
174
211
|
|
175
212
|
```ruby
|
176
|
-
|
213
|
+
PropelAuthentication.configure do |config|
|
177
214
|
# JWT Configuration
|
178
|
-
config.jwt_secret = Rails.application.
|
179
|
-
|
215
|
+
config.jwt_secret = Rails.application.config.secret_key_base ||
|
216
|
+
Rails.application.credentials.secret_key_base ||
|
217
|
+
ENV['SECRET_KEY_BASE']
|
218
|
+
config.jwt_expiration = Rails.env.production? ? 2.hours : 24.hours
|
180
219
|
config.jwt_algorithm = 'HS256'
|
181
220
|
|
182
221
|
# Password requirements
|
183
222
|
config.password_length = 8..128
|
184
223
|
|
224
|
+
# User registration settings
|
225
|
+
config.allow_registration = true
|
226
|
+
|
185
227
|
# Account lockout settings
|
186
228
|
config.max_failed_attempts = 10
|
187
229
|
config.lockout_duration = 30.minutes
|
@@ -191,100 +233,196 @@ PropelAuth.configure do |config|
|
|
191
233
|
config.password_reset_rate_limit = 1.minute
|
192
234
|
|
193
235
|
# Email settings
|
194
|
-
config.frontend_url = 'http://localhost:3000'
|
195
|
-
config.email_from_address = "noreply
|
236
|
+
config.frontend_url = Rails.env.development? ? 'http://localhost:3000' : 'https://yourapp.com'
|
237
|
+
config.email_from_address = "noreply@yourapp.com"
|
238
|
+
config.support_email = "support@yourapp.com"
|
196
239
|
config.enable_email_notifications = true
|
197
240
|
end
|
198
241
|
```
|
199
242
|
|
200
243
|
## Generated Files
|
201
244
|
|
202
|
-
After installation,
|
245
|
+
After installation, PropelAuthentication creates:
|
203
246
|
|
204
247
|
### Models
|
205
|
-
- `app/models/user.rb` - Primary user model
|
206
|
-
- `app/models/organization.rb` -
|
207
|
-
- `app/models/agency.rb` - Agency management
|
248
|
+
- `app/models/user.rb` - Primary user model with authentication
|
249
|
+
- `app/models/organization.rb` - Multi-tenant organization model
|
250
|
+
- `app/models/agency.rb` - Agency management within organizations
|
208
251
|
- `app/models/agent.rb` - Agent user accounts
|
209
252
|
- `app/models/invitation.rb` - User invitation system
|
210
253
|
- `app/models/concerns/authenticatable.rb` - JWT authentication logic
|
211
|
-
- `app/models/concerns/confirmable.rb` - Email confirmation
|
212
|
-
- `app/models/concerns/lockable.rb` - Account locking
|
213
|
-
- `app/models/concerns/recoverable.rb` - Password recovery
|
254
|
+
- `app/models/concerns/confirmable.rb` - Email confirmation (future feature)
|
255
|
+
- `app/models/concerns/lockable.rb` - Account locking functionality
|
256
|
+
- `app/models/concerns/recoverable.rb` - Password recovery logic
|
214
257
|
|
215
258
|
### Controllers
|
216
|
-
- `app/controllers/auth/tokens_controller.rb` - Login
|
217
|
-
- `app/controllers/auth/passwords_controller.rb` - Password reset
|
218
|
-
- `app/controllers/concerns/
|
219
|
-
- `app/controllers/concerns/rack_session_disable.rb` - Session management
|
259
|
+
- `app/controllers/auth/tokens_controller.rb` - Login, logout, user info
|
260
|
+
- `app/controllers/auth/passwords_controller.rb` - Password reset functionality
|
261
|
+
- `app/controllers/concerns/propel_authentication_concern.rb` - Authentication helpers
|
262
|
+
- `app/controllers/concerns/rack_session_disable.rb` - Session management for APIs
|
220
263
|
|
221
264
|
### Services
|
222
|
-
- `app/services/auth_notification_service.rb` - Email
|
223
|
-
|
224
|
-
### Mailers
|
225
|
-
- `app/mailers/auth_mailer.rb` - Authentication
|
226
|
-
- `app/views/auth_mailer
|
227
|
-
|
228
|
-
|
265
|
+
- `app/services/auth_notification_service.rb` - Email notification service
|
266
|
+
|
267
|
+
### Mailers and Views
|
268
|
+
- `app/mailers/auth_mailer.rb` - Authentication email mailer
|
269
|
+
- `app/views/auth_mailer/password_reset.html.erb` - Password reset email template
|
270
|
+
- `app/views/auth_mailer/password_reset.text.erb` - Text version
|
271
|
+
- `app/views/auth_mailer/account_unlock.html.erb` - Account unlock email template
|
272
|
+
- `app/views/auth_mailer/account_unlock.text.erb` - Text version
|
273
|
+
- `app/views/auth_mailer/user_invitation.html.erb` - User invitation email template
|
274
|
+
- `app/views/auth_mailer/user_invitation.text.erb` - Text version
|
275
|
+
- `app/views/auth_mailer/email_confirmation.html.erb` - Email confirmation template
|
276
|
+
- `app/views/auth_mailer/email_confirmation.text.erb` - Text version
|
277
|
+
|
278
|
+
### Database Migrations
|
229
279
|
- User, Organization, Agency, Agent, and Invitation table creation
|
230
|
-
- Authentication-related fields
|
280
|
+
- Authentication-related fields (password_digest, failed_attempts, locked_at, etc.)
|
281
|
+
- Proper indexes for performance
|
282
|
+
- Foreign key relationships
|
231
283
|
|
232
284
|
### Tests
|
233
|
-
-
|
234
|
-
-
|
235
|
-
-
|
236
|
-
-
|
285
|
+
- `test/models/user_test.rb` - User model tests
|
286
|
+
- `test/controllers/auth/tokens_controller_test.rb` - Authentication controller tests
|
287
|
+
- `test/mailers/auth_mailer_test.rb` - Email functionality tests
|
288
|
+
- `test/concerns/` - Tests for all authentication concerns
|
289
|
+
- `test/controllers/auth/` - Integration tests for authentication flows
|
290
|
+
- Complete fixture files for all models
|
237
291
|
|
238
|
-
### Configuration
|
239
|
-
- `config/initializers/
|
240
|
-
- `lib/
|
292
|
+
### Configuration and Runtime
|
293
|
+
- `config/initializers/propel_authentication.rb` - Configuration file
|
294
|
+
- `lib/propel_authentication.rb` - Complete runtime library (extracted from gem)
|
295
|
+
- `config/environments/development_email.rb` - Email configuration for development
|
241
296
|
|
242
|
-
##
|
297
|
+
## Advanced Usage
|
243
298
|
|
244
|
-
|
299
|
+
### Custom Authentication Logic
|
245
300
|
|
246
|
-
```
|
247
|
-
|
248
|
-
|
301
|
+
```ruby
|
302
|
+
class Api::V1::UsersController < ApplicationController
|
303
|
+
include PropelAuthenticationConcern
|
304
|
+
before_action :authenticate_user
|
305
|
+
|
306
|
+
def index
|
307
|
+
# current_user is available after authenticate_user
|
308
|
+
users = current_user.organization.users
|
309
|
+
render json: users
|
310
|
+
end
|
311
|
+
|
312
|
+
def show
|
313
|
+
# Access control based on organization
|
314
|
+
user = current_user.organization.users.find(params[:id])
|
315
|
+
render json: user
|
316
|
+
end
|
317
|
+
end
|
318
|
+
```
|
319
|
+
|
320
|
+
### Multi-Tenant Organization Structure
|
249
321
|
|
250
|
-
|
322
|
+
```ruby
|
323
|
+
# Users belong to organizations
|
324
|
+
user = User.find(1)
|
325
|
+
user.organization.name # => "Acme Corp"
|
326
|
+
|
327
|
+
# Organizations can have multiple agencies
|
328
|
+
organization = Organization.find(1)
|
329
|
+
organization.agencies.count # => 3
|
330
|
+
|
331
|
+
# Agencies have agents (specialized users)
|
332
|
+
agency = Agency.find(1)
|
333
|
+
agency.agents.active.count # => 5
|
251
334
|
```
|
252
335
|
|
253
|
-
|
336
|
+
### Email Customization
|
254
337
|
|
255
|
-
|
256
|
-
- **BCrypt ~> 3.1.20** - Secure password hashing
|
257
|
-
- **JWT ~> 2.7** - JSON Web Token authentication
|
338
|
+
All email templates are extracted to your application and can be customized:
|
258
339
|
|
259
|
-
|
340
|
+
```erb
|
341
|
+
<!-- app/views/auth_mailer/password_reset.html.erb -->
|
342
|
+
<h1>Password Reset Request</h1>
|
343
|
+
<p>Hello <%= @user.first_name %>,</p>
|
344
|
+
<p>You requested a password reset for your account.</p>
|
345
|
+
<p><%= link_to "Reset Password", @reset_url %></p>
|
346
|
+
```
|
260
347
|
|
261
|
-
|
262
|
-
# Run generator tests
|
263
|
-
cd propel_auth
|
264
|
-
bundle exec rake test
|
348
|
+
## Generator Customization
|
265
349
|
|
266
|
-
|
267
|
-
|
350
|
+
Extract generator templates for customization:
|
351
|
+
|
352
|
+
```bash
|
353
|
+
rails generate propel_authentication:unpack
|
268
354
|
```
|
269
355
|
|
270
|
-
|
356
|
+
This creates `lib/generators/propel_authentication/` with all templates, allowing you to:
|
357
|
+
- Modify model templates
|
358
|
+
- Customize controller logic
|
359
|
+
- Change email templates
|
360
|
+
- Adjust migration structure
|
361
|
+
|
362
|
+
## Dependencies
|
363
|
+
|
364
|
+
- **Rails 7.0+** - Modern Rails framework support
|
365
|
+
- **BCrypt ~> 3.1.20** - Secure password hashing
|
366
|
+
- **JWT ~> 2.7** - JSON Web Token authentication
|
367
|
+
- **Letter Opener** (development) - Email preview in development
|
368
|
+
|
369
|
+
## Integration with PropelRails Ecosystem
|
271
370
|
|
272
|
-
|
371
|
+
PropelAuthentication integrates seamlessly with other PropelRails gems:
|
273
372
|
|
373
|
+
### With PropelAPI
|
274
374
|
```ruby
|
275
375
|
# Generated API controllers automatically include authentication
|
276
376
|
class Api::V1::ApiController < ApplicationController
|
277
|
-
include
|
377
|
+
include PropelAuthenticationConcern
|
278
378
|
before_action :authenticate_user
|
279
379
|
|
280
380
|
# Your API methods here
|
281
381
|
end
|
282
382
|
```
|
283
383
|
|
384
|
+
### With PropelFacets
|
385
|
+
```ruby
|
386
|
+
# Use authentication with JSON facets
|
387
|
+
class Api::V1::UsersController < Api::V1::ApiController
|
388
|
+
def index
|
389
|
+
users = current_user.organization.users
|
390
|
+
render_facet users, :summary
|
391
|
+
end
|
392
|
+
end
|
393
|
+
```
|
394
|
+
|
395
|
+
## Development and Testing
|
396
|
+
|
397
|
+
```bash
|
398
|
+
# Run all authentication tests
|
399
|
+
rails test test/models/user_test.rb
|
400
|
+
rails test test/controllers/auth/
|
401
|
+
rails test test/concerns/
|
402
|
+
rails test test/mailers/
|
403
|
+
|
404
|
+
# Test specific authentication flows
|
405
|
+
rails test test/controllers/auth/tokens_controller_test.rb
|
406
|
+
rails test test/controllers/auth/password_reset_integration_test.rb
|
407
|
+
|
408
|
+
# Run generator tests (if gem is in development)
|
409
|
+
cd propel_authentication
|
410
|
+
bundle exec rake test
|
411
|
+
```
|
412
|
+
|
413
|
+
## Version History
|
414
|
+
|
415
|
+
### 0.2.0 (Current)
|
416
|
+
- Fixed generator extraction issues
|
417
|
+
- Enhanced JWT authentication with proper secret handling
|
418
|
+
- Complete test suite passing
|
419
|
+
- Improved "no black box" policy implementation
|
420
|
+
- Better integration with PropelRails ecosystem
|
421
|
+
|
284
422
|
## Contributing
|
285
423
|
|
286
|
-
Bug reports and pull requests are welcome on GitHub.
|
424
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/propel-web/propel_rails.
|
287
425
|
|
288
426
|
## License
|
289
427
|
|
290
|
-
The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
|
428
|
+
The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
|