devise_sms_verifiable 0.0.6 → 0.0.8
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/app/controllers/devise/sms_verifiable_controller.rb +11 -6
- data/app/views/devise/sms_verifiable/new.html.erb +2 -1
- data/config/locales/en.yml +10 -0
- data/config/locales/ru.yml +10 -0
- data/lib/devise_sms_verifiable.rb +3 -6
- data/lib/devise_sms_verifiable/controllers/internal_helpers.rb +16 -6
- data/lib/devise_sms_verifiable/errors.rb +0 -2
- data/lib/devise_sms_verifiable/model.rb +33 -2
- data/lib/devise_sms_verifiable/version.rb +1 -1
- data/lib/generators/devise_sms_verifiable/install_generator.rb +3 -4
- data/lib/generators/devise_sms_verifiable/migration_generator.rb +10 -5
- data/lib/generators/devise_sms_verifiable/templates/README +0 -6
- metadata +25 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c51a8259b8b1fa460ebf008eaa844531ca4c92e4
|
4
|
+
data.tar.gz: d854dd3f18aa902e15ca032d16579c6c29c02ec2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f1b9bc706b2849084769f69bf30140a931ee95fd3a326912d619540241ee30b75785b2a02111ce9a501e074416305489d045794e082827d58a1bc869c498cb3
|
7
|
+
data.tar.gz: 8d1b8d98dcde47c913205ae0e9fdcab07a7df8888da30d6242ecce94186790358d3973271f9cad125eaef49f20d69266d02ba612a3dbbac6e979a9048e2ade05
|
@@ -1,16 +1,18 @@
|
|
1
1
|
class Devise::SmsVerifiableController < DeviseController
|
2
|
-
append_before_filter :sms_check_settings
|
2
|
+
append_before_filter :sms_check_settings!
|
3
3
|
|
4
4
|
def new
|
5
|
+
set_flash_message :notice, :sms_activation_required
|
5
6
|
end
|
6
7
|
|
7
8
|
def create
|
8
9
|
resource.sms_secret = public_send("current_#{resource_name}").public_send(Devise::sms_answer_field)
|
9
10
|
secret = params[:user][:sms_secret]
|
10
|
-
if secret && resource.sms_secret && resource.
|
11
|
-
public_send("current_#{resource_name}").public_send(:update, Hash[Devise::phone_confirmation_field, true])
|
11
|
+
if secret && resource.sms_secret && resource.valid_token?(secret)
|
12
|
+
public_send("current_#{resource_name}").public_send(:update, Hash[Devise::phone_confirmation_field, true, :sms_token_confirmed_at, DateTime.now])
|
12
13
|
redirect_to Devise::successful_path
|
13
14
|
else
|
15
|
+
set_flash_message :notice, :sms_token_invalid
|
14
16
|
render :new
|
15
17
|
end
|
16
18
|
end
|
@@ -18,13 +20,16 @@ class Devise::SmsVerifiableController < DeviseController
|
|
18
20
|
def send_pass
|
19
21
|
number = public_send("current_#{resource_name}").public_send(Devise::phone_field)
|
20
22
|
provider = Devise::sms_provider
|
21
|
-
|
22
|
-
|
23
|
-
provider.public_send(:send_sms, number,
|
23
|
+
if [number, provider].all? && !public_send("current_#{resource_name}").sms_confirmed?
|
24
|
+
token = public_send("current_#{resource_name}").sms_confirm!
|
25
|
+
provider.public_send(:send_sms, number, token)
|
26
|
+
set_flash_message :notice, :send_token, phone: number
|
24
27
|
end
|
25
28
|
render :new
|
26
29
|
end
|
27
30
|
|
31
|
+
protected
|
32
|
+
|
28
33
|
def resource
|
29
34
|
_resource = resource_class.new
|
30
35
|
instance_variable_set(:@user, _resource)
|
@@ -1,8 +1,9 @@
|
|
1
|
+
<%= flash[:notice] if flash[:notice] %>
|
1
2
|
<h2>Sms verifiable</h2>
|
2
3
|
<%= form_for(resource, :as => resource_name, :url => sms_path(resource_name)) do |f| %>
|
3
4
|
<%= devise_error_messages! %>
|
4
5
|
<p><%= f.label :sms_secret %><br />
|
5
|
-
<%= f.text_field :sms_secret %></p>
|
6
|
+
<%= f.text_field :sms_secret, value: nil %></p>
|
6
7
|
<p><%= f.submit "send" %></p>
|
7
8
|
<% end %>
|
8
9
|
<%= button_to 'send sms', public_send("send_pass_#{resource_name}_sms_path"), data: { method: :post } %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
en:
|
2
|
+
errors:
|
3
|
+
messages:
|
4
|
+
sms_token_invalid: "Invalid token"
|
5
|
+
devise:
|
6
|
+
sms_verifiable:
|
7
|
+
send_token: 'An activation token was sent by SMS to %{phone}.'
|
8
|
+
sms_token_invalid: 'The sms token provided is not valid!'
|
9
|
+
confirmed: 'Your account has been activated.'
|
10
|
+
sms_activation_required: 'SMS Activation is required'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
ru:
|
2
|
+
errors:
|
3
|
+
messages:
|
4
|
+
sms_token_invalid: "Неверный код"
|
5
|
+
devise:
|
6
|
+
sms_verifiable:
|
7
|
+
send_token: 'Выслано SMS с кодом подтверждения на номер %{phone}.'
|
8
|
+
sms_token_invalid: 'Неверный код'
|
9
|
+
confirmed: 'Спасибо Ваш номер подтверждён'
|
10
|
+
sms_activation_required: 'Подтвердите аккаунт с помощью телефона'
|
@@ -12,12 +12,6 @@ require 'devise_sms_verifiable/engine'
|
|
12
12
|
require 'devise_sms_verifiable/errors'
|
13
13
|
|
14
14
|
module Devise
|
15
|
-
mattr_accessor :sms_confirmation_method
|
16
|
-
@@sms_confirmation_method = :sms_confirmation?
|
17
|
-
|
18
|
-
mattr_accessor :sms_secret_method
|
19
|
-
@@sms_secret_method = :sms_secret
|
20
|
-
|
21
15
|
mattr_accessor :sms_answer_field
|
22
16
|
@@sms_answer_field = :sms_answer
|
23
17
|
|
@@ -30,6 +24,9 @@ module Devise
|
|
30
24
|
mattr_accessor :successful_path
|
31
25
|
@@successful_path = '/'
|
32
26
|
|
27
|
+
mattr_accessor :token_generator
|
28
|
+
@@token_generator = :default
|
29
|
+
|
33
30
|
mattr_accessor :sms_provider
|
34
31
|
@@sms_provider = DeviseSmsVerifiable::Provider
|
35
32
|
|
@@ -1,22 +1,32 @@
|
|
1
1
|
module DeviseSmsVerifiable
|
2
2
|
module Controllers
|
3
3
|
module InternalHelpers
|
4
|
-
extend ActiveSupport::Concern
|
5
4
|
|
6
|
-
def sms_check_settings
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
raise
|
5
|
+
def sms_check_settings!
|
6
|
+
if public_send("current_#{Devise::default_scope}").nil?
|
7
|
+
public_send(:redirect_to, %I[new #{Devise::default_scope} session]) and return
|
8
|
+
end
|
9
|
+
raise PhoneFieldNotFound unless public_send("current_#{Devise::default_scope}").respond_to?(Devise::phone_field)
|
10
|
+
raise PhoneFieldEmpty unless public_send("current_#{Devise::default_scope}").public_send(Devise::phone_field)
|
11
11
|
raise ValidSendSmsMethodNotFound unless InternalHelpers::valid_method?(Devise::sms_provider, :send_sms)
|
12
12
|
rescue DeviseSmsVerifiableError, ArgumentError
|
13
13
|
raise "DeviseSmsVerifiableError module error: #{$!.message} "
|
14
14
|
end
|
15
15
|
|
16
|
+
def require_sms_verifiable!
|
17
|
+
sms_check_settings!
|
18
|
+
unless public_send(:"current_#{Devise::default_scope}").public_send("#{Devise::phone_confirmation_field}?")
|
19
|
+
redirect_to %I[new #{Devise::default_scope} sms] and return
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
16
25
|
def self.valid_method?(caller, method)
|
17
26
|
method.kind_of?(Symbol) && caller.respond_to?(method)
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
21
30
|
end
|
31
|
+
ActionController::Base.send :include, DeviseSmsVerifiable::Controllers::InternalHelpers
|
22
32
|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
class DeviseSmsVerifiableError < RuntimeError;end
|
2
|
-
class UnauthorizedAccess < DeviseSmsVerifiableError;end
|
3
2
|
class ConfirmationMethodNotFound < DeviseSmsVerifiableError;end
|
4
|
-
class SecretMethodNotFound < DeviseSmsVerifiableError;end
|
5
3
|
class PhoneFieldNotFound < DeviseSmsVerifiableError;end
|
6
4
|
class PhoneFieldEmpty < DeviseSmsVerifiableError;end
|
7
5
|
class ValidSendSmsMethodNotFound < DeviseSmsVerifiableError;end
|
@@ -5,8 +5,39 @@ module Devise
|
|
5
5
|
mattr_accessor :sms_secret
|
6
6
|
@@sms_secret = nil
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def sms_confirmed?
|
9
|
+
public_send("#{Devise::phone_confirmation_field}?")
|
10
|
+
end
|
11
|
+
|
12
|
+
def sms_unconfirm!
|
13
|
+
unconfirm_hash = Hash[Devise::sms_answer_field, nil,
|
14
|
+
Devise::phone_confirmation_field, false,
|
15
|
+
Devise::sms_token_sent_at, nil,
|
16
|
+
Devise::sms_token_confirmed_at, nil]
|
17
|
+
public_send(:update, unconfirm_hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
def sms_confirm!
|
21
|
+
token = generate_token!
|
22
|
+
public_send(:update, Hash[Devise::sms_answer_field, token,
|
23
|
+
:sms_token_sent_at, DateTime.now])
|
24
|
+
token
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid_token?(incoming_token)
|
28
|
+
@@sms_secret == incoming_token.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def generate_token!
|
34
|
+
meth = Devise::token_generator
|
35
|
+
token = if meth.is_a? Symbol
|
36
|
+
rand(2000..4000)
|
37
|
+
elsif meth.is_a? Proc
|
38
|
+
meth.call
|
39
|
+
end
|
40
|
+
token
|
10
41
|
end
|
11
42
|
end
|
12
43
|
end
|
@@ -17,10 +17,6 @@ module DeviseSmsVerifiable
|
|
17
17
|
# ==> Configuration for :sms_verifiable
|
18
18
|
# Field in model for confirm phone(must be boolean)
|
19
19
|
#config.phone_confirmation_field = :phone_confirm
|
20
|
-
# Method for check sms confirmation. Define in ApplicationController
|
21
|
-
#config.sms_confirmation_method = :sms_confirmation?
|
22
|
-
# Method generate secret and write to model. Define in ApplicationController
|
23
|
-
#config.sms_secret_method = :sms_secret
|
24
20
|
# Attribut on model return rigth answer
|
25
21
|
#config.sms_answer_field = :sms_answer
|
26
22
|
# Field in model which phone number
|
@@ -29,6 +25,9 @@ module DeviseSmsVerifiable
|
|
29
25
|
#config.phone_confirmation_field = :phone_confirm
|
30
26
|
# Path after successful confirmation
|
31
27
|
#config.successful_path = '/'
|
28
|
+
# Token generator method(default 4 digit)
|
29
|
+
# must return valid token
|
30
|
+
#config.token_generator = -> { rand(1000..2000) }
|
32
31
|
# SMS provider module(have default for STREAM-TELECOM)
|
33
32
|
#config.sms_provider = DeviseSmsVerifiable::Provider
|
34
33
|
# Send sms silent for test
|
@@ -6,19 +6,20 @@ module DeviseSmsVerifiable
|
|
6
6
|
def add_migrations
|
7
7
|
table_name = Devise::default_scope.to_s.pluralize
|
8
8
|
exist_migration = Dir.glob('db/migrate/*_devise_sms_verifiable_add_to_*')
|
9
|
-
exist_migration.any?
|
10
|
-
|
9
|
+
if exist_migration.any? && self.behavior == :invoke
|
10
|
+
p("Check db/migrate, look like have sms verifiable migration")
|
11
|
+
end
|
12
|
+
if exist_migration.blank? && self.behavior != :revoke
|
11
13
|
migration_path = "db/migrate/#{Time.now.strftime("%Y%m%d%H%M%S")}_devise_sms_verifiable_add_to_#{table_name}.rb"
|
12
14
|
migration_template = <<-RUBY
|
13
15
|
class DeviseSmsVerifiableAddTo#{table_name.camelize} < ActiveRecord::Migration
|
14
16
|
def self.up
|
15
17
|
change_table :#{table_name} do |t|
|
16
|
-
# Field in the model which phone number
|
17
18
|
t.string :phone
|
18
|
-
# Field in the model which returns the correct answer
|
19
19
|
t.string :sms_answer
|
20
|
-
# Field in the model which returns phone confirm or no
|
21
20
|
t.boolean :phone_confirm, default: false
|
21
|
+
t.datetime :sms_token_sent_at
|
22
|
+
t.datetime :sms_token_confirmed_at
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -26,10 +27,14 @@ class DeviseSmsVerifiableAddTo#{table_name.camelize} < ActiveRecord::Migration
|
|
26
27
|
remove_column :#{table_name}, :phone
|
27
28
|
remove_column :#{table_name}, :sms_answer
|
28
29
|
remove_column :#{table_name}, :phone_confirm
|
30
|
+
remove_column :#{table_name}, :sms_token_sent_at
|
31
|
+
remove_column :#{table_name}, :sms_token_confirmed_at
|
29
32
|
end
|
30
33
|
end
|
31
34
|
RUBY
|
32
35
|
create_file(migration_path, migration_template)
|
36
|
+
elsif self.behavior == :revoke
|
37
|
+
FileUtils.rm_rf *exist_migration if exist_migration.any?
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
@@ -5,12 +5,6 @@ Some setup you must do manually if you haven't yet(in config/initializers/devise
|
|
5
5
|
You need field in model for confirm phone(must be boolean).
|
6
6
|
config.phone_confirmation_field = :phone_confirm
|
7
7
|
|
8
|
-
You need define method for check sms confirmation. (in ApplicationController)
|
9
|
-
config.sms_confirmation_method = :sms_confirmation?
|
10
|
-
|
11
|
-
Need a method that generates, writes the word model, returns the secret word. (in ApplicationController)
|
12
|
-
config.sms_secret_method = :sms_secret
|
13
|
-
|
14
8
|
Field in the model which returns the correct answer
|
15
9
|
config.sms_answer_field = :sms_answer
|
16
10
|
|
metadata
CHANGED
@@ -1,139 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_sms_verifiable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kiselenko Roman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4
|
19
|
+
version: '4'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4
|
26
|
+
version: '4'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: devise
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3
|
33
|
+
version: '3'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3
|
40
|
+
version: '3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rest_client
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec-rails
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: capybara
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: factory_girl_rails
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: ffaker
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: pry
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
80
|
+
- - '>='
|
123
81
|
- !ruby/object:Gem::Version
|
124
82
|
version: '0'
|
125
83
|
- !ruby/object:Gem::Dependency
|
126
84
|
name: sqlite3
|
127
85
|
requirement: !ruby/object:Gem::Requirement
|
128
86
|
requirements:
|
129
|
-
- -
|
87
|
+
- - '>='
|
130
88
|
- !ruby/object:Gem::Version
|
131
89
|
version: '0'
|
132
90
|
type: :development
|
133
91
|
prerelease: false
|
134
92
|
version_requirements: !ruby/object:Gem::Requirement
|
135
93
|
requirements:
|
136
|
-
- -
|
94
|
+
- - '>='
|
137
95
|
- !ruby/object:Gem::Version
|
138
96
|
version: '0'
|
139
97
|
description: |2
|
@@ -148,6 +106,8 @@ files:
|
|
148
106
|
- Rakefile
|
149
107
|
- app/controllers/devise/sms_verifiable_controller.rb
|
150
108
|
- app/views/devise/sms_verifiable/new.html.erb
|
109
|
+
- config/locales/en.yml
|
110
|
+
- config/locales/ru.yml
|
151
111
|
- lib/devise_sms_verifiable.rb
|
152
112
|
- lib/devise_sms_verifiable/controllers/internal_helpers.rb
|
153
113
|
- lib/devise_sms_verifiable/controllers/url_helpers.rb
|
@@ -163,7 +123,8 @@ files:
|
|
163
123
|
- lib/generators/devise_sms_verifiable/templates/README
|
164
124
|
- lib/generators/devise_sms_verifiable/views_generator.rb
|
165
125
|
homepage: https://github.com/fishbullet/devise_sms_verifiable
|
166
|
-
licenses:
|
126
|
+
licenses:
|
127
|
+
- MIT
|
167
128
|
metadata: {}
|
168
129
|
post_install_message:
|
169
130
|
rdoc_options: []
|
@@ -171,17 +132,17 @@ require_paths:
|
|
171
132
|
- lib
|
172
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
173
134
|
requirements:
|
174
|
-
- -
|
135
|
+
- - '>='
|
175
136
|
- !ruby/object:Gem::Version
|
176
137
|
version: '0'
|
177
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
139
|
requirements:
|
179
|
-
- -
|
140
|
+
- - '>='
|
180
141
|
- !ruby/object:Gem::Version
|
181
142
|
version: '0'
|
182
143
|
requirements: []
|
183
144
|
rubyforge_project:
|
184
|
-
rubygems_version: 2.
|
145
|
+
rubygems_version: 2.4.3
|
185
146
|
signing_key:
|
186
147
|
specification_version: 4
|
187
148
|
summary: DeviseSmsVerifiable it is simple fork devise_sms_activable for my project`s
|