shieldify 0.1.2.pre.alpha → 0.2.9.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6517cc618765bddd3e12fae12071e15d5c1fce7caba98f48468b8997d7269d72
4
- data.tar.gz: b62d7d9fd12ffbaa0dd40261925e537bbfe88dbcaafa40f54b2fb666b44c400d
3
+ metadata.gz: 8007ae4f6ae3303eea8c4c4e235e5f44e6ab2fee48462cbee91a298401bcb218
4
+ data.tar.gz: 65351705a326f96589ab63b68a09c1b253e6a2a7460960aa3fa7b3a6ee54c367
5
5
  SHA512:
6
- metadata.gz: cde0954c079bd2fa807002523e8f0b9d6fa929efef4c8c2154fb737625fa6c8e9a54041426718172e663f46cc664eb158f42fd3b2e783acdf3a7f375a7ec9394
7
- data.tar.gz: 05e5de36f1b7344fbdd56610ad32b0169be7e9e57c4cbea03b32483a7f7972a220d7915fa024dbb1f298b4eac00204852df081a4f456cc7ccfd6bc45f2ccf4ac
6
+ metadata.gz: 4227ce3246d89c0e59c6aa4d788d026ca529a1d64811da6a0185f2af48a8144b7f4547c325136e05224a09705617cba8016d89692b877e228337f3851d7165d8
7
+ data.tar.gz: 9980cb0d979723be2cc09199e08e093ab1983bdaef237cf04bda874f3d3a239aa9954e9564d79c08009c962ea27472bf2a58fbc5cb5eed0124879a0375d0a972
@@ -1,16 +1,7 @@
1
1
  module Users
2
- class AccessController < ActionController::Base
3
- # GET /users/access/:token/unlock
2
+ class AccessController < ActionController::API
4
3
  def show
5
- user = User.find_by(unlock_token: params[:token])
6
-
7
- if user.present? && user.unlock_access
8
- # Asume que `unlock_access` es un método en tu modelo User que realiza la lógica necesaria
9
- # para desbloquear el acceso del usuario y limpiar el token de desbloqueo.
10
- render json: { message: 'Tu cuenta ha sido desbloqueada exitosamente. Ahora puedes iniciar sesión.' }, status: :ok
11
- else
12
- render json: { error: 'El token proporcionado no es válido o ya ha sido utilizado.' }, status: :not_found
13
- end
4
+ # pending
14
5
  end
15
6
  end
16
7
  end
@@ -1,30 +1,33 @@
1
1
  module Users
2
2
  module Emails
3
- class ResetPasswordsController < ActionController::Base
4
- # POST /users/email/reset_password
3
+ class ResetPasswordsController < ActionController::API
4
+ # Action to request a password reset
5
5
  def create
6
6
  user = User.find_by(email: params[:email])
7
+ message = I18n.t("shieldify.controllers.emails.reset_passwords.create.success")
7
8
 
8
- if user.present?
9
- # Aquí se asume la existencia de un método que genera un token de restablecimiento
10
- # de contraseña y envía un correo electrónico al usuario con instrucciones.
11
- user.send_reset_email_password_instructions
12
- render json: { message: 'Se ha enviado un correo con instrucciones para restablecer tu contraseña.' }, status: :ok
13
- else
14
- render json: { error: 'No se encontró un usuario con ese correo electrónico.' }, status: :not_found
15
- end
9
+ user.send_reset_email_password_instructions if user
10
+
11
+ render json: { message: message }, status: :ok
16
12
  end
17
13
 
18
- # PUT /users/email/:token/reset_password
14
+ # Action to update the password
19
15
  def update
20
- user = User.find_by(reset_email_password_token: params[:token])
21
-
22
- if user.present? && user.reset_password(params[:password], params[:password_confirmation])
23
- render json: { message: 'Tu contraseña ha sido restablecida exitosamente.' }, status: :ok
16
+ user = User.find_by_reset_email_password_token(params[:token])
17
+
18
+ if user
19
+ if user.reset_password(new_password: params[:password], new_password_confirmation: params[:password_confirmation])
20
+ message = I18n.t("shieldify.controllers.emails.reset_passwords.update.success")
21
+ render json: { message: message }, status: :ok
22
+ else
23
+ render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
24
+ end
24
25
  else
