propel_authentication 0.1.4 → 0.2.1

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -2
  3. data/README.md +6 -6
  4. data/lib/generators/propel_authentication/install_generator.rb +135 -153
  5. data/lib/generators/propel_authentication/templates/application_mailer.rb +6 -0
  6. data/lib/generators/propel_authentication/templates/auth/passwords_controller.rb.tt +84 -78
  7. data/lib/generators/propel_authentication/templates/auth/signup_controller.rb.tt +242 -0
  8. data/lib/generators/propel_authentication/templates/{tokens_controller.rb.tt → auth/tokens_controller.rb.tt} +39 -22
  9. data/lib/generators/propel_authentication/templates/auth_mailer.rb +3 -1
  10. data/lib/generators/propel_authentication/templates/authenticatable.rb +8 -2
  11. data/lib/generators/propel_authentication/templates/concerns/confirmable.rb +1 -1
  12. data/lib/generators/propel_authentication/templates/concerns/lockable.rb +4 -2
  13. data/lib/generators/propel_authentication/templates/concerns/{propel_authentication.rb → propel_authentication_concern.rb} +33 -3
  14. data/lib/generators/propel_authentication/templates/concerns/recoverable.rb +16 -6
  15. data/lib/generators/propel_authentication/templates/core/configuration_methods.rb +104 -64
  16. data/lib/generators/propel_authentication/templates/db/seeds.rb +50 -4
  17. data/lib/generators/propel_authentication/templates/doc/signup_flow.md +315 -0
  18. data/lib/generators/propel_authentication/templates/models/agency.rb.tt +13 -0
  19. data/lib/generators/propel_authentication/templates/models/agent.rb.tt +13 -0
  20. data/lib/generators/propel_authentication/templates/{invitation.rb → models/invitation.rb.tt} +6 -0
  21. data/lib/generators/propel_authentication/templates/models/organization.rb.tt +12 -0
  22. data/lib/generators/propel_authentication/templates/{user.rb → models/user.rb.tt} +5 -0
  23. data/lib/generators/propel_authentication/templates/propel_authentication.rb.tt +94 -9
  24. data/lib/generators/propel_authentication/templates/routes/auth_routes.rb.tt +55 -0
  25. data/lib/generators/propel_authentication/templates/services/auth_notification_service.rb +3 -3
  26. data/lib/generators/propel_authentication/templates/test/concerns/confirmable_test.rb.tt +34 -10
  27. data/lib/generators/propel_authentication/templates/test/concerns/propel_authentication_test.rb.tt +1 -1
  28. data/lib/generators/propel_authentication/templates/test/concerns/recoverable_test.rb.tt +4 -4
  29. data/lib/generators/propel_authentication/templates/test/controllers/auth/lockable_integration_test.rb.tt +18 -15
  30. data/lib/generators/propel_authentication/templates/test/controllers/auth/password_reset_integration_test.rb.tt +38 -40
  31. data/lib/generators/propel_authentication/templates/test/controllers/auth/signup_controller_test.rb.tt +201 -0
  32. data/lib/generators/propel_authentication/templates/test/controllers/auth/tokens_controller_test.rb.tt +33 -25
  33. data/lib/generators/propel_authentication/templates/test/mailers/auth_mailer_test.rb.tt +51 -36
  34. data/lib/generators/propel_authentication/templates/views/auth_mailer/email_confirmation.html.erb +2 -2
  35. data/lib/generators/propel_authentication/templates/views/auth_mailer/email_confirmation.text.erb +1 -1
  36. data/lib/generators/propel_authentication/test/generators/authentication/install_generator_test.rb +4 -4
  37. data/lib/generators/propel_authentication/test/generators/authentication/uninstall_generator_test.rb +1 -1
  38. data/lib/generators/propel_authentication/test/integration/generator_integration_test.rb +1 -1
  39. data/lib/generators/propel_authentication/test/integration/multi_version_generator_test.rb +13 -12
  40. data/lib/generators/propel_authentication/unpack_generator.rb +19 -15
  41. data/lib/propel_authentication.rb +1 -1
  42. metadata +14 -11
  43. data/lib/generators/propel_authentication/templates/agency.rb +0 -7
  44. data/lib/generators/propel_authentication/templates/agent.rb +0 -7
  45. data/lib/generators/propel_authentication/templates/auth/base_passwords_controller.rb.tt +0 -99
  46. data/lib/generators/propel_authentication/templates/auth/base_tokens_controller.rb.tt +0 -90
  47. data/lib/generators/propel_authentication/templates/organization.rb +0 -7
@@ -85,10 +85,10 @@ class PropelAuthentication::UnpackGenerator < Rails::Generators::Base
85
85
  elsif options[:tests_only]
86
86
  return %w[tests]
87
87
  elsif options[:templates_only]
