Module: DeviseTokenAuth::Concerns::User

Extended by:
ActiveSupport::Concern
Defined in:
app/models/devise_token_auth/concerns/user.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.tokens_match?(token_hash, token) ⇒ Boolean

Returns:

  • (Boolean)


6
7
8
9
10
11
12
13
# File 'app/models/devise_token_auth/concerns/user.rb', line 6

def self.tokens_match?(token_hash, token)
  @token_equality_cache ||= {}

  key = "#{token_hash}/#{token}"
  result = @token_equality_cache[key] ||= DeviseTokenAuth::TokenFactory.token_hash_is_token?(token_hash, token)
  @token_equality_cache = {} if @token_equality_cache.size > 10000
  result
end

Instance Method Details

#build_auth_headers(token, client = 'default') ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'app/models/devise_token_auth/concerns/user.rb', line 182

def build_auth_headers(token, client = 'default')
  # client may use expiry to prevent validation request if expired
  # must be cast as string or headers will break
  expiry = tokens[client]['expiry'] || tokens[client][:expiry]
  headers = {
    DeviseTokenAuth.headers_names[:"access-token"] => token,
    DeviseTokenAuth.headers_names[:"token-type"]   => 'Bearer',
    DeviseTokenAuth.headers_names[:"client"]       => client,
    DeviseTokenAuth.headers_names[:"expiry"]       => expiry.to_s,
    DeviseTokenAuth.headers_names[:"uid"]          => uid
  }
  headers.merge(build_bearer_token(headers))
end

#build_auth_url(base_url, args) ⇒ Object



212
213
214
215
216
217
# File 'app/models/devise_token_auth/concerns/user.rb', line 212

def build_auth_url(base_url, args)
  args[:uid]    = uid
  args[:expiry] = tokens[args[:client_id]]['expiry']

  DeviseTokenAuth::Url.generate(base_url, args)
end

#build_bearer_token(auth) ⇒ Object



196
197
198
199
200
201
202
# File 'app/models/devise_token_auth/concerns/user.rb', line 196

def build_bearer_token(auth)
  return {} if DeviseTokenAuth.cookie_enabled # There is no need for the bearer token if it is using cookies

  encoded_token = Base64.strict_encode64(auth.to_json)
  bearer_token = "Bearer #{encoded_token}"
  { DeviseTokenAuth.headers_names[:"authorization"] => bearer_token }
end

#confirmed?Boolean

Returns:

  • (Boolean)


224
225
226
# File 'app/models/devise_token_auth/concerns/user.rb', line 224

def confirmed?
  devise_modules.exclude?(:confirmable) || super
end

#create_new_auth_token(client = nil) ⇒ Object

update user’s auth token (should happen on each request)



169
170
171
172
173
174
175
176
177
178
179
180
# File 'app/models/devise_token_auth/concerns/user.rb', line 169

def create_new_auth_token(client = nil)
  now = Time.zone.now

  token = create_token(
    client: client,
    previous_token: tokens.fetch(client, {})['token'],
    last_token: tokens.fetch(client, {})['previous_token'],
    updated_at: now
  )

  update_auth_headers(token.token, token.client)
end

#does_token_match?(token_hash, token) ⇒ Boolean

check if the hash of received token matches the stored token

Returns:

  • (Boolean)


144
145
146
147
148
# File 'app/models/devise_token_auth/concerns/user.rb', line 144

def does_token_match?(token_hash, token)
  return false if token_hash.nil?

  DeviseTokenAuth::Concerns::User.tokens_match?(token_hash, token)
end

#extend_batch_buffer(token, client) ⇒ Object



219
220
221
222
# File 'app/models/devise_token_auth/concerns/user.rb', line 219

def extend_batch_buffer(token, client)
  tokens[client]['updated_at'] = Time.zone.now
  update_auth_headers(token, client)
end

#send_confirmation_notification?Boolean

this must be done from the controller so that additional params can be passed on from the client

Returns:

  • (Boolean)


117
# File 'app/models/devise_token_auth/concerns/user.rb', line 117

def send_confirmation_notification?; false; end

#token_can_be_reused?(token, client) ⇒ Boolean

allow batch requests to use the last token

Returns:

  • (Boolean)


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'app/models/devise_token_auth/concerns/user.rb', line 151

def token_can_be_reused?(token, client)
  # ghetto HashWithIndifferentAccess
  updated_at = tokens[client]['updated_at'] || tokens[client][:updated_at]
  last_token_hash = tokens[client]['last_token'] || tokens[client][:last_token]

  return true if (
    # ensure that the last token and its creation time exist
    updated_at && last_token_hash &&

    # ensure that last token falls within the batch buffer throttle time of the last request
    updated_at.to_time > Time.zone.now - DeviseTokenAuth.batch_request_buffer_throttle &&

    # ensure that the token is valid
    DeviseTokenAuth::TokenFactory.token_hash_is_token?(last_token_hash, token)
  )
end

#token_is_current?(token, client) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'app/models/devise_token_auth/concerns/user.rb', line 119

def token_is_current?(token, client)
  # ghetto HashWithIndifferentAccess
  expiry     = tokens[client]['expiry'] || tokens[client][:expiry]
  token_hash = tokens[client]['token'] || tokens[client][:token]
  previous_token_hash = tokens[client]['previous_token'] || tokens[client][:previous_token]

  return true if (
    # ensure that expiry and token are set
    expiry && token &&

    # ensure that the token has not yet expired
    DateTime.strptime(expiry.to_s, '%s') > Time.zone.now &&

    # ensure that the token is valid
    (
      # check if the latest token matches
      does_token_match?(token_hash, token) ||

      # check if the previous token matches
      does_token_match?(previous_token_hash, token)
    )
  )
end

#token_validation_responseObject



228
229
230
# File 'app/models/devise_token_auth/concerns/user.rb', line 228

def token_validation_response
  as_json(except: %i[tokens created_at updated_at])
end

#update_auth_headers(token, client = 'default') ⇒ Object



204
205
206
207
208
209
210
# File 'app/models/devise_token_auth/concerns/user.rb', line 204

def update_auth_headers(token, client = 'default')
  headers = build_auth_headers(token, client)
  clean_old_tokens
  save!

  headers
end

#valid_token?(token, client = 'default') ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
# File 'app/models/devise_token_auth/concerns/user.rb', line 106

def valid_token?(token, client = 'default')
  return false unless tokens[client]
  return true if token_is_current?(token, client)
  return true if token_can_be_reused?(token, client)

  # return false if none of the above conditions are met
  false
end