public void VerifyTokenWorksWithMultiplePendingRequests() { var emailCredential = Factors.ForUser(_userAccount).CreateCredential <EmailFeatureType>(_userEmailAddress); var verificationResult = Factors.ForUser(_userAccount).VerifyToken <EmailFeatureType>(emailCredential.TokenRequestId.Value, emailCredential.TokenDetails.VerificationToken); Assert.IsTrue(verificationResult.Success); var totalCredentialsCreated = 0; var tokenRequestPos = new Random().Next(25, 75); FactorsTokenRequestResult tokenRequest = null; while (totalCredentialsCreated < 100 || tokenRequest == null) { totalCredentialsCreated++; if (totalCredentialsCreated == tokenRequestPos) { tokenRequest = Factors.ForUser(_userAccount).BeginTokenRequest <EmailFeatureType>(_userEmailAddress); } else { Factors.ForUser(_userAccount).BeginTokenRequest <EmailFeatureType>(_userEmailAddress); } } var tokenResult = Factors.ForUser(_userAccount).VerifyToken <EmailFeatureType>(tokenRequest.TokenRequestId.Value, tokenRequest.TokenDetails.VerificationToken); Assert.IsTrue(tokenResult.Success); }
private async Task <FactorsTokenRequestResult> BeginTokenRequestAsync(IFactorsApplication instance, string credentialKey, bool runAsAsync, params KeyValuePair <string, string>[] parameters) { // // Sets up our return model on the event of a successful // credential creation // var credentialResult = new FactorsTokenRequestResult { IsSuccess = true, Message = "Validation token sent to credential", }; // // Check to see if this request is for sending out a message // by phone call. If it is, validate phone call handling is configured // and abort if it's not configured // var sendAsPhoneCall = parameters?.Any(p => p.Key == "phonecall" && p.Value == "true") == true; if (sendAsPhoneCall && (!_configuration.EnablePhoneCallSupport || _configuration.PhoneCallInboundEndpoint == null)) { return(new FactorsTokenRequestResult { IsSuccess = false, Message = "Phone call support is currently not enabled, please enable first before attempting to use" }); } // // Make sure we have a matching credential in the database, even // if it's an unverified one // var credentialList = runAsAsync ? await instance.Configuration.StorageDatabase.ListCredentialsForAsync(instance.UserAccount, _featureType, FactorsCredentialListQueryType.AllAccount).ConfigureAwait(false) : instance.Configuration.StorageDatabase.ListCredentialsFor(instance.UserAccount, _featureType, FactorsCredentialListQueryType.AllAccount); if (credentialList?.Any(cd => String.Equals(cd.CredentialKey, credentialKey, StringComparison.InvariantCultureIgnoreCase)) != true) { return(new FactorsTokenRequestResult { IsSuccess = false, Message = $"There was an issue when sending out the token: Unable to identify user account is setup for email tokens" }); } // // Generates a new token to be used to verify the credential // var newToken = instance.Configuration.TokenProvider.GenerateToken(); // // Stores the new token in the database // var tokenDetails = new FactorsCredentialGeneratedToken { UserAccountId = instance.UserAccount, VerificationToken = newToken, FeatureTypeGuid = _featureType.FeatureGuid, ExpirationDateUtc = DateTime.UtcNow.Add(_configuration.TokenExpirationTime), CredentialKey = credentialKey }; credentialResult.TokenDetails = runAsAsync ? await instance.Configuration.StorageDatabase.StoreTokenAsync(tokenDetails).ConfigureAwait(false) : instance.Configuration.StorageDatabase.StoreToken(tokenDetails); // // Generate the outbound message text // var messageText = _configuration.TextMessageTemplate .Replace("@APPNAME@", instance.Configuration.ApplicationName) .Replace("@APPCODE@", newToken); // // Send out the verification token to the user's phone number // var messageSendResult = runAsAsync ? await SendTokenMessageAsync(credentialKey, messageText, newToken, sendAsPhoneCall).ConfigureAwait(false) : SendTokenMessage(credentialKey, messageText, newToken, sendAsPhoneCall); if (!messageSendResult.IsSuccess) { return(new FactorsTokenRequestResult { IsSuccess = false, Message = messageSendResult.Message }); } // // And finally return our result // return(credentialResult); }
private async Task <FactorsTokenRequestResult> BeginTokenRequestAsync(IFactorsApplication instance, string credentialKey, bool runAsAsync, params KeyValuePair <string, string>[] parameters) { // // Sets up our return model on the event of a successful // credential creation // var credentialResult = new FactorsTokenRequestResult { IsSuccess = true, Message = "Validation token sent to credential", }; // // Make sure we have a matching credential in the database, even // if it's an unverified one // var credentialList = runAsAsync ? await instance.Configuration.StorageDatabase.ListCredentialsForAsync(instance.UserAccount, _featureType, FactorsCredentialListQueryType.AllAccount).ConfigureAwait(false) : instance.Configuration.StorageDatabase.ListCredentialsFor(instance.UserAccount, _featureType, FactorsCredentialListQueryType.AllAccount); if (credentialList?.Any(cd => String.Equals(cd.CredentialKey, credentialKey, StringComparison.InvariantCultureIgnoreCase)) != true) { return(new FactorsTokenRequestResult { IsSuccess = false, Message = $"There was an issue when sending out the token: Unable to identify user account is setup for email tokens" }); } // // Generates a new token to be used to verify the credential // var newToken = instance.Configuration.TokenProvider.GenerateToken(); // // Stores the new token in the database // var tokenDetails = new FactorsCredentialGeneratedToken { UserAccountId = instance.UserAccount, VerificationToken = newToken, FeatureTypeGuid = _featureType.FeatureGuid, ExpirationDateUtc = DateTime.UtcNow.Add(_configuration.TokenExpirationTime), CredentialKey = credentialKey }; credentialResult.TokenDetails = runAsAsync ? await instance.Configuration.StorageDatabase.StoreTokenAsync(tokenDetails).ConfigureAwait(false) : instance.Configuration.StorageDatabase.StoreToken(tokenDetails); // // Send out the verification token to the user's email address // var messageSendResult = runAsAsync ? await SendTokenMessageAsync(credentialKey, newToken).ConfigureAwait(false) : SendTokenMessage(credentialKey, newToken); if (!messageSendResult.IsSuccess) { return(new FactorsTokenRequestResult { IsSuccess = false, Message = messageSendResult.Message }); } // // And finally return our result // return(credentialResult); }