diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a84b8d..9c9cc2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 1.4.1 (2017-06-02) + +This is a bug-fixing release only + +### Fixed + +- \#86 Error when opening KeeAnywhere Settings 1.4.0 +- \#87 Authentication failed with Google Drive +- \#88 Google Drive: can't open/save database to/from root folder + + ## 1.4.0 (2017-05-31) This release brings two new features: Offline-Caching and Simple Automatic Backup. diff --git a/KeeAnywhere/Configuration/ConfigurationService.cs b/KeeAnywhere/Configuration/ConfigurationService.cs index 009b859..d04907b 100644 --- a/KeeAnywhere/Configuration/ConfigurationService.cs +++ b/KeeAnywhere/Configuration/ConfigurationService.cs @@ -158,6 +158,9 @@ private void LoadPluginConfiguration() this.PluginConfiguration.BackupToLocalFolder = Path.Combine(AppConfigSerializer.LocalAppDataDirectory, "KeeAnywhereBackups"); } + + if (this.PluginConfiguration.BackupCopies < 1) + this.PluginConfiguration.BackupCopies = 10; } private void SavePluginConfiguration() diff --git a/KeeAnywhere/OAuth2/IOAuth2Provider.cs b/KeeAnywhere/OAuth2/IOAuth2Provider.cs index aa56c74..5c3c1a8 100644 --- a/KeeAnywhere/OAuth2/IOAuth2Provider.cs +++ b/KeeAnywhere/OAuth2/IOAuth2Provider.cs @@ -9,6 +9,7 @@ namespace KeeAnywhere.OAuth2 public interface IOAuth2Provider { Task Initialize(); + bool CanClaim(Uri uri, string documentTitle); Task Claim(Uri uri, string documentTitle); Uri PreAuthorizationUrl { get; } diff --git a/KeeAnywhere/OAuth2/OAuth2Form.cs b/KeeAnywhere/OAuth2/OAuth2Form.cs index cd7b15d..339f35f 100644 --- a/KeeAnywhere/OAuth2/OAuth2Form.cs +++ b/KeeAnywhere/OAuth2/OAuth2Form.cs @@ -10,6 +10,7 @@ public partial class OAuth2Form : Form { private IOAuth2Provider m_provider; private bool m_isPreAuthorization; + private bool m_isClaimed; public OAuth2Form() { @@ -70,15 +71,16 @@ private async void OnNavigated(object sender, WebBrowserNavigatedEventArgs e) return; } - - // we need to ignore all navigation that isn't to the redirect uri. - if (!e.Url.ToString().StartsWith(m_provider.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase)) + // we need to ignore all navigation that is already claimed or could not be claimed (due to missing code). + if (m_isClaimed || !m_provider.CanClaim(e.Url, m_browser.DocumentTitle)) { return; } - m_pnlWait.Visible = true; + m_isClaimed = true; + m_browser.Stop(); m_browser.Visible = false; + m_pnlWait.Visible = true; try { @@ -92,7 +94,6 @@ private async void OnNavigated(object sender, WebBrowserNavigatedEventArgs e) } finally { - m_browser.Stop(); Close(); } } diff --git a/KeeAnywhere/Properties/AssemblyInfo.cs b/KeeAnywhere/Properties/AssemblyInfo.cs index 0a837c3..017a908 100644 --- a/KeeAnywhere/Properties/AssemblyInfo.cs +++ b/KeeAnywhere/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: //[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] -[assembly: AssemblyInformationalVersion("1.4.0")] +[assembly: AssemblyVersion("1.4.1.0")] +[assembly: AssemblyFileVersion("1.4.1.0")] +[assembly: AssemblyInformationalVersion("1.4.1")] diff --git a/KeeAnywhere/StorageProviders/AmazonDrive/AmazonDriveStorageConfigurator.cs b/KeeAnywhere/StorageProviders/AmazonDrive/AmazonDriveStorageConfigurator.cs index 56342d5..cb50469 100644 --- a/KeeAnywhere/StorageProviders/AmazonDrive/AmazonDriveStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/AmazonDrive/AmazonDriveStorageConfigurator.cs @@ -48,6 +48,11 @@ public async Task Initialize() this.AuthorizationUrl = new Uri(loginUri); } + public bool CanClaim(Uri uri, string documentTitle) + { + return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); + } + public async Task Claim(Uri uri, string documentTitle) { var error = HttpUtility.ParseQueryString(uri.Query).Get("error_description"); diff --git a/KeeAnywhere/StorageProviders/Box/BoxStorageConfigurator.cs b/KeeAnywhere/StorageProviders/Box/BoxStorageConfigurator.cs index b615909..93d86e9 100644 --- a/KeeAnywhere/StorageProviders/Box/BoxStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/Box/BoxStorageConfigurator.cs @@ -35,6 +35,11 @@ public async Task Initialize() this.AuthorizationUrl = BoxHelper.Config.AuthCodeUri; } + public bool CanClaim(Uri uri, string documentTitle) + { + return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); + } + public async Task Claim(Uri uri, string documentTitle) { IDictionary keyDictionary = new Dictionary(); diff --git a/KeeAnywhere/StorageProviders/Dropbox/DropboxStorageConfigurator.cs b/KeeAnywhere/StorageProviders/Dropbox/DropboxStorageConfigurator.cs index 27760af..10e293b 100644 --- a/KeeAnywhere/StorageProviders/Dropbox/DropboxStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/Dropbox/DropboxStorageConfigurator.cs @@ -45,6 +45,11 @@ public async Task Initialize() _isAccessRestricted ? DropboxHelper.DropboxAppFolderOnlyClientId : DropboxHelper.DropboxFullAccessClientId, RedirectionUrl, _state); } + public bool CanClaim(Uri uri, string documentTitle) + { + return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); + } + public Task Claim(Uri uri, string documentTitle) { var cs = new TaskCompletionSource(); diff --git a/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageConfigurator.cs b/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageConfigurator.cs index b40f8c1..8b2e911 100644 --- a/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageConfigurator.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web; @@ -45,18 +46,22 @@ public async Task Initialize() this.RedirectionUrl = new Uri(GoogleAuthConsts.ApprovalUrl); } - public async Task Claim(Uri uri, string documentTitle) + public bool CanClaim(Uri uri, string documentTitle) { - var parts = HttpUtility.ParseQueryString(uri.Query); - - if (parts.Count < 1 || parts.Get("response") == null) + if (!uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase)) return false; - var code = parts.Get("response"); - if (!code.Contains("code")) - return false; + return GetCodeFromDocumentTitle(documentTitle) != null || GetCodeFromUri(uri) != null; + } - code = code.Split('=')[1]; + public async Task Claim(Uri uri, string documentTitle) + { + var code = GetCodeFromDocumentTitle(documentTitle); + if (code == null) + code = GetCodeFromUri(uri); + + if (code == null) + return false; try { @@ -76,5 +81,54 @@ public async Task Claim(Uri uri, string documentTitle) public Uri AuthorizationUrl { get; protected set; } public Uri RedirectionUrl { get; protected set; } public string FriendlyProviderName { get { return "Google Drive"; } } + + private string GetCodeFromDocumentTitle(string documentTitle) + { + try + { + if (string.IsNullOrEmpty(documentTitle) || + !documentTitle.StartsWith("Success code=")) + { + return null; + } + + var parts = documentTitle.Split(' '); + + //if (parts.Length < 1 || parts[0] != "Success") + // return null; + + var code = parts[1].Split('=')[1]; + + return code; + } + catch + { + return null; + } + } + + private string GetCodeFromUri(Uri uri) + { + try + { + var parts = HttpUtility.ParseQueryString(uri.Query); + + if (parts.Count < 1 || parts.AllKeys.All(p => p != "response")) + return null; + + var code = parts.Get("response"); + if (code == null || !code.StartsWith("code=")) + return null; + + code = code.Split('=')[1]; + + return code; + } + catch + { + return null; + } + } + } } \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageProvider.cs b/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageProvider.cs index f8e3d4a..ec65e94 100644 --- a/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageProvider.cs +++ b/KeeAnywhere/StorageProviders/GoogleDrive/GoogleDriveStorageProvider.cs @@ -59,16 +59,20 @@ public async Task Save(Stream stream, string path) var folderName = CloudPath.GetDirectoryName(path); var fileName = CloudPath.GetFileName(path); - var folder = await api.GetFileByPath(folderName); - if (folder == null) - throw new InvalidOperationException(string.Format("Folder does not exist: {0}", folderName)); - file = new File() { - Name = fileName, - Parents = new[] {folder.Id}, + Name = fileName }; + if (!string.IsNullOrEmpty(folderName)) + { + var folder = await api.GetFileByPath(folderName); + if (folder == null) + throw new InvalidOperationException(string.Format("Folder does not exist: {0}", folderName)); + + file.Parents = new[] {folder.Id}; + } + progress = await api.Files.Create(file, stream, "application/octet-stream").UploadAsync(); } diff --git a/KeeAnywhere/StorageProviders/HiDrive/HiDriveStorageConfigurator.cs b/KeeAnywhere/StorageProviders/HiDrive/HiDriveStorageConfigurator.cs index ca912c6..ffb111a 100644 --- a/KeeAnywhere/StorageProviders/HiDrive/HiDriveStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/HiDrive/HiDriveStorageConfigurator.cs @@ -47,6 +47,11 @@ public async Task Initialize() this.RedirectionUrl = new Uri(HiDriveHelper.RedirectUri); } + public bool CanClaim(Uri uri, string documentTitle) + { + return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); + } + public async Task Claim(Uri uri, string documentTitle) { var code = _authenticator.GetAuthorizationCodeFromResponseUrl(uri); diff --git a/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs b/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs index f114571..3a42204 100644 --- a/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs @@ -34,6 +34,11 @@ public async Task Initialize() this.RedirectionUrl = new Uri(HubiCHelper.RedirectUri); } + public bool CanClaim(Uri uri, string documentTitle) + { + return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); + } + public async Task Claim(Uri uri, string documentTitle) { //_token = HubiCHelper.GetAccessTokenFromFragment(uri); diff --git a/KeeAnywhere/StorageProviders/OneDrive/OneDriveStorageConfigurator.cs b/KeeAnywhere/StorageProviders/OneDrive/OneDriveStorageConfigurator.cs index 05c677b..0900ff3 100644 --- a/KeeAnywhere/StorageProviders/OneDrive/OneDriveStorageConfigurator.cs +++ b/KeeAnywhere/StorageProviders/OneDrive/OneDriveStorageConfigurator.cs @@ -40,6 +40,11 @@ public async Task Initialize() this.AuthorizationUrl = new Uri(url); } + public bool CanClaim(Uri uri, string documentTitle) + { + return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); + } + public async Task Claim(Uri uri, string documentTitle) { var authenticationResponseValues = UrlHelper.GetQueryOptions(uri); diff --git a/build.cmd b/build.cmd index 8b7f4c3..33f7630 100644 --- a/build.cmd +++ b/build.cmd @@ -1,5 +1,5 @@ @echo off -set version=1.4.0 +set version=1.4.1 set zip="packages\7-Zip.CommandLine.9.20.0\tools\7za.exe" set msbuildcmd="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsMSBuildCmd.bat" diff --git a/chocolatey/keepass-plugin-keeanywhere.nuspec b/chocolatey/keepass-plugin-keeanywhere.nuspec index d8964b0..2533bd3 100644 --- a/chocolatey/keepass-plugin-keeanywhere.nuspec +++ b/chocolatey/keepass-plugin-keeanywhere.nuspec @@ -3,7 +3,7 @@ keepass-plugin-keeanywhere KeePass Plugin KeeAnywhere - 1.4.0 + 1.4.1 Daniel Bölts Kyrodan Plugin for KeePass 2.x to to add support for cloud storage providers @@ -31,7 +31,18 @@ Supported providers: © 2015-2017 Daniel Bölts https://github.com/Kyrodan/KeeAnywhere/blob/master/LICENSE false - ## 1.4.0 (2017-05-31) + ## 1.4.1 (2017-06-02) + + This is a bug-fixing release only + + ### Fixed + + - \#86 Error when opening KeeAnywhere Settings 1.4.0 + - \#87 Authentication failed with Google Drive + - \#88 Google Drive: can't open/save database to/from root folder + + + ## 1.4.0 (2017-05-31) This release brings two new features: Offline-Caching and Simple Automatic Backup. diff --git a/version_manifest.txt b/version_manifest.txt index d4fcc92..a7b97db 100644 --- a/version_manifest.txt +++ b/version_manifest.txt @@ -1,3 +1,3 @@ : -KeeAnywhere:1.4.0.0 +KeeAnywhere:1.4.1.0 : \ No newline at end of file