88
- return %w[models controllers tests views concerns services config db core]
88
+ return %w[models controllers tests views concerns services config db core doc]
89
89
  else
90
90
  # Default: everything including generator logic
91
- return %w[models controllers tests views concerns services config db core generator]
91
+ return %w[models controllers tests views concerns services config db core doc generator]
92
92
  end
93
93
  end
94
94
 
@@ -120,6 +120,8 @@ class PropelAuthentication::UnpackGenerator < Rails::Generators::Base
120
120
  copy_db_templates(destination_path)
121
121
  when 'core'
122
122
  copy_core_templates(destination_path)
123
+ when 'doc'
124
+ copy_doc_templates(destination_path)
123
125
  when 'generator'
124
126
  copy_generator_logic(destination_path)
125
127
  else
@@ -130,18 +132,11 @@ class PropelAuthentication::UnpackGenerator < Rails::Generators::Base
130
132
  def copy_model_templates(destination_path)
131
133
  say "📂 Extracting model generator templates...", :blue
132
134
 
133
- model_files = %w[
134
- user.rb
135
- organization.rb
136
- agency.rb
137
- agent.rb
138
- invitation.rb
139
- authenticatable.rb
140
- ]
141
-
142
- model_files.each do |file|
143
- copy_template_file(file, destination_path)
144
- end
135
+ # Copy the models directory with all .rb.tt templates
136
+ copy_directory_templates("models", destination_path)
137
+
138
+ # Also copy the authenticatable concern from root
139
+ copy_template_file("authenticatable.rb", destination_path)
145
140
 
146
141
  say " ✅ Model generator templates extracted", :green
147
142
  end
@@ -157,7 +152,7 @@ class PropelAuthentication::UnpackGenerator < Rails::Generators::Base
157
152
  def copy_controller_templates(destination_path)
158
153
  say "📂 Extracting controller generator templates...", :blue
159
154
 
160
- copy_template_file("tokens_controller.rb.tt", destination_path)
155
+ # All controller templates are now in the auth directory for better organization
161
156
  copy_directory_templates("auth", destination_path)
162
157
 
163
158
  say " ✅ Controller generator templates extracted", :green
@@ -214,6 +209,14 @@ class PropelAuthentication::UnpackGenerator < Rails::Generators::Base
214
209
  say " ✅ Database generator templates extracted", :green
215
210
  end
216
211
 
212
+ def copy_doc_templates(destination_path)
213
+ say "📂 Extracting documentation generator templates...", :blue
214
+
215
+ copy_directory_templates("doc", destination_path)
216
+
217
+ say " ✅ Documentation generator templates extracted", :green
218
+ end
219
+
217
220
  def copy_generator_logic(destination_path)
218
221
  say "📂 Extracting generator logic code...", :blue
219
222
 
@@ -331,6 +334,7 @@ class PropelAuthentication::UnpackGenerator < Rails::Generators::Base
331
334
  say " 🧪 Test templates: #{destination_path}/templates/test/"
332
335
  say " 📧 Email templates: #{destination_path}/templates/views/auth_mailer/"
333
336
  say " ⚙️ Config templates: #{destination_path}/templates/config/"
337
+ say " 📚 Documentation templates: #{destination_path}/templates/doc/"
334
338
  say ""
335
339
 
336
340
  say "⚠️ Important: You now have a LOCAL GENERATOR, not gem generator:", :yellow
@@ -1,3 +1,3 @@
1
1
  module PropelAuthentication
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propel_authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Propel Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-15 00:00:00.000000000 Z
11
+ date: 2025-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -72,16 +72,15 @@ files:
72
72
  - README.md
73
73
  - Rakefile
74
74
  - lib/generators/propel_authentication/install_generator.rb
75
- - lib/generators/propel_authentication/templates/agency.rb
76
- - lib/generators/propel_authentication/templates/agent.rb
77
- - lib/generators/propel_authentication/templates/auth/base_passwords_controller.rb.tt
78
- - lib/generators/propel_authentication/templates/auth/base_tokens_controller.rb.tt
75
+ - lib/generators/propel_authentication/templates/application_mailer.rb
79
76
  - lib/generators/propel_authentication/templates/auth/passwords_controller.rb.tt
77
+ - lib/generators/propel_authentication/templates/auth/signup_controller.rb.tt
78
+ - lib/generators/propel_authentication/templates/auth/tokens_controller.rb.tt
80
79
  - lib/generators/propel_authentication/templates/auth_mailer.rb
81
80
  - lib/generators/propel_authentication/templates/authenticatable.rb
82
81
  - lib/generators/propel_authentication/templates/concerns/confirmable.rb
83
82
  - lib/generators/propel_authentication/templates/concerns/lockable.rb