25
- render json: { error: 'El token no es válido o las contraseñas no coinciden.' }, status: :unprocessable_entity
26
+ message = I18n.t("shieldify.controllers.emails.reset_passwords.update.failure")
27
+ render json: { error: message }, status: :unprocessable_entity
26
28
  end
27
29
  end
28
30
  end
29
31
  end
30
- end
32
+ end
33
+
@@ -1,17 +1,23 @@
1
1
  module Users
2
- class EmailsController < ActionController::Base
2
+ class EmailsController < ActionController::API
3
+ # Action to confirm an email
3
4
  def show
4
5
  token = params[:token]
5
6
  user = User.confirm_email_by_token(token)
6
7
 
7
- if user.errors.blank?
8
- render(
9
- json: { message: I18n.t("shieldify.controllers.emails.confirmation.success_messages") },
10
- status: :ok
11
- )
12
- else
13
- render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
14
- end
8
+ message = user.errors.blank? ? I18n.t("shieldify.controllers.emails.confirmation.success_messages") : user.errors.full_messages.last
9
+ status = user.errors.blank? ? 'success' : 'error'
10
+
11
+ set_cookie('shfy_message', message)
12
+ set_cookie('shfy_status', status)
13
+
14
+ redirect_to(Shieldify::Configuration.before_confirmation_url, allow_other_host: true)
15
+ end
16
+
17
+ private
18
+
19
+ def set_cookie(name, value)
20
+ response.set_cookie(name, { value: value, expires: 1.hour.from_now, path: '/' })
15
21
  end
16
22
  end
17
- end
23
+ end
@@ -30,13 +30,14 @@ module Shieldify
30
30
 
31
31
  def copy_locale_file
32
32
  template "locales/en.shieldify.yml", File.join("config", "locales", "en.shieldify.yml")
33
+ template "locales/es.shieldify.yml", File.join("config", "locales", "es.shieldify.yml")
33
34
  end
34
35
 
35
36
  private
36
37
 
37
38
  def model_contents
38
39
  <<-CONTENT
39
- shieldify email_authenticatable: %i[registerable confirmable]
40
+ shieldify email_authenticatable: %i[registerable confirmable password_recoverable]
40
41
  CONTENT
41
42
  end
42
43
 
@@ -1,4 +1,19 @@
1
1
  Shieldify.setup do |conf|
2
+
3
+ ## Reset Email Password
4
+
5
+ # This configuration defines the URL of the frontend form where users will be redirected to reset their password.
6
+ # When a user requests a password reset, the backend will generate a token and include this URL in the email sent to the user.
7
+ # The URL should point to the password reset form on the frontend application, and it will include the reset token as a query parameter.
8
+ # conf.reset_password_form_url = "http://localhost:3000/reset-password"
9
+
10
+ ## Email Confirmation
11
+
12
+ # This configuration defines the URL to redirect users to after they have confirmed their email address.
13
+ # This URL is used for redirection following a successful email confirmation.
14
+ # It can be set to any page in your frontend application where users should land after their email has been confirmed.
15
+ # conf.before_confirmation_url = "http://localhost:3000/login"
16
+
2
17
  ## Mailer
3
18
 
4
19
  # The parent mailer for internal mailers.
@@ -1,26 +1,33 @@
1
1
  en:
2
+ activerecord:
3
+ attributes:
4
+ user:
5
+ email: "Email"
6
+ unconfirmed_email: "Unconfirmed Email"
7
+ password: "Password"
8
+ email_confirmation_token: "Email Confirmation Token"
9
+ email_confirmation_token_generated_at: "Email Confirmation Token Generated At"
10
+ reset_email_password_token: "Reset Email Password Token"
11
+ reset_email_password_token_generated_at: "Reset Email Password Token Generated At"
12
+ errors:
13
+ messages:
14
+ invalid: "is not valid"
15
+ invalid_or_expired: "is invalid or has expired"
16
+ password_not_match: "doesn't match Password"
17
+ password_complexity: "It must include at least one uppercase letter, one lowercase letter, one number, and one special character (@$!%*?&)"
18
+ expired: "has expired"
19
+ not_found: "not found"
2
20
  shieldify:
