TSphinxConfig event for OnSend2FACode

Add an event To TSphinxConfig so that a 2FA code can be emailed to the user.

There are a few problems with this:

  1. Sphinx doesn't automatically generate 2fa code. It's you, the developer who does that by calling UserManager.ResetAuthenticatorKey. So no need for an event in this case.

  2. Usually users have to confirm at least one authenticator code to enable 2fa. So receiving the secret would, ideally, still require that they input the authentication code to enable 2fa.

I think I didn't express it clearly enough.

When the form form for the validation code, the one where the code from a validator app is entered, it would be useful to have an event on the server that can be used so the developer can calculate and email the required code to the user.

Although the authenticator apps are the preferred method for retrieving a code some clients want a code sent by email or sms (I am still amazed that the banks use this method, but that's people for you).

Still currently it doesn't make much sense, as the validation code is by default valid for 30 seconds only.

We have a solution in one of our webbroker apps where the user can choose the method of receiving the code - App, Email, SMS and depending on what they have selected determines how long the code is valid for, so in this example EmailValidationTime is a constant

const
  OTPValidationTime = 30;
  SMSValidationTime = 400;
  EmailValidationTime = 600;


lCode := TOTPGen.GenerateTOTP(lUser.MFAKey, EmailValidationTime);

class function TOTPGen.GenerateTOTP(const pBase32EncodedSecretKey:string; const TimeStepWindow:integer = 30; const pOutputLength:TOTPLength = TOTPLength.SixDigits):string;
begin
  Result := GenerateHOTP(pBase32EncodedSecretKey, GetCurrentUnixTimestamp(TimeStepWindow), pOutputLength);
end;

Just wanted to re-raise this as we will likely have a need for it in the near future.

Ideally the TUser entity would need a field MfaKind (mfaApp, mfaEmail, mfaSMS) and the TSphinxConfig an OnSendMFA event.

Or maybe a OnGetMFA(const TimeToLIve: integer);

Alternatively, if you can think of a work around we could do to implement this ourselves, that would be great.

Maybe another case study in the offing then :wink:

Ok, maybe the correct solution is to allow multiple ways for user to confirm second factor authentication.

That should not be the same code as the one from the authenticator because, as I mentioned, such code only lasts 30 seconds.

Probably we should generate a specific authenticator token for e-mail/SMS and then use it if user wants to authenticate via e-mail/SMS.

This is not rocket science but not trivial, especially because it will require significant changes in the UI, a new step in UI will be required to show the options for 2fa authentication with options like "receive code via e-mail", "use authenticator app", etc.

2 Likes