84
- - lib/generators/propel_authentication/templates/concerns/propel_authentication.rb
83
+ - lib/generators/propel_authentication/templates/concerns/propel_authentication_concern.rb
85
84
  - lib/generators/propel_authentication/templates/concerns/rack_session_disable.rb
86
85
  - lib/generators/propel_authentication/templates/concerns/recoverable.rb
87
86
  - lib/generators/propel_authentication/templates/config/environments/development_email.rb
@@ -92,9 +91,14 @@ files:
92
91
  - lib/generators/propel_authentication/templates/db/migrate/create_organizations.rb
93
92
  - lib/generators/propel_authentication/templates/db/migrate/create_users.rb
94
93
  - lib/generators/propel_authentication/templates/db/seeds.rb
95
- - lib/generators/propel_authentication/templates/invitation.rb
96
- - lib/generators/propel_authentication/templates/organization.rb
94
+ - lib/generators/propel_authentication/templates/doc/signup_flow.md
95
+ - lib/generators/propel_authentication/templates/models/agency.rb.tt
96
+ - lib/generators/propel_authentication/templates/models/agent.rb.tt
97
+ - lib/generators/propel_authentication/templates/models/invitation.rb.tt
98
+ - lib/generators/propel_authentication/templates/models/organization.rb.tt
99
+ - lib/generators/propel_authentication/templates/models/user.rb.tt
97
100
  - lib/generators/propel_authentication/templates/propel_authentication.rb.tt
101
+ - lib/generators/propel_authentication/templates/routes/auth_routes.rb.tt
98
102
  - lib/generators/propel_authentication/templates/services/auth_notification_service.rb
99
103
  - lib/generators/propel_authentication/templates/test/concerns/confirmable_test.rb.tt
100
104
  - lib/generators/propel_authentication/templates/test/concerns/lockable_test.rb.tt
@@ -102,11 +106,10 @@ files:
102
106
  - lib/generators/propel_authentication/templates/test/concerns/recoverable_test.rb.tt
103
107
  - lib/generators/propel_authentication/templates/test/controllers/auth/lockable_integration_test.rb.tt
104
108
  - lib/generators/propel_authentication/templates/test/controllers/auth/password_reset_integration_test.rb.tt
109
+ - lib/generators/propel_authentication/templates/test/controllers/auth/signup_controller_test.rb.tt
105
110
  - lib/generators/propel_authentication/templates/test/controllers/auth/tokens_controller_test.rb.tt
106
111
  - lib/generators/propel_authentication/templates/test/mailers/auth_mailer_test.rb.tt
107
112
  - lib/generators/propel_authentication/templates/test/mailers/previews/auth_mailer_preview.rb
108
- - lib/generators/propel_authentication/templates/tokens_controller.rb.tt
109
- - lib/generators/propel_authentication/templates/user.rb
110
113
  - lib/generators/propel_authentication/templates/user_test.rb.tt
111
114
  - lib/generators/propel_authentication/templates/views/auth_mailer/account_unlock.html.erb
112
115
  - lib/generators/propel_authentication/templates/views/auth_mailer/account_unlock.text.erb