3
21
  controllers:
4
22
  emails:
5
23
  confirmation:
6
24
  success_messages: "Email successfully confirmed"
7
- models:
8
- email_authenticatable:
9
- registerable:
10
- password:
11
- errors:
12
- invalid: "invalid"
13
- password_complexity:
14
- format: It must include at least one uppercase letter, one lowercase letter, one number, and one special character (@$!%*?&)
15
- confirmable:
16
- email_confirmation_token:
17
- errors:
18
- invalid: "invalid"
19
- expired: "has expired"
20
- unconfirmed_email:
21
- errors:
22
- not_found: "not found"
23
- email_confirmation_token_generated_at:
25
+ reset_passwords:
26
+ create:
27
+ success: "If the email exists, the reset password instructions will be sent to your email."
28
+ update:
29
+ success: "Password has been reset successfully."
30
+ failure: "Password reset failed. Please try again."
24
31
  mailer:
25
32
  email_confirmation_instructions:
26
33
  subject: "Email Confirmation Instructions"
@@ -29,7 +36,7 @@ en:
29
36
  thanks: "Please confirm your email by clicking on the following link:"
30
37
  confirm_account: "Confirm email"
31
38
  ignore: "If you did not request this confirmation, please ignore this email."
32
- reset_password_instructions:
39
+ reset_email_password_instructions:
33
40
  subject: "Password Reset Instructions"
34
41
  title: "Password Reset Instructions"
35
42
  greeting: "Hello %{email},"
@@ -1,16 +1,34 @@
1
1
  es:
2
+ activerecord:
3
+ attributes:
4
+ user:
5
+ email: "Correo electrónico"
6
+ unconfirmed_email: "Correo electrónico no confirmado"
7
+ password: "Contraseña"
8
+ current_password: "Contraseña actual"
9
+ email_confirmation_token: "Token de confirmación del correo electrónico"
10
+ email_confirmation_token_generated_at: "Token de confirmación del correo electrónico generado en"
11
+ reset_email_password_token: "Token de restablecimiento de contraseña del correo electrónico"
12
+ reset_email_password_token_generated_at: "Token de restablecimiento de contraseña del correo electrónico generado en"
13
+ errors:
14
+ messages:
15
+ invalid: "no es válido"
16
+ invalid_or_expired: "no es válido o ha expirado"
17
+ password_not_match: "no coincide con la contraseña"
18
+ password_complexity: "Debe incluir al menos una letra mayúscula, una letra minúscula, un número y un carácter especial (@$!%*?&)"
19
+ expired: "ha expirado"
20
+ not_found: "no encontrado"
2
21
  shieldify:
3
- models:
4
- email_authenticatable:
5
- confirmable:
6
- email_confirmation_token:
7
- errors:
8
- invalid: "inválido"
9
- expired: "ha expirado"
10
- unconfirmed_email:
11
- errors:
12
- not_found: "no encontrado"
13
- email_confirmation_token_generated_at:
22
+ controllers:
23
+ emails:
24
+ confirmation:
25
+ success_messages: "Correo electrónico confirmado con éxito"
26
+ reset_passwords:
27
+ create:
28
+ success: "Si el correo electrónico existe, se enviarán las instrucciones para restablecer la contraseña."
29
+ update:
30
+ success: "La contraseña se ha restablecido con éxito."
31
+ failure: "El restablecimiento de la contraseña falló. Por favor, inténtalo de nuevo."
14
32
  mailer:
15
33
  email_confirmation_instructions:
16
34
  subject: "Instrucciones de Confirmación de Email"
@@ -19,7 +37,7 @@ es:
19
37
  thanks: "Por favor confirma tu email haciendo clic en el siguiente enlace:"
20
38
  confirm_account: "Confirmar email"
21
39
  ignore: "Si no has solicitado esta confirmación, por favor ignora este correo."
22
- reset_password_instructions:
40
+ reset_email_password_instructions:
23
41
  subject: "Instrucciones para Restablecer Contraseña"
24
42
  title: "Instrucciones para Restablecer Contraseña"
25
43
  greeting: "Hola %{email},"
