Skip to content

Commit

Permalink
Merge remote-tracking branch 'lynn/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
RavenXce committed Jan 6, 2016
2 parents 23bf409 + d154b02 commit e7a5062
Show file tree
Hide file tree
Showing 34 changed files with 605 additions and 159 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
language: ruby
cache: bundler
sudo: false

rvm:
- 1.9.3
Expand Down
18 changes: 10 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ GIT
PATH
remote: .
specs:
devise_token_auth (0.1.37.beta3)
devise (= 3.5.2)
rails (>= 4.2)
devise_token_auth (0.1.37.beta4)
devise (~> 3.5.2)
rails (< 6)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -86,7 +86,8 @@ GEM
codeclimate-test-reporter (0.4.8)
simplecov (>= 0.7.1, < 1.0.0)
coderay (1.1.0)
devise (3.5.2)
concurrent-ruby (1.0.0)
devise (3.5.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
Expand Down Expand Up @@ -132,7 +133,7 @@ GEM
mime-types (>= 1.16, < 3)
metaclass (0.0.4)
method_source (0.8.2)
mime-types (2.6.2)
mime-types (2.99)
mini_portile (0.6.2)
minitest (5.8.1)
minitest-focus (1.1.2)
Expand Down Expand Up @@ -220,7 +221,8 @@ GEM
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
slop (3.6.0)
sprockets (3.4.0)
sprockets (3.5.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (2.3.3)
actionpack (>= 3.0)
Expand All @@ -231,7 +233,7 @@ GEM
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
warden (1.2.3)
warden (1.2.4)
rack (>= 1.0)

PLATFORMS
Expand Down Expand Up @@ -263,4 +265,4 @@ DEPENDENCIES
thor

BUNDLED WITH
1.10.5
1.10.6
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,11 @@ The following settings are available for configuration in `config/initializers/d
| **`token_lifespan`** | `2.weeks` | Set the length of your tokens' lifespans. Users will need to re-authenticate after this duration of time has passed since their last login. |
| **`batch_request_buffer_throttle`** | `5.seconds` | Sometimes it's necessary to make several requests to the API at the same time. In this case, each request in the batch will need to share the same auth token. This setting determines how far apart the requests can be while still using the same auth token. [Read more](#about-batch-requests). |
| **`omniauth_prefix`** | `"/omniauth"` | This route will be the prefix for all oauth2 redirect callbacks. For example, using the default '/omniauth' setting, the github oauth2 provider will redirect successful authentications to '/omniauth/github/callback'. [Read more](#omniauth-provider-settings). |
| **`default_confirm_success_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful email confirmation. If this param is set, the API will redirect to this value when no value is provided by the cilent. |
| **`default_password_reset_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful password resets. If this param is set, the API will redirect to this value when no value is provided by the cilent. |
| **`default_confirm_success_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful email confirmation. If this param is set, the API will redirect to this value when no value is provided by the client. |
| **`default_password_reset_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful password resets. If this param is set, the API will redirect to this value when no value is provided by the client. |
| **`redirect_whitelist`** | `nil` | As an added security measure, you can limit the URLs to which the API will redirect after email token validation (password reset, email confirmation, etc.). This value should be an array containing exact matches to the client URLs to be visited after validation. |
| **`enable_standard_devise_support`** | `false` | By default, only Bearer Token authentication is implemented out of the box. If, however, you wish to integrate with legacy Devise authentication, you can do so by enabling this flag. NOTE: This feature is highly experimental! |
| **`remove_tokens_after_password_reset`** | `false` | By default, old tokens are not invalidated when password is changed. Enable this option if you want to make passwords updates to logout other devices. |


Additionally, you can configure other aspects of devise by manually creating the traditional devise.rb file at `config/initializers/devise.rb`. Here are some examples of what you can do in this file:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ def redirect_callbacks

# derive target redirect route from 'resource_class' param, which was set
# before authentication.
devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym
redirect_route = "#{request.protocol}#{request.host_with_port}/#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"
devise_mapping = request.env['omniauth.params']['resource_class'].underscore.gsub("/", "_").to_sym
redirect_route = "#{request.protocol}#{request.host_with_port}/#{Devise.mappings[devise_mapping].fullpath}/#{params[:provider]}/callback"

# preserve omniauth info for success route. ignore 'extra' in twitter
# auth response to avoid CookieOverflow.
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/devise_token_auth/passwords_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def edit
config: params[:config]
}))
else
raise ActionController::RoutingError.new('Not Found')
render_edit_error
end
end

Expand Down Expand Up @@ -179,6 +179,10 @@ def render_create_error
}, status: @error_status
end

def render_edit_error
raise ActionController::RoutingError.new('Not Found')
end

def render_update_error_unauthorized
render json: {
success: false,
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/devise_token_auth/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ def resource_update_method
end

def validate_sign_up_params
validate_post_data sign_up_params, I18n.t("errors.validate_sign_up_params")
validate_post_data sign_up_params, I18n.t("errors.messages.validate_sign_up_params")
end

def validate_account_update_params
validate_post_data account_update_params, I18n.t("errors.validate_account_update_params")
validate_post_data account_update_params, I18n.t("errors.messages.validate_account_update_params")
end

def validate_post_data which, message
Expand Down
20 changes: 17 additions & 3 deletions app/models/devise_token_auth/concerns/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ def self.tokens_match?(token_hash, token)
# get rid of dead tokens
before_save :destroy_expired_tokens

# remove old tokens if password has changed
before_save :remove_tokens_after_password_reset

# allows user to change password without current_password
attr_writer :allow_password_change
def allow_password_change
Expand Down Expand Up @@ -178,12 +181,12 @@ def create_new_auth_token(client_id=nil)
last_token: last_token,
updated_at: Time.now
}

max_clients = DeviseTokenAuth.max_number_of_devices
while self.tokens.keys.length > 0 and max_clients < self.tokens.keys.length
oldest_token = self.tokens.min_by { |cid, v| v[:expiry] || v["expiry"] }
self.tokens.delete(oldest_token.first)
end
end

self.save!

Expand Down Expand Up @@ -239,7 +242,7 @@ def token_validation_response
# only validate unique email among users that registered by email
def unique_email_user
if provider == 'email' and self.class.where(provider: 'email', email: email).count > 0
errors.add(:email, :already_in_use)
errors.add(:email, I18n.t("errors.messages.already_in_use"))
end
end

Expand All @@ -260,4 +263,15 @@ def destroy_expired_tokens
end
end

def remove_tokens_after_password_reset
there_is_more_than_one_token = self.tokens && self.tokens.keys.length > 1
should_remove_old_tokens = DeviseTokenAuth.remove_tokens_after_password_reset &&
encrypted_password_changed? && there_is_more_than_one_token

if should_remove_old_tokens
latest_token = self.tokens.max_by { |cid, v| v[:expiry] || v["expiry"] }
self.tokens = {latest_token.first => latest_token.last}
end
end

end
12 changes: 6 additions & 6 deletions app/validators/email_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ def validate_each(record, attribute, value)
record.errors[attribute] << email_invalid_message
end
end

private

def email_invalid_message
# Try strictly set message:
message = options[:message]

if message.nil?
# Try DeviceTokenAuth translations or fallback to ActiveModel translations
message = I18n.t(:'errors.not_email', default: :'errors.messages.invalid')
message = I18n.t(:'errors.messages.not_email', default: :'errors.messages.invalid')
end

message
end
end
end
6 changes: 3 additions & 3 deletions app/views/devise/mailer/confirmation_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p>Welcome <%= @email %>!</p>
<p><%= t(:welcome).capitalize + ' ' + @email %>!</p>

<p>You can confirm your account email through the link below:</p>
<p><%= t '.confirm_link_msg' %> </p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, {confirmation_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url']}).html_safe %></p>
<p><%= link_to t('.confirm_account_link'), confirmation_url(@resource, {confirmation_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url']}).html_safe %></p>
10 changes: 5 additions & 5 deletions app/views/devise/mailer/reset_password_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p>Hello <%= @resource.email %>!</p>
<p><%= t(:hello).capitalize %> <%= @resource.email %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>
<p><%= t '.request_reset_link_msg' %></p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url'].to_s).html_safe %></p>
<p><%= link_to t('.password_change_link'), edit_password_url(@resource, reset_password_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url'].to_s).html_safe %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
<p><%= t '.ignore_mail_msg' %></p>
<p><%= t '.no_changes_msg' %></p>
8 changes: 4 additions & 4 deletions app/views/devise/mailer/unlock_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<p>Hello <%= @resource.email %>!</p>
<p><%= t :hello %> <%= @resource.email %>!</p>

<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
<p><%= t '.account_lock_msg' %></p>

<p>Click the link below to unlock your account:</p>
<p><%= t '.unlock_link_msg' %></p>

<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token).html_safe %></p>
<p><%= link_to t('.unlock_link'), unlock_url(@resource, unlock_token: @token) %></p>
44 changes: 31 additions & 13 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,50 @@
de:
devise_token_auth:
sessions:
not_confirmed: "Ein E-Mail zu Bestätigung wurde an Ihre Adresse %{email} gesendet. Sie müssen den Anleitungsschritten im E-Mail folgen, um Ihren Account zu aktivieren"
not_confirmed: "Ein E-Mail zu Bestätigung wurde an Ihre Adresse '%{email}'' gesendet. Sie müssen den Anleitungsschritten im E-Mail folgen, um Ihren Account zu aktivieren"
bad_credentials: "Ungültige Anmeldeinformationen. Bitte versuchen Sie es erneut."
not_supported: "Verwenden Sie POST /sign_in zur Anmeldung. GET wird nicht unterstützt."
user_not_found: "Benutzer wurde nicht gefunden oder konnte nicht angemeldet werden."
token_validations:
invalid: "Ungültige Anmeldeinformationen"
registrations:
missing_confirm_success_url: "Fehlender Paramter `confirm_success_url`."
redirect_url_not_allowed: "Weiterleitung zu %{redirect_url} ist nicht gestattet."
email_already_exists: "Es gibt bereits einen Account für %{email}."
account_with_uid_destroyed: "Account mit der uid %{uid} wurde gelöscht."
missing_confirm_success_url: "Fehlender Paramter 'confirm_success_url'."
redirect_url_not_allowed: "Weiterleitung zu '%{redirect_url}' ist nicht gestattet."
email_already_exists: "Es gibt bereits einen Account für '%{email}'."
account_with_uid_destroyed: "Account mit der uid '%{uid}' wurde gelöscht."
account_to_destroy_not_found: "Der Account, der gelöscht werden soll, kann nicht gefunden werden."
user_not_found: "Benutzer kann nicht gefunden werden."
passwords:
missing_email: "Sie müssen eine E-Mail Adresse angeben."
missing_redirect_url: "Es fehlt der URL zu Weiterleitung."
not_allowed_redirect_url: "Weiterleitung zu %{redirect_url} ist nicht gestattet."
sended: "Ein E-Mail mit Anleitung zum Rücksetzen Ihres Passwortes wurde an %{email} gesendet."
not_allowed_redirect_url: "Weiterleitung zu '%{redirect_url}' ist nicht gestattet."
sended: "Ein E-Mail mit Anleitung zum Rücksetzen Ihres Passwortes wurde an '%{email}' gesendet."
user_not_found: "Der Benutzer mit E-Mail-Adresse '%{email}' kann nicht gefunden werden."
password_not_required: "Dieser Account benötigt kein Passwort. Melden Sie Sich stattdessen über Ihren Account bei %{provider} an."
missing_passwords: 'Sie müssen die Felder "Passwort" and "Passwortbestätigung" ausfüllen.'
password_not_required: "Dieser Account benötigt kein Passwort. Melden Sie Sich stattdessen über Ihren Account bei '%{provider}' an."
missing_passwords: "Sie müssen die Felder 'Passwort' and 'Passwortbestätigung' ausfüllen."
successfully_updated: "Ihr Passwort wurde erfolgreich aktualisiert."

errors:
validate_sign_up_params: "Bitte übermitteln sie vollständige Anmeldeinformationen im Body des Requests."
validate_account_update_params: "Bitte übermitteln sie vollständige Informationen zur Aktualisierung im Body des Requests."
not_email: "ist keine E-Mail Adresse"
messages:
validate_sign_up_params: "Bitte übermitteln sie vollständige Anmeldeinformationen im Body des Requests."
validate_account_update_params: "Bitte übermitteln sie vollständige Informationen zur Aktualisierung im Body des Requests."
not_email: "ist keine E-Mail Adresse"
already_in_use: "bereits in Verwendung"
devise:
mailer:
confirmation_instructions:
subject: "Bestätigungs-"
confirm_link_msg: "Sie können Ihr Konto E-Mail über den untenstehenden Link bestätigen:"
confirm_account_link: "Ihr Konto zu bestätigen"
reset_password_instructions:
subject: "Wiederherstellungskennwort Anweisungen"
request_reset_link_msg: "Jemand hat einen Link auf Ihr Kennwort zu ändern angefordert. Sie können dies durch den folgenden Link tun:"
password_change_link: "Kennwort ändern"
ignore_mail_msg: "Wenn Sie nicht angefordert haben diese , ignorieren Sie bitte diese E-Mail:"
no_changes_msg: "Ihr Passwort wird nicht geändert , bis Sie auf den obigen Link zugreifen und eine neue erstellen ."
unlock_instructions:
subject: "entsperren Anweisungen"
account_lock_msg: "Ihr Konto wurde aufgrund einer übermäßigen Anzahl von erfolglosen Zeichen in Versuchen gesperrt."
unlock_link_msg: "Klicken Sie auf den Link unten , um Ihr Konto zu entsperren :"
unlock_link: "Entsperren Sie Ihr Konto "
hello: "hallo"
welcome: "willkommen"
45 changes: 30 additions & 15 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
en:
devise_token_auth:
sessions:
not_confirmed: "A confirmation email was sent to your account at %{email}. You must follow the instructions in the email before your account can be activated"
not_confirmed: "A confirmation email was sent to your account at '%{email}'. You must follow the instructions in the email before your account can be activated"
bad_credentials: "Invalid login credentials. Please try again."
not_supported: "Use POST /sign_in to sign in. GET is not supported."
user_not_found: "User was not found or was not logged in."
token_validations:
invalid: "Invalid login credentials"
registrations:
missing_confirm_success_url: "Missing `confirm_success_url` param."
redirect_url_not_allowed: "Redirect to %{redirect_url} not allowed."
email_already_exists: "An account already exists for %{email}"
account_with_uid_destroyed: "Account with uid %{uid} has been destroyed."
missing_confirm_success_url: "Missing 'confirm_success_url' parameter."
redirect_url_not_allowed: "Redirect to '%{redirect_url}' not allowed."
email_already_exists: "An account already exists for '%{email}'"
account_with_uid_destroyed: "Account with UID '%{uid}' has been destroyed."
account_to_destroy_not_found: "Unable to locate account for destruction."
user_not_found: "User not found."
confirmations:
Expand All @@ -23,17 +23,32 @@ en:
user_not_found: "Unable to find user with email '%{email}'."
passwords:
missing_email: "You must provide an email address."
missing_redirect_url: "Missing redirect url."
redirect_url_not_allowed: "Redirect to %{redirect_url} not allowed."
email_sent: "An email has been sent to %{email} containing instructions for resetting your password."
missing_redirect_url: "Missing redirect URL."
redirect_url_not_allowed: "Redirect to '%{redirect_url}' not allowed."
email_sent: "An email has been sent to '%{email}' containing instructions for resetting your password."
user_not_found: "Unable to find user with email '%{email}'."
password_not_required: "This account does not require a password. Sign in using your %{provider} account instead."
missing_passwords: 'You must fill out the fields labeled "password" and "password confirmation".'
password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
missing_passwords: "You must fill out the fields labeled 'Password' and 'Password confirmation'."
successfully_updated: "Your password has been successfully updated."

errors:
validate_sign_up_params: "Please submit proper sign up data in request body."
validate_account_update_params: "Please submit proper account update data in request body."
not_email: "is not an email"
messages:
already_in_use: already in use
already_in_use: "already in use"
validate_sign_up_params: "Please submit proper sign up data in request body."
validate_account_update_params: "Please submit proper account update data in request body."
not_email: "is not an email"
devise:
mailer:
confirmation_instructions:
confirm_link_msg: "You can confirm your account email through the link below:"
confirm_account_link: "Confirm my account"
reset_password_instructions:
request_reset_link_msg: "Someone has requested a link to change your password. You can do this through the link below."
password_change_link: "Change my password"
ignore_mail_msg: "If you didn't request this, please ignore this email."
no_changes_msg: "Your password won't change until you access the link above and create a new one."
unlock_instructions:
account_lock_msg: "Your account has been locked due to an excessive number of unsuccessful sign in attempts."
unlock_link_msg: "Click the link below to unlock your account:"
unlock_link: "Unlock my account"
hello: "hello"
welcome: "welcome"
Loading

0 comments on commit e7a5062

Please sign in to comment.