public async Task StartEmailValidation(string emailToValidate, User user, App app, PlatformDataClaim?platformDataClaim, string acceptUrl, string declineUrl, IAsyncDocumentSession session, string platformId = "None", CancellationToken cancellationToken = default) { emailToValidate = emailToValidate.ToLowerInvariant(); var existingUserEmail = user.UserEmails.SingleOrDefault(ue => ue.Email == emailToValidate); if (existingUserEmail == null) { user.UserEmails.Add(new UserEmail(emailToValidate, UserEmailState.AwaitingVerification)); } var existingPromptsForEmail = await session.Query <EmailPrompt>() .Where(ep => ep.EmailAddress == emailToValidate, true).ToListAsync(cancellationToken); if (existingPromptsForEmail.Any()) { var unexpiredPrompt = existingPromptsForEmail.SingleOrDefault(p => !p.HasExpired()); if (unexpiredPrompt != null) { if (!unexpiredPrompt.PlatformIdToAppId.ContainsKey(platformId)) { unexpiredPrompt.PlatformIdToAppId.Add(platformId, new List <string>()); } if (unexpiredPrompt.PlatformIdToAppId[platformId].All(appId => appId != app.Id)) { unexpiredPrompt.PlatformIdToAppId[platformId].Add(app.Id); } } } var promptId = Guid.NewGuid(); var expiresAt = DateTimeOffset.UtcNow.AddHours(48).ToUnixTimeSeconds(); acceptUrl = acceptUrl.Replace("{promptId}", promptId.ToString()); declineUrl = declineUrl.Replace("{promptId}", promptId.ToString()); await _mailManager.SendConfirmEmailAddressMail(emailToValidate, acceptUrl, declineUrl, cancellationToken); var createdPrompt = new EmailPrompt(promptId, user.Id, emailToValidate, expiresAt, app.Id, platformId, platformDataClaim); await session.StoreAsync(createdPrompt, cancellationToken); }