Class: OtpSecret
- Inherits:
-
Object
show all
- Defined in:
- app/models/otp_secret.rb
Defined Under Namespace
Classes: InvalidUserError
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(user) ⇒ OtpSecret
Returns a new instance of OtpSecret.
8
9
10
11
|
# File 'app/models/otp_secret.rb', line 8
def initialize(user)
@user = user
@secret = user.otp_secret
end
|
Instance Attribute Details
#secret ⇒ Object
Returns the value of attribute secret.
6
7
8
|
# File 'app/models/otp_secret.rb', line 6
def secret
@secret
end
|
#user ⇒ Object
Returns the value of attribute user.
6
7
8
|
# File 'app/models/otp_secret.rb', line 6
def user
@user
end
|
Instance Method Details
#account_name ⇒ Object
13
14
15
|
# File 'app/models/otp_secret.rb', line 13
def account_name
user.email
end
|
#disable! ⇒ Object
17
18
19
20
21
22
|
# File 'app/models/otp_secret.rb', line 17
def disable!
user.update(otp_enabled: false,
otp_secret: nil,
last_otp_at: nil,
recovery_codes: [])
end
|
#enable!(recovery_codes) ⇒ Object
24
25
26
27
28
29
|
# File 'app/models/otp_secret.rb', line 24
def enable!(recovery_codes)
user.update(otp_enabled: true,
otp_secret: secret,
last_otp_at: Time.zone.now,
recovery_codes:)
end
|
#generate ⇒ Object
31
32
33
|
# File 'app/models/otp_secret.rb', line 31
def generate
@secret = ROTP::Base32.random
end
|
#generate_recovery_codes ⇒ Object
35
36
37
|
# File 'app/models/otp_secret.rb', line 35
def generate_recovery_codes
Array.new(10) { SecureRandom.alphanumeric(16) }
end
|
#provisioning_uri ⇒ Object
39
40
41
|
# File 'app/models/otp_secret.rb', line 39
def provisioning_uri
totp.provisioning_uri(account_name)
end
|
#regenerate_recovery_codes! ⇒ Object
43
44
45
46
47
|
# File 'app/models/otp_secret.rb', line 43
def regenerate_recovery_codes!
generate_recovery_codes.tap do |recovery_codes|
user.update(recovery_codes:)
end
end
|
#signed_message ⇒ Object
49
50
51
52
53
|
# File 'app/models/otp_secret.rb', line 49
def signed_message
message_verifier.generate(
{ user_id: user.id, secret: }, expires_in: 1.hour
)
end
|
#validate_otp!(code) ⇒ Object
55
56
57
58
59
60
|
# File 'app/models/otp_secret.rb', line 55
def validate_otp!(code)
return false unless valid_otp?(code)
user.update(last_otp_at: Time.zone.now)
true
end
|
#validate_otp_or_recovery_code!(code) ⇒ Object
62
63
64
65
66
67
68
|
# File 'app/models/otp_secret.rb', line 62
def validate_otp_or_recovery_code!(code)
if /^\d{6}$/.match?(code)
validate_otp!(code)
else
validate_recovery_code!(code)
end
end
|
#validate_recovery_code!(code) ⇒ Object
70
71
72
|
# File 'app/models/otp_secret.rb', line 70
def validate_recovery_code!(code)
user.use_recovery_code!(code)
end
|
#verify(params) ⇒ Object
74
75
76
77
|
# File 'app/models/otp_secret.rb', line 74
def verify(params)
@secret = verify_secret(params[:signed_message])
valid_otp?(params[:otp])
end
|