@@ -1,7 +0,0 @@
1
- class Agency < ApplicationRecord
2
- # Multi-tenant associations
3
- belongs_to :organization
4
- has_many :agents, dependent: :destroy
5
-
6
- validates :name, presence: true
7
- end
@@ -1,7 +0,0 @@
1
- class Agent < ApplicationRecord
2
- # Multi-tenant associations
3
- belongs_to :agency
4
- belongs_to :user
5
-
6
- validates :user_id, uniqueness: { scope: :agency_id }
7
- end
@@ -1,99 +0,0 @@
1
- class Api::Auth::BasePasswordsController < ApplicationController
2
- <%- unless api_only_app? -%>
3
- include RackSessionDisable
4
- <%- end -%>
5
- include PropelAuthentication
6
-
7
- # POST /api/{version}/auth/reset
8
- def create
9
- user = User.find_by(email_address: params[:email_address])
10
-
11
- if user
12
- # Generate and save reset token
13
- user.generate_password_reset_token!
14
-
15
- # Send password reset email
16
- AuthNotificationService.send_password_reset_email(user)
17
-
18
- render json: {
19
- message: 'Password reset instructions sent to your email'
20
- }, status: :ok
21
- else
22
- # Don't reveal whether user exists for security
23
- render json: {
24
- message: 'Password reset instructions sent to your email'
25
- }, status: :ok
26
- end
27
- rescue => e
28
- render json: {
29
- error: 'Unable to process password reset request'
30
- }, status: :unprocessable_entity
31
- end
32
-
33
- # GET /api/{version}/auth/reset?token=xyz
34
- def show
35
- token = params[:token]
36
-
37
- if token.blank?
38
- render json: { error: 'Reset token is required' }, status: :unprocessable_entity
39
- return
40
- end
41
-
42
- user = User.find_by_password_reset_token(token)
43
-
44
- if user&.password_reset_token_valid?
45
- render json: {
46
- message: 'Token is valid',
47
- token: token
48
- }, status: :ok
49
- else
50
- render json: {
51
- error: 'Invalid or expired reset token'
52
- }, status: :unauthorized
53
- end
54
- end
55
-
56
- # PATCH /api/{version}/auth/reset
57
- def update
58
- token = params[:token]
59
- new_password = params[:password]
60
- password_confirmation = params[:password_confirmation]
61
-
62
- if token.blank? || new_password.blank?
63
- render json: {
64
- error: 'Token and password are required'
65
- }, status: :unprocessable_entity
66
- return
67
- end
68
-
69
- if new_password != password_confirmation
70
- render json: {
71
- error: 'Password confirmation does not match'
72
- }, status: :unprocessable_entity
73
- return
74
- end
75
-
76
- user = User.find_by_password_reset_token(token)
77
-
78
- if user&.password_reset_token_valid?
79
- if user.reset_password!(new_password)
80
- render json: {
81
- message: 'Password successfully reset'
82
- }, status: :ok
83
- else
84
- render json: {
85
- error: 'Password could not be reset',
86
- details: user.errors.full_messages
87
- }, status: :unprocessable_entity
88
- end
89
- else
90
- render json: {
91
- error: 'Invalid or expired reset token'
92
- }, status: :unauthorized
93
- end
94
- rescue => e
95
- render json: {
96
- error: 'Unable to reset password'
97
- }, status: :unprocessable_entity
98
- end
99
- end
@@ -1,90 +0,0 @@
1
- class Api::Auth::BaseTokensController < ApplicationController
2
- <%- unless api_only_app? -%>
3
- include RackSessionDisable
4
- <%- end -%>
5
- include PropelAuthentication
6
-
7
- # POST /api/{version}/auth/login
8
- def create
9
- user = User.find_by(email_address: params[:user][:email_address])
10
-
11
- if user&.authenticate(params[:user][:password])
12
- if user.status == 1 # inactive
13
- render json: { error: 'Account is inactive' }, status: :unauthorized
14
- return
15
- end
16
-
17
- # Update last login timestamp
18
- user.update(last_login_at: Time.current)
19
-
20
- # Reset failed login attempts on successful login
21
- user.reset_failed_attempts! if user.respond_to?(:reset_failed_attempts!)
22
-
23
- render json: {
24
- token: user.generate_jwt_token,
25
- user: user_response(user)
26
- }, status: :ok
27
- else
28
- # Increment failed login attempts if user exists and has lockable functionality
29
- if user&.respond_to?(:increment_failed_attempts!)
30
- user.increment_failed_attempts!
31
- end
32
-
33
- render json: { error: 'Invalid credentials' }, status: :unauthorized
34
- end
35
- rescue ActionController::ParameterMissing
36
- render json: { error: 'Missing required parameters' }, status: :unprocessable_entity
37
- end
38
-
39
- # DELETE /api/{version}/auth/logout
40
- def destroy
41
- # For JWT, logout is handled client-side by removing the token
42
- # Server-side logout would require token blacklisting (future enhancement)
43
- render json: { message: 'Logged out successfully' }, status: :ok
44
- end
45
-
46
- # GET /api/{version}/auth/me
47
- def me
48
- return unless authenticate_user
49
- render json: { user: user_response(current_user) }, status: :ok
50
- end
51
-
52
- def refresh
53
- render json: { token: @current_user.generate_jwt_token }
54
- end
55
-
56
- # POST /api/{version}/auth/unlock
57
- def unlock
58
- token = params[:token]
59
-
60
- if token.blank?
61
- render json: { error: 'Token is required' }, status: :unprocessable_entity
62
- return
63
- end
64
-
65
- user = User.find_by_unlock_token(token)
66
-
67
- if user
68
- user.unlock_account!
69
- render json: { message: 'Account unlocked successfully' }, status: :ok
70
- else
71
- render json: { error: 'Invalid or expired unlock token' }, status: :unauthorized
72
- end
73
- rescue => e
74
- render json: { error: 'Invalid unlock token' }, status: :unauthorized
75
- end
76
-
77
- private
78
-
79
- def user_response(user)
80
- {
81
- id: user.id,
82
- email_address: user.email_address,
83
- username: user.username,
84
- first_name: user.first_name,
85
- last_name: user.last_name,
86
- organization_id: user.organization_id,
87
- last_login_at: user.last_login_at
88
- }
89
- end
90
- end
@@ -1,7 +0,0 @@
1
- class Organization < ApplicationRecord
2
- # Multi-tenant associations
3
- has_many :users, dependent: :destroy
4
- has_many :agencies, dependent: :destroy
5
-
6
- validates :name, presence: true
7
- end