@@ -1,7 +1,6 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= t('shieldify.mailer.confirmation_instructions.title') %></title>
5
4
  <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
6
5
  </head>
7
6
  <body>
@@ -1,3 +1 @@
1
- <%= t('shieldify.mailer.email_changed.title') %>
2
-
3
1
  <%= yield %>
@@ -1,5 +1,5 @@
1
- <h1><%= t('shieldify.mailer.reset_password_instructions.greeting', name: @user.name) %></h1>
2
- <p><%= t('shieldify.mailer.reset_password_instructions.instructions') %></p>
3
- <p><%= link_to t('shieldify.mailer.reset_password_instructions.change_password'), edit_password_url(@user.reset_password_token) %></p>
4
- <p><%= t('shieldify.mailer.reset_password_instructions.link_expiration', expiration_hours: 24) %></p>
5
- <p><%= t('shieldify.mailer.reset_password_instructions.ignore') %></p>
1
+ <h1><%= t('shieldify.mailer.reset_email_password_instructions.greeting', email: @user.email) %></h1>
2
+ <p><%= t('shieldify.mailer.reset_email_password_instructions.instructions') %></p>
3
+ <p><%= link_to t('shieldify.mailer.reset_email_password_instructions.change_password'), @reset_password_form_url %></p>
4
+ <p><%= t('shieldify.mailer.reset_email_password_instructions.link_expiration', expiration_hours: 24) %></p>
5
+ <p><%= t('shieldify.mailer.reset_email_password_instructions.ignore') %></p>
@@ -1,9 +1,9 @@
1
- <%= t('shieldify.mailer.reset_password_instructions.greeting', name: @user.name) %>
1
+ <%= t('shieldify.mailer.reset_email_password_instructions.greeting', email: @user.email) %>
2
2
 
3
- <%= t('shieldify.mailer.reset_password_instructions.instructions') %>
3
+ <%= t('shieldify.mailer.reset_email_password_instructions.instructions') %>
4
4
 
5
- <%= edit_password_url(@user.reset_password_token) %>
5
+ <%= @reset_password_form_url %>
6
6
 
7
- <%= t('shieldify.mailer.reset_password_instructions.link_expiration', expiration_hours: 24) %>
7
+ <%= t('shieldify.mailer.reset_email_password_instructions.link_expiration', expiration_hours: 24) %>
8
8
 
9
- <%= t('shieldify.mailer.reset_password_instructions.ignore') %>
9
+ <%= t('shieldify.mailer.reset_email_password_instructions.ignore') %>
@@ -12,6 +12,10 @@ class ShieldifyCreateUsers < ActiveRecord::Migration<%= migration_version %>
12
12
  t.string :email_confirmation_token
13
13
  t.string :email_confirmation_token_generated_at
14
14
 
15
+ ## Email password recoverable
16
+ t.string :reset_email_password_token
17
+ t.string :reset_email_password_token_generated_at
18
+
15
19
  t.timestamps null: false
16
20
  end
17
21
 
@@ -22,7 +26,7 @@ class ShieldifyCreateUsers < ActiveRecord::Migration<%= migration_version %>
22
26
  t.timestamps
23
27
  end
24
28
 
25
- add_index :users, :email, unique: true
29
+ add_index :users, :email
26
30
  add_index :jwt_sessions, :jti, unique: true
27
31
  end
28
32
  end
@@ -5,8 +5,8 @@ module Shieldify
5
5
  layout 'layouts/shieldify/mailer'
6
6
 
7
7
  default(
8
- from: Shieldify::Configuration.mailer_sender,
9
- reply_to: Shieldify::Configuration.reply_to
8
+ from: -> { Shieldify::Configuration.mailer_sender },
9
+ reply_to: -> { Shieldify::Configuration.reply_to }
10
10
  )
11
11
 
12
12
  def base_mailer
@@ -123,8 +123,7 @@ module Shieldify
123
123
  return add_error_to_empty_user(:email_confirmation_token, :invalid) if user.blank?
124
124
 
125
125
  if user.email_confirmation_token_expired?
126
- msg = I18n.t('shieldify.models.email_authenticatable.confirmable.email_confirmation_token.errors.expired')
127
- user.errors.add(:email_confirmation_token, msg)
126
+ user.errors.add(:email_confirmation_token, :expired)
128
127
 
