Required Features
Closed this issue · 3 comments
Thanks to @janko, I've been able to play with this lib with Rails. I have some "missing" features that are required for my apps.
I'm willing to create them but I'd like your opinion if it's possible to create them or if it needs to be a separate plugin (and maybe a separate gem)
- Send OTP via email
- Similar to the verify email, send an email with a code to enter to validate login
- Request OTP before an action
- Right now, when logging with OTP,
session[authenticated_by_session_key]
is an array that contains strings - We should add a new key
otp_used_at
that contains the last time the OTP has been entered. Thus, we should be able to specify a delay after which the OTP is required again
- Right now, when logging with OTP,
- Request password before an action
- Same as "Request OTP before an action"
- We should add a new key
password_used_at
that contains the last time the password has been entered
- Block disposable emails
- I'll create a separate gem for that
Request password before an action
This one is already possible using #require_password_authentication
method from the confirm_password feature, together with password_grace_period feature which remembers an entered password for a period of time (in a session, as far as I remember). For example:
configure do
enable :confirm_password, :password_grace_period
# ...
end
route do |r|
# ...
if r.path == "/action"
rodauth.require_password_authentication
end
# ...
end
Send OTP via email
In general, the email_authentication feature works the exact same way, but is more secure as it uses a link instead of a 6-digit code. Is there a reason you wouldn't want to use that?
Assuming you did have a specific reason for using a short code instead of a link, this would probably need to be implemented as a separate feature similar to the SMS implementation, but without having to register a phone number. You wouldn't want to build it on top of the OTP feature (which uses TOTP).
Request OTP before an action
The otp
feature stores the last time used. We could probably add a method you could call get to get the last use time, then you could do something like the following at the top of the routing tree:
if rodauth.authenticated_by&.include?('otp') && rodauth.otp_last_use < Time.now - 3600
rodauth.authenticated_by.delete('otp')
end
rodauth.require_authentication
However, this assumes you are using the otp feature, and not OTP codes via email.
I implemented otp_last_use
. You can use it pretty much in the same way the code example I gave, though using 'totp'
instead of 'otp'
as the string.
Note that this probably isn't the best way to handle the issue, since otp_last_use
is not limited to the current session. You are probably better off using after_two_factor_authentication
, setting the session key to the current time, and checking that:
after_two_factor_authentication do
session['mfa_at'] = Time.now.to_i
end
Then you can check session['mfa_at']
and use it to implement your expiration.
Still, I think otp_last_use
is a good general method to add, even if not particularly useful for expiration.
I did not implement the other features you requested, though potentially we could discuss the possibility of adding them on the Google Group. As reminder, per the contribution guidelines, GitHub Issues should only be used for reporting bugs in the library, not for feature requests. Please discuss feature requests on the Google Group.