devise_invitable 2.0.5 → 2.0.7

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.

Potentially problematic release.


This version of devise_invitable might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0517f954240bfc3c1fd255df0d502d5fdbd461d4e695cd0c5ec725854af50dcf
4
- data.tar.gz: 239b887a32e66dbc38fbf1e04625def2f1dea325fcc6d20af0e1befd066dd000
3
+ metadata.gz: f2a7d1c4ae3cc61e2992fa9920ddd35e6626745dd32333a88e8231fb267e2cb0
4
+ data.tar.gz: ee68fbb505a629c391934bee8c644c0ade499333d5c7065745426fd6e419642a
5
5
  SHA512:
6
- metadata.gz: 957006ebe6e94715459f941b52004a1002e72005e9344baca46679398bc34e360604e3a8a205d9099a4ff5015be597c1c02a89055137db6c12f10ecf03949db7
7
- data.tar.gz: 17200aa6cf76d5abf07de1e4c0987f197140087a7a3210df0bf948a6098602eeeab05d65983cc69ef2185f2de741813ebc778a28d476a86bc5b1527bbd918f4c
6
+ metadata.gz: fd3ead62e8c2246f9246fbac3a2138ea6ff4f1abcf3c577faad920b339f1c1795b54497d03b34f4bc685be6131f62692d2497fbc5d1081e740e0a85d7e1a25c2
7
+ data.tar.gz: 0453554d47731a99e931c81dbd44e77eca935ff6ca453172f40f394da84bd1d5a92507aafa881ab491202cee5fa534aef4ba9b2a4ac1fa37327a664c7ceb8e61
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ - Allow customizing invalid_token_path_for, the path to redirect users who try to accept with invalid token
2
+ - Don't override registrations controller in routes if module option is used
3
+ - Fix typo in spanish translation, add Catalan translation ([#857](https://github.com/scambra/devise_invitable/pull/857))
4
+ - Fix for ruby 3.2.0
5
+
6
+ ## 2.0.6
7
+ - Fix submit form failure with turbolinks, fixes ([#865](https://github.com/scambra/devise_invitable/issues/865))
8
+ - Fix obsolete symbols in German translation ([#864](https://github.com/scambra/devise_invitable/pull/864))
9
+ - Allow to provide validate option to the instance method "invite!", default to follow the setting validate_on_invite
10
+
1
11
  ## 2.0.5
2
12
  - Fix NoMethodError in random_password when validatable is not used ([#850](https://github.com/scambra/devise_invitable/pull/850))
3
13
 
data/README.rdoc CHANGED
@@ -1,5 +1,7 @@
1
1
  = DeviseInvitable
2
- {<img src="https://badge.fury.io/rb/devise_invitable.svg"/>}[http://badge.fury.io/rb/devise_invitable] {<img src="https://travis-ci.org/scambra/devise_invitable.svg"/>}[https://travis-ci.org/scambra/devise_invitable] {<img src="https://codeclimate.com/github/scambra/devise_invitable/badges/gpa.svg"/>}[https://codeclimate.com/github/scambra/devise_invitable]
2
+ {<img src="https://badge.fury.io/rb/devise_invitable.svg"/>}[http://badge.fury.io/rb/devise_invitable]
3
+ {<img src="https://github.com/scambra/devise_invitable/actions/workflows/ci.yml/badge.svg"/>}[https://github.com/scambra/devise_invitable/actions/workflows/ci.yml]
4
+ {<img src="https://codeclimate.com/github/scambra/devise_invitable/badges/gpa.svg"/>}[https://codeclimate.com/github/scambra/devise_invitable]
3
5
 
4
6
  It adds support to Devise[https://github.com/plataformatec/devise] for sending invitations by email (it requires to be authenticated) and accept the invitation setting the password.
5
7
 
@@ -35,14 +37,14 @@ Replace MODEL by the class name you want to add DeviseInvitable, like <tt>User</
35
37
 
36
38
  Follow the walkthrough for Devise and after it's done, follow this walkthrough.
37
39
 
38
- == Devise Configuration
40
+ ==== Devise Configuration
39
41
  Add <tt>:invitable</tt> to the <tt>devise</tt> call in your model (we’re assuming here you already have a User model with some Devise modules):
40
42
 
41
43
  class User < ActiveRecord::Base
42
44
  devise :database_authenticatable, :confirmable, :invitable
43
45
  end
44
46
 
45
- == ActiveRecord Migration
47
+ ==== ActiveRecord Migration
46
48
  Add <tt>t.invitable</tt> to your Devise model migration:
47
49
 
48
50
  create_table :users do
@@ -217,6 +219,61 @@ Here is an example of what your application controller might need to include in
217
219
  devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name, :phone])
218
220
  end
219
221
 
222
+ Here is an example setting a User's first name, last name, and role for a custom invitation:
223
+
224
+ #Configuring the InvitationsController to accept :first_name, :last_name, and :role
225
+
226
+ class Users::InvitationsController < Devise::InvitationsController
227
+ before_action :configure_permitted_parameters
228
+
229
+ protected
230
+
231
+ # Permit the new params here.
232
+ def configure_permitted_parameters
233
+ devise_parameter_sanitizer.permit(:invite, keys: [:first_name, :last_name, :role])
234
+ end
235
+ end
236
+
237
+ #Define your roles in the User model
238
+
239
+ class User < ApplicationRecord
240
+ has_many :models
241
+
242
+ enum role: {Role 1 Name: 0, Role 2 Name: 1, Role 3 Name: 2, etc...}
243
+ end
244
+
245
+ #In the Invitation view
246
+
247
+ <h2><%= t "devise.invitations.new.header" %></h2>
248
+
249
+ <%= form_for(resource, as: resource_name, url: invitation_path(resource_name), html: { method: :post }) do |f| %>
250
+ <%= render "devise/shared/error_messages", resource: resource %>
251
+ <% resource.class.invite_key_fields.each do |field| -%>
252
+ <div class="field">
253
+ <%= f.label field %><br />
254
+ <%= f.text_field field %>
255
+ </div>
256
+ <% end %>
257
+
258
+ <div class="field">
259
+ <%= f.label :first_name %>
260
+ <%= f.text_field :first_name %>
261
+ </div>
262
+
263
+ <div class="field">
264
+ <%= f.label :last_name %>
265
+ <%= f.text_field :last_name %>
266
+ </div>
267
+
268
+ <div class="field">
269
+ <%= f.label :role %>
270
+ <%= f.select :role, options_for_select(User.roles.map { |key, value| [key.humanize, key] }), {prompt: "Select Role"} %>
271
+ </div>
272
+
273
+ <div class="actions">
274
+ <%= f.submit t("devise.invitations.new.submit_button") %>
275
+ </div>
276
+ <% end %>
220
277
 
221
278
  == Usage
222
279
 
@@ -315,7 +372,7 @@ After an invitation is created and sent, the inviter will be redirected to <tt>a
315
372
 
316
373
  After an invitation is accepted, the invitee will be redirected to <tt>after_accept_path_for(resource)</tt>, which is the same path as <tt>signed_in_root_path</tt> by default. If you want to override the path, override invitations controller and define <tt>after_accept_path_for</tt> method. This is useful in the common case that a user is invited to a specific location in your application. More on {Devise's README}[https://github.com/plataformatec/devise], "Controller filters and helpers" section.
317
374
 
318
- The invitation email includes a link to accept the invitation that looks like this: <tt>/users/invitation/accept?invitation_token=abcd123</tt>. When clicked, the invited must set a password in order to accept its invitation. Note that if the <tt>invitation_token</tt> is not present or not valid, the invited is redirected to <tt>after_sign_out_path_for(resource_name)</tt>.
375
+ The invitation email includes a link to accept the invitation that looks like this: <tt>/users/invitation/accept?invitation_token=abcd123</tt>. When clicked, the invited must set a password in order to accept its invitation. Note that if the <tt>invitation_token</tt> is not present or not valid, the invited is redirected to <tt>invalid_token_path_for(resource_name)</tt>, which by default is <tt>after_sign_out_path_for(resource_name)</tt>.
319
376
 
320
377
  The controller sets the <tt>invited_by_id</tt> attribute for the new user to the current user. This will let you easily keep track of who invited whom.
321
378
 
@@ -31,7 +31,7 @@ class Devise::InvitationsController < DeviseController
31
31
  respond_with resource, location: after_invite_path_for(current_inviter, resource)
32
32
  end
33
33
  else
34
- respond_with_navigational(resource) { render :new }
34
+ respond_with_navigational(resource) { render :new, status: :unprocessable_entity }
35
35
  end
36
36
  end
37
37
 
@@ -63,7 +63,7 @@ class Devise::InvitationsController < DeviseController
63
63
  end
64
64
  else
65
65
  resource.invitation_token = raw_invitation_token
66
- respond_with_navigational(resource) { render :edit }
66
+ respond_with_navigational(resource) { render :edit, status: :unprocessable_entity }
67
67
  end
68
68
  end
69
69
 
@@ -99,7 +99,7 @@ class Devise::InvitationsController < DeviseController
99
99
  def resource_from_invitation_token
100
100
  unless params[:invitation_token] && self.resource = resource_class.find_by_invitation_token(params[:invitation_token], true)
101
101
  set_flash_message(:alert, :invitation_token_invalid) if is_flashing_format?
102
- redirect_to after_sign_out_path_for(resource_name)
102
+ redirect_to invalid_token_path_for(resource_name)
103
103
  end
104
104
  end
105
105
 
@@ -0,0 +1,32 @@
1
+
2
+ ca:
3
+ devise:
4
+ failure:
5
+ invited: "Tens una invitació pendent, accepta-la per acabar de crear el teu compte."
6
+ invitations:
7
+ send_instructions: "S'ha enviat una invitació a %{email}."
8
+ invitation_token_invalid: "La invitació no es vàlida!"
9
+ updated: "S'ha configurat la seva contrasenya i s'ha ingressat al sistema"
10
+ updated_not_active: "La seva contrasenya s'ha configurat correctament."
11
+ no_invitations_remaining: "No queden invitacions"
12
+ invitation_removed: "S'ha retirat la seva invitació"
13
+ new:
14
+ header: "Enviar Invitació"
15
+ submit_button: "Envia una invitació"
16
+ edit:
17
+ header: "Establir contrasenya"
18
+ submit_button: "Guardar la meva contrasenya"
19
+ mailer:
20
+ invitation_instructions:
21
+ subject: "Instruccions de la invitació"
22
+ hello: "Hola %{email}"
23
+ someone_invited_you: "Has estat invitat a %{url}, pots acceptar-ho seguint el següent enllaç"
24
+ accept: "Aceptar la invitació"
25
+ accept_until: "Aquesta invitació expirarà en %{due_date}."
26
+ ignore: "Si no li interessa aquesta invitació, simplement ignori aquest correu. No es crearà el teu compte fins que accedeixis a l'anterior enllaç i creïs una contrasenya"
27
+ time:
28
+ formats:
29
+ devise:
30
+ mailer:
31
+ invitation_instructions:
32
+ accept_until_format: "%d de %B de %Y, %H:%M"
@@ -1,31 +1,31 @@
1
- de:
2
- devise:
3
- failure:
4
- invited: "Du hast bereits eine Einladung erhalten. Nimm die Einladung an um dein Nutzerkonto zu erstellen."
5
- invitations:
6
- send_instructions: "Eine Einladung wurde an %{email} verschickt."
7
- invitation_token_invalid: "Der Einladungs-Code ist ungültig!"
8
- updated: "Dein Passwort wurde gesetzt. Du bist nun angemeldet."
9
- updated_not_active: "Dein Passwort wurde gesetzt."
10
- no_invitations_remaining: "Es gibt keine weiteren Einladungen"
11
- invitation_removed: "Deine Einladung wurde gelöscht."
12
- new:
13
- header: "Einladung schicken"
14
- submit_button: "Einladung schicken"
15
- edit:
16
- header: "Setze ein Passwort"
17
- submit_button: "Passwort setzen"
18
- mailer:
19
- invitation_instructions:
20
- subject: "Einladung"
21
- hello: "Hallo %{email}"
22
- someone_invited_you: "Jemand hat dich zu %{url} eingeladen. Du kannst die Einladung mit dem Link unten annehmen."
23
- accept: "Einladung annehmen"
24
- accept_until: "Diese Einladung ist gültig bis zum %{due_date}."
25
- ignore: "Wenn du die Einladung nicht annehmen willst, ignoriere diese E-Mail einfach.<br />\nEs wird kein Benutzerkonto erstellt solange du nicht die Einladung mi↪ttels des Links oben annimmst."
26
- time:
27
- formats:
28
- devise:
29
- mailer:
30
- invitation_instructions:
31
- accept_until_format: "%d. %B %Y %H:%M"
1
+ de:
2
+ devise:
3
+ failure:
4
+ invited: "Du hast bereits eine Einladung erhalten. Nimm die Einladung an um dein Nutzerkonto zu erstellen."
5
+ invitations:
6
+ send_instructions: "Eine Einladung wurde an %{email} verschickt."
7
+ invitation_token_invalid: "Der Einladungs-Code ist ungültig!"
8
+ updated: "Dein Passwort wurde gesetzt. Du bist nun angemeldet."
9
+ updated_not_active: "Dein Passwort wurde gesetzt."
10
+ no_invitations_remaining: "Es gibt keine weiteren Einladungen"
11
+ invitation_removed: "Deine Einladung wurde gelöscht."
12
+ new:
13
+ header: "Einladung schicken"
14
+ submit_button: "Einladung schicken"
15
+ edit:
16
+ header: "Setze ein Passwort"
17
+ submit_button: "Passwort setzen"
18
+ mailer:
19
+ invitation_instructions:
20
+ subject: "Einladung"
21
+ hello: "Hallo %{email}"
22
+ someone_invited_you: "Jemand hat dich zu %{url} eingeladen. Du kannst die Einladung mit dem Link unten annehmen."
23
+ accept: "Einladung annehmen"
24
+ accept_until: "Diese Einladung ist gültig bis zum %{due_date}."
25
+ ignore: "Wenn du die Einladung nicht annehmen willst, ignoriere diese E-Mail einfach. Es wird kein Benutzerkonto erstellt solange du nicht die Einladung mittels des Links oben annimmst."
26
+ time:
27
+ formats:
28
+ devise:
29
+ mailer:
30
+ invitation_instructions:
31
+ accept_until_format: "%d. %B %Y %H:%M"
@@ -17,7 +17,7 @@ es:
17
17
  submit_button: "Guardar mi contraseña"
18
18
  mailer:
19
19
  invitation_instructions:
20
- subject: "Instruciones de la invitación"
20
+ subject: "Instrucciones de la invitación"
21
21
  hello: "Hola %{email}"
22
22
  someone_invited_you: "Has sido invitado a %{url}, puedes aceptarlo siguiendo el siguiente enlace"
23
23
  accept: "Aceptar la invitación"
@@ -12,6 +12,10 @@ module DeviseInvitable::Controllers::Helpers
12
12
  signed_in_root_path(resource)
13
13
  end
14
14
 
15
+ def invalid_token_path_for(resource_name)
16
+ after_sign_out_path_for(resource_name)
17
+ end
18
+
15
19
  protected
16
20
 
17
21
  def authenticate_inviter!
@@ -3,8 +3,10 @@ module DeviseInvitable
3
3
  private
4
4
 
5
5
  def default_controllers(options)
6
- options[:controllers] ||= {}
7
- options[:controllers][:registrations] ||= 'devise_invitable/registrations'
6
+ unless options[:module]
7
+ options[:controllers] ||= {}
8
+ options[:controllers][:registrations] ||= 'devise_invitable/registrations'
9
+ end
8
10
  super
9
11
  end
10
12
  end
@@ -158,7 +158,8 @@ module Devise
158
158
  self.downcase_keys if new_record_and_responds_to?(:downcase_keys)
159
159
  self.strip_whitespace if new_record_and_responds_to?(:strip_whitespace)
160
160
 
161
- if save(validate: false)
161
+ validate = options.key?(:validate) ? options[:validate] : self.class.validate_on_invite
162
+ if save(validate: validate)
162
163
  self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
163
164
  deliver_invitation(options) unless skip_invitation
164
165
  end
@@ -324,7 +325,7 @@ module Devise
324
325
  end
325
326
 
326
327
  yield invitable if block_given?
327
- mail = invitable.invite!(nil, options) if invitable.errors.empty?
328
+ mail = invitable.invite!(nil, options.merge(validate: false)) if invitable.errors.empty?
328
329
  [invitable, mail]
329
330
  end
330
331
 
@@ -1,3 +1,3 @@
1
1
  module DeviseInvitable
2
- VERSION = '2.0.5'.freeze
2
+ VERSION = '2.0.7'.freeze
3
3
  end
@@ -7,7 +7,7 @@ module DeviseInvitable
7
7
 
8
8
  def inject_devise_invitable_content
9
9
  path = File.join('app', 'models', "#{file_path}.rb")
10
- inject_into_file(path, 'invitable, :', after: 'devise :') if File.exists?(path)
10
+ inject_into_file(path, 'invitable, :', after: 'devise :') if File.exist?(path)
11
11
  end
12
12
 
13
13
  hook_for :orm
@@ -41,4 +41,14 @@ class ControllerHelpersTest < ActionController::TestCase
41
41
  assert Devise::InvitationsController.method_defined? :after_accept_path_for
42
42
  assert !Devise::InvitationsController.instance_methods(false).include?(:after_accept_path_for)
43
43
  end
44
+
45
+ test 'invalid token path defaults to after sign out path' do
46
+ assert_equal @controller.send(:after_sign_out_path_for, :user), @controller.invalid_token_path_for(:user)
47
+ end
48
+
49
+ test 'invalid token path is customizable from application controller' do
50
+ custom_path = 'customized/invalid/token/path'
51
+ @controller.instance_eval "def invalid_token_path_for(resource_name) '#{custom_path}' end"
52
+ assert_equal @controller.invalid_token_path_for(:user), custom_path
53
+ end
44
54
  end
@@ -102,7 +102,7 @@ class InvitationMailTest < ActionMailer::TestCase
102
102
  def initialize(*args); end
103
103
  def deliver; end
104
104
  end
105
- Devise.mailer = CustomMailer
105
+ Devise.mailer = 'InvitationMailTest::CustomMailer'
106
106
 
107
107
  User.invite!({ email: 'valid@email.com' }, nil, { invited_at: Time.now })
108
108
  end
@@ -1,6 +1,6 @@
1
1
  class ActiveSupport::TestCase
2
2
  def setup_mailer
3
- Devise.mailer = Devise::Mailer
3
+ Devise.mailer = 'Devise::Mailer'
4
4
  ActionMailer::Base.deliveries = []
5
5
  end
6
6
 
@@ -89,12 +89,12 @@ class InvitableTest < ActiveSupport::TestCase
89
89
  user.invite!
90
90
  old_invitation_created_at = 3.days.ago
91
91
  old_invitation_sent_at = 3.days.ago
92
- user.update_attributes(invitation_sent_at: old_invitation_sent_at, invitation_created_at: old_invitation_created_at)
92
+ user.update(invitation_sent_at: old_invitation_sent_at, invitation_created_at: old_invitation_created_at)
93
93
  3.times do
94
94
  user.invite!
95
95
  refute_equal old_invitation_sent_at, user.invitation_sent_at
96
96
  refute_equal old_invitation_created_at, user.invitation_created_at
97
- user.update_attributes(invitation_sent_at: old_invitation_sent_at, invitation_created_at: old_invitation_created_at)
97
+ user.update(invitation_sent_at: old_invitation_sent_at, invitation_created_at: old_invitation_created_at)
98
98
  end
99
99
  end
100
100
 
@@ -1,7 +1,12 @@
1
1
  ActiveRecord::Migration.verbose = false
2
2
  ActiveRecord::Base.logger = Logger.new(nil)
3
3
 
4
- if defined? ActiveRecord::MigrationContext # rails >= 5.2
4
+ if ActiveRecord::VERSION::MAJOR >= 6
5
+ ActiveRecord::MigrationContext.new(
6
+ File.expand_path('../../rails_app/db/migrate/', __FILE__),
7
+ ActiveRecord::Base.connection.schema_migration
8
+ ).migrate
9
+ elsif defined? ActiveRecord::MigrationContext # rails >= 5.2
5
10
  ActiveRecord::MigrationContext.new(File.expand_path('../../rails_app/db/migrate/', __FILE__)).migrate
6
11
  else
7
12
  ActiveRecord::Migrator.migrate(File.expand_path('../../rails_app/db/migrate/', __FILE__))
data/test/test_helper.rb CHANGED
@@ -7,7 +7,7 @@ require "rails_app/config/environment"
7
7
  require 'rails/test_help'
8
8
  require "orm/#{DEVISE_ORM}"
9
9
  require 'capybara/rails'
10
- require 'mocha/setup'
10
+ require 'mocha/minitest'
11
11
 
12
12
  ActionMailer::Base.delivery_method = :test
13
13
  ActionMailer::Base.perform_deliveries = true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_invitable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergio Cambra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-19 00:00:00.000000000 Z
11
+ date: 2023-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -70,6 +70,7 @@ files:
70
70
  - app/views/devise/mailer/invitation_instructions.html.erb
71
71
  - app/views/devise/mailer/invitation_instructions.text.erb
72
72
  - config/locales/ar.yml
73
+ - config/locales/ca.yml
73
74
  - config/locales/da.yml
74
75
  - config/locales/de.yml
75
76
  - config/locales/en.yml
@@ -186,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
187
  - !ruby/object:Gem::Version
187
188
  version: '0'
188
189
  requirements: []
189
- rubygems_version: 3.0.8
190
+ rubygems_version: 3.3.7
190
191
  signing_key:
191
192
  specification_version: 4
192
193
  summary: An invitation strategy for Devise