129
128
  return user
130
129
  end
@@ -144,12 +143,7 @@ module Shieldify
144
143
 
145
144
  def add_error_to_empty_user(param, error)
146
145
  user = new
147
-
148
- user.errors.add(
149
- param.to_sym,
150
- I18n.t("shieldify.models.email_authenticatable.confirmable.#{param.to_sym}.errors.#{error.to_sym}")
151
- )
152
-
146
+ user.errors.add(param, error)
153
147
  user
154
148
  end
155
149
  end
@@ -0,0 +1,76 @@
1
+ module Shieldify
2
+ module Models
3
+ module EmailAuthenticatable
4
+ module PasswordRecoverable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_save :clear_reset_email_password_token, if: -> { password_digest_changed? }
9
+ end
10
+
11
+ class_methods do
12
+ def find_by_reset_email_password_token(token)
13
+ return nil if token.nil?
14
+
15
+ find_by(reset_email_password_token: token)
16
+ end
17
+ end
18
+
19
+ def generate_reset_email_password_token
20
+ self.reset_email_password_token = SecureRandom.hex(10)
21
+ self.reset_email_password_token_generated_at = Time.current
22
+ save
23
+ end
24
+
25
+ def send_reset_email_password_instructions
26
+ generate_reset_email_password_token
27
+
28
+ params = {
29
+ user: self,
30
+ email_to: email,
31
+ reset_password_form_url: reset_password_form_url(reset_email_password_token),
32
+ action: :reset_email_password_instructions
33
+ }
34
+
35
+ Shieldify::Mailer.with(params).base_mailer.deliver_now
36
+ end
37
+
38
+ def reset_password(new_password:, new_password_confirmation:)
39
+ if reset_email_password_token_valid?
40
+ if new_password == new_password_confirmation
41
+ self.password = new_password
42
+ clear_reset_email_password_token
43
+ save
44
+ else
45
+ errors.add(:password_confirmation, :password_not_match)
46
+ false
47
+ end
48
+ else
49
+ errors.add(:reset_email_password_token, :invalid_or_expired)
50
+ false
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def clear_reset_email_password_token
57
+ self.reset_email_password_token = nil
58
+ self.reset_email_password_token_generated_at = nil
59
+ end
60
+
61
+ def reset_email_password_token_valid?
62
+ reset_email_password_token_generated_at && reset_email_password_token_generated_at >= 2.hours.ago
63
+ end
64
+
65
+ def reset_password_form_url(token = nil)
66
+ if token.present?
67
+ Shieldify::Configuration.reset_password_form_url + "?token=#{token}"
68
+ else
69
+ Shieldify::Configuration.reset_password_form_url
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+
@@ -55,13 +55,10 @@ module Shieldify
55
55
  def update_password(current_password:, new_password:, password_confirmation:)
56
56
  if authenticate(current_password)
57
57
  if update(password: new_password, password_confirmation: password_confirmation)
58
- send_password_changed_notification if Shieldify::Configuration.send_password_changed_notification
58
+ send_password_changed_notification if should_send_password_changed_notification?
59
59
  end
60
60
  else
61
- errors.add(
62
- :current_password,
63
- I18n.t("shieldify.models.email_authenticatable.registerable.password.errors.invalid")
64
- )
61
+ errors.add(:password, :invalid)
65
62
  end
66
63
 
67
64
  self
@@ -75,12 +72,10 @@ module Shieldify
75
72
  def update_email(current_password:, new_email:)
76
73
  if authenticate(current_password)
77
74
  if update(email: new_email)
78
- send_email_changed_notification if Shieldify::Configuration.send_email_changed_notification
75
+ send_email_changed_notification if should_send_email_changed_notification?
79
76
  end
80
77
  else
81
- errors.add(
82
- :password,
83
- I18n.t("shieldify.models.email_authenticatable.registerable.password.errors.invalid"))
78
+ errors.add(:password, :invalid)
84
79
  end
85
80
 
86
81
  self
@@ -105,12 +100,17 @@ module Shieldify
105
100
  regex = Shieldify::Configuration.password_complexity
106
101
 
107
102
  unless password.match?(regex)
