decidim-verifications 0.15.2 → 0.16.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/README.md +37 -7
- data/app/commands/decidim/verifications/id_documents/admin/confirm_user_offline_authorization.rb +74 -0
- data/app/commands/decidim/verifications/id_documents/admin/update_config.rb +39 -0
- data/app/controllers/decidim/verifications/id_documents/admin/config_controller.rb +40 -0
- data/app/controllers/decidim/verifications/id_documents/admin/offline_confirmations_controller.rb +40 -0
- data/app/controllers/decidim/verifications/id_documents/admin/pending_authorizations_controller.rb +13 -2
- data/app/controllers/decidim/verifications/id_documents/authorizations_controller.rb +30 -2
- data/app/controllers/decidim/verifications/sms/authorizations_controller.rb +76 -0
- data/app/forms/decidim/verifications/id_documents/admin/config_form.rb +42 -0
- data/app/forms/decidim/verifications/id_documents/admin/offline_confirmation_form.rb +16 -0
- data/app/forms/decidim/verifications/id_documents/information_form.rb +12 -1
- data/app/forms/decidim/verifications/id_documents/upload_form.rb +2 -1
- data/app/forms/decidim/verifications/sms/confirmation_form.rb +19 -0
- data/app/forms/decidim/verifications/sms/mobile_phone_form.rb +59 -0
- data/app/views/decidim/verifications/id_documents/admin/config/edit.html.erb +26 -0
- data/app/views/decidim/verifications/id_documents/admin/confirmations/new.html.erb +1 -0
- data/app/views/decidim/verifications/id_documents/admin/offline_confirmations/new.html.erb +24 -0
- data/app/views/decidim/verifications/id_documents/admin/pending_authorizations/index.html.erb +3 -1
- data/app/views/decidim/verifications/id_documents/authorizations/_form.html.erb +17 -0
- data/app/views/decidim/verifications/id_documents/authorizations/choose.html.erb +21 -0
- data/app/views/decidim/verifications/id_documents/authorizations/edit.html.erb +14 -23
- data/app/views/decidim/verifications/id_documents/authorizations/new.html.erb +6 -13
- data/app/views/decidim/verifications/sms/authorizations/edit.html.erb +27 -0
- data/app/views/decidim/verifications/sms/authorizations/new.html.erb +27 -0
- data/config/locales/ca.yml +51 -1
- data/config/locales/de.yml +50 -0
- data/config/locales/en.yml +51 -1
- data/config/locales/es-PY.yml +50 -0
- data/config/locales/es.yml +51 -1
- data/config/locales/eu.yml +50 -0
- data/config/locales/fi-pl.yml +51 -1
- data/config/locales/fi.yml +51 -1
- data/config/locales/fr.yml +50 -0
- data/config/locales/gl.yml +50 -0
- data/config/locales/hu.yml +50 -0
- data/config/locales/id-ID.yml +51 -1
- data/config/locales/it.yml +50 -0
- data/config/locales/nl.yml +50 -0
- data/config/locales/pl.yml +50 -0
- data/config/locales/pt-BR.yml +50 -0
- data/config/locales/pt.yml +50 -0
- data/config/locales/sv.yml +50 -0
- data/config/locales/tr-TR.yml +51 -1
- data/lib/decidim/verifications.rb +1 -0
- data/lib/decidim/verifications/id_documents/admin_engine.rb +3 -0
- data/lib/decidim/verifications/id_documents/engine.rb +6 -2
- data/lib/decidim/verifications/sms.rb +4 -0
- data/lib/decidim/verifications/sms/engine.rb +29 -0
- data/lib/decidim/verifications/sms/example_gateway.rb +21 -0
- data/lib/decidim/verifications/version.rb +1 -1
- metadata +27 -9
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module IdDocuments
|
6
|
+
# A form object to be used as the base for identity document verification
|
7
|
+
module Admin
|
8
|
+
class ConfigForm < Decidim::Form
|
9
|
+
include TranslatableAttributes
|
10
|
+
mimic :config
|
11
|
+
|
12
|
+
attribute :offline, Boolean
|
13
|
+
attribute :online, Boolean
|
14
|
+
translatable_attribute :offline_explanation, String
|
15
|
+
|
16
|
+
validates :offline_explanation, translatable_presence: true, if: :offline
|
17
|
+
validate :has_some_method_selected?
|
18
|
+
|
19
|
+
def map_model(model)
|
20
|
+
self.online = model.id_documents_methods.include?("online")
|
21
|
+
self.offline = model.id_documents_methods.include?("offline")
|
22
|
+
self.offline_explanation = model.id_documents_explanation_text
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_some_method_selected?
|
26
|
+
return if online || offline
|
27
|
+
|
28
|
+
errors.add(:online, :invalid)
|
29
|
+
errors.add(:offline, :invalid)
|
30
|
+
end
|
31
|
+
|
32
|
+
def selected_methods
|
33
|
+
methods = []
|
34
|
+
methods << "offline" if offline
|
35
|
+
methods << "online" if online
|
36
|
+
methods
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module IdDocuments
|
6
|
+
# A form object to be used as the base for identity document verification
|
7
|
+
module Admin
|
8
|
+
class OfflineConfirmationForm < InformationForm
|
9
|
+
attribute :email, String
|
10
|
+
|
11
|
+
validates :email, presence: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -11,6 +11,7 @@ module Decidim
|
|
11
11
|
|
12
12
|
attribute :document_number, String
|
13
13
|
attribute :document_type, String
|
14
|
+
attribute :verification_type, String
|
14
15
|
|
15
16
|
validates :document_type,
|
16
17
|
inclusion: { in: DOCUMENT_TYPES },
|
@@ -20,6 +21,10 @@ module Decidim
|
|
20
21
|
format: { with: /\A[A-Z0-9]*\z/, message: I18n.t("errors.messages.uppercase_only_letters_numbers") },
|
21
22
|
presence: true
|
22
23
|
|
24
|
+
validates :verification_type,
|
25
|
+
presence: true,
|
26
|
+
inclusion: { in: %w(offline online) }
|
27
|
+
|
23
28
|
def handler_name
|
24
29
|
"id_documents"
|
25
30
|
end
|
@@ -27,12 +32,14 @@ module Decidim
|
|
27
32
|
def map_model(model)
|
28
33
|
self.document_type = model.verification_metadata["document_type"]
|
29
34
|
self.document_number = model.verification_metadata["document_number"]
|
35
|
+
self.verification_type = model.verification_metadata["verification_type"].presence || "online"
|
30
36
|
end
|
31
37
|
|
32
38
|
def verification_metadata
|
33
39
|
{
|
34
40
|
"document_type" => document_type,
|
35
|
-
"document_number" => document_number
|
41
|
+
"document_number" => document_number,
|
42
|
+
"verification_type" => verification_type
|
36
43
|
}
|
37
44
|
end
|
38
45
|
|
@@ -44,6 +51,10 @@ module Decidim
|
|
44
51
|
]
|
45
52
|
end
|
46
53
|
end
|
54
|
+
|
55
|
+
def uses_online_method?
|
56
|
+
verification_type == "online"
|
57
|
+
end
|
47
58
|
end
|
48
59
|
end
|
49
60
|
end
|
@@ -13,7 +13,8 @@ module Decidim
|
|
13
13
|
validates :verification_attachment,
|
14
14
|
file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
|
15
15
|
file_content_type: { allow: ["image/jpeg", "image/png"] },
|
16
|
-
presence: true
|
16
|
+
presence: true,
|
17
|
+
if: :uses_online_method?
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module Sms
|
6
|
+
# A form object that just holds a verification code that the user will
|
7
|
+
# have received by SMS.
|
8
|
+
class ConfirmationForm < AuthorizationHandler
|
9
|
+
attribute :verification_code, String
|
10
|
+
|
11
|
+
validates :verification_code, presence: true
|
12
|
+
|
13
|
+
def verification_metadata
|
14
|
+
{ "verification_code" => verification_code }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Verifications
|
7
|
+
module Sms
|
8
|
+
# A form object to be used when public users want to get verified using their phone.
|
9
|
+
class MobilePhoneForm < AuthorizationHandler
|
10
|
+
attribute :mobile_phone_number, String
|
11
|
+
|
12
|
+
validates :mobile_phone_number, :verification_code, :sms_gateway, presence: true
|
13
|
+
|
14
|
+
def handler_name
|
15
|
+
"sms"
|
16
|
+
end
|
17
|
+
|
18
|
+
# A mobile phone can only be verified once but it should be private.
|
19
|
+
def unique_id
|
20
|
+
Digest::MD5.hexdigest(
|
21
|
+
"#{mobile_phone_number}-#{Rails.application.secrets.secret_key_base}"
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
# When there's a phone number, sanitize it allowing only numbers and +.
|
26
|
+
def mobile_phone_number
|
27
|
+
return unless super
|
28
|
+
super.gsub(/[^\+0-9]/, "")
|
29
|
+
end
|
30
|
+
|
31
|
+
# The verification metadata to validate in the next step.
|
32
|
+
def verification_metadata
|
33
|
+
{
|
34
|
+
verification_code: verification_code,
|
35
|
+
code_sent_at: Time.current
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def verification_code
|
42
|
+
return unless sms_gateway
|
43
|
+
return @verification_code if defined?(@verification_code)
|
44
|
+
|
45
|
+
return unless sms_gateway.new(mobile_phone_number, generated_code).deliver_code
|
46
|
+
@verification_code = generated_code
|
47
|
+
end
|
48
|
+
|
49
|
+
def sms_gateway
|
50
|
+
Decidim.sms_gateway_service.to_s.safe_constantize
|
51
|
+
end
|
52
|
+
|
53
|
+
def generated_code
|
54
|
+
@generated_code ||= SecureRandom.random_number(1_000_000).to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%= decidim_form_for(@form, url: { action: :update },
|
2
|
+
html: { class: "form" }) do |form| %>
|
3
|
+
<div class="card">
|
4
|
+
<div class="card-divider">
|
5
|
+
<h2 class="card-title">
|
6
|
+
<%= t(".title") %>
|
7
|
+
</h2>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div class="card-section">
|
11
|
+
<div class="row column">
|
12
|
+
<%= label_tag(:available_methods, t("activemodel.attributes.config.available_methods")) %>
|
13
|
+
<%= form.check_box :online %>
|
14
|
+
<%= form.check_box :offline %>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div class="row column">
|
18
|
+
<%= form.translated :editor, :offline_explanation, lines: 10 %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div class="button--double form-general-submit">
|
24
|
+
<%= form.submit t(".update") %>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
@@ -16,6 +16,7 @@
|
|
16
16
|
<div class="row column">
|
17
17
|
<%= form.select :document_type, @form.document_types_for_select, prompt: true, selected: nil %>
|
18
18
|
<%= form.text_field :document_number, value: nil %>
|
19
|
+
<%= form.hidden_field :verification_type, value: :online %>
|
19
20
|
</div>
|
20
21
|
</div>
|
21
22
|
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= decidim_form_for(@form, url: offline_confirmation_path,
|
2
|
+
html: { class: "form" }) do |form| %>
|
3
|
+
<div class="card">
|
4
|
+
<div class="card-divider">
|
5
|
+
<h2 class="card-title">
|
6
|
+
<%= t(".introduce_user_data") %>
|
7
|
+
</h2>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div class="card-section">
|
11
|
+
<div class="row column">
|
12
|
+
<%= form.text_field :email %>
|
13
|
+
<%= form.select :document_type, @form.document_types_for_select, prompt: true %>
|
14
|
+
<%= form.text_field :document_number %>
|
15
|
+
<%= form.hidden_field :verification_type, value: :offline %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<div class="button--double form-general-submit">
|
21
|
+
<%= form.submit t(".verify") %>
|
22
|
+
<%= link_to t(".cancel"), root_path, class: "button hollow" %>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
data/app/views/decidim/verifications/id_documents/admin/pending_authorizations/index.html.erb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
<div class="card-divider">
|
3
3
|
<h2 class="card-title">
|
4
4
|
<%= t(".title") %>
|
5
|
+
<%= link_to t(".config"), edit_config_path, class: "button tiny button--title" %>
|
6
|
+
<%= link_to t(".offline_verification"), new_offline_confirmation_path, class: "button tiny button--title" if has_offline_method? %>
|
5
7
|
</h2>
|
6
8
|
</div>
|
7
9
|
<div class="card-section">
|
@@ -14,7 +16,7 @@
|
|
14
16
|
</thead>
|
15
17
|
<tbody>
|
16
18
|
<tr>
|
17
|
-
<% @
|
19
|
+
<% @pending_online_authorizations.each do |authorization| %>
|
18
20
|
<td>
|
19
21
|
<%= link_to t(".verification_number", n: authorization.id),
|
20
22
|
new_pending_authorization_confirmation_path(authorization.id) %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="card-section">
|
2
|
+
<div class="field">
|
3
|
+
<%= form.select :document_type, @form.document_types_for_select, prompt: true %>
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<div class="field">
|
7
|
+
<%= form.text_field :document_number %>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<% if using_online? %>
|
11
|
+
<div class="field">
|
12
|
+
<%= form.upload :verification_attachment %>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<%= form.hidden_field :verification_type, value: verification_type %>
|
17
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="wrapper">
|
2
|
+
<div class="row collapse">
|
3
|
+
<div class="row collapse">
|
4
|
+
<div class="columns large-8 large-centered text-center page-title">
|
5
|
+
<h1><%= t(".title") %></h1>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="row">
|
10
|
+
<div class="columns large-6 medium-centered">
|
11
|
+
<div class="card">
|
12
|
+
<div class="card__content">
|
13
|
+
<p><%= t(".choose_a_type") %></p>
|
14
|
+
<%= link_to t(".offline"), { action: :new, using: :offline }, class: "button button--sc expanded hollow" %>
|
15
|
+
<%= link_to t(".online"), { action: :new, using: :online }, class: "button button--sc expanded" %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
@@ -17,37 +17,28 @@
|
|
17
17
|
</div>
|
18
18
|
</div>
|
19
19
|
|
20
|
-
|
21
|
-
<div class="
|
22
|
-
<div class="
|
23
|
-
<div class="
|
24
|
-
<div class="
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
<div class="field">
|
29
|
-
<%= form.select :document_type, @form.document_types_for_select, prompt: true %>
|
30
|
-
</div>
|
31
|
-
|
32
|
-
<div class="field">
|
33
|
-
<%= form.text_field :document_number %>
|
34
|
-
</div>
|
35
|
-
|
36
|
-
<div class="field">
|
37
|
-
<%= form.upload :verification_attachment, optional: false %>
|
38
|
-
</div>
|
39
|
-
</div>
|
20
|
+
<div class="row">
|
21
|
+
<div class="columns large-6 medium-centered">
|
22
|
+
<div class="row column">
|
23
|
+
<div class="card">
|
24
|
+
<div class="card__content">
|
25
|
+
<%= translated_attribute(current_organization.id_documents_explanation_text).html_safe unless using_online? %>
|
26
|
+
<%= decidim_form_for(@form, url: authorization_path, method: :put) do |form| %>
|
27
|
+
<%= render partial: "form", locals: { form: form } %>
|
40
28
|
|
41
29
|
<div class="card-section">
|
42
30
|
<div class="actions">
|
43
31
|
<%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %>
|
32
|
+
<% if available_methods.count > 1 %>
|
33
|
+
<%= link_to t(".offline"), { action: :edit, using: :offline }, class: "button expanded hollow" if using_online? %>
|
34
|
+
<%= link_to t(".online"), { action: :edit, using: :online }, class: "button expanded hollow" if using_offline? %>
|
35
|
+
<% end %>
|
44
36
|
</div>
|
45
37
|
</div>
|
46
|
-
|
47
|
-
</div>
|
38
|
+
<% end %>
|
48
39
|
</div>
|
49
40
|
</div>
|
50
41
|
</div>
|
51
42
|
</div>
|
52
|
-
|
43
|
+
</div>
|
53
44
|
</div>
|
@@ -10,21 +10,14 @@
|
|
10
10
|
<div class="columns large-6 medium-centered">
|
11
11
|
<div class="card">
|
12
12
|
<div class="card__content">
|
13
|
+
<%= translated_attribute(current_organization.id_documents_explanation_text).html_safe unless using_online? %>
|
13
14
|
<%= decidim_form_for(@form, url: authorization_path) do |form| %>
|
14
|
-
|
15
|
-
<%= form.select :document_type, @form.document_types_for_select, prompt: true %>
|
16
|
-
</div>
|
17
|
-
|
18
|
-
<div class="field">
|
19
|
-
<%= form.text_field :document_number %>
|
20
|
-
</div>
|
21
|
-
|
22
|
-
<div class="field">
|
23
|
-
<%= form.upload :verification_attachment %>
|
24
|
-
</div>
|
15
|
+
<%= render partial: "form", locals: { form: form } %>
|
25
16
|
|
26
|
-
<div class="
|
27
|
-
|
17
|
+
<div class="card-section">
|
18
|
+
<div class="actions">
|
19
|
+
<%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %>
|
20
|
+
</div>
|
28
21
|
</div>
|
29
22
|
<% end %>
|
30
23
|
</div>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div class="wrapper">
|
2
|
+
<div class="row collapse">
|
3
|
+
<div class="row collapse">
|
4
|
+
<div class="columns large-8 large-centered text-center page-title">
|
5
|
+
<h1><%= t(".title") %></h1>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="row">
|
10
|
+
<div class="columns large-6 medium-centered">
|
11
|
+
<div class="card">
|
12
|
+
<div class="card__content">
|
13
|
+
<%= decidim_form_for(@form, url: authorization_path, method: :put) do |form| %>
|
14
|
+
<div class="field">
|
15
|
+
<%= form.text_field :verification_code %>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="actions">
|
19
|
+
<%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</div>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div class="wrapper">
|
2
|
+
<div class="row collapse">
|
3
|
+
<div class="row collapse">
|
4
|
+
<div class="columns large-8 large-centered text-center page-title">
|
5
|
+
<h1><%= t(".title") %></h1>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="row">
|
10
|
+
<div class="columns large-6 medium-centered">
|
11
|
+
<div class="card">
|
12
|
+
<div class="card__content">
|
13
|
+
<%= decidim_form_for(@form, url: authorization_path) do |form| %>
|
14
|
+
<div class="field">
|
15
|
+
<%= form.text_field :mobile_phone_number %>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="actions">
|
19
|
+
<%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</div>
|