Skip to content
10 changes: 7 additions & 3 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ def show

def device_and_events
user_id = current_user.id
@events = DeviceTracking::ListDeviceEvents.call(user_id, device_id, 0, EVENTS_PAGE_SIZE).
map(&:decorate)
@device = Device.where(user_id: user_id).find(device_id)
device = Device.where(user_id: user_id).find(device_id)
return if !device

@events = Event.where(user_id: user_id, device_id: device.id).order(created_at: :desc).
limit(EVENTS_PAGE_SIZE).
map(&:decorate)
@device = device.decorate
end

def device_id
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users/forget_all_browsers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def show
end

def destroy
DeviceTracking::ForgetAllBrowsers.new(current_user).call
ForgetAllBrowsers.new(current_user).call

analytics.track_event(Analytics::FORGET_ALL_BROWSERS_SUBMITTED)

Expand Down
11 changes: 10 additions & 1 deletion app/decorators/device_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DeviceDecorator = Struct.new(:device) do
delegate :nice_name, :last_used_at, :id, to: :device
delegate :last_used_at, :id, to: :device

def last_sign_in_location_and_ip
I18n.t('account.index.sign_in_location_and_ip', location: last_location, ip: device.last_ip)
Expand All @@ -12,4 +12,13 @@ def last_location
def happened_at
device.last_used_at.utc
end

def nice_name
browser = BrowserCache.parse(device.user_agent)
I18n.t(
'account.index.device',
browser: "#{browser.name} #{browser.version}",
os: "#{browser.platform.name} #{browser.platform.version.split('.').first}",
)
end
end
3 changes: 2 additions & 1 deletion app/decorators/user_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ def identity_events
end

def recent_devices
DeviceTracking::ListDevices.call(user.id, 0, MAX_RECENT_DEVICES).map(&:decorate)
@recent_devices ||= user.devices.order(last_used_at: :desc).limit(MAX_RECENT_DEVICES).
map(&:decorate)
end

def devices?
Expand Down
8 changes: 6 additions & 2 deletions app/models/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ def decorate
DeviceDecorator.new(self)
end

def device_name
DeviceTracking::DeviceName.call(self)
# @return [Device]
def update_last_used_ip(remote_ip, now: Time.zone.now)
self.last_used_at = now
self.last_ip = remote_ip
save
self
end
end
15 changes: 0 additions & 15 deletions app/services/device_tracking/create_device.rb

This file was deleted.

12 changes: 0 additions & 12 deletions app/services/device_tracking/device_name.rb

This file was deleted.

19 changes: 0 additions & 19 deletions app/services/device_tracking/forget_all_browsers.rb

This file was deleted.

9 changes: 0 additions & 9 deletions app/services/device_tracking/list_device_events.rb

This file was deleted.

9 changes: 0 additions & 9 deletions app/services/device_tracking/list_devices.rb

This file was deleted.

7 changes: 0 additions & 7 deletions app/services/device_tracking/lookup_device_for_user.rb

This file was deleted.

10 changes: 0 additions & 10 deletions app/services/device_tracking/update_device.rb

This file was deleted.

17 changes: 17 additions & 0 deletions app/services/forget_all_browsers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class ForgetAllBrowsers
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was just de-namespaced/moved

attr_reader :user, :remember_device_revoked_at

def initialize(user, remember_device_revoked_at: nil)
@user = user
@remember_device_revoked_at = remember_device_revoked_at || Time.zone.now
end

def call
UpdateUser.new(
user: user,
attributes: {
remember_device_revoked_at: remember_device_revoked_at,
},
).call
end
end
2 changes: 1 addition & 1 deletion app/services/reset_user_password.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def reset_user_password
end

def forget_all_browsers
DeviceTracking::ForgetAllBrowsers.new(
ForgetAllBrowsers.new(
user,
remember_device_revoked_at: remember_device_revoked_at,
).call
Expand Down
16 changes: 12 additions & 4 deletions app/services/user_event_creator.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class UserEventCreator
COOKIE_LENGTH = 128

attr_reader :request, :current_user

def initialize(current_user:, request: nil)
Expand All @@ -8,7 +10,7 @@ def initialize(current_user:, request: nil)

def create_user_event(event_type, user = current_user)
return unless user&.id
existing_device = DeviceTracking::LookupDeviceForUser.call(user.id, cookies[:device])
existing_device = Device.find_by(user_id: user.id, cookie_uuid: cookies[:device])
if existing_device.present?
create_event_for_existing_device(event_type: event_type, user: user, device: existing_device)
else
Expand All @@ -30,7 +32,7 @@ def create_user_event_with_disavowal(event_type, user = current_user)
private

def create_event_for_existing_device(event_type:, user:, device:)
DeviceTracking::UpdateDevice.call(device, request.remote_ip)
device.update_last_used_ip(request.remote_ip)
create_event_for_device(event_type: event_type, user: user, device: device)
end

Expand All @@ -47,8 +49,14 @@ def create_event_for_new_device(event_type:, user:)
end

def create_device_for_user(user)
device = DeviceTracking::CreateDevice.call(
user.id, request.remote_ip, request.user_agent, cookies[:device]
cookie_uuid = cookies[:device].presence || SecureRandom.hex(COOKIE_LENGTH / 2)

device = Device.create!(
user: user,
user_agent: request.user_agent.to_s,
cookie_uuid: cookie_uuid,
last_used_at: Time.zone.now,
last_ip: request.remote_ip,
)
assign_device_cookie(device.cookie_uuid)
device
Expand Down
2 changes: 1 addition & 1 deletion app/views/events/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<div class="margin-bottom-4 card profile-info-box">
<div class="border-bottom border-primary-light">
<h2 class="margin-top-0">
<%= @device.device_name %>
<%= @device.nice_name %>
</h2>

<% @events.each do |event| %>
Expand Down
12 changes: 12 additions & 0 deletions spec/decorators/device_decorator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'rails_helper'

RSpec.describe DeviceDecorator do
let(:device) { create(:device) }
subject(:decorator) { DeviceDecorator.new(device) }

describe '#nice_name' do
it 'gives a shortened os and browser name' do
expect(decorator.nice_name).to eq('Chrome 58 on Windows 10')
end
end
end
16 changes: 16 additions & 0 deletions spec/models/device_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,20 @@
expect(device).to be_valid
end
end

describe '#update_last_used_ip' do
let(:user) { create(:user) }
let(:remote_ip) { '1.2.3.4' }
let(:user_agent) { 'Chrome/58.0.3029.110 Safari/537.36' }
let(:uuid) { 'abc123' }
let(:now) { Time.zone.now }
let(:old_timestamp) { now - 1.hour }
let(:device) { create(:device, last_used_at: old_timestamp) }

it 'updates the last ip and last_used_at' do
expect { device.update_last_used_ip(remote_ip) }.
to(change { device.reload.last_used_at.to_i }.from(old_timestamp.to_i).to(now.to_i).
and(change { device.reload.last_ip }.to(remote_ip)))
end
end
end
23 changes: 0 additions & 23 deletions spec/services/device_tracking/create_device_spec.rb

This file was deleted.

12 changes: 0 additions & 12 deletions spec/services/device_tracking/device_name_spec.rb

This file was deleted.

55 changes: 0 additions & 55 deletions spec/services/device_tracking/list_device_events_spec.rb

This file was deleted.

Loading