diff --git a/.gitignore b/.gitignore index 47a9505..fdc52b9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ buildd.err buildd.log buildd.prf buildd.wrn +*.binlog data/ objd/ public/lock diff --git a/src/Build.Common.StandardAndLegacy.props b/src/Build.Common.StandardAndLegacy.props index 663c988..1822113 100644 --- a/src/Build.Common.StandardAndLegacy.props +++ b/src/Build.Common.StandardAndLegacy.props @@ -4,7 +4,7 @@ - net5.0;net48;net462 + net6.0;net48;net462 netstandard2.0;net48;net462 false diff --git a/src/Build.Shared.props b/src/Build.Shared.props index 57c87db..66f3140 100644 --- a/src/Build.Shared.props +++ b/src/Build.Shared.props @@ -1,15 +1,19 @@ + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.9.1 + 2.10.0 3.19.8 4.35.1 4.7.9489-v9.0-master 4.7.9409-v9.0-master 4.6.6061-weekly-2108.5 4.7.6346-master - 11.0.2 + 13.0.1 2.3.20 9.0.2.42 9.0.2.34 @@ -19,9 +23,11 @@ 3.1.8 + 17.2.0 + 2.2.10 4.16.0 2.4.1 - 2.4.3 + 2.4.5 5.10.3 diff --git a/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs b/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs index f458e12..03849a9 100644 --- a/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs +++ b/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs @@ -14,7 +14,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Auth { internal class MSALHttpRetryHandlerHelper : DelegatingHandler { - private readonly int MaxRetryCount = ClientServiceProviders.Instance.GetService>().Value.MsalRetryCount; + private readonly int MaxRetryCount = ClientServiceProviders.Instance.GetService>().Value.MSALRetryCount; /// /// Handel Failure and retry diff --git a/src/GeneralTools/DataverseClient/Client/ConnectionService.cs b/src/GeneralTools/DataverseClient/Client/ConnectionService.cs index df4c126..3a322ec 100644 --- a/src/GeneralTools/DataverseClient/Client/ConnectionService.cs +++ b/src/GeneralTools/DataverseClient/Client/ConnectionService.cs @@ -1320,20 +1320,20 @@ private async Task InitServiceAsync() return null; } - // Do a WHO AM I request to make sure the connection is good. - if (!UseExternalConnection) - { - Guid guIntialTrackingID = Guid.NewGuid(); - logEntry.Log(string.Format("Beginning Validation of Dataverse Connection. RequestID: {0}", guIntialTrackingID.ToString())); - dtQueryTimer.Restart(); - user = await GetWhoAmIDetails(dvService, guIntialTrackingID).ConfigureAwait(false); - dtQueryTimer.Stop(); - logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Validation of Dataverse Connection Complete, total duration: {0}", dtQueryTimer.Elapsed.ToString())); - } - else - { - logEntry.Log("External Dataverse Connection Provided, Skipping Validation"); - } + //// Do a WHO AM I request to make sure the connection is good. + //if (!UseExternalConnection) + //{ + // Guid guIntialTrackingID = Guid.NewGuid(); + // logEntry.Log(string.Format("Beginning Validation of Dataverse Connection. RequestID: {0}", guIntialTrackingID.ToString())); + // dtQueryTimer.Restart(); + // user = await GetWhoAmIDetails(dvService, guIntialTrackingID).ConfigureAwait(false); + // dtQueryTimer.Stop(); + // logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Validation of Dataverse Connection Complete, total duration: {0}", dtQueryTimer.Elapsed.ToString())); + //} + //else + //{ + // logEntry.Log("External Dataverse Connection Provided, Skipping Validation"); + //} return (IOrganizationService)dvService; @@ -1528,11 +1528,11 @@ private async Task RefreshInstanceDetails(IOrganizationService dvService, Uri ur var request = new RetrieveCurrentOrganizationRequest() { AccessType = 0, RequestId = trackingID }; RetrieveCurrentOrganizationResponse resp; - logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - RetrieveCurrentOrganizationRequest : RequestId={0}", dtQueryTimer.Elapsed.ToString())); + logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - RetrieveCurrentOrganizationRequest : RequestId={0}", trackingID)); if (_configuration.Value.UseWebApiLoginFlow) { OrganizationResponse orgResp = await Command_WebAPIProcess_ExecuteAsync( - request, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken(), uriOfInstance).ConfigureAwait(false); + request, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken(), uriOfInstance, true).ConfigureAwait(false); try { resp = (RetrieveCurrentOrganizationResponse)orgResp; @@ -1643,7 +1643,7 @@ internal async Task GetWhoAmIDetails(IOrganizationService dvServ if (_configuration.Value.UseWebApiLoginFlow) { resp = (WhoAmIResponse)(await Command_WebAPIProcess_ExecuteAsync( - req, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken()).ConfigureAwait(false)); + req, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken(), inLoginFlow:true).ConfigureAwait(false)); } else { @@ -1738,11 +1738,11 @@ internal void SetClonedProperties(ServiceClient sourceClient) #region WebAPI Interface Utilities internal async Task Command_WebAPIProcess_ExecuteAsync(OrganizationRequest req, string logMessageTag, bool bypassPluginExecution, - MetadataUtility metadataUtlity, Guid callerId, bool disableConnectionLocking, int maxRetryCount, TimeSpan retryPauseTime, CancellationToken cancellationToken, Uri uriOfInstance = null) + MetadataUtility metadataUtlity, Guid callerId, bool disableConnectionLocking, int maxRetryCount, TimeSpan retryPauseTime, CancellationToken cancellationToken, Uri uriOfInstance = null, bool inLoginFlow = false) { cancellationToken.ThrowIfCancellationRequested(); - if (!Utilities.IsRequestValidForTranslationToWebAPI(req)) // THIS WILL GET REMOVED AT SOME POINT, TEMP FOR TRANSTION //TODO:REMOVE ON COMPELTE + if (!Utilities.IsRequestValidForTranslationToWebAPI(req , inLoginFlow)) // THIS WILL GET REMOVED AT SOME POINT, TEMP FOR TRANSTION //TODO:REMOVE ON COMPELTE { logEntry.Log("Execute Organization Request failed, WebAPI is only supported for limited type of messages at this time.", TraceEventType.Error); return null; @@ -1927,7 +1927,6 @@ internal async Task Command_WebAPIProcess_ExecuteAsync(Org { postUri = $"{postUri}?{addedQueryParams}"; } - // Execute request var sResp = await Command_WebExecuteAsync(postUri, bodyOfRequest, methodToExecute, headers, "application/json", logMessageTag, callerId, disableConnectionLocking, maxRetryCount, retryPauseTime, uriOfInstance, cancellationToken: cancellationToken).ConfigureAwait(false); if (sResp != null && sResp.IsSuccessStatusCode) @@ -1962,7 +1961,6 @@ internal async Task Command_WebAPIProcess_ExecuteAsync(Org else { var json = await sResp.Content.ReadAsStringAsync().ConfigureAwait(false); - if (_knownTypesFactory.TryCreate($"{req.RequestName}Response", out var response, json)) { OrganizationResponse resp = (OrganizationResponse)response; diff --git a/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs b/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs index 5275b9f..3a41cae 100644 --- a/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs +++ b/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs @@ -24,7 +24,7 @@ internal sealed class DataverseTraceLogger : TraceLoggerBase // Internal connection of exceptions since last clear. private List _ActiveExceptionsList; - private ILogger _logger; + internal ILogger _logger; #region Properties /// @@ -318,9 +318,9 @@ public void LogFailure(OrganizationRequest req, Guid requestTrackingId, Guid? se internal string GetFormatedRequestSessionIdString( Guid requestId, Guid? sessionId ) { - return string.Format("RequestID={0} {1}", + return string.Format("RequestID={0}{1}", requestId.ToString(), - sessionId.HasValue && sessionId.Value != Guid.Empty ? $": SessionID={sessionId.Value.ToString()} : " : ""); + sessionId.HasValue && sessionId.Value != Guid.Empty ? $" : SessionID={sessionId.Value.ToString()} : " : ""); } /// diff --git a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs index 30bf9ac..f4fccfb 100644 --- a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs +++ b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs @@ -390,7 +390,7 @@ internal WhoAmIResponse SystemUser return _connectionSvc.CurrentUser; else { - WhoAmIResponse resp = _connectionSvc.GetWhoAmIDetails(this).ConfigureAwait(false).GetAwaiter().GetResult(); + WhoAmIResponse resp = Task.Run(async () => await _connectionSvc.GetWhoAmIDetails(this).ConfigureAwait(false)).Result; _connectionSvc.CurrentUser = resp; return resp; } @@ -1056,6 +1056,11 @@ internal void ConnectToService(string connectionString, ILogger logger = null) MakeSecureString(password), domainname, string.Empty, string.Empty, useSsl, parsedConnStr.UseUniqueConnectionInstance, null, instanceUrl: parsedConnStr.SkipDiscovery ? parsedConnStr.ServiceUri : null, externalLogger: logger); break; + case AuthenticationType.ExternalTokenManagement: + CreateServiceConnection(null, parsedConnStr.AuthenticationType, string.Empty, string.Empty, string.Empty, null, + string.Empty, null, string.Empty, string.Empty, string.Empty, true, parsedConnStr.UseUniqueConnectionInstance, null, + string.Empty, null, PromptBehavior.Never, null, string.Empty, StoreName.My, null, parsedConnStr.ServiceUri, externalLogger: logger); + break; } } @@ -1369,6 +1374,7 @@ public ServiceClient Clone(System.Reflection.Assembly strongTypeAsm, ILogger log { // Get Current Access Token. // This will get the current access token + if (logger == null) logger = _logEntry._logger; proxy.HeaderToken = this.CurrentAccessToken; var SvcClient = new ServiceClient(proxy, true, _connectionSvc.AuthenticationTypeInUse, _connectionSvc?.OrganizationVersion, logger: logger); SvcClient._connectionSvc.SetClonedProperties(this); diff --git a/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs b/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs index a7746f2..06ac16a 100644 --- a/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs +++ b/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs @@ -264,11 +264,15 @@ public static bool IsValidOnlineHost(Uri hostUri) /// This is a temp method to support the staged transition to the webAPI and will be removed or reintegrated with the overall pipeline at some point in the future. /// /// + /// /// - internal static bool IsRequestValidForTranslationToWebAPI(OrganizationRequest req) + internal static bool IsRequestValidForTranslationToWebAPI(OrganizationRequest req, bool inLoginFlow = false) { bool useWebApi = ClientServiceProviders.Instance.GetService>().Value.UseWebApi; - bool useWebApiForLogin = ClientServiceProviders.Instance.GetService>().Value.UseWebApiLoginFlow; + bool useWebApiForLogin = false; + if (inLoginFlow) + useWebApiForLogin = ClientServiceProviders.Instance.GetService>().Value.UseWebApiLoginFlow; + switch (req.RequestName.ToLowerInvariant()) { case "create": diff --git a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj index d809a2f..09247a6 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj @@ -11,14 +11,14 @@ - + - + - + diff --git a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs index 224ccf9..d4ad14e 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs +++ b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs @@ -816,6 +816,50 @@ public void ConnectUsingServiceIdentity_ClientSecret_Consetup() ValidateConnection(client); } + [SkippableConnectionTest] + [Trait("Category", "Live Connect Required")] + public void ConnectUsingServiceIdentity_ClientSecret_ExternalAuth_CtorV1() + { + System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; + var Conn_Url = System.Environment.GetEnvironmentVariable("XUNITCONNTESTURI"); + + // Connection params. + var client = new ServiceClient(new Uri(Conn_Url), testSupport.GetS2SAccessTokenForRequest , true, Ilogger); + Assert.True(client.IsReady, "Failed to Create Connection via Constructor"); + + // Validate connection + ValidateConnection(client , usingExternalAuth:true); + } + + [SkippableConnectionTest] + [Trait("Category", "Live Connect Required")] + public void ConnectUsingServiceIdentity_ClientSecret_ExternalAuth_Consetup() + { + System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; + + ConnectionOptions connectionOptions = new ConnectionOptions() + { + AccessTokenProviderFunctionAsync = testSupport.GetS2SAccessTokenForRequest, + ServiceUri = new Uri(System.Environment.GetEnvironmentVariable("XUNITCONNTESTURI")), + Logger = Ilogger + }; + + // Connection params. + var client = new ServiceClient(connectionOptions, deferConnection: true); + Assert.NotNull(client); + Assert.False(client.IsReady, "Client is showing True on Deferred Connection."); + Assert.True(client.Connect(), "Connection was not activated"); + Assert.True(client.IsReady, "Failed to Create Connection via Constructor"); + + // Validate connection + ValidateConnection(client , usingExternalAuth:true); + + // test clone + var clientClone = client.Clone(); + ValidateConnection(clientClone, usingExternalAuth: true); + } + + /// /// This Tests connection for UID/PW via connection string - direct connect. /// @@ -977,9 +1021,10 @@ public void ConnectUsingUserIdentity_UIDPW_ConSetup() #region connectionValidationHelper - private void ValidateConnection(ServiceClient client) + private void ValidateConnection(ServiceClient client , bool usingExternalAuth = false) { - client._connectionSvc.AuthContext.Should().NotBeNull(); + if (!usingExternalAuth) + client._connectionSvc.AuthContext.Should().NotBeNull(); // Validate it var rslt = client.Execute(new WhoAmIRequest()); diff --git a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/TestSupport.cs b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/TestSupport.cs index f365e5f..d145bae 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/TestSupport.cs +++ b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/TestSupport.cs @@ -1,5 +1,6 @@ -using Microsoft.Crm.Sdk.Messages; +using Microsoft.Crm.Sdk.Messages; using Microsoft.Extensions.Logging; +using Microsoft.Identity.Client; using Microsoft.PowerPlatform.Dataverse.Client; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Messages; @@ -14,6 +15,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Xunit; namespace Client_Core_UnitTests { @@ -28,6 +30,13 @@ public class TestSupport public Uri _SampleAppRedirect = new Uri("app://58145B91-0C36-4500-8554-080854F2AC97"); #endregion + private readonly string TenantId = System.Environment.GetEnvironmentVariable("XUNITCONNTESTTENANT"); + private readonly string S2SAppId = System.Environment.GetEnvironmentVariable("XUNITCONNTESTAPPID"); + private readonly string S2SAppSecret = System.Environment.GetEnvironmentVariable("XUNITCONNTESTSECRET"); + private readonly List Scopes = new List(); + private IConfidentialClientApplication cApp = null; + + public ILogger logger { get; set; } #region BoilerPlate @@ -200,5 +209,39 @@ private void SetupMetadataHandlersForAccount(Mock orgSvc) #endregion + #region ExternalAuthHandler + + public async Task GetS2SAccessTokenForRequest(string targetUrl) + { + if (cApp == null) + { + Assert.NotNull(TenantId); + Assert.NotNull(S2SAppId); + Assert.NotNull(S2SAppSecret); + + // This is purposed for Client Secret only... + cApp = ConfidentialClientApplicationBuilder.CreateWithApplicationOptions( + new ConfidentialClientApplicationOptions() + { + ClientId = S2SAppId + }) + .WithTenantId(TenantId) + .WithClientSecret(S2SAppSecret) + .Build(); + } + + // Set up scope. + Uri baseUri = new Uri(targetUrl); + Scopes.Clear(); + Scopes.Add($"{baseUri.Scheme}://{baseUri.DnsSafeHost}/.default"); + + // Get token. + var authResult = await cApp.AcquireTokenForClient(Scopes).ExecuteAsync().ConfigureAwait(false); + + return authResult.AccessToken; + } + + #endregion + } } diff --git a/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj b/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj index ed9c80c..a30ebb5 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj @@ -14,9 +14,9 @@ - + - + diff --git a/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj b/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj index 1167584..b43a06e 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj b/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj index d201006..31e247d 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.ReleaseNotes.txt b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.ReleaseNotes.txt index 786139e..3b6b303 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.ReleaseNotes.txt +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.ReleaseNotes.txt @@ -3,6 +3,9 @@ Notice: This package is intended to work with .net full framework 4.6.2, 4.7.2 and 4.8, .net 3.1, net 5, and .net 6.0 ++CURRENTRELEASEID++ + No updates + +1.0.1: updated min dependency to DV ServiceClient 1.0.0 0.5.10: diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec index 9e0961f..bdba207 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec @@ -9,7 +9,7 @@ https://github.com/microsoft/PowerPlatform-DataverseServiceClient images\Dataverse.128x128.png true - This package contains the preview of the .net core ServiceClient Dynamics Extensions. Used to connect to Microsoft Dataverse. This Package has been authored by the Microsoft Dataverse SDK team. + This package contains the .net core ServiceClient Dynamics Extensions. Used to connect to Microsoft Dataverse. This Package has been authored by the Microsoft Dataverse SDK team. ServiceClient and supporting libraries for use in building client applications to interact with the Dataverse © Microsoft Corporation. All rights reserved. Dynamics CommonDataService CDS PowerApps PowerPlatform ServiceClient Dataverse diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt index 7b52b46..a2750dd 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt @@ -7,6 +7,12 @@ Notice: Note: Only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time. ++CURRENTRELEASEID++ +Fixed an issue with External Authentication and Connection and configuration constructor where external auth was not being respected correctly. +Fixed a bug on clone where Ilogger was not being propagated to the cloned connection correctly +Removed a call to WhoAmI during login flow as process of talking to Dataverse to verify the connection is delt with during get environment information call. +Updated Newtonsoft dependencies to 13.0.1 per https://github.com/advisories/GHSA-5crp-9r3c-p9vr + +1.0.1: Fixed a "Duplicate Key Error" issue created when manually adding some request parameters to an organization request, while also setting the appropriate property in the client Fix formatting issue with RequestId and Session Id. Fix exponential back off issue for WebAPI based calls when retrying based on a throttled connection. diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec index 8cc0c4f..e1744b0 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec @@ -22,7 +22,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -71,7 +71,7 @@ - + diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.ConnectControl.ReleaseNotes.txt b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.ConnectControl.ReleaseNotes.txt index 74f964e..06d0dd6 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.ConnectControl.ReleaseNotes.txt +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.ConnectControl.ReleaseNotes.txt @@ -3,4 +3,7 @@ Notice: This package is intended to work with .net full framework 4.6.2, 4.7.2 and 4.8 ++CURRENTRELEASEID++ +No Updates + +1.0.1: Initial release