108
- errors.add(
109
- :password,
110
- I18n.t("shieldify.models.email_authenticatable.registerable.password_complexity.format")
111
- )
103
+ errors.add(:password, :password_complexity)
112
104
  end
113
105
  end
106
+
107
+ def should_send_password_changed_notification?
108
+ Shieldify::Configuration.send_password_changed_notification
109
+ end
110
+
111
+ def should_send_email_changed_notification?
112
+ Shieldify::Configuration.send_email_changed_notification
113
+ end
114
114
  end
115
115
  end
116
116
  end
@@ -3,9 +3,8 @@ module Shieldify
3
3
  initializer 'shieldify.add_routes' do |app|
4
4
  app.routes.prepend do
5
5
  get 'shfy/users/email/:token/confirm', to: 'users/emails#show', as: :users_email_confirmation
6
- # post 'shfy/users/email/reset_password', to: 'users/emails/reset_passwords#create'
7
- # put 'shfy/users/email/:token/reset_password', to: 'users/emails/reset_passwords#update'
8
- # get 'shfy/users/access/:token/unlock', to: 'users/access#show'
6
+ post 'shfy/users/email/request_password_recovery', to: 'users/emails/reset_passwords#create', as: :users_request_password_recovery
7
+ put 'shfy/users/email/reset_password', to: 'users/emails/reset_passwords#update', as: :users_reset_password
9
8
  end
10
9
  end
11
10
 
@@ -29,6 +28,7 @@ module Shieldify
29
28
  initializer 'shieldify.require' do
30
29
  require_relative '../../app/models/jwt_session'
31
30
  require_relative '../../app/controllers/users/emails_controller'
31
+ require_relative '../../app/controllers/users/emails/reset_passwords_controller'
32
32
  end
33
33
 
34
34
  initializer 'shieldify.active_record' do
@@ -1,3 +1,3 @@
1
1
  module Shieldify
2
- VERSION = "0.1.2-alpha"
2
+ VERSION = "0.2.9-alpha"
3
3
  end
data/lib/shieldify.rb CHANGED
@@ -13,6 +13,18 @@ module Shieldify
13
13
  class Configuration
14
14
  include Singleton
15
15
 
16
+ # This configuration defines the URL of the frontend form where users will be redirected to reset their password.
17
+ # When a user requests a password reset, the backend will generate a token and include this URL in the email sent to the user.
18
+ # The URL should point to the password reset form on the frontend application, and it will include the reset token as a query parameter.
19
+ mattr_accessor :reset_password_form_url
20
+ @@reset_password_form_url = "http://localhost:3000/reset-password"
21
+
22
+ # This configuration defines the URL to redirect users to after they have confirmed their email address.
23
+ # This URL is used for redirection following a successful email confirmation.
24
+ # It can be set to any page in your frontend application where users should land after their email has been confirmed.
25
+ mattr_accessor :before_confirmation_url
26
+ @@before_confirmation_url = "http://localhost:3000/login"
27
+
16
28
  # Default mailer sender.
17
29
  mattr_accessor :mailer_sender
18
30
  @@mailer_sender = "shieldify@example.com"
@@ -70,5 +82,6 @@ end
70
82
  require "shieldify/models/email_authenticatable"
71
83
  require "shieldify/models/email_authenticatable/registerable"
72
84
  require "shieldify/models/email_authenticatable/confirmable"
85
+ require "shieldify/models/email_authenticatable/password_recoverable"
73
86
  require "shieldify/jwt_service"
74
87
  require "shieldify/mailer"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shieldify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.pre.alpha
4
+ version: 0.2.9.pre.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Armando Alejandre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-07 00:00:00.000000000 Z
11
+ date: 2024-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -127,6 +127,7 @@ files:
127
127
  - lib/shieldify/model_extensions.rb
128
128
  - lib/shieldify/models/email_authenticatable.rb
129
129
  - lib/shieldify/models/email_authenticatable/confirmable.rb
130
+ - lib/shieldify/models/email_authenticatable/password_recoverable.rb
130
131
  - lib/shieldify/models/email_authenticatable/registerable.rb
131
132
  - lib/shieldify/railtie.rb
132
133
  - lib/shieldify/strategies/email.rb