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.
10
11
12
13
|
# File 'app/models/otp_secret.rb', line 10
def initialize(user)
@user = user
@secret = user.otp_secret
end
|
Instance Attribute Details
#secret ⇒ Object
Returns the value of attribute secret.
8
9
10
|
# File 'app/models/otp_secret.rb', line 8
def secret
@secret
end
|
#user ⇒ Object
Returns the value of attribute user.
8
9
10
|
# File 'app/models/otp_secret.rb', line 8
def user
@user
end
|
Instance Method Details
#account_name ⇒ Object
15
16
17
|
# File 'app/models/otp_secret.rb', line 15
def account_name
user.email
end
|
#disable! ⇒ Object
19
20
21
22
23
24
|
# File 'app/models/otp_secret.rb', line 19
def disable!
user.update(otp_enabled: false,
otp_secret: nil,
last_otp_at: nil,
recovery_codes: [])
end
|
#enable!(recovery_codes) ⇒ Object
26
27
28
29
30
31
|
# File 'app/models/otp_secret.rb', line 26
def enable!(recovery_codes)
user.update(otp_enabled: true,
otp_secret: secret,
last_otp_at: Time.zone.now,
recovery_codes:)
end
|
#generate ⇒ Object
33
34
35
|
# File 'app/models/otp_secret.rb', line 33
def generate
@secret = ROTP::Base32.random
end
|
#generate_recovery_codes ⇒ Object
37
38
39
|
# File 'app/models/otp_secret.rb', line 37
def generate_recovery_codes
Array.new(10) { SecureRandom.alphanumeric(16) }
end
|
#provisioning_uri ⇒ Object
41
42
43
|
# File 'app/models/otp_secret.rb', line 41
def provisioning_uri
totp.provisioning_uri(account_name)
end
|
#regenerate_recovery_codes! ⇒ Object
45
46
47
48
49
|
# File 'app/models/otp_secret.rb', line 45
def regenerate_recovery_codes!
generate_recovery_codes.tap do |recovery_codes|
user.update(recovery_codes:)
end
end
|
#signed_message ⇒ Object
51
52
53
54
55
|
# File 'app/models/otp_secret.rb', line 51
def signed_message
message_verifier.generate(
{ user_id: user.id, secret: }, expires_in: 1.hour
)
end
|
#validate_otp!(code) ⇒ Object
57
58
59
60
61
62
|
# File 'app/models/otp_secret.rb', line 57
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
64
65
66
67
68
69
70
|
# File 'app/models/otp_secret.rb', line 64
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
72
73
74
|
# File 'app/models/otp_secret.rb', line 72
def validate_recovery_code!(code)
user.use_recovery_code!(code)
end
|
#verify(params) ⇒ Object
76
77
78
79
|
# File 'app/models/otp_secret.rb', line 76
def verify(params)
@secret = verify_secret(params[:signed_message])
valid_otp?(params[:otp])
end
|