1
2
3
4
5
6
7
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
88
89
90
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
125
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
167
168
169
170
171
172
173
174
175
176
177
|
# frozen_string_literal: true
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
# encrypted_password :string default(""), not null
# reset_password_token :string
# reset_password_sent_at :datetime
# remember_created_at :datetime
# sign_in_count :integer default(0), not null
# current_sign_in_at :datetime
# last_sign_in_at :datetime
# current_sign_in_ip :inet
# last_sign_in_ip :inet
# admin :boolean default(FALSE), not null
# confirmation_token :string
# confirmed_at :datetime
# confirmation_sent_at :datetime
# unconfirmed_email :string
# locale :string
# encrypted_otp_secret :string
# encrypted_otp_secret_iv :string
# encrypted_otp_secret_salt :string
# consumed_timestep :integer
# otp_required_for_login :boolean default(FALSE), not null
# last_emailed_at :datetime
# otp_backup_codes :string is an Array
# filtered_languages :string default([]), not null, is an Array
# account_id :integer not null
# disabled :boolean default(FALSE), not null
#
class User < ApplicationRecord
include Settings::Extend
ACTIVE_DURATION = 14.days
devise :registerable, :recoverable,
:rememberable, :trackable, :validatable, :confirmable,
:two_factor_authenticatable, :two_factor_backupable,
otp_secret_encryption_key: ENV['OTP_SECRET'],
otp_number_of_backup_codes: 10
belongs_to :account, inverse_of: :user, required: true
accepts_nested_attributes_for :account
has_many :applications, class_name: 'Doorkeeper::Application', as: :owner
validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
validates_with BlacklistedEmailValidator, if: :email_changed?
scope :recent, -> { order(id: :desc) }
scope :admins, -> { where(admin: true) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended: false }) }
scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) }
scope :with_recent_ip_address, ->(value) { where(arel_table[:current_sign_in_ip].eq(value).or(arel_table[:last_sign_in_ip].eq(value))) }
before_validation :sanitize_languages
# This avoids a deprecation warning from Rails 5.1
# It seems possible that a future release of devise-two-factor will
# handle this itself, and this can be removed from our User class.
attribute :otp_secret
has_many :session_activations, dependent: :destroy
def confirmed?
confirmed_at.present?
end
def disable!
update!(disabled: true,
last_sign_in_at: current_sign_in_at,
current_sign_in_at: nil)
end
def enable!
update!(disabled: false)
end
def disable_two_factor!
self.otp_required_for_login = false
otp_backup_codes&.clear
save!
end
def active_for_authentication?
super && !disabled?
end
def setting_default_privacy
settings.default_privacy || (account.locked? ? 'private' : 'public')
end
def setting_default_sensitive
settings.default_sensitive
end
def setting_unfollow_modal
settings.unfollow_modal
end
def setting_boost_modal
settings.boost_modal
end
def setting_delete_modal
settings.delete_modal
end
def setting_auto_play_gif
settings.auto_play_gif
end
def setting_reduce_motion
settings.reduce_motion
end
def setting_system_font_ui
settings.system_font_ui
end
def setting_noindex
settings.noindex
end
def setting_theme
settings.theme
end
def token_for_app(a)
return nil if a.nil? || a.owner != self
Doorkeeper::AccessToken
.find_or_create_by(application_id: a.id, resource_owner_id: id) do |t|
t.scopes = a.scopes
t.expires_in = Doorkeeper.configuration.access_token_expires_in
t.use_refresh_token = Doorkeeper.configuration.refresh_token_enabled?
end
end
def activate_session(request)
session_activations.activate(session_id: SecureRandom.hex,
user_agent: request.user_agent,
ip: request.remote_ip).session_id
end
def exclusive_session(id)
session_activations.exclusive(id)
end
def session_active?(id)
session_activations.active? id
end
def web_push_subscription(session)
session.web_push_subscription.nil? ? nil : session.web_push_subscription.as_payload
end
protected
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later
end
private
def sanitize_languages
filtered_languages.reject!(&:blank?)
end
end
|