diff --git a/ActiveDirectory.dnn b/ActiveDirectory.dnn index da783ad..6c00f65 100644 --- a/ActiveDirectory.dnn +++ b/ActiveDirectory.dnn @@ -1,6 +1,6 @@  - + DNN_ActiveDirectoryAuthentication The DotNetNuke Active Directory Authentication Project is an Authentication provider for DotNetNuke that uses the Windows Active Directory authentication protocol to authenticate users. @@ -33,7 +33,7 @@ bin\Providers DotNetNuke.Authentication.ActiveDirectory.dll - 06.01.02 + 07.00.00 bin diff --git a/AssemblyInfo.vb b/AssemblyInfo.vb index 7bfa0fe..b594a34 100644 --- a/AssemblyInfo.vb +++ b/AssemblyInfo.vb @@ -12,7 +12,7 @@ Imports System.Runtime.InteropServices - + @@ -29,7 +29,7 @@ Imports System.Runtime.InteropServices ' ' You can specify all the values or you can default the Build and Revision Numbers ' by using the '*' as shown below: -' +' - - + + diff --git a/Components/AuthenticationController.vb b/Components/AuthenticationController.vb index ee4d21a..a764350 100644 --- a/Components/AuthenticationController.vb +++ b/Components/AuthenticationController.vb @@ -36,6 +36,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory Private ReadOnly _mProviderTypeName As String = "" Private ReadOnly _portalSettings As PortalSettings + Private _config As Configuration = Configuration.GetConfig() ''' ------------------------------------------------------------------- ''' @@ -47,9 +48,9 @@ Namespace DotNetNuke.Authentication.ActiveDirectory ''' ''' ------------------------------------------------------------------- Sub New() - Dim config As Configuration = Configuration.GetConfig() + _portalSettings = PortalController.Instance.GetCurrentPortalSettings - _mProviderTypeName = config.ProviderTypeName + _mProviderTypeName = _config.ProviderTypeName End Sub ''' ------------------------------------------------------------------- @@ -136,7 +137,14 @@ Namespace DotNetNuke.Authentication.ActiveDirectory End If End If End If + 'debug logging issue #54 steven west 2/6/2019 + If _config.EnableDebugMode Then + Utilities.objEventLog.AddLog("Description", "@AUTHENTICATIONLOGON:Dumping redirect url: URL:" & strUrl, _portalSettings, -1, Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT) + End If HttpContext.Current.Response.Redirect(strUrl, True) + Else + 'added error issue #54 steven west 2/6/2019 + LogException(New Exception("There was an error trying to create user account: " & loggedOnUserName)) End If Else ' Not Windows Authentication @@ -180,6 +188,41 @@ Namespace DotNetNuke.Authentication.ActiveDirectory End Function + ''' ------------------------------------------------------------------- + ''' + ''' + ''' + ''' + ''' + ''' [sawest] 02/06/2019 Created for issue #56 long upn names + ''' + ''' + ''' ------------------------------------------------------------------- + Public Function UPNManualLogon(ByVal userName As String, ByVal strPassword As String, + ByRef loginStatus As UserLoginStatus, ByVal ipAddress As String) As UserInfo + Dim objAuthUser As ADUserInfo = ProcessFormAuthentication(userName, strPassword) + Dim _config As Configuration = Configuration.GetConfig() + Dim objUser As UserInfo = Nothing + Dim objReturnUser As UserInfo = Nothing + + If (userName.Length > 0) And (objAuthUser IsNot Nothing) Then + If _config.StripDomainName Then + userName = Utilities.TrimUserDomainName(userName) + End If + objAuthUser.Username = userName + objUser = DNNUserController.GetUserByName(_portalSettings.PortalId, userName) + + objReturnUser = AuthenticateUser(objUser, objAuthUser, loginStatus, ipAddress) + If Not (objReturnUser Is Nothing) Then + objAuthUser.LastIPAddress = ipAddress + UpdateDNNUser(objReturnUser, objAuthUser) + End If + End If + + Return objReturnUser + + End Function + ''' ------------------------------------------------------------------- ''' ''' Process the authentication of the user whether they've logged in @@ -383,6 +426,12 @@ Namespace DotNetNuke.Authentication.ActiveDirectory OnUserCreateCompleted(args) 'Item 7703 + + 'debug logging issue #54 steven west 2/6/2019 + If _config.EnableDebugMode Then + Utilities.AddEventLog(_portalSettings, "@CREATEUSER:Dumping create status: CreateStatus: " & createStatus.ToString) + End If + If createStatus = UserCreateStatus.Success Or createStatus = UserCreateStatus.UserAlreadyRegistered Then loginStatus = UserLoginStatus.LOGIN_SUCCESS Else @@ -525,9 +574,9 @@ Namespace DotNetNuke.Authentication.ActiveDirectory If config.WindowsAuthentication Then Dim userName As String = loggedOnUserName - If config.StripDomainName Then - userName = Utilities.TrimUserDomainName(userName) - End If + 'If config.StripDomainName Then + ' userName = Utilities.TrimUserDomainName(userName) + 'End If Dim objAuthUser As ADUserInfo = objAuthUserController.GetUser(userName, loggedOnPassword) Return objAuthUser diff --git a/Components/Config/Configuration.vb b/Components/Config/Configuration.vb index 2712049..c6316e7 100644 --- a/Components/Config/Configuration.vb +++ b/Components/Config/Configuration.vb @@ -51,6 +51,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory Public Const AD_SEARCHBOTS As String = "AD_SearchBots" Public Const AD_SYNCPHOTO As String = "AD_SyncPhoto" Public Const AD_ENABLEAUTOLOGIN As String = "AD_ENABLEAUTOLOGIN" + Public Const AD_ENABLEDEBUGMODE As String = "AD_ENABLEDEBUGMODE" Private mPortalId As Integer @@ -75,6 +76,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory Private mBots As String = "" Private mPhoto As Boolean = False Private mEnableAutoLogin As Boolean = False + Private mEnableDebugMode As Boolean = False ''' ------------------------------------------------------------------- ''' @@ -92,6 +94,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory ''' [sawest] 12/16/2016 Added if contain statements. If a key was missing, an error was thrown in the try block and the rest of the settings did not load. ''' [sawest] 12/16/2016 Switched to using constants for setting names ''' [sawest] 01/02/2017 Added photo setting and constant + ''' [sawest] 02/06/2019 Added debug mode setting and constant ''' ''' ------------------------------------------------------------------- Sub New() @@ -160,6 +163,9 @@ Namespace DotNetNuke.Authentication.ActiveDirectory If CambrianSettings.ContainsKey(AD_ENABLEAUTOLOGIN) Then mEnableAutoLogin = CType(Null.GetNull(CambrianSettings(AD_ENABLEAUTOLOGIN), mEnableAutoLogin), Boolean) End If + If CambrianSettings.ContainsKey(AD_ENABLEDEBUGMODE) Then + mEnableDebugMode = CType(Null.GetNull(CambrianSettings(AD_ENABLEDEBUGMODE), mEnableDebugMode), Boolean) + End If End If Catch ex As Exception 'Log the exception @@ -251,7 +257,8 @@ Namespace DotNetNuke.Authentication.ActiveDirectory ByVal AutoCreateUsers As Boolean, ByVal Bots As String, ByVal Photo As Boolean, - ByVal EnableAutoLogin As Boolean) + ByVal EnableAutoLogin As Boolean, + ByVal EnableDebugMode As Boolean) Dim objSecurity As New PortalSecurity 'Item 8512 @@ -274,6 +281,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory PortalController.UpdatePortalSetting(PortalID, AD_SEARCHBOTS, If(String.IsNullOrEmpty(Bots), "", Bots)) PortalController.UpdatePortalSetting(PortalID, AD_SYNCPHOTO, Photo.ToString) PortalController.UpdatePortalSetting(PortalID, AD_ENABLEAUTOLOGIN, EnableAutoLogin.ToString) + PortalController.UpdatePortalSetting(PortalID, AD_ENABLEDEBUGMODE, EnableDebugMode.ToString) 'Only update password if it has been changed If AuthenticationPassword.Length > 0 Then PortalController.UpdatePortalSetting(PortalID, AD_AUTHENTICATIONPASSWORD, Convert.ToString(objSecurity.Encrypt(AUTHENTICATION_KEY, AuthenticationPassword))) @@ -635,6 +643,20 @@ Namespace DotNetNuke.Authentication.ActiveDirectory Return mEnableAutoLogin End Get End Property + ''' ------------------------------------------------------------------- + ''' + ''' + ''' + ''' + ''' + ''' [sawest] 02/06/2019 Created + ''' + ''' ------------------------------------------------------------------- + Public ReadOnly Property EnableDebugMode() As String + Get + Return mEnableDebugMode + End Get + End Property diff --git a/DotNetNuke.Authentication.ActiveDirectory.vbproj b/DotNetNuke.Authentication.ActiveDirectory.vbproj index 6b964ed..c9761c3 100644 --- a/DotNetNuke.Authentication.ActiveDirectory.vbproj +++ b/DotNetNuke.Authentication.ActiveDirectory.vbproj @@ -32,7 +32,7 @@ On - v4.0 + v4.5 false @@ -58,9 +58,9 @@ false - + False - ..\..\..\..\Sites\dnndev7\bin\DotNetNuke.dll + ..\..\..\..\Sites\dnndev80\bin\DotNetNuke.dll diff --git a/Login.ascx.vb b/Login.ascx.vb index a7b3ed7..72b5099 100644 --- a/Login.ascx.vb +++ b/Login.ascx.vb @@ -110,61 +110,64 @@ Namespace DotNetNuke.Authentication.ActiveDirectory Dim theUser As String = String.Empty Dim strDomain As String = String.Empty - Dim userinfo As String() + 'Dim userinfo As String() If Not String.IsNullOrEmpty(txtUsername.Text) Then - 'If UPN username provided, strip domain, translate to netBiOS - If txtUsername.Text.Contains("@") Then - - '***Changed Steven A West 1-11-2018 Bug fix #12 & #24 - theUser = ADSI.Utilities.UPNToLogonName0(txtUsername.Text.ToLower) - - '***Commented Out Steven A West 1-11-2018 Bug fix #12 & #24************** - ' userinfo = Split(txtUsername.Text, "@") - ' theUser = userinfo(0) - 'theUser = Left(txtUsername.Text, txtUsername.Text.IndexOf("@")) ***Changed Steven A West 2-25-2017 Bug fix #12 - ' strDomain = UCase(userinfo(1)) - - '***Changed Steven A West 2-25-2017 Bug fix #12 - 'strDomain = Right(txtUsername.Text, Len(txtUsername.Text) - (Len(theUser) + 1)).ToUpper - '***Changed Steven A West 8-29-2017 Bug fix #12 - 'If strDomain.Contains(sDefaultDomain) Then - ' theUser = Trim(sDefaultDomain).Replace("\", "") & "\" & theUser - 'Else - ' theUser = strDomain & "\" & theUser - 'End If - 'If Not String.IsNullOrEmpty(sDefaultDomain) Then - ' If strDomain.Contains(sDefaultDomain) Then - ' theUser = Trim(sDefaultDomain).Replace("\", "") & "\" & theUser - ' Else - ' theUser = strDomain & "\" & theUser - ' End If - 'End If - - '**************************************************************************** + 'Changing code for long UPN ability issue #56 sawest 2-6-2019 + 'needs to be cleaned up and removed in later version + + ''If UPN username provided, strip domain, translate to netBiOS + 'If txtUsername.Text.Contains("@") Then + + ' '***Changed Steven A West 1-11-2018 Bug fix #12 & #24 + ' theUser = ADSI.Utilities.UPNToLogonName0(txtUsername.Text.ToLower) + + ' '***Commented Out Steven A West 1-11-2018 Bug fix #12 & #24************** + ' ' userinfo = Split(txtUsername.Text, "@") + ' ' theUser = userinfo(0) + ' 'theUser = Left(txtUsername.Text, txtUsername.Text.IndexOf("@")) ***Changed Steven A West 2-25-2017 Bug fix #12 + ' ' strDomain = UCase(userinfo(1)) + + ' '***Changed Steven A West 2-25-2017 Bug fix #12 + ' 'strDomain = Right(txtUsername.Text, Len(txtUsername.Text) - (Len(theUser) + 1)).ToUpper + ' '***Changed Steven A West 8-29-2017 Bug fix #12 + ' 'If strDomain.Contains(sDefaultDomain) Then + ' ' theUser = Trim(sDefaultDomain).Replace("\", "") & "\" & theUser + ' 'Else + ' ' theUser = strDomain & "\" & theUser + ' 'End If + ' 'If Not String.IsNullOrEmpty(sDefaultDomain) Then + ' ' If strDomain.Contains(sDefaultDomain) Then + ' ' theUser = Trim(sDefaultDomain).Replace("\", "") & "\" & theUser + ' ' Else + ' ' theUser = strDomain & "\" & theUser + ' ' End If + ' 'End If + + ' '**************************************************************************** + 'Else + + 'If username doesn't contain the DOMAIN\ already and config uses Default Domain + 'Then prepend default domain as prefix + If (Not txtUsername.Text.Contains("\")) And (sDefaultDomain <> "" And Not txtUsername.Text.Contains("@")) Then + theUser = Trim(sDefaultDomain).Replace("\", "") & "\" & txtUsername.Text Else - 'If username doesn't contain the DOMAIN\ already and config uses Default Domain - 'Then append default domain as prefix - If (Not txtUsername.Text.Contains("\")) And (sDefaultDomain <> "") Then - theUser = Trim(sDefaultDomain).Replace("\", "") & "\" & txtUsername.Text - Else - 'if username contains domain\ then check if domain provided is canonical and translate - If txtUsername.Text.Contains("\") Then - - '***Changed Steven A West 1-11-2018 Bug fix #12 & #24 - strDomain = UCase(Split(txtUsername.Text, "\")(0)) - theUser = UCase(Split(txtUsername.Text, "\")(1)) - If strDomain.Contains(".") Then 'canonical domain provided, translate - strDomain = ADSI.Utilities.CanonicalToNetBIOS(strDomain.ToLower) - End If - If Not String.IsNullOrEmpty(strDomain) Then - theUser = strDomain & "\" & theUser - End If - '******** - Else - 'no domain provided and no default domain set - theUser = txtUsername.Text + 'if username contains domain\ then check if domain provided is canonical and translate + If txtUsername.Text.Contains("\") And Not txtUsername.Text.Contains("@") Then + + '***Changed Steven A West 1-11-2018 Bug fix #12 & #24 + strDomain = UCase(Split(txtUsername.Text, "\")(0)) + theUser = UCase(Split(txtUsername.Text, "\")(1)) + If strDomain.Contains(".") Then 'canonical domain provided, translate + strDomain = ADSI.Utilities.CanonicalToNetBIOS(strDomain.ToLower) + End If + If Not String.IsNullOrEmpty(strDomain) Then + theUser = strDomain & "\" & theUser End If + '******** + Else + 'no domain provided and no default domain set or UPN given + theUser = txtUsername.Text End If End If End If @@ -277,9 +280,9 @@ Namespace DotNetNuke.Authentication.ActiveDirectory Dim loginStatus As UserLoginStatus = UserLoginStatus.LOGIN_FAILURE Dim objAuthentication As New AuthenticationController Dim objUser As DNNUserInfo = Nothing - If UserName.Contains("\") Then - objUser = objAuthentication.ManualLogon(UserName, txtPassword.Text, loginStatus, IPAddress) - End If + ' If UserName.Contains("\") Then + objUser = objAuthentication.ManualLogon(UserName, txtPassword.Text, loginStatus, IPAddress) + 'End If Dim authenticated As Boolean = Null.NullBoolean Dim message As String = Null.NullString authenticated = (loginStatus <> UserLoginStatus.LOGIN_FAILURE) diff --git a/Providers/ADSIProvider/ADSIProvider.vb b/Providers/ADSIProvider/ADSIProvider.vb index 7d1103d..7e373a9 100644 --- a/Providers/ADSIProvider/ADSIProvider.vb +++ b/Providers/ADSIProvider/ADSIProvider.vb @@ -223,7 +223,30 @@ Namespace DotNetNuke.Authentication.ActiveDirectory.ADSI End If Try + 'debug logging issue #54 steven west 2/6/2019 + If _config.EnableDebugMode Then + Utilities.objEventLog.AddLog("Description", "@GETUSER:Getting ready to getUserEntryByName. LoggedOnUserName: " & LoggedOnUserName, _portalSettings, -1, Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT) + End If Dim entry As DirectoryEntry = Utilities.GetUserEntryByName(LoggedOnUserName) + + 'debug logging issue #54 steven west 2/6/2019 + If _config.EnableDebugMode Then + If Not entry Is Nothing Then + Dim key As String + Dim entryStr As New StringBuilder + For Each key In entry.Properties.PropertyNames + Dim sPropertyValues As String = "" + For Each value As Object In entry.Properties(key) + sPropertyValues += Convert.ToString(value) + ";" + Next + sPropertyValues = sPropertyValues.Substring(0, sPropertyValues.Length - 1) + entryStr.AppendLine(key + "=" + sPropertyValues) + Next + Utilities.objEventLog.AddLog("Description", "@GETUSER:Successfully retrieved user entry by name. Username: " & LoggedOnUserName & " Entry object: " & entryStr.ToString, _portalSettings, -1, Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT) + Else + Utilities.objEventLog.AddLog("Description", "@GETUSER:Could not retrieve user entry by name. Username: " & LoggedOnUserName, _portalSettings, -1, Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT) + End If + End If #If DEBUG Then Dim key As String For Each key In entry.Properties.PropertyNames @@ -235,8 +258,8 @@ Namespace DotNetNuke.Authentication.ActiveDirectory.ADSI Debug.Print(key + "=" + sPropertyValues) Next #End If - 'Check authenticated - Dim path As String + 'Check authenticated + Dim path As String If Not entry Is Nothing Then path = entry.Path Else @@ -264,9 +287,18 @@ Namespace DotNetNuke.Authentication.ActiveDirectory.ADSI FillUserInfo(entry, objAuthUser) + 'debug logging issue #54 steven west 2/6/2019 + If _config.EnableDebugMode Then + Utilities.objEventLog.AddLog("Description", "@GETUSER:Successfully filled objAuthUser object. objAuthUser object JSON: " & Json.Serialize(Of ADUserInfo)(objAuthUser).ToString(), _portalSettings, -1, Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT) + End If + Return objAuthUser Catch exc As Exception + 'debug logging issue #54 steven west 2/6/2019 + If _config.EnableDebugMode Then + Utilities.objEventLog.AddLog("Description", "@GETUSER:ERROR:" & exc.Message, _portalSettings, -1, Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT) + End If LogException(exc) Return Nothing End Try diff --git a/Providers/ADSIProvider/Utilities.vb b/Providers/ADSIProvider/Utilities.vb index cc363a2..7399254 100644 --- a/Providers/ADSIProvider/Utilities.vb +++ b/Providers/ADSIProvider/Utilities.vb @@ -255,7 +255,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory.ADSI Public Shared Function GetUserEntryByName(ByVal Name As String) As DirectoryEntry ' Create search object then assign required params to get user entry in Active Directory Dim objSearch As New Search(GetRootDomain) - Dim userEntries As ArrayList + Dim userEntries As New ArrayList Dim userEntry As DirectoryEntry Dim userDomain As Domain @@ -263,7 +263,19 @@ Namespace DotNetNuke.Authentication.ActiveDirectory.ADSI .AddFilter(Configuration.ADSI_CLASS, CompareOperator.Is, ObjectClass.person.ToString) .AddFilter(Configuration.ADSI_ACCOUNTNAME, CompareOperator.Is, TrimUserDomainName(Name)) - userEntries = .GetEntries + For Each _entry In .GetEntries + userEntries.Add(_entry) + Next + + 'add ability to search by UPN for long usernames + .SearchFilters.Clear() + .AddFilter(Configuration.ADSI_CLASS, CompareOperator.Is, ObjectClass.person.ToString) + .AddFilter(Configuration.ADSI_UPN, CompareOperator.Is, Name) + + For Each _entry In .GetEntries + userEntries.Add(_entry) + Next + Select Case userEntries.Count Case 0 'Found no entry, return nothing diff --git a/Resources.zip b/Resources.zip index e00c305..57e0539 100644 Binary files a/Resources.zip and b/Resources.zip differ diff --git a/Settings.ascx b/Settings.ascx index bf5e6f0..40270d2 100644 --- a/Settings.ascx +++ b/Settings.ascx @@ -38,6 +38,10 @@ + + + + diff --git a/Settings.ascx.designer.vb b/Settings.ascx.designer.vb index d7429f9..6a27518 100644 --- a/Settings.ascx.designer.vb +++ b/Settings.ascx.designer.vb @@ -203,6 +203,33 @@ Namespace DotNetNuke.Authentication.ActiveDirectory ''' Protected WithEvents chkAutoCreate As Global.System.Web.UI.WebControls.CheckBox + ''' + '''Tr1 control. + ''' + ''' + '''Auto-generated field. + '''To modify move field declaration from designer file to code-behind file. + ''' + Protected WithEvents Tr1 As Global.System.Web.UI.HtmlControls.HtmlTableRow + + ''' + '''plDebugMode control. + ''' + ''' + '''Auto-generated field. + '''To modify move field declaration from designer file to code-behind file. + ''' + Protected WithEvents plDebugMode As Global.System.Web.UI.UserControl + + ''' + '''chkDebugMode control. + ''' + ''' + '''Auto-generated field. + '''To modify move field declaration from designer file to code-behind file. + ''' + Protected WithEvents chkDebugMode As Global.System.Web.UI.WebControls.CheckBox + ''' '''plStripDomainName control. ''' diff --git a/Settings.ascx.vb b/Settings.ascx.vb index ab1924b..c96fd57 100644 --- a/Settings.ascx.vb +++ b/Settings.ascx.vb @@ -135,7 +135,7 @@ Namespace DotNetNuke.Authentication.ActiveDirectory 'Code Cleanup If Not chkAuthentication.Checked Then Configuration.UpdateConfig(_portalSettings.PortalId, False, False, "", "", "", "", False, False, - False, "", "", "", "", False, "", False, False) + False, "", "", "", "", False, "", False, False, False) Configuration.ResetConfig() Else Dim providerTypeName As String = cboProviders.SelectedItem.Value @@ -154,14 +154,16 @@ Namespace DotNetNuke.Authentication.ActiveDirectory txtPassword.Text, chkSynchronizeRole.Checked, chkSynchronizePassword.Checked, chkStripDomainName.Checked, providerTypeName, authenticationType, txtAutoIP.Text, - txtDefaultDomain.Text, chkAutoCreate.Checked, txtBots.Text, chkSynchronizePhoto.Checked, chkAutoLogin.Checked) + txtDefaultDomain.Text, chkAutoCreate.Checked, txtBots.Text, + chkSynchronizePhoto.Checked, chkAutoLogin.Checked, chkDebugMode.Checked) Else Configuration.UpdateConfig(_portalSettings.PortalId, False, chkHidden.Checked, txtRootDomain.Text, txtEmailDomain.Text, txtUserName.Text, txtPassword.Text, chkSynchronizeRole.Checked, chkSynchronizePassword.Checked, chkStripDomainName.Checked, providerTypeName, authenticationType, - txtAutoIP.Text, txtDefaultDomain.Text, chkAutoCreate.Checked, txtBots.Text, chkSynchronizePhoto.Checked, chkAutoLogin.Checked) + txtAutoIP.Text, txtDefaultDomain.Text, chkAutoCreate.Checked, txtBots.Text, + chkSynchronizePhoto.Checked, chkAutoLogin.Checked, chkDebugMode.Checked) End If Configuration.ResetConfig() Dim objAuthenticationController As New AuthenticationController @@ -258,6 +260,9 @@ Namespace DotNetNuke.Authentication.ActiveDirectory txtDefaultDomain.Text = config.DefaultDomain 'ACD-4259 chkAutoCreate.Checked = config.AutoCreateUsers + chkAutoLogin.Checked = config.EnableAutoLogin + chkDebugMode.Checked = config.EnableDebugMode + 'WorkItems 4766 and 4077 txtBots.Text = config.Bots If (txtBots.Text = "") Then diff --git a/version.txt b/version.txt index c72014b..9cac065 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -6.1.2.19 \ No newline at end of file +7.0.0.13 \ No newline at end of file