about summary refs log tree commit diff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/auth/omniauth_callbacks_controller.rb9
-rw-r--r--app/controllers/auth/sessions_controller.rb44
-rw-r--r--app/controllers/concerns/sign_in_token_authentication_concern.rb5
-rw-r--r--app/controllers/concerns/two_factor_authentication_concern.rb10
-rw-r--r--app/controllers/follower_accounts_controller.rb2
-rw-r--r--app/controllers/following_accounts_controller.rb2
-rw-r--r--app/controllers/settings/login_activities_controller.rb7
7 files changed, 61 insertions, 18 deletions
diff --git a/app/controllers/auth/omniauth_callbacks_controller.rb b/app/controllers/auth/omniauth_callbacks_controller.rb
index 682c77016..7925e23cb 100644
--- a/app/controllers/auth/omniauth_callbacks_controller.rb
+++ b/app/controllers/auth/omniauth_callbacks_controller.rb
@@ -10,6 +10,15 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
       @user = User.find_for_oauth(request.env['omniauth.auth'], current_user)
 
       if @user.persisted?
+        LoginActivity.create(
+          user: user,
+          success: true,
+          authentication_method: :omniauth,
+          provider: provider,
+          ip: request.remote_ip,
+          user_agent: request.user_agent
+        )
+
         sign_in_and_redirect @user, event: :authentication
         set_flash_message(:notice, :success, kind: provider_id.capitalize) if is_navigational_format?
       else
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 548832b21..f07f38075 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -27,9 +27,11 @@ class Auth::SessionsController < Devise::SessionsController
 
   def create
     super do |resource|
-      resource.update_sign_in!(request, new_sign_in: true)
-      remember_me(resource)
-      flash.delete(:notice)
+      # We only need to call this if this hasn't already been
+      # called from one of the two-factor or sign-in token
+      # authentication methods
+
+      on_authentication_success(resource, :password) unless @on_authentication_success_called
     end
   end
 
@@ -44,10 +46,8 @@ class Auth::SessionsController < Devise::SessionsController
   def webauthn_options
     user = find_user
 
-    if user.webauthn_enabled?
-      options_for_get = WebAuthn::Credential.options_for_get(
-        allow: user.webauthn_credentials.pluck(:external_id)
-      )
+    if user&.webauthn_enabled?
+      options_for_get = WebAuthn::Credential.options_for_get(allow: user.webauthn_credentials.pluck(:external_id))
 
       session[:webauthn_challenge] = options_for_get.challenge
 
@@ -142,4 +142,34 @@ class Auth::SessionsController < Devise::SessionsController
     session.delete(:attempt_user_id)
     session.delete(:attempt_user_updated_at)
   end
+
+  def on_authentication_success(user, security_measure)
+    @on_authentication_success_called = true
+
+    clear_attempt_from_session
+
+    user.update_sign_in!(request, new_sign_in: true)
+    remember_me(user)
+    sign_in(user)
+    flash.delete(:notice)
+
+    LoginActivity.create(
+      user: user,
+      success: true,
+      authentication_method: security_measure,
+      ip: request.remote_ip,
+      user_agent: request.user_agent
+    )
+  end
+
+  def on_authentication_failure(user, security_measure, failure_reason)
+    LoginActivity.create(
+      user: user,
+      success: false,
+      authentication_method: security_measure,
+      failure_reason: failure_reason,
+      ip: request.remote_ip,
+      user_agent: request.user_agent
+    )
+  end
 end
diff --git a/app/controllers/concerns/sign_in_token_authentication_concern.rb b/app/controllers/concerns/sign_in_token_authentication_concern.rb
index 51ebcb115..016ab8f52 100644
--- a/app/controllers/concerns/sign_in_token_authentication_concern.rb
+++ b/app/controllers/concerns/sign_in_token_authentication_concern.rb
@@ -29,10 +29,9 @@ module SignInTokenAuthenticationConcern
 
   def authenticate_with_sign_in_token_attempt(user)
     if valid_sign_in_token_attempt?(user)
-      clear_attempt_from_session
-      remember_me(user)
-      sign_in(user)
+      on_authentication_success(user, :sign_in_token)
     else
+      on_authentication_failure(user, :sign_in_token, :invalid_sign_in_token)
       flash.now[:alert] = I18n.t('users.invalid_sign_in_token')
       prompt_for_sign_in_token(user)
     end
diff --git a/app/controllers/concerns/two_factor_authentication_concern.rb b/app/controllers/concerns/two_factor_authentication_concern.rb
index 4800db348..d3f00a4b4 100644
--- a/app/controllers/concerns/two_factor_authentication_concern.rb
+++ b/app/controllers/concerns/two_factor_authentication_concern.rb
@@ -52,21 +52,19 @@ module TwoFactorAuthenticationConcern
     webauthn_credential = WebAuthn::Credential.from_get(user_params[:credential])
 
     if valid_webauthn_credential?(user, webauthn_credential)
-      clear_attempt_from_session
-      remember_me(user)
-      sign_in(user)
+      on_authentication_success(user, :webauthn)
       render json: { redirect_path: root_path }, status: :ok
     else
+      on_authentication_failure(user, :webauthn, :invalid_credential)
       render json: { error: t('webauthn_credentials.invalid_credential') }, status: :unprocessable_entity
     end
   end
 
   def authenticate_with_two_factor_via_otp(user)
     if valid_otp_attempt?(user)
-      clear_attempt_from_session
-      remember_me(user)
-      sign_in(user)
+      on_authentication_success(user, :otp)
     else
+      on_authentication_failure(user, :otp, :invalid_otp_token)
       flash.now[:alert] = I18n.t('users.invalid_otp_token')
       prompt_for_two_factor(user)
     end
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index 18b281325..d519138cd 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -86,7 +86,7 @@ class FollowerAccountsController < ApplicationController
     if page_requested? || !@account.user_hides_network?
       # Return all fields
     else
-      %i(id type totalItems)
+      %i(id type total_items)
     end
   end
 end
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index eba44d34b..4b4978fb9 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -86,7 +86,7 @@ class FollowingAccountsController < ApplicationController
     if page_requested? || !@account.user_hides_network?
       # Return all fields
     else
-      %i(id type totalItems)
+      %i(id type total_items)
     end
   end
 end
diff --git a/app/controllers/settings/login_activities_controller.rb b/app/controllers/settings/login_activities_controller.rb
new file mode 100644
index 000000000..57fa6aef0
--- /dev/null
+++ b/app/controllers/settings/login_activities_controller.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class Settings::LoginActivitiesController < Settings::BaseController
+  def index
+    @login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page])
+  end
+end