Class: DeviseTokenAuth::PasswordsController

Inherits:
ApplicationController show all
Defined in:
app/controllers/devise_token_auth/passwords_controller.rb

Instance Method Summary collapse

Methods inherited from ApplicationController

#resource_class

Instance Method Details

#createObject

this action is responsible for generating password reset tokens and sending emails



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/controllers/devise_token_auth/passwords_controller.rb', line 8

def create
  unless resource_params[:email]
    return render json: {
      success: false,
      errors: [I18n.t("devise_token_auth.passwords.missing_email")]
    }, status: 401
  end

  # give redirect value from params priority
  redirect_url = params[:redirect_url]

  # fall back to default value if provided
  redirect_url ||= DeviseTokenAuth.default_password_reset_url

  unless redirect_url
    return render json: {
      success: false,
      errors: [I18n.t("devise_token_auth.passwords.missing_redirect_url")]
    }, status: 401
  end

  # if whitelist is set, validate redirect_url against whitelist
  if DeviseTokenAuth.redirect_whitelist
    unless DeviseTokenAuth.redirect_whitelist.include?(redirect_url)
      return render json: {
        status: 'error',
        data:   @resource.as_json,
        errors: [I18n.t("devise_token_auth.passwords.not_allowed_redirect_url", redirect_url: redirect_url)]
      }, status: 403
    end
  end

  # honor devise configuration for case_insensitive_keys
  if resource_class.case_insensitive_keys.include?(:email)
    email = resource_params[:email].downcase
  else
    email = resource_params[:email]
  end

  q = "uid = ? AND provider='email'"

  # fix for mysql default case insensitivity
  if ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'
    q = "BINARY uid = ? AND provider='email'"
  end

  @resource = resource_class.where(q, email).first

  errors = nil
  error_status = 400

  if @resource
    yield if block_given?
    @resource.send_reset_password_instructions({
      email: email,
      provider: 'email',
      redirect_url: redirect_url,
      client_config: params[:config_name]
    })

    if @resource.errors.empty?
      render json: {
        success: true,
        message: I18n.t("devise_token_auth.passwords.sended", email: email)
      }
    else
      errors = @resource.errors
    end
  else
    errors = [I18n.t("devise_token_auth.passwords.user_not_found", email: email)]
    error_status = 404
  end

  if errors
    render json: {
      success: false,
      errors: errors,
    }, status: error_status
  end
end

#editObject

this is where users arrive after visiting the password reset confirmation link



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'app/controllers/devise_token_auth/passwords_controller.rb', line 91

def edit
  @resource = resource_class.reset_password_by_token({
    reset_password_token: resource_params[:reset_password_token]
  })

  if @resource and @resource.id
    client_id  = SecureRandom.urlsafe_base64(nil, false)
    token      = SecureRandom.urlsafe_base64(nil, false)
    token_hash = BCrypt::Password.create(token)
    expiry     = (Time.now + DeviseTokenAuth.token_lifespan).to_i

    @resource.tokens[client_id] = {
      token:  token_hash,
      expiry: expiry
    }

    # ensure that user is confirmed
    @resource.skip_confirmation! if @resource.devise_modules.include?(:confirmable) && !@resource.confirmed_at

    @resource.save!
    yield if block_given?

    redirect_to(@resource.build_auth_url(params[:redirect_url], {
      token:          token,
      client_id:      client_id,
      reset_password: true,
      config:         params[:config]
    }))
  else
    render json: {
      success: false
    }, status: 404
  end
end

#password_resource_paramsObject



176
177
178
# File 'app/controllers/devise_token_auth/passwords_controller.rb', line 176

def password_resource_params
  params.permit(devise_parameter_sanitizer.for(:account_update))
end

#resource_paramsObject



180
181
182
# File 'app/controllers/devise_token_auth/passwords_controller.rb', line 180

def resource_params
  params.permit(:email, :password, :password_confirmation, :current_password, :reset_password_token)
end

#resource_update_methodObject



168
169
170
171
172
173
174
# File 'app/controllers/devise_token_auth/passwords_controller.rb', line 168

def resource_update_method
  if DeviseTokenAuth.check_current_password_before_update != false
    "update_with_password"
  else
    "update_attributes"
  end
end

#updateObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'app/controllers/devise_token_auth/passwords_controller.rb', line 126

def update
  # make sure user is authorized
  unless @resource
    return render json: {
      success: false,
      errors: ['Unauthorized']
    }, status: 401
  end

  # make sure account doesn't use oauth2 provider
  unless @resource.provider == 'email'
    return render json: {
      success: false,
      errors: [I18n.t("devise_token_auth.passwords.password_not_required", provider: @resource.provider.humanize)]
    }, status: 422
  end

  # ensure that password params were sent
  unless password_resource_params[:password] and password_resource_params[:password_confirmation]
    return render json: {
      success: false,
      errors: [I18n.t("devise_token_auth.passwords.missing_passwords")]
    }, status: 422
  end

  if @resource.send(resource_update_method, password_resource_params)
    yield if block_given?
    return render json: {
      success: true,
      data: {
        user: @resource,
        message: I18n.t("devise_token_auth.passwords.successfully_updated")
      }
    }
  else
    return render json: {
      success: false,
      errors: @resource.errors.to_hash.merge(full_messages: @resource.errors.full_messages)
    }, status: 422
  end
end