/// <summary> /// Send one-time-pin /// </summary> public async Task <SendPinDto> SendPinAsync(SendPinInput input) { if (string.IsNullOrWhiteSpace(input.SendTo)) { throw new Exception($"{input.SendTo} must be specified"); } // generate new pin and save var otp = new OtpDto() { OperationId = Guid.NewGuid(), Pin = _otpGenerator.GeneratePin(), SendTo = input.SendTo, SendType = input.SendType, RecipientId = input.RecipientId, RecipientType = input.RecipientType, ActionType = input.ActionType, }; // send otp if (_otpSettings.IgnoreOtpValidation) { otp.SendStatus = OtpSendStatus.Ignored; } else { try { otp.SentOn = DateTime.Now; await SendInternal(otp); otp.SendStatus = OtpSendStatus.Sent; } catch (Exception e) { otp.SendStatus = OtpSendStatus.Failed; otp.ErrorMessage = e.FullMessage(); } } // set expiration and save var lifeTime = input.Lifetime ?? _otpSettings.DefaultLifetime; if (lifeTime == 0) { lifeTime = OtpSettingProvider.DefaultLifetime; } otp.ExpiresOn = DateTime.Now.AddSeconds(lifeTime); await _otpStorage.SaveAsync(otp); // return response var response = new SendPinDto { OperationId = otp.OperationId, SentTo = otp.SendTo }